1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
5 class Link < ArvadosModel
8 include CommonApiTemplate
10 # Posgresql JSONB columns should NOT be declared as serialized, Rails 5
11 # already know how to properly treat them.
12 attribute :properties, :jsonbHash, default: {}
14 validate :name_links_are_obsolete
15 before_create :permission_to_attach_to_objects
16 before_update :permission_to_attach_to_objects
17 after_update :call_update_permissions
18 after_create :call_update_permissions
19 before_destroy :clear_permissions
20 after_destroy :check_permissions
22 api_accessible :user, extend: :common do |t|
33 if k = ArvadosModel::resource_class_for_uuid(head_uuid)
39 if k = ArvadosModel::resource_class_for_uuid(tail_uuid)
46 def permission_to_attach_to_objects
47 # Anonymous users cannot write links
48 return false if !current_user
50 # All users can write links that don't affect permissions
51 return true if self.link_class != 'permission'
53 # Administrators can grant permissions
54 return true if current_user.is_admin
56 head_obj = ArvadosModel.find_by_uuid(head_uuid)
58 # No permission links can be pointed to past collection versions
59 return false if head_obj.is_a?(Collection) && head_obj.current_version_uuid != head_uuid
61 # All users can grant permissions on objects they own or can manage
62 return true if current_user.can?(manage: head_obj)
75 def call_update_permissions
76 if self.link_class == 'permission'
77 update_permissions tail_uuid, head_uuid, PERM_LEVEL[name]
82 if self.link_class == 'permission'
83 update_permissions tail_uuid, head_uuid, REVOKE_PERM
88 if self.link_class == 'permission'
89 check_permissions_against_full_refresh
93 def name_links_are_obsolete
94 if link_class == 'name'
95 errors.add('name', 'Name links are obsolete')
102 # A user is permitted to create, update or modify a permission link
103 # if and only if they have "manage" permission on the object
104 # indicated by the permission link's head_uuid.
106 # All other links are treated as regular ArvadosModel objects.
108 def ensure_owner_uuid_is_permitted
109 if link_class == 'permission'
110 ob = ArvadosModel.find_by_uuid(head_uuid)
111 raise PermissionDeniedError unless current_user.can?(manage: ob)
112 # All permission links should be owned by the system user.
113 self.owner_uuid = system_user_uuid