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 Rails.configuration.Users.ActivatedUsersAreVisibleToOthers = false
222 manager = create :active_user, first_name: "Manage", last_name: "Er"
223 minion = create :active_user, first_name: "Min", last_name: "Ion"
224 minions_specimen = act_as_user minion do
225 g = Group.create! name: "minon project", group_class: "project"
226 Collection.create! owner_uuid: g.uuid
228 # Manager creates a group. (Make sure it doesn't magically give
229 # anyone any additional permissions.)
231 act_as_user manager do
232 g = create :group, name: "NoBigSecret Lab", group_class: "role"
233 assert_empty(User.readable_by(manager).where(uuid: minion.uuid),
234 "saw a user I shouldn't see")
235 assert_raises(ArvadosModel::PermissionDeniedError,
236 ActiveRecord::RecordInvalid,
237 "gave can_read permission to a user I shouldn't see") do
238 create(:permission_link,
239 name: 'can_read', tail_uuid: minion.uuid, head_uuid: g.uuid)
241 %w(can_manage can_write can_read).each do |perm_type|
242 assert_raises(ArvadosModel::PermissionDeniedError,
243 ActiveRecord::RecordInvalid,
244 "escalated privileges") do
245 create(:permission_link,
246 name: perm_type, tail_uuid: g.uuid, head_uuid: minion.uuid)
249 assert_empty(User.readable_by(manager).where(uuid: minion.uuid),
250 "manager saw minion too soon")
251 assert_empty(User.readable_by(minion).where(uuid: manager.uuid),
252 "minion saw manager too soon")
253 assert_empty(Group.readable_by(minion).where(uuid: g.uuid),
254 "minion saw manager's new NoBigSecret Lab group too soon")
256 # Manager declares everybody on the system should be able to see
257 # the NoBigSecret Lab group.
258 create(:permission_link,
260 tail_uuid: 'zzzzz-j7d0g-fffffffffffffff',
262 # ...but nobody has joined the group yet. Manager still can't see
264 assert_empty(User.readable_by(manager).where(uuid: minion.uuid),
265 "manager saw minion too soon")
268 act_as_user minion do
269 # Minion can see the group.
270 assert_not_empty(Group.readable_by(minion).where(uuid: g.uuid),
271 "minion could not see the NoBigSecret Lab group")
272 # Minion joins the group.
273 create(:permission_link,
276 head_uuid: minion.uuid)
279 act_as_user manager do
280 # Now, manager can see minion.
281 assert_not_empty(User.readable_by(manager).where(uuid: minion.uuid),
282 "manager could not see minion")
283 # But cannot obtain further privileges this way.
284 assert_raises(ArvadosModel::PermissionDeniedError,
285 "escalated privileges") do
286 create(:permission_link,
287 name: 'can_manage', tail_uuid: manager.uuid, head_uuid: minion.uuid)
289 assert_empty(Collection
290 .readable_by(manager)
291 .where(uuid: minions_specimen.uuid),
292 "manager saw the minion's private stuff")
293 assert_raises(ArvadosModel::PermissionDeniedError,
294 "manager could update minion's private stuff") do
295 minions_specimen.update_attributes(properties: {'x' => 'y'})
299 act_as_system_user do
300 # Root can give Manager more privileges over Minion.
301 create(:permission_link,
302 name: 'can_manage', tail_uuid: g.uuid, head_uuid: minion.uuid)
305 act_as_user manager do
306 # Now, manager can read and write Minion's stuff.
307 assert_not_empty(Collection
308 .readable_by(manager)
309 .where(uuid: minions_specimen.uuid),
310 "manager could not find minion's specimen by uuid")
312 minions_specimen.update_attributes(properties: {'x' => 'y'}),
313 "manager could not update minion's specimen object")
317 test "users with bidirectional read permission in group can see each other, but cannot see each other's private articles" do
318 Rails.configuration.Users.ActivatedUsersAreVisibleToOthers = false
319 a = create :active_user, first_name: "A"
320 b = create :active_user, first_name: "B"
321 other = create :active_user, first_name: "OTHER"
323 assert_empty(User.readable_by(b).where(uuid: a.uuid),
324 "#{b.first_name} should not be able to see 'a' in the user list")
325 assert_empty(User.readable_by(a).where(uuid: b.uuid),
326 "#{a.first_name} should not be able to see 'b' in the user list")
328 act_as_system_user do
329 g = create :group, group_class: "role"
331 create(:permission_link,
332 name: 'can_read', tail_uuid: u.uuid, head_uuid: g.uuid)
333 create(:permission_link,
334 name: 'can_read', head_uuid: u.uuid, tail_uuid: g.uuid)
338 assert_not_empty(User.readable_by(b).where(uuid: a.uuid),
339 "#{b.first_name} should be able to see 'a' in the user list")
340 assert_not_empty(User.readable_by(a).where(uuid: b.uuid),
341 "#{a.first_name} should be able to see 'b' in the user list")
343 a_specimen = act_as_user a do
346 assert_not_empty(Collection.readable_by(a).where(uuid: a_specimen.uuid),
347 "A cannot read own Collection, following test probably useless.")
348 assert_empty(Collection.readable_by(b).where(uuid: a_specimen.uuid),
349 "B can read A's Collection")
351 assert_empty(User.readable_by(u).where(uuid: other.uuid),
352 "#{u.first_name} can see OTHER in the user list")
353 assert_empty(User.readable_by(other).where(uuid: u.uuid),
354 "OTHER can see #{u.first_name} in the user list")
356 assert_raises ArvadosModel::PermissionDeniedError, "wrote without perm" do
357 other.update_attributes!(prefs: {'pwned' => true})
359 assert_equal(true, u.update_attributes!(prefs: {'thisisme' => true}),
360 "#{u.first_name} can't update its own prefs")
363 assert_raises(ArvadosModel::PermissionDeniedError,
364 "OTHER wrote #{u.first_name} without perm") do
365 u.update_attributes!(prefs: {'pwned' => true})
367 assert_equal(true, other.update_attributes!(prefs: {'thisisme' => true}),
368 "OTHER can't update its own prefs")
373 test "cannot create with owner = unwritable user" do
374 set_user_from_auth :rominiadmin
375 assert_raises ArvadosModel::PermissionDeniedError, "created with owner = unwritable user" do
376 Collection.create!(owner_uuid: users(:active).uuid)
380 test "cannot change owner to unwritable user" do
381 set_user_from_auth :rominiadmin
382 ob = Collection.create!
383 assert_raises ArvadosModel::PermissionDeniedError, "changed owner to unwritable user" do
384 ob.update_attributes!(owner_uuid: users(:active).uuid)
388 test "cannot create with owner = unwritable group" do
389 set_user_from_auth :rominiadmin
390 assert_raises ArvadosModel::PermissionDeniedError, "created with owner = unwritable group" do
391 Collection.create!(owner_uuid: groups(:aproject).uuid)
395 test "cannot change owner to unwritable group" do
396 set_user_from_auth :rominiadmin
397 ob = Collection.create!
398 assert_raises ArvadosModel::PermissionDeniedError, "changed owner to unwritable group" do
399 ob.update_attributes!(owner_uuid: groups(:aproject).uuid)
403 def container_logs(container, user)
404 Log.readable_by(users(user)).
405 where(object_uuid: containers(container).uuid, event_type: "test")
408 test "container logs created by dispatch are visible to container requestor" do
409 set_user_from_auth :dispatch1
410 Log.create!(object_uuid: containers(:running).uuid,
413 assert_not_empty container_logs(:running, :admin)
414 assert_not_empty container_logs(:running, :active)
415 assert_empty container_logs(:running, :spectator)
418 test "container logs created by dispatch are public if container request is public" do
419 set_user_from_auth :dispatch1
420 Log.create!(object_uuid: containers(:running_older).uuid,
423 assert_not_empty container_logs(:running_older, :anonymous)
426 test "add user to group, then remove them" do
427 set_user_from_auth :admin
428 grp = Group.create!(owner_uuid: system_user_uuid, group_class: "role")
429 col = Collection.create!(owner_uuid: system_user_uuid)
431 l0 = Link.create!(tail_uuid: grp.uuid,
433 link_class: 'permission',
436 assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid)
437 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
439 l1 = Link.create!(tail_uuid: users(:active).uuid,
441 link_class: 'permission',
443 l2 = Link.create!(tail_uuid: grp.uuid,
444 head_uuid: users(:active).uuid,
445 link_class: 'permission',
448 l3 = Link.create!(tail_uuid: users(:project_viewer).uuid,
450 link_class: 'permission',
452 l4 = Link.create!(tail_uuid: grp.uuid,
453 head_uuid: users(:project_viewer).uuid,
454 link_class: 'permission',
457 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
458 assert User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid).first
463 assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid)
464 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
469 test "add user to group, then change permission level" do
470 set_user_from_auth :admin
471 grp = Group.create!(owner_uuid: system_user_uuid, group_class: "project")
472 col = Collection.create!(owner_uuid: grp.uuid)
473 assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid)
474 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
476 l1 = Link.create!(tail_uuid: users(:active).uuid,
478 link_class: 'permission',
481 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
482 assert users(:active).can?(read: col.uuid)
483 assert users(:active).can?(write: col.uuid)
484 assert users(:active).can?(manage: col.uuid)
489 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
490 assert users(:active).can?(read: col.uuid)
491 assert !users(:active).can?(write: col.uuid)
492 assert !users(:active).can?(manage: col.uuid)
494 l1.name = 'can_write'
497 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
498 assert users(:active).can?(read: col.uuid)
499 assert users(:active).can?(write: col.uuid)
500 assert !users(:active).can?(manage: col.uuid)
504 test "add user to group, then add overlapping permission link to group" do
505 set_user_from_auth :admin
506 grp = Group.create!(owner_uuid: system_user_uuid, group_class: "project")
507 col = Collection.create!(owner_uuid: grp.uuid)
508 assert_empty Collection.readable_by(users(:active)).where(uuid: col.uuid)
509 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
511 l1 = Link.create!(tail_uuid: users(:active).uuid,
513 link_class: 'permission',
516 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
517 assert users(:active).can?(read: col.uuid)
518 assert users(:active).can?(write: col.uuid)
519 assert users(:active).can?(manage: col.uuid)
521 l3 = Link.create!(tail_uuid: users(:active).uuid,
523 link_class: 'permission',
526 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
527 assert users(:active).can?(read: col.uuid)
528 assert users(:active).can?(write: col.uuid)
529 assert users(:active).can?(manage: col.uuid)
533 assert Collection.readable_by(users(:active)).where(uuid: col.uuid).first
534 assert users(:active).can?(read: col.uuid)
535 assert users(:active).can?(write: col.uuid)
536 assert users(:active).can?(manage: col.uuid)
540 test "add user to group, then add overlapping permission link to subproject" do
541 set_user_from_auth :admin
542 grp = Group.create!(owner_uuid: system_user_uuid, group_class: "role")
543 prj = Group.create!(owner_uuid: system_user_uuid, group_class: "project")
545 l0 = Link.create!(tail_uuid: grp.uuid,
547 link_class: 'permission',
550 assert_empty Group.readable_by(users(:active)).where(uuid: prj.uuid)
551 assert_empty User.readable_by(users(:active)).where(uuid: users(:project_viewer).uuid)
553 l1 = Link.create!(tail_uuid: users(:active).uuid,
555 link_class: 'permission',
557 l2 = Link.create!(tail_uuid: grp.uuid,
558 head_uuid: users(:active).uuid,
559 link_class: 'permission',
562 assert Group.readable_by(users(:active)).where(uuid: prj.uuid).first
563 assert users(:active).can?(read: prj.uuid)
564 assert users(:active).can?(write: prj.uuid)
565 assert users(:active).can?(manage: prj.uuid)
567 l3 = Link.create!(tail_uuid: grp.uuid,
569 link_class: 'permission',
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)
579 assert Group.readable_by(users(:active)).where(uuid: prj.uuid).first
580 assert users(:active).can?(read: prj.uuid)
581 assert users(:active).can?(write: prj.uuid)
582 assert users(:active).can?(manage: prj.uuid)
585 [system_user_uuid, anonymous_user_uuid].each do |u|
586 test "cannot delete system user #{u}" do
587 act_as_system_user do
588 assert_raises ArvadosModel::PermissionDeniedError do
589 User.find_by_uuid(u).destroy
595 [system_group_uuid, anonymous_group_uuid, public_project_uuid].each do |g|
596 test "cannot delete system group #{g}" do
597 act_as_system_user do
598 assert_raises ArvadosModel::PermissionDeniedError do
599 Group.find_by_uuid(g).destroy