X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/d8de76141cbe9a9af10dfc408b6d656cc727bbe5..c1e7255a85dfc2807ba78e1cf9d109d896c80b42:/services/api/app/models/arvados_model.rb diff --git a/services/api/app/models/arvados_model.rb b/services/api/app/models/arvados_model.rb index 154929171f..a6c9d31d41 100644 --- a/services/api/app/models/arvados_model.rb +++ b/services/api/app/models/arvados_model.rb @@ -1,4 +1,5 @@ -require 'assign_uuid' +require 'has_uuid' + class ArvadosModel < ActiveRecord::Base self.abstract_class = true @@ -14,7 +15,6 @@ class ArvadosModel < ActiveRecord::Base before_save :ensure_ownership_path_leads_to_user before_destroy :ensure_owner_uuid_is_permitted before_destroy :ensure_permission_to_destroy - before_create :update_modified_by_fields before_update :maybe_update_modified_by_fields after_create :log_create @@ -64,6 +64,24 @@ class ArvadosModel < ActiveRecord::Base self.columns.select { |col| col.name == attr.to_s }.first end + # Return nil if current user is not allowed to see the list of + # writers. Otherwise, return a list of user_ and group_uuids with + # write permission. (If not returning nil, current_user is always in + # the list because can_manage permission is needed to see the list + # of writers.) + def writable_by + unless (owner_uuid == current_user.uuid or + current_user.is_admin or + current_user.groups_i_can(:manage).index(owner_uuid)) + return nil + end + [owner_uuid, current_user.uuid] + permissions.collect do |p| + if ['can_write', 'can_manage'].index p.name + p.tail_uuid + end + end.compact.uniq + end + # Return a query with read permissions restricted to the union of of the # permissions of the members of users_list, i.e. if something is readable by # any user in users_list, it will be readable in the query returned by this @@ -169,9 +187,13 @@ class ArvadosModel < ActiveRecord::Base def ensure_owner_uuid_is_permitted raise PermissionDeniedError if !current_user - self.owner_uuid ||= current_user.uuid + if respond_to? :owner_uuid= + self.owner_uuid ||= current_user.uuid + end if self.owner_uuid_changed? - if current_user.uuid == self.owner_uuid or + if new_record? + return true + elsif current_user.uuid == self.owner_uuid or current_user.can? write: self.owner_uuid # current_user is, or has :write permission on, the new owner else @@ -229,6 +251,7 @@ class ArvadosModel < ActiveRecord::Base def maybe_update_modified_by_fields update_modified_by_fields if self.changed? or self.new_record? + true end def update_modified_by_fields @@ -237,6 +260,7 @@ class ArvadosModel < ActiveRecord::Base self.modified_at = Time.now self.modified_by_user_uuid = current_user ? current_user.uuid : nil self.modified_by_client_uuid = current_api_client ? current_api_client.uuid : nil + true end def ensure_serialized_attribute_type