@@ -120,10 +120,10 @@ org_members := {orgID |
120
120
# 'org' is the same as 'site' except we need to iterate over each organization
121
121
# that the actor is a member of.
122
122
default org:= 0
123
- org:= org_allow (input.subject.roles)
123
+ org:= org_allow (input.subject.roles, " org " )
124
124
125
125
default scope_org:= 0
126
- scope_org:= org_allow ([input.subject.scope])
126
+ scope_org:= org_allow ([input.subject.scope], " org " )
127
127
128
128
# org_allow_set is a helper function that iterates over all orgs that the actor
129
129
# is a member of. For each organization it sets the numerical allow value
@@ -135,12 +135,12 @@ scope_org := org_allow([input.subject.scope])
135
135
# The reason we calculate this for all orgs, and not just the input.object.org_owner
136
136
# is that sometimes the input.object.org_owner is unknown. In those cases
137
137
# we have a list of org_ids that can we use in a SQL 'WHERE' clause.
138
- org_allow_set (roles):= allow_set if {
138
+ org_allow_set (roles, key ):= allow_set if {
139
139
allow_set:= {id: num|
140
140
id:= org_members[_]
141
141
set:= {is_allowed|
142
142
# Iterate over all org permissions in all roles
143
- perm:= roles[_].org [id][_]
143
+ perm:= roles[_][key] [id][_]
144
144
perm.action in [input.action," *" ]
145
145
perm.resource_type in [input.object.type," *" ]
146
146
@@ -151,11 +151,11 @@ org_allow_set(roles) := allow_set if {
151
151
}
152
152
}
153
153
154
- org_allow (roles):= num if {
154
+ org_allow (roles, key ):= num if {
155
155
# If the object has "any_org" set to true, then use the other
156
156
# org_allow block.
157
157
not input.object.any_org
158
- allow:= org_allow_set (roles)
158
+ allow:= org_allow_set (roles, key )
159
159
160
160
# Return only the org value of the input's org.
161
161
# The reason why we do not do this up front, is that we need to make sure
@@ -171,9 +171,9 @@ org_allow(roles) := num if {
171
171
# This is useful for UI elements when we want to conclude, "Can the user create
172
172
# a new template in any organization?"
173
173
# It is easier than iterating over every organization the user is apart of.
174
- org_allow (roles):= num if {
174
+ org_allow (roles, key ):= num if {
175
175
input.object.any_org# if this is false, this code block is not used
176
- allow:= org_allow_set (roles)
176
+ allow:= org_allow_set (roles, key )
177
177
178
178
# allow is a map of {"<org_id>": <number>}. We only care about values
179
179
# that are 1, and ignore the rest.
@@ -232,6 +232,8 @@ scope_user := user_allow([input.subject.scope])
232
232
233
233
user_allow (roles):= num if {
234
234
input.object.owner!= " "
235
+ # if there is an org, use org_member permissions instead
236
+ input.object.org_owner!= " "
235
237
input.subject.id= input.object.owner
236
238
237
239
allow:= {is_allowed|
@@ -250,35 +252,22 @@ user_allow(roles) := num if {
250
252
# Organization Member Owner Rules
251
253
# -------------------
252
254
253
- # 'org_member_owner' combines org membership and ownership requirements.
254
- # These rules only apply if:
255
- # 1. The user is a member of the organization the resource belongs to
256
- # 2. The user is the owner of the resource
257
- default org_member_owner:= 0
258
- org_member_owner:= org_member_owner_allow (input.subject.roles)
255
+ # 'org_member' applies if the object is owned by both the user and an organization.
256
+ # It replaces the `user` permissions in this case.
257
+ default org_member:= 0
258
+ org_member_owner:= num if {
259
+ # Object must be jointly owned by the user
260
+ input.object.owner!= " "
261
+ input.subject.id= input.object.owner
262
+ num:= org_allow (input.subject.roles," org_member" )
263
+ }
259
264
260
265
default scope_org_member_owner:= 0
261
- scope_org_member_owner:= org_member_owner_allow ([input.subject.scope])
262
-
263
- org_member_owner_allow (roles):= num if {
264
- # Must be the owner of the object
266
+ scope_org_member_owner:= num if {
267
+ # Object must be jointly owned by the user
265
268
input.object.owner!= " "
266
269
input.subject.id= input.object.owner
267
-
268
- # Must be a member of the organization
269
- input.object.org_owner!= " "
270
- input.object.org_owner in org_members
271
-
272
- allow:= {is_allowed|
273
- # Iterate over all org_member_owner permissions in all roles
274
- perm:= roles[_].org_member_owner[_]
275
- perm.action in [input.action," *" ]
276
- perm.resource_type in [input.object.type," *" ]
277
-
278
- # is_allowed is either 'true' or 'false' if a matching permission exists.
279
- is_allowed:= bool_flip (perm.negate)
280
- }
281
- num:= number (allow)
270
+ num:= org_allow ([input.subject.scope]," org_member" )
282
271
}
283
272
284
273
# Scope allow_list is a list of resource (Type, ID) tuples explicitly allowed by the scope.
@@ -320,16 +309,16 @@ scope_allow_list if {
320
309
# Role-Specific Rules
321
310
# -------------------
322
311
323
- role_allow if {
312
+ role_allow if {# site level authed
324
313
site= 1
325
314
}
326
315
327
- role_allow if {
316
+ role_allow if {# org level authed
328
317
not site= - 1
329
318
org= 1
330
319
}
331
320
332
- role_allow if {
321
+ role_allow if {# user level authed
333
322
not site= - 1
334
323
not org= - 1
335
324
@@ -339,31 +328,30 @@ role_allow if {
339
328
user= 1
340
329
}
341
330
342
- role_allow if {
331
+ role_allow if {# org member auth
343
332
not site= - 1
344
333
not org= - 1
345
- not user= - 1
346
334
347
335
# Organization member owner permissions require both ownership and org membership
348
- org_member_owner = 1
336
+ org_member = 1
349
337
}
350
338
351
339
# -------------------
352
340
# Scope-Specific Rules
353
341
# -------------------
354
342
355
- scope_allow if {
343
+ scope_allow if {# scope site level authed
356
344
scope_allow_list
357
345
scope_site= 1
358
346
}
359
347
360
- scope_allow if {
348
+ scope_allow if {# scope org level authed
361
349
scope_allow_list
362
350
not scope_site= - 1
363
351
scope_org= 1
364
352
}
365
353
366
- scope_allow if {
354
+ scope_allow if {# scope user level authed
367
355
scope_allow_list
368
356
not scope_site= - 1
369
357
not scope_org= - 1
@@ -374,11 +362,10 @@ scope_allow if {
374
362
scope_user= 1
375
363
}
376
364
377
- scope_allow if {
365
+ scope_allow if {# scope org member auth
378
366
scope_allow_list
379
367
not scope_site= - 1
380
368
not scope_org= - 1
381
- not scope_user= - 1
382
369
383
370
# Organization member owner permissions require both ownership and org membership
384
371
scope_org_member_owner= 1