github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/privilege/privilege.go (about)

     1  // Copyright 2015 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package privilege
    12  
    13  import (
    14  	"bytes"
    15  	"sort"
    16  	"strings"
    17  
    18  	"github.com/cockroachdb/errors"
    19  )
    20  
    21  //go:generate stringer -type=Kind
    22  
    23  // Kind defines a privilege. This is output by the parser,
    24  // and used to generate the privilege bitfields in the PrivilegeDescriptor.
    25  type Kind uint32
    26  
    27  // List of privileges. ALL is specifically encoded so that it will automatically
    28  // pick up new privileges.
    29  const (
    30  	_ Kind = iota
    31  	ALL
    32  	CREATE
    33  	DROP
    34  	GRANT
    35  	SELECT
    36  	INSERT
    37  	DELETE
    38  	UPDATE
    39  	ZONECONFIG
    40  )
    41  
    42  // Predefined sets of privileges.
    43  var (
    44  	ReadData      = List{GRANT, SELECT}
    45  	ReadWriteData = List{GRANT, SELECT, INSERT, DELETE, UPDATE}
    46  )
    47  
    48  // Mask returns the bitmask for a given privilege.
    49  func (k Kind) Mask() uint32 {
    50  	return 1 << k
    51  }
    52  
    53  // ByValue is just an array of privilege kinds sorted by value.
    54  var ByValue = [...]Kind{
    55  	ALL, CREATE, DROP, GRANT, SELECT, INSERT, DELETE, UPDATE, ZONECONFIG,
    56  }
    57  
    58  // ByName is a map of string -> kind value.
    59  var ByName = map[string]Kind{
    60  	"ALL":        ALL,
    61  	"CREATE":     CREATE,
    62  	"DROP":       DROP,
    63  	"GRANT":      GRANT,
    64  	"SELECT":     SELECT,
    65  	"INSERT":     INSERT,
    66  	"DELETE":     DELETE,
    67  	"UPDATE":     UPDATE,
    68  	"ZONECONFIG": ZONECONFIG,
    69  }
    70  
    71  // List is a list of privileges.
    72  type List []Kind
    73  
    74  // Len, Swap, and Less implement the Sort interface.
    75  func (pl List) Len() int {
    76  	return len(pl)
    77  }
    78  
    79  func (pl List) Swap(i, j int) {
    80  	pl[i], pl[j] = pl[j], pl[i]
    81  }
    82  
    83  func (pl List) Less(i, j int) bool {
    84  	return pl[i] < pl[j]
    85  }
    86  
    87  // names returns a list of privilege names in the same
    88  // order as 'pl'.
    89  func (pl List) names() []string {
    90  	ret := make([]string, len(pl))
    91  	for i, p := range pl {
    92  		ret[i] = p.String()
    93  	}
    94  	return ret
    95  }
    96  
    97  // Format prints out the list in a buffer.
    98  // This keeps the existing order and uses ", " as separator.
    99  func (pl List) Format(buf *bytes.Buffer) {
   100  	for i, p := range pl {
   101  		if i > 0 {
   102  			buf.WriteString(", ")
   103  		}
   104  		buf.WriteString(p.String())
   105  	}
   106  }
   107  
   108  // String implements the Stringer interface.
   109  // This keeps the existing order and uses ", " as separator.
   110  func (pl List) String() string {
   111  	return strings.Join(pl.names(), ", ")
   112  }
   113  
   114  // SortedString is similar to String() but returns
   115  // privileges sorted by name and uses "," as separator.
   116  func (pl List) SortedString() string {
   117  	names := pl.SortedNames()
   118  	return strings.Join(names, ",")
   119  }
   120  
   121  // SortedNames returns a list of privilege names
   122  // in sorted order.
   123  func (pl List) SortedNames() []string {
   124  	names := pl.names()
   125  	sort.Strings(names)
   126  	return names
   127  }
   128  
   129  // ToBitField returns the bitfield representation of
   130  // a list of privileges.
   131  func (pl List) ToBitField() uint32 {
   132  	var ret uint32
   133  	for _, p := range pl {
   134  		ret |= p.Mask()
   135  	}
   136  	return ret
   137  }
   138  
   139  // ListFromBitField takes a bitfield of privileges and
   140  // returns a list. It is ordered in increasing
   141  // value of privilege.Kind.
   142  func ListFromBitField(m uint32) List {
   143  	ret := List{}
   144  	for _, p := range ByValue {
   145  		if m&p.Mask() != 0 {
   146  			ret = append(ret, p)
   147  		}
   148  	}
   149  	return ret
   150  }
   151  
   152  // ListFromStrings takes a list of strings and attempts to build a list of Kind.
   153  // We convert each string to uppercase and search for it in the ByName map.
   154  // If an entry is not found in ByName, an error is returned.
   155  func ListFromStrings(strs []string) (List, error) {
   156  	ret := make(List, len(strs))
   157  	for i, s := range strs {
   158  		k, ok := ByName[strings.ToUpper(s)]
   159  		if !ok {
   160  			return nil, errors.Errorf("not a valid privilege: %q", s)
   161  		}
   162  		ret[i] = k
   163  	}
   164  	return ret, nil
   165  }