X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/6e86ca6fa82619f721643f2aabc81851cb1e272a..a14f6bf083841a868c054e7e00149c6a1bf0b708:/services/api/app/models/user.rb diff --git a/services/api/app/models/user.rb b/services/api/app/models/user.rb index 677685d67a..7cd6ac40e5 100644 --- a/services/api/app/models/user.rb +++ b/services/api/app/models/user.rb @@ -13,6 +13,8 @@ class User < ArvadosModel before_create :check_auto_admin after_create :add_system_group_permission_link after_create :send_admin_notifications + after_update :send_profile_created_notification + has_many :authorized_keys, :foreign_key => :authorized_user_uuid, :primary_key => :uuid @@ -51,9 +53,13 @@ class User < ArvadosModel def can?(actions) return true if is_admin actions.each do |action, target| - target_uuid = target - if target.respond_to? :uuid - target_uuid = target.uuid + unless target.nil? + if target.respond_to? :uuid + target_uuid = target.uuid + else + target_uuid = target + target = ArvadosModel.find_by_uuid(target_uuid) + end end next if target_uuid == self.uuid next if (group_permissions[target_uuid] and @@ -75,19 +81,30 @@ class User < ArvadosModel # Return a hash of {group_uuid: perm_hash} where perm_hash[:read] # and perm_hash[:write] are true if this user can read and write # objects owned by group_uuid. + # + # The permission graph is built by repeatedly enumerating all + # permission links reachable from self.uuid, and then calling + # search_permissions def group_permissions Rails.cache.fetch "groups_for_user_#{self.uuid}" do permissions_from = {} todo = {self.uuid => true} done = {} + # Build the equivalence class of permissions starting with + # self.uuid. On each iteration of this loop, todo contains + # the next set of uuids in the permission equivalence class + # to evaluate. while !todo.empty? lookup_uuids = todo.keys lookup_uuids.each do |uuid| done[uuid] = true end todo = {} newgroups = [] + # include all groups owned by the current set of uuids. Group.where('owner_uuid in (?)', lookup_uuids).each do |group| newgroups << [group.owner_uuid, group.uuid, 'can_manage'] end + # add any permission links from the current lookup_uuids to a + # User or Group. Link.where('tail_uuid in (?) and link_class = ? and (head_uuid like ? or head_uuid like ?)', lookup_uuids, 'permission', @@ -146,7 +163,7 @@ class User < ArvadosModel # delete repo_perms for this user repo_perms = Link.where(tail_uuid: self.uuid, link_class: 'permission', - name: 'can_write') + name: 'can_manage') repo_perms.each do |perm| Link.delete perm end @@ -183,6 +200,19 @@ class User < ArvadosModel self.save! end + # update current user profile + def profile updated_profile + user_profile = self.prefs['profile'] + user_profile ||= {} + updated_profile.each do |entry| + if entry[0].starts_with? 'profile_' + user_profile[entry[0].partition('_').last] = entry[1] + end + end + self.prefs['profile'] = user_profile + self.save! + end + protected def ensure_ownership_path_leads_to_user @@ -203,7 +233,7 @@ class User < ArvadosModel def check_auto_admin if User.where("uuid not like '%-000000000000000'").where(:is_admin => true).count == 0 and Rails.configuration.auto_admin_user - if current_user.email == Rails.configuration.auto_admin_user + if self.email == Rails.configuration.auto_admin_user self.is_admin = true self.is_active = true end @@ -297,7 +327,7 @@ class User < ArvadosModel repo_perms = Link.where(tail_uuid: self.uuid, head_uuid: repo[:uuid], link_class: 'permission', - name: 'can_write') + name: 'can_manage') if repo_perms.any? logger.warn "User already has repository access " + repo_perms.collect { |p| p[:uuid] }.inspect @@ -312,7 +342,7 @@ class User < ArvadosModel repo_perm = Link.create(tail_uuid: self.uuid, head_uuid: repo[:uuid], link_class: 'permission', - name: 'can_write') + name: 'can_manage') logger.info { "repo permission: " + repo_perm[:uuid] } return repo_perm end @@ -414,4 +444,15 @@ class User < ArvadosModel AdminNotifier.new_inactive_user(self).deliver end end + + # Send notification if the user saved profile for the first time + def send_profile_created_notification + if self.changes.andand.include?(:prefs) + if !self.changes[:prefs][0].andand.keys.andand.any? + profile_notification_address = Rails.configuration.user_profile_notification_address + ProfileNotifier.profile_created(self, profile_notification_address).deliver if profile_notification_address + end + end + end + end