1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
7 class PermissionTest < ActiveSupport::TestCase
8 include CurrentApiClient
10 test "Grant permissions on an object I own" do
11 set_user_from_auth :active_trustedclient
13 ob = Collection.create
16 # Ensure I have permission to manage this group even when its owner changes
17 perm_link = Link.create(tail_uuid: users(:active).uuid,
19 link_class: 'permission',
21 assert perm_link.save, "should give myself permission on my own object"
24 test "Delete permission links when deleting an object" do
25 set_user_from_auth :active_trustedclient
27 ob = Collection.create!
28 Link.create!(tail_uuid: users(:active).uuid,
30 link_class: 'permission',
33 assert ob.destroy, "Could not destroy object with 1 permission link"
34 assert_empty(Link.where(head_uuid: ob_uuid),
35 "Permission link was not deleted when object was deleted")
38 test "permission links owned by root" do
39 set_user_from_auth :active_trustedclient
40 ob = Collection.create!
41 perm_link = Link.create!(tail_uuid: users(:active).uuid,
43 link_class: 'permission',
45 assert_equal system_user_uuid, perm_link.owner_uuid
49 set_user_from_auth :active_trustedclient
51 ob = Collection.create!
52 Link.create!(tail_uuid: users(:active).uuid,
54 link_class: 'permission',
56 assert Collection.readable_by(users(:active)).where(uuid: ob.uuid).any?, "user does not have read permission"
60 set_user_from_auth :active_trustedclient
62 ob = Collection.create!
63 Link.create!(tail_uuid: users(:active).uuid,
65 link_class: 'permission',
67 assert ob.writable_by.include?(users(:active).uuid), "user does not have write permission"
70 test "update permission link" do
71 set_user_from_auth :admin
73 grp = Group.create! name: "blah project", group_class: "project"
74 ob = Collection.create! owner_uuid: grp.uuid
76 assert !users(:active).can?(write: ob)
77 assert !users(:active).can?(read: ob)
79 l1 = Link.create!(tail_uuid: users(:active).uuid,
81 link_class: 'permission',
84 assert users(:active).can?(write: ob)
85 assert users(:active).can?(read: ob)
87 l1.update_attributes!(name: 'can_read')
89 assert !users(:active).can?(write: ob)
90 assert users(:active).can?(read: ob)
94 assert !users(:active).can?(write: ob)
95 assert !users(:active).can?(read: ob)
98 test "writable_by reports requesting user's own uuid for a writable project" do
99 invited_to_write = users(:project_viewer)
100 group = groups(:asubproject)
102 # project_view can read, but cannot see write or see writers list
103 set_user_from_auth :project_viewer
104 assert_equal([group.owner_uuid],
106 "writers list should just have owner_uuid")
108 # allow project_viewer to write for the remainder of the test
109 set_user_from_auth :admin
110 Link.create!(tail_uuid: invited_to_write.uuid,
111 head_uuid: group.uuid,
112 link_class: 'permission',
114 group.permissions.reload
116 # project_viewer should see self in writers list (but not all writers)
117 set_user_from_auth :project_viewer
118 assert_not_nil(group.writable_by,
119 "can write but cannot see writers list")
120 assert_includes(group.writable_by, invited_to_write.uuid,
121 "self missing from writers list")
122 assert_includes(group.writable_by, group.owner_uuid,
123 "project owner missing from writers list")
124 refute_includes(group.writable_by, users(:active).uuid,
125 "saw :active user in writers list")
127 # active user should see full writers list
128 set_user_from_auth :active
129 assert_includes(group.writable_by, invited_to_write.uuid,
130 "permission just added, but missing from writers list")
132 # allow project_viewer to manage for the remainder of the test
133 set_user_from_auth :admin
134 Link.create!(tail_uuid: invited_to_write.uuid,
135 head_uuid: group.uuid,
136 link_class: 'permission',
138 # invite another writer we can test for
139 Link.create!(tail_uuid: users(:spectator).uuid,
140 head_uuid: group.uuid,
141 link_class: 'permission',
143 group.permissions.reload
145 set_user_from_auth :project_viewer
146 assert_not_nil(group.writable_by,
147 "can manage but cannot see writers list")
148 assert_includes(group.writable_by, users(:spectator).uuid,
149 ":spectator missing from writers list")
152 test "user owns group, group can_manage object's group, user can add permissions" do
153 set_user_from_auth :admin
155 owner_grp = Group.create!(owner_uuid: users(:active).uuid, group_class: "role")
156 sp_grp = Group.create!(group_class: "project")
158 Link.create!(link_class: 'permission',
160 tail_uuid: owner_grp.uuid,
161 head_uuid: sp_grp.uuid)
163 sp = Collection.create!(owner_uuid: sp_grp.uuid)
165 # active user owns owner_grp, which has can_manage permission on sp_grp
166 # user should be able to add permissions on sp.
167 set_user_from_auth :active_trustedclient
168 test_perm = Link.create(tail_uuid: users(:active).uuid,
170 link_class: 'permission',
172 assert test_perm.save, "could not save new permission on target object"
173 assert test_perm.destroy, "could not delete new permission on target object"
177 skip "can_manage permission on a non-group object" do
178 set_user_from_auth :admin
180 ob = Collection.create!
181 # grant can_manage permission to active
182 perm_link = Link.create!(tail_uuid: users(:active).uuid,
184 link_class: 'permission',
186 # ob is owned by :admin, the link is owned by root
187 assert_equal users(:admin).uuid, ob.owner_uuid
188 assert_equal system_user_uuid, perm_link.owner_uuid
190 # user "active" can modify the permission link
191 set_user_from_auth :active_trustedclient
192 perm_link.properties["foo"] = 'bar'
193 assert perm_link.save, "could not save modified link"
195 assert_equal 'bar', perm_link.properties['foo'], "link properties do not include foo = bar"
198 test "user without can_manage permission may not modify permission link" do
199 set_user_from_auth :admin
201 ob = Collection.create!
202 # grant can_manage permission to active
203 perm_link = Link.create!(tail_uuid: users(:active).uuid,
205 link_class: 'permission',
207 # ob is owned by :admin, the link is owned by root
208 assert_equal ob.owner_uuid, users(:admin).uuid
209 assert_equal perm_link.owner_uuid, system_user_uuid
211 # user "active" may not modify the permission link
212 set_user_from_auth :active_trustedclient
213 perm_link.name = 'can_manage'
214 assert_raises ArvadosModel::PermissionDeniedError do
219 test "manager user gets permission to minions' articles via can_manage link" do
220 manager = create :active_user, first_name: "Manage", last_name: "Er"
221 minion = create :active_user, first_name: "Min", last_name: "Ion"
222 minions_specimen = act_as_user minion do
223 g = Group.create! name: "minon project", group_class: "project"
224 Collection.create! owner_uuid: g.uuid
226 # Manager creates a group. (Make sure it doesn't magically give
227 # anyone any additional permissions.)
229 act_as_user manager do
230 g = create :group, name: "NoBigSecret Lab"
231 assert_empty(User.readable_by(manager).where(uuid: minion.uuid),
232 "saw a user I shouldn't see")
233 assert_raises(ArvadosModel::PermissionDeniedError,
234 ActiveRecord::RecordInvalid,
235 "gave can_read permission to a user I shouldn't see") do
236 create(:permission_link,
237 name: 'can_read', tail_uuid: minion.uuid, head_uuid: g.uuid)
239 %w(can_manage can_write can_read).each do |perm_type|
240 assert_raises(ArvadosModel::PermissionDeniedError,
241 ActiveRecord::RecordInvalid,
242 "escalated privileges") do
243 create(:permission_link,
244 name: perm_type, tail_uuid: g.uuid, head_uuid: minion.uuid)
247 assert_empty(User.readable_by(manager).where(uuid: minion.uuid),
248 "manager saw minion too soon")
249 assert_empty(User.readable_by(minion).where(uuid: manager.uuid),
250 "minion saw manager too soon")
251 assert_empty(Group.readable_by(minion).where(uuid: g.uuid),
252 "minion saw manager's new NoBigSecret Lab group too soon")
254 # Manager declares everybody on the system should be able to see
255 # the NoBigSecret Lab group.
256 create(:permission_link,
258 tail_uuid: 'zzzzz-j7d0g-fffffffffffffff',
260 # ...but nobody has joined the group yet. Manager still can't see
262 assert_empty(User.readable_by(manager).where(uuid: minion.uuid),
263 "manager saw minion too soon")
266 act_as_user minion do
267 # Minion can see the group.
268 assert_not_empty(Group.readable_by(minion).where(uuid: g.uuid),
269 "minion could not see the NoBigSecret Lab group")
270 # Minion joins the group.
271 create(:permission_link,
274 head_uuid: minion.uuid)
277 act_as_user manager do
278 # Now, manager can see minion.
279 assert_not_empty(User.readable_by(manager).where(uuid: minion.uuid),
280 "manager could not see minion")
281 # But cannot obtain further privileges this way.
282 assert_raises(ArvadosModel::PermissionDeniedError,
283 "escalated privileges") do
284 create(:permission_link,
285 name: 'can_manage', tail_uuid: manager.uuid, head_uuid: minion.uuid)
287 assert_empty(Collection
288 .readable_by(manager)
289 .where(uuid: minions_specimen.uuid),
290 "manager saw the minion's private stuff")
291 assert_raises(ArvadosModel::PermissionDeniedError,
292 "manager could update minion's private stuff") do
293 minions_specimen.update_attributes(properties: {'x' => 'y'})
297 act_as_system_user do
298 # Root can give Manager more privileges over Minion.
299 create(:permission_link,
300 name: 'can_manage', tail_uuid: g.uuid, head_uuid: minion.uuid)
303 act_as_user manager do
304 # Now, manager can read and write Minion's stuff.
305 assert_not_empty(Collection
306 .readable_by(manager)
307 .where(uuid: minions_specimen.uuid),
308 "manager could not find minion's specimen by uuid")
310 minions_specimen.update_attributes(properties: {'x' => 'y'}),
311 "manager could not update minion's specimen object")
315 test "users with bidirectional read permission in group can see each other, but cannot see each other's private articles" do
316 a = create :active_user, first_name: "A"
317 b = create :active_user, first_name: "B"
318 other = create :active_user, first_name: "OTHER"
320 assert_empty(User.readable_by(b).where(uuid: a.uuid),
321 "#{b.first_name} should not be able to see 'a' in the user list")
322 assert_empty(User.readable_by(a).where(uuid: b.uuid),
323 "#{a.first_name} should not be able to see 'b' in the user list")
325 act_as_system_user do
328 create(:permission_link,
329 name: 'can_read', tail_uuid: u.uuid, head_uuid: g.uuid)
330 create(:permission_link,
331 name: 'can_read', head_uuid: u.uuid, tail_uuid: g.uuid)
335 assert_not_empty(User.readable_by(b).where(uuid: a.uuid),
336 "#{b.first_name} should be able to see 'a' in the user list")
337 assert_not_empty(User.readable_by(a).where(uuid: b.uuid),
338 "#{a.first_name} should be able to see 'b' in the user list")
340 a_specimen = act_as_user a do
343 assert_not_empty(Collection.readable_by(a).where(uuid: a_specimen.uuid),
344 "A cannot read own Collection, following test probably useless.")
345 assert_empty(Collection.readable_by(b).where(uuid: a_specimen.uuid),
346 "B can read A's Collection")
348 assert_empty(User.readable_by(u).where(uuid: other.uuid),
349 "#{u.first_name} can see OTHER in the user list")
350 assert_empty(User.readable_by(other).where(uuid: u.uuid),
351 "OTHER can see #{u.first_name} in the user list")
353 assert_raises ArvadosModel::PermissionDeniedError, "wrote without perm" do
354 other.update_attributes!(prefs: {'pwned' => true})
356 assert_equal(true, u.update_attributes!(prefs: {'thisisme' => true}),
357 "#{u.first_name} can't update its own prefs")
360 assert_raises(ArvadosModel::PermissionDeniedError,
361 "OTHER wrote #{u.first_name} without perm") do
362 u.update_attributes!(prefs: {'pwned' => true})
364 assert_equal(true, other.update_attributes!(prefs: {'thisisme' => true}),
365 "OTHER can't update its own prefs")
370 test "cannot create with owner = unwritable user" do
371 set_user_from_auth :rominiadmin
372 assert_raises ArvadosModel::PermissionDeniedError, "created with owner = unwritable user" do
373 Collection.create!(owner_uuid: users(:active).uuid)
377 test "cannot change owner to unwritable user" do
378 set_user_from_auth :rominiadmin
379 ob = Collection.create!
380 assert_raises ArvadosModel::PermissionDeniedError, "changed owner to unwritable user" do
381 ob.update_attributes!(owner_uuid: users(:active).uuid)
385 test "cannot create with owner = unwritable group" do
386 set_user_from_auth :rominiadmin
387 assert_raises ArvadosModel::PermissionDeniedError, "created with owner = unwritable group" do
388 Collection.create!(owner_uuid: groups(:aproject).uuid)
392 test "cannot change owner to unwritable group" do
393 set_user_from_auth :rominiadmin
394 ob = Collection.create!
395 assert_raises ArvadosModel::PermissionDeniedError, "changed owner to unwritable group" do
396 ob.update_attributes!(owner_uuid: groups(:aproject).uuid)
400 def container_logs(container, user)
401 Log.readable_by(users(user)).
402 where(object_uuid: containers(container).uuid, event_type: "test")
405 test "container logs created by dispatch are visible to container requestor" do
406 set_user_from_auth :dispatch1
407 Log.create!(object_uuid: containers(:running).uuid,
410 assert_not_empty container_logs(:running, :admin)
411 assert_not_empty container_logs(:running, :active)
412 assert_empty container_logs(:running, :spectator)
415 test "container logs created by dispatch are public if container request is public" do
416 set_user_from_auth :dispatch1
417 Log.create!(object_uuid: containers(:running_older).uuid,
420 assert_not_empty container_logs(:running_older, :anonymous)
423 test "add user to group, then remove them" do
424 set_user_from_auth :admin
425 grp = Group.create!(owner_uuid: system_user_uuid, group_class: "role")
426 col = Collection.create!(owner_uuid: grp.uuid)
427 assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid)
428 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
430 l1 = Link.create!(tail_uuid: users(:active).uuid,
432 link_class: 'permission',
434 l2 = Link.create!(tail_uuid: grp.uuid,
435 head_uuid: users(:active).uuid,
436 link_class: 'permission',
439 l3 = Link.create!(tail_uuid: users(:project_viewer).uuid,
441 link_class: 'permission',
443 l4 = Link.create!(tail_uuid: grp.uuid,
444 head_uuid: users(:project_viewer).uuid,
445 link_class: 'permission',
448 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
449 assert User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid).first
454 assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid)
455 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
460 test "add user to group, then change permission level" do
461 set_user_from_auth :admin
462 grp = Group.create!(owner_uuid: system_user_uuid, group_class: "role")
463 col = Collection.create!(owner_uuid: grp.uuid)
464 assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid)
465 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
467 l1 = Link.create!(tail_uuid: users(:active).uuid,
469 link_class: 'permission',
471 l2 = Link.create!(tail_uuid: grp.uuid,
472 head_uuid: users(:active).uuid,
473 link_class: 'permission',
476 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
477 assert users(:active).can?(read: col.uuid)
478 assert users(:active).can?(write: col.uuid)
479 assert users(:active).can?(manage: col.uuid)
484 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
485 assert users(:active).can?(read: col.uuid)
486 assert !users(:active).can?(write: col.uuid)
487 assert !users(:active).can?(manage: col.uuid)
489 l1.name = 'can_write'
492 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
493 assert users(:active).can?(read: col.uuid)
494 assert users(:active).can?(write: col.uuid)
495 assert !users(:active).can?(manage: col.uuid)
499 test "add user to group, then add overlapping permission link to group" do
500 set_user_from_auth :admin
501 grp = Group.create!(owner_uuid: system_user_uuid, group_class: "role")
502 col = Collection.create!(owner_uuid: grp.uuid)
503 assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid)
504 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
506 l1 = Link.create!(tail_uuid: users(:active).uuid,
508 link_class: 'permission',
510 l2 = Link.create!(tail_uuid: grp.uuid,
511 head_uuid: users(:active).uuid,
512 link_class: 'permission',
515 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
516 assert users(:active).can?(read: col.uuid)
517 assert users(:active).can?(write: col.uuid)
518 assert users(:active).can?(manage: col.uuid)
520 l3 = Link.create!(tail_uuid: users(:active).uuid,
522 link_class: 'permission',
525 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
526 assert users(:active).can?(read: col.uuid)
527 assert users(:active).can?(write: col.uuid)
528 assert users(:active).can?(manage: col.uuid)
532 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
533 assert users(:active).can?(read: col.uuid)
534 assert users(:active).can?(write: col.uuid)
535 assert users(:active).can?(manage: col.uuid)
539 test "add user to group, then add overlapping permission link to subproject" do
540 set_user_from_auth :admin
541 grp = Group.create!(owner_uuid: system_user_uuid, group_class: "project")
542 prj = Group.create!(owner_uuid: grp.uuid, group_class: "project")
543 assert_empty Group.readable_by(users(:active)).where(uuid: prj.uuid)
544 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
546 l1 = Link.create!(tail_uuid: users(:active).uuid,
548 link_class: 'permission',
550 l2 = Link.create!(tail_uuid: grp.uuid,
551 head_uuid: users(:active).uuid,
552 link_class: 'permission',
555 assert Group.readable_by(users(:active)).where(uuid: prj.uuid).first
556 assert users(:active).can?(read: prj.uuid)
557 assert users(:active).can?(write: prj.uuid)
558 assert users(:active).can?(manage: prj.uuid)
560 l3 = Link.create!(tail_uuid: grp.uuid,
562 link_class: 'permission',
565 assert Group.readable_by(users(:active)).where(uuid: prj.uuid).first
566 assert users(:active).can?(read: prj.uuid)
567 assert users(:active).can?(write: prj.uuid)
568 assert users(:active).can?(manage: prj.uuid)
572 assert Group.readable_by(users(:active)).where(uuid: prj.uuid).first
573 assert users(:active).can?(read: prj.uuid)
574 assert users(:active).can?(write: prj.uuid)
575 assert users(:active).can?(manage: prj.uuid)