@@ -61,24 +61,48 @@ number(set) := c if {
61
61
c:= 1
62
62
}
63
63
64
+ prebuild_workspace_type:= " prebuilt_workspace"
65
+ default_object_set:= [input.object.type," *" ]
66
+
67
+ is_prebuild_workspace:= true if {
68
+ input.object.type= " workspace"
69
+ input.object.owner= " c42fdf75-3097-471c-8c33-fb52454d81c0"
70
+ }
71
+
64
72
# site, org, and user rules are all similar. Each rule should return a number
65
73
# from [-1, 1]. The number corresponds to "negative", "abstain", and "positive"
66
74
# for the given level. See the 'allow' rules for how these numbers are used.
67
75
default site:= 0
68
76
69
- site:= site_allow (input.subject.roles)
77
+ site:= num if {
78
+ not is_prebuild_workspace
79
+ num:= site_allow (input.subject.roles, default_object_set)
80
+ }
81
+
82
+ site:= num if {
83
+ is_prebuild_workspace
84
+ num:= site_allow (input.subject.roles, [input.object.type," *" , prebuild_workspace_type])
85
+ }
70
86
71
87
default scope_site:= 0
72
88
73
- scope_site:= site_allow ([input.subject.scope])
89
+ scope_site:= num if {
90
+ is_prebuild_workspace
91
+ num:= site_allow ([input.subject.scope], default_object_set)
92
+ }
93
+
94
+ scope_site:= num if {
95
+ not is_prebuild_workspace
96
+ num:= site_allow ([input.subject.scope], [input.object.type," *" , prebuild_workspace_type])
97
+ }
74
98
75
- site_allow (roles):= num if {
99
+ site_allow (roles, object_set ):= num if {
76
100
# allow is a set of boolean values without duplicates.
77
101
allow:= {x|
78
102
# Iterate over all site permissions in all roles
79
103
perm:= roles[_].site[_]
80
104
perm.action in [input.action," *" ]
81
- perm.resource_type in [input.object.type, " * " ]
105
+ perm.resource_type in object_set
82
106
83
107
# x is either 'true' or 'false' if a matching permission exists.
84
108
x:= bool_flip (perm.negate)
@@ -95,11 +119,27 @@ org_members := {orgID |
95
119
# that the actor is a member of.
96
120
default org:= 0
97
121
98
- org:= org_allow (input.subject.roles)
122
+ org:= num if {
123
+ not is_prebuild_workspace
124
+ num:= org_allow (input.subject.roles, default_object_set)
125
+ }
126
+
127
+ org:= num if {
128
+ is_prebuild_workspace
129
+ num:= org_allow (input.subject.roles, [input.object.type," *" , prebuild_workspace_type])
130
+ }
99
131
100
132
default scope_org:= 0
101
133
102
- scope_org:= org_allow ([input.scope])
134
+ scope_org:= num if {
135
+ not is_prebuild_workspace
136
+ num:= org_allow ([input.subject.scope], default_object_set)
137
+ }
138
+
139
+ scope_org:= num if {
140
+ is_prebuild_workspace
141
+ num:= org_allow ([input.subject.scope], [input.object.type," *" , prebuild_workspace_type])
142
+ }
103
143
104
144
# org_allow_set is a helper function that iterates over all orgs that the actor
105
145
# is a member of. For each organization it sets the numerical allow value
@@ -111,24 +151,24 @@ scope_org := org_allow([input.scope])
111
151
# The reason we calculate this for all orgs, and not just the input.object.org_owner
112
152
# is that sometimes the input.object.org_owner is unknown. In those cases
113
153
# we have a list of org_ids that can we use in a SQL 'WHERE' clause.
114
- org_allow_set (roles):= allow_set if {
154
+ org_allow_set (roles, object_set ):= allow_set if {
115
155
allow_set:= {id: num|
116
156
id:= org_members[_]
117
157
set:= {x|
118
158
perm:= roles[_].org[id][_]
119
159
perm.action in [input.action," *" ]
120
- perm.resource_type in [input.object.type, " * " ]
160
+ perm.resource_type in object_set
121
161
x:= bool_flip (perm.negate)
122
162
}
123
163
num:= number (set)
124
164
}
125
165
}
126
166
127
- org_allow (roles):= num if {
167
+ org_allow (roles, object_set ):= num if {
128
168
# If the object has "any_org" set to true, then use the other
129
169
# org_allow block.
130
170
not input.object.any_org
131
- allow:= org_allow_set (roles)
171
+ allow:= org_allow_set (roles, object_set )
132
172
133
173
# Return only the org value of the input's org.
134
174
# The reason why we do not do this up front, is that we need to make sure
@@ -144,9 +184,9 @@ org_allow(roles) := num if {
144
184
# This is useful for UI elements when we want to conclude, "Can the user create
145
185
# a new template in any organization?"
146
186
# It is easier than iterating over every organization the user is apart of.
147
- org_allow (roles):= num if {
187
+ org_allow (roles, object_set ):= num if {
148
188
input.object.any_org# if this is false, this code block is not used
149
- allow:= org_allow_set (roles)
189
+ allow:= org_allow_set (roles, object_set )
150
190
151
191
# allow is a map of {"<org_id>": <number>}. We only care about values
152
192
# that are 1, and ignore the rest.
@@ -195,19 +235,35 @@ org_ok if {
195
235
# the user is apart of the org (if the object has an org).
196
236
default user:= 0
197
237
198
- user:= user_allow (input.subject.roles)
238
+ user:= num if {
239
+ not is_prebuild_workspace
240
+ num:= user_allow (input.subject.roles, default_object_set)
241
+ }
242
+
243
+ user:= num if {
244
+ is_prebuild_workspace
245
+ num:= user_allow (input.subject.roles, [input.object.type," *" , prebuild_workspace_type])
246
+ }
199
247
200
248
default user_scope:= 0
201
249
202
- scope_user:= user_allow ([input.scope])
250
+ scope_user:= num if {
251
+ not is_prebuild_workspace
252
+ num:= user_allow ([input.subject.scope], default_object_set)
253
+ }
254
+
255
+ scope_user:= num if {
256
+ is_prebuild_workspace
257
+ num:= user_allow ([input.subject.scope], [input.object.type," *" , prebuild_workspace_type])
258
+ }
203
259
204
- user_allow (roles):= num if {
260
+ user_allow (roles, object_set ):= num if {
205
261
input.object.owner!= " "
206
262
input.subject.id= input.object.owner
207
263
allow:= {x|
208
264
perm:= roles[_].user[_]
209
265
perm.action in [input.action," *" ]
210
- perm.resource_type in [input.object.type, " * " ]
266
+ perm.resource_type in object_set
211
267
x:= bool_flip (perm.negate)
212
268
}
213
269
num:= number (allow)