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 }