|
5 | 5 | "strings"
|
6 | 6 |
|
7 | 7 | "github.com/google/uuid"
|
| 8 | + "github.com/open-policy-agent/opa/ast" |
8 | 9 |
|
9 | 10 | "golang.org/x/xerrors"
|
10 | 11 | )
|
@@ -128,86 +129,100 @@ func ReloadBuiltinRoles(opts *RoleOptions) {
|
128 | 129 | )
|
129 | 130 | }
|
130 | 131 |
|
| 132 | + // Static roles that never change should be allocated in a closure. |
| 133 | + // This is to ensure these data structures are only allocated once and not |
| 134 | + // on every authorize call. 'withCachedRegoValue' can be used as well to |
| 135 | + // preallocate the rego value that is used by the rego eval engine. |
| 136 | + ownerRole := Role{ |
| 137 | + Name: owner, |
| 138 | + DisplayName: "Owner", |
| 139 | + Site: allPermsExcept(ownerAndAdminExceptions...), |
| 140 | + Org: map[string][]Permission{}, |
| 141 | + User: []Permission{}, |
| 142 | + }.withCachedRegoValue() |
| 143 | + |
| 144 | + memberRole := Role{ |
| 145 | + Name: member, |
| 146 | + DisplayName: "", |
| 147 | + Site: Permissions(map[string][]Action{ |
| 148 | + // All users can read all other users and know they exist. |
| 149 | + ResourceUser.Type: {ActionRead}, |
| 150 | + ResourceRoleAssignment.Type: {ActionRead}, |
| 151 | + // All users can see the provisioner daemons. |
| 152 | + ResourceProvisionerDaemon.Type: {ActionRead}, |
| 153 | + }), |
| 154 | + Org: map[string][]Permission{}, |
| 155 | + User: allPermsExcept(), |
| 156 | + }.withCachedRegoValue() |
| 157 | + |
| 158 | + auditorRole := Role{ |
| 159 | + Name: auditor, |
| 160 | + DisplayName: "Auditor", |
| 161 | + Site: Permissions(map[string][]Action{ |
| 162 | + // Should be able to read all template details, even in orgs they |
| 163 | + // are not in. |
| 164 | + ResourceTemplate.Type: {ActionRead}, |
| 165 | + ResourceAuditLog.Type: {ActionRead}, |
| 166 | + }), |
| 167 | + Org: map[string][]Permission{}, |
| 168 | + User: []Permission{}, |
| 169 | + }.withCachedRegoValue() |
| 170 | + |
| 171 | + templateAdminRole := Role{ |
| 172 | + Name: templateAdmin, |
| 173 | + DisplayName: "Template Admin", |
| 174 | + Site: Permissions(map[string][]Action{ |
| 175 | + ResourceTemplate.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
| 176 | + // CRUD all files, even those they did not upload. |
| 177 | + ResourceFile.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
| 178 | + ResourceWorkspace.Type: {ActionRead}, |
| 179 | + // CRUD to provisioner daemons for now. |
| 180 | + ResourceProvisionerDaemon.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
| 181 | + // Needs to read all organizations since |
| 182 | + ResourceOrganization.Type: {ActionRead}, |
| 183 | + }), |
| 184 | + Org: map[string][]Permission{}, |
| 185 | + User: []Permission{}, |
| 186 | + }.withCachedRegoValue() |
| 187 | + |
| 188 | + userAdminRole := Role{ |
| 189 | + Name: userAdmin, |
| 190 | + DisplayName: "User Admin", |
| 191 | + Site: Permissions(map[string][]Action{ |
| 192 | + ResourceRoleAssignment.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
| 193 | + ResourceUser.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
| 194 | + // Full perms to manage org members |
| 195 | + ResourceOrganizationMember.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
| 196 | + ResourceGroup.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
| 197 | + }), |
| 198 | + Org: map[string][]Permission{}, |
| 199 | + User: []Permission{}, |
| 200 | + }.withCachedRegoValue() |
| 201 | + |
131 | 202 | builtInRoles = map[string]func(orgID string) Role{
|
132 | 203 | // admin grants all actions to all resources.
|
133 | 204 | owner: func(_ string) Role {
|
134 |
| - return Role{ |
135 |
| - Name: owner, |
136 |
| - DisplayName: "Owner", |
137 |
| - Site: allPermsExcept(ownerAndAdminExceptions...), |
138 |
| - Org: map[string][]Permission{}, |
139 |
| - User: []Permission{}, |
140 |
| - } |
| 205 | + return ownerRole |
141 | 206 | },
|
142 | 207 |
|
143 | 208 | // member grants all actions to all resources owned by the user
|
144 | 209 | member: func(_ string) Role {
|
145 |
| - return Role{ |
146 |
| - Name: member, |
147 |
| - DisplayName: "", |
148 |
| - Site: Permissions(map[string][]Action{ |
149 |
| - // All users can read all other users and know they exist. |
150 |
| - ResourceUser.Type: {ActionRead}, |
151 |
| - ResourceRoleAssignment.Type: {ActionRead}, |
152 |
| - // All users can see the provisioner daemons. |
153 |
| - ResourceProvisionerDaemon.Type: {ActionRead}, |
154 |
| - }), |
155 |
| - Org: map[string][]Permission{}, |
156 |
| - User: allPermsExcept(), |
157 |
| - } |
| 210 | + return memberRole |
158 | 211 | },
|
159 | 212 |
|
160 | 213 | // auditor provides all permissions required to effectively read and understand
|
161 | 214 | // audit log events.
|
162 | 215 | // TODO: Finish the auditor as we add resources.
|
163 | 216 | auditor: func(_ string) Role {
|
164 |
| - return Role{ |
165 |
| - Name: auditor, |
166 |
| - DisplayName: "Auditor", |
167 |
| - Site: Permissions(map[string][]Action{ |
168 |
| - // Should be able to read all template details, even in orgs they |
169 |
| - // are not in. |
170 |
| - ResourceTemplate.Type: {ActionRead}, |
171 |
| - ResourceAuditLog.Type: {ActionRead}, |
172 |
| - }), |
173 |
| - Org: map[string][]Permission{}, |
174 |
| - User: []Permission{}, |
175 |
| - } |
| 217 | + return auditorRole |
176 | 218 | },
|
177 | 219 |
|
178 | 220 | templateAdmin: func(_ string) Role {
|
179 |
| - return Role{ |
180 |
| - Name: templateAdmin, |
181 |
| - DisplayName: "Template Admin", |
182 |
| - Site: Permissions(map[string][]Action{ |
183 |
| - ResourceTemplate.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
184 |
| - // CRUD all files, even those they did not upload. |
185 |
| - ResourceFile.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
186 |
| - ResourceWorkspace.Type: {ActionRead}, |
187 |
| - // CRUD to provisioner daemons for now. |
188 |
| - ResourceProvisionerDaemon.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
189 |
| - // Needs to read all organizations since |
190 |
| - ResourceOrganization.Type: {ActionRead}, |
191 |
| - }), |
192 |
| - Org: map[string][]Permission{}, |
193 |
| - User: []Permission{}, |
194 |
| - } |
| 221 | + return templateAdminRole |
195 | 222 | },
|
196 | 223 |
|
197 | 224 | userAdmin: func(_ string) Role {
|
198 |
| - return Role{ |
199 |
| - Name: userAdmin, |
200 |
| - DisplayName: "User Admin", |
201 |
| - Site: Permissions(map[string][]Action{ |
202 |
| - ResourceRoleAssignment.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
203 |
| - ResourceUser.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
204 |
| - // Full perms to manage org members |
205 |
| - ResourceOrganizationMember.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
206 |
| - ResourceGroup.Type: {ActionCreate, ActionRead, ActionUpdate, ActionDelete}, |
207 |
| - }), |
208 |
| - Org: map[string][]Permission{}, |
209 |
| - User: []Permission{}, |
210 |
| - } |
| 225 | + return userAdminRole |
211 | 226 | },
|
212 | 227 |
|
213 | 228 | // orgAdmin returns a role with all actions allows in a given
|
@@ -333,6 +348,10 @@ type Role struct {
|
333 | 348 | // roles.
|
334 | 349 | Org map[string][]Permission `json:"org"`
|
335 | 350 | User []Permission `json:"user"`
|
| 351 | + |
| 352 | + // cachedRegoValue can be used to cache the rego value for this role. |
| 353 | + // This is helpful for static roles that never change. |
| 354 | + cachedRegoValue ast.Value |
336 | 355 | }
|
337 | 356 |
|
338 | 357 | type Roles []Role
|
|
0 commit comments