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 :admin
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 :admin
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")
157 sp_grp = Group.create!(group_class: "project")
159 Link.create!(link_class: 'permission',
161 tail_uuid: owner_grp.uuid,
162 head_uuid: sp_grp.uuid)
164 sp = Collection.create!(owner_uuid: sp_grp.uuid)
166 # active user owns owner_grp, which has can_manage permission on sp_grp
167 # user should be able to add permissions on sp.
168 set_user_from_auth :active_trustedclient
169 test_perm = Link.create(tail_uuid: users(:active).uuid,
171 link_class: 'permission',
173 assert test_perm.save, "could not save new permission on target object"
174 assert test_perm.destroy, "could not delete new permission on target object"
178 skip "can_manage permission on a non-group object" do
179 set_user_from_auth :admin
181 ob = Collection.create!
182 # grant can_manage permission to active
183 perm_link = Link.create!(tail_uuid: users(:active).uuid,
185 link_class: 'permission',
187 # ob is owned by :admin, the link is owned by root
188 assert_equal users(:admin).uuid, ob.owner_uuid
189 assert_equal system_user_uuid, perm_link.owner_uuid
191 # user "active" can modify the permission link
192 set_user_from_auth :active_trustedclient
193 perm_link.properties["foo"] = 'bar'
194 assert perm_link.save, "could not save modified link"
196 assert_equal 'bar', perm_link.properties['foo'], "link properties do not include foo = bar"
199 test "user without can_manage permission may not modify permission link" do
200 set_user_from_auth :admin
202 ob = Collection.create!
203 # grant can_manage permission to active
204 perm_link = Link.create!(tail_uuid: users(:active).uuid,
206 link_class: 'permission',
208 # ob is owned by :admin, the link is owned by root
209 assert_equal ob.owner_uuid, users(:admin).uuid
210 assert_equal perm_link.owner_uuid, system_user_uuid
212 # user "active" may not modify the permission link
213 set_user_from_auth :active_trustedclient
214 perm_link.name = 'can_manage'
215 assert_raises ArvadosModel::PermissionDeniedError do
220 test "manager user gets permission to minions' articles via can_manage link" do
221 manager = create :active_user, first_name: "Manage", last_name: "Er"
222 minion = create :active_user, first_name: "Min", last_name: "Ion"
223 minions_specimen = act_as_user minion do
224 g = Group.create! name: "minon project", group_class: "project"
225 Collection.create! owner_uuid: g.uuid
227 # Manager creates a group. (Make sure it doesn't magically give
228 # anyone any additional permissions.)
230 act_as_user manager do
231 g = create :group, name: "NoBigSecret Lab", group_class: "role"
232 assert_empty(User.readable_by(manager).where(uuid: minion.uuid),
233 "saw a user I shouldn't see")
234 assert_raises(ArvadosModel::PermissionDeniedError,
235 ActiveRecord::RecordInvalid,
236 "gave can_read permission to a user I shouldn't see") do
237 create(:permission_link,
238 name: 'can_read', tail_uuid: minion.uuid, head_uuid: g.uuid)
240 %w(can_manage can_write can_read).each do |perm_type|
241 assert_raises(ArvadosModel::PermissionDeniedError,
242 ActiveRecord::RecordInvalid,
243 "escalated privileges") do
244 create(:permission_link,
245 name: perm_type, tail_uuid: g.uuid, head_uuid: minion.uuid)
248 assert_empty(User.readable_by(manager).where(uuid: minion.uuid),
249 "manager saw minion too soon")
250 assert_empty(User.readable_by(minion).where(uuid: manager.uuid),
251 "minion saw manager too soon")
252 assert_empty(Group.readable_by(minion).where(uuid: g.uuid),
253 "minion saw manager's new NoBigSecret Lab group too soon")
255 # Manager declares everybody on the system should be able to see
256 # the NoBigSecret Lab group.
257 create(:permission_link,
259 tail_uuid: 'zzzzz-j7d0g-fffffffffffffff',
261 # ...but nobody has joined the group yet. Manager still can't see
263 assert_empty(User.readable_by(manager).where(uuid: minion.uuid),
264 "manager saw minion too soon")
267 act_as_user minion do
268 # Minion can see the group.
269 assert_not_empty(Group.readable_by(minion).where(uuid: g.uuid),
270 "minion could not see the NoBigSecret Lab group")
271 # Minion joins the group.
272 create(:permission_link,
275 head_uuid: minion.uuid)
278 act_as_user manager do
279 # Now, manager can see minion.
280 assert_not_empty(User.readable_by(manager).where(uuid: minion.uuid),
281 "manager could not see minion")
282 # But cannot obtain further privileges this way.
283 assert_raises(ArvadosModel::PermissionDeniedError,
284 "escalated privileges") do
285 create(:permission_link,
286 name: 'can_manage', tail_uuid: manager.uuid, head_uuid: minion.uuid)
288 assert_empty(Collection
289 .readable_by(manager)
290 .where(uuid: minions_specimen.uuid),
291 "manager saw the minion's private stuff")
292 assert_raises(ArvadosModel::PermissionDeniedError,
293 "manager could update minion's private stuff") do
294 minions_specimen.update_attributes(properties: {'x' => 'y'})
298 act_as_system_user do
299 # Root can give Manager more privileges over Minion.
300 create(:permission_link,
301 name: 'can_manage', tail_uuid: g.uuid, head_uuid: minion.uuid)
304 act_as_user manager do
305 # Now, manager can read and write Minion's stuff.
306 assert_not_empty(Collection
307 .readable_by(manager)
308 .where(uuid: minions_specimen.uuid),
309 "manager could not find minion's specimen by uuid")
311 minions_specimen.update_attributes(properties: {'x' => 'y'}),
312 "manager could not update minion's specimen object")
316 test "users with bidirectional read permission in group can see each other, but cannot see each other's private articles" do
317 a = create :active_user, first_name: "A"
318 b = create :active_user, first_name: "B"
319 other = create :active_user, first_name: "OTHER"
321 assert_empty(User.readable_by(b).where(uuid: a.uuid),
322 "#{b.first_name} should not be able to see 'a' in the user list")
323 assert_empty(User.readable_by(a).where(uuid: b.uuid),
324 "#{a.first_name} should not be able to see 'b' in the user list")
326 act_as_system_user do
327 g = create :group, group_class: "role"
329 create(:permission_link,
330 name: 'can_read', tail_uuid: u.uuid, head_uuid: g.uuid)
331 create(:permission_link,
332 name: 'can_read', head_uuid: u.uuid, tail_uuid: g.uuid)
336 assert_not_empty(User.readable_by(b).where(uuid: a.uuid),
337 "#{b.first_name} should be able to see 'a' in the user list")
338 assert_not_empty(User.readable_by(a).where(uuid: b.uuid),
339 "#{a.first_name} should be able to see 'b' in the user list")
341 a_specimen = act_as_user a do
344 assert_not_empty(Collection.readable_by(a).where(uuid: a_specimen.uuid),
345 "A cannot read own Collection, following test probably useless.")
346 assert_empty(Collection.readable_by(b).where(uuid: a_specimen.uuid),
347 "B can read A's Collection")
349 assert_empty(User.readable_by(u).where(uuid: other.uuid),
350 "#{u.first_name} can see OTHER in the user list")
351 assert_empty(User.readable_by(other).where(uuid: u.uuid),
352 "OTHER can see #{u.first_name} in the user list")
354 assert_raises ArvadosModel::PermissionDeniedError, "wrote without perm" do
355 other.update_attributes!(prefs: {'pwned' => true})
357 assert_equal(true, u.update_attributes!(prefs: {'thisisme' => true}),
358 "#{u.first_name} can't update its own prefs")
361 assert_raises(ArvadosModel::PermissionDeniedError,
362 "OTHER wrote #{u.first_name} without perm") do
363 u.update_attributes!(prefs: {'pwned' => true})
365 assert_equal(true, other.update_attributes!(prefs: {'thisisme' => true}),
366 "OTHER can't update its own prefs")
371 test "cannot create with owner = unwritable user" do
372 set_user_from_auth :rominiadmin
373 assert_raises ArvadosModel::PermissionDeniedError, "created with owner = unwritable user" do
374 Collection.create!(owner_uuid: users(:active).uuid)
378 test "cannot change owner to unwritable user" do
379 set_user_from_auth :rominiadmin
380 ob = Collection.create!
381 assert_raises ArvadosModel::PermissionDeniedError, "changed owner to unwritable user" do
382 ob.update_attributes!(owner_uuid: users(:active).uuid)
386 test "cannot create with owner = unwritable group" do
387 set_user_from_auth :rominiadmin
388 assert_raises ArvadosModel::PermissionDeniedError, "created with owner = unwritable group" do
389 Collection.create!(owner_uuid: groups(:aproject).uuid)
393 test "cannot change owner to unwritable group" do
394 set_user_from_auth :rominiadmin
395 ob = Collection.create!
396 assert_raises ArvadosModel::PermissionDeniedError, "changed owner to unwritable group" do
397 ob.update_attributes!(owner_uuid: groups(:aproject).uuid)
401 def container_logs(container, user)
402 Log.readable_by(users(user)).
403 where(object_uuid: containers(container).uuid, event_type: "test")
406 test "container logs created by dispatch are visible to container requestor" do
407 set_user_from_auth :dispatch1
408 Log.create!(object_uuid: containers(:running).uuid,
411 assert_not_empty container_logs(:running, :admin)
412 assert_not_empty container_logs(:running, :active)
413 assert_empty container_logs(:running, :spectator)
416 test "container logs created by dispatch are public if container request is public" do
417 set_user_from_auth :dispatch1
418 Log.create!(object_uuid: containers(:running_older).uuid,
421 assert_not_empty container_logs(:running_older, :anonymous)
424 test "add user to group, then remove them" do
425 set_user_from_auth :admin
426 grp = Group.create!(owner_uuid: system_user_uuid, group_class: "role")
427 col = Collection.create!(owner_uuid: system_user_uuid)
429 l0 = Link.create!(tail_uuid: grp.uuid,
431 link_class: 'permission',
434 assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid)
435 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
437 l1 = Link.create!(tail_uuid: users(:active).uuid,
439 link_class: 'permission',
441 l2 = Link.create!(tail_uuid: grp.uuid,
442 head_uuid: users(:active).uuid,
443 link_class: 'permission',
446 l3 = Link.create!(tail_uuid: users(:project_viewer).uuid,
448 link_class: 'permission',
450 l4 = Link.create!(tail_uuid: grp.uuid,
451 head_uuid: users(:project_viewer).uuid,
452 link_class: 'permission',
455 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
456 assert User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid).first
461 assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid)
462 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
467 test "add user to group, then change permission level" do
468 set_user_from_auth :admin
469 grp = Group.create!(owner_uuid: system_user_uuid, group_class: "project")
470 col = Collection.create!(owner_uuid: grp.uuid)
471 assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid)
472 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
474 l1 = Link.create!(tail_uuid: users(:active).uuid,
476 link_class: 'permission',
479 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
480 assert users(:active).can?(read: col.uuid)
481 assert users(:active).can?(write: col.uuid)
482 assert users(:active).can?(manage: col.uuid)
487 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
488 assert users(:active).can?(read: col.uuid)
489 assert !users(:active).can?(write: col.uuid)
490 assert !users(:active).can?(manage: col.uuid)
492 l1.name = 'can_write'
495 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
496 assert users(:active).can?(read: col.uuid)
497 assert users(:active).can?(write: col.uuid)
498 assert !users(:active).can?(manage: col.uuid)
502 test "add user to group, then add overlapping permission link to group" do
503 set_user_from_auth :admin
504 grp = Group.create!(owner_uuid: system_user_uuid, group_class: "project")
505 col = Collection.create!(owner_uuid: grp.uuid)
506 assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid)
507 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
509 l1 = Link.create!(tail_uuid: users(:active).uuid,
511 link_class: 'permission',
514 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
515 assert users(:active).can?(read: col.uuid)
516 assert users(:active).can?(write: col.uuid)
517 assert users(:active).can?(manage: col.uuid)
519 l3 = Link.create!(tail_uuid: users(:active).uuid,
521 link_class: 'permission',
524 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
525 assert users(:active).can?(read: col.uuid)
526 assert users(:active).can?(write: col.uuid)
527 assert users(:active).can?(manage: col.uuid)
531 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
532 assert users(:active).can?(read: col.uuid)
533 assert users(:active).can?(write: col.uuid)
534 assert users(:active).can?(manage: col.uuid)
538 test "add user to group, then add overlapping permission link to subproject" do
539 set_user_from_auth :admin
540 grp = Group.create!(owner_uuid: system_user_uuid, group_class: "role")
541 prj = Group.create!(owner_uuid: system_user_uuid, group_class: "project")
543 l0 = Link.create!(tail_uuid: grp.uuid,
545 link_class: 'permission',
548 assert_empty Group.readable_by(users(:active)).where(uuid: prj.uuid)
549 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
551 l1 = Link.create!(tail_uuid: users(:active).uuid,
553 link_class: 'permission',
555 l2 = Link.create!(tail_uuid: grp.uuid,
556 head_uuid: users(:active).uuid,
557 link_class: 'permission',
560 assert Group.readable_by(users(:active)).where(uuid: prj.uuid).first
561 assert users(:active).can?(read: prj.uuid)
562 assert users(:active).can?(write: prj.uuid)
563 assert users(:active).can?(manage: prj.uuid)
565 l3 = Link.create!(tail_uuid: grp.uuid,
567 link_class: 'permission',
570 assert Group.readable_by(users(:active)).where(uuid: prj.uuid).first
571 assert users(:active).can?(read: prj.uuid)
572 assert users(:active).can?(write: prj.uuid)
573 assert users(:active).can?(manage: prj.uuid)
577 assert Group.readable_by(users(:active)).where(uuid: prj.uuid).first
578 assert users(:active).can?(read: prj.uuid)
579 assert users(:active).can?(write: prj.uuid)
580 assert users(:active).can?(manage: prj.uuid)
583 [system_user_uuid, anonymous_user_uuid].each do |u|
584 test "cannot delete system user #{u}" do
585 act_as_system_user do
586 assert_raises ArvadosModel::PermissionDeniedError do
587 User.find_by_uuid(u).destroy
593 [system_group_uuid, anonymous_group_uuid, public_project_uuid].each do |g|
594 test "cannot delete system group #{g}" do
595 act_as_system_user do
596 assert_raises ArvadosModel::PermissionDeniedError do
597 Group.find_by_uuid(g).destroy