X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/42a27c7cabdacb00bd5a9ba06443c8a72322738b..d22f7ca7789a9e1c00f41864e577b8aac5154123:/services/api/app/models/user.rb diff --git a/services/api/app/models/user.rb b/services/api/app/models/user.rb index 4df38ced67..a47a4583cd 100644 --- a/services/api/app/models/user.rb +++ b/services/api/app/models/user.rb @@ -12,6 +12,7 @@ class User < ArvadosModel before_update :prevent_inactive_admin before_create :check_auto_admin after_create :add_system_group_permission_link + after_create :auto_setup_new_user after_create :send_admin_notifications after_update :send_profile_created_notification @@ -28,6 +29,7 @@ class User < ArvadosModel t.add :is_admin t.add :is_invited t.add :prefs + t.add :writable_by end ALL_PERMISSIONS = {read: true, write: true, manage: true} @@ -69,6 +71,30 @@ class User < ArvadosModel next if (group_permissions[target.owner_uuid] and group_permissions[target.owner_uuid][action]) end + sufficient_perms = case action + when :manage + ['can_manage'] + when :write + ['can_manage', 'can_write'] + when :read + ['can_manage', 'can_write', 'can_read'] + else + # (Skip this kind of permission opportunity + # if action is an unknown permission type) + end + if sufficient_perms + # Check permission links with head_uuid pointing directly at + # the target object. If target is a Group, this is redundant + # and will fail except [a] if permission caching is broken or + # [b] during a race condition, where a permission link has + # *just* been added. + if Link.where(link_class: 'permission', + name: sufficient_perms, + tail_uuid: groups_i_can(action) + [self.uuid], + head_uuid: target_uuid).any? + next + end + end return false end true @@ -208,11 +234,13 @@ class User < ArvadosModel end def check_auto_admin - if User.where("uuid not like '%-000000000000000'").where(:is_admin => true).count == 0 and Rails.configuration.auto_admin_user - if self.email == Rails.configuration.auto_admin_user - self.is_admin = true - self.is_active = true - end + return if self.uuid.end_with?('anonymouspublic') + if (User.where("email = ?",self.email).where(:is_admin => true).count == 0 and + Rails.configuration.auto_admin_user and self.email == Rails.configuration.auto_admin_user) or + (User.where("uuid not like '%-000000000000000'").where(:is_admin => true).count == 0 and + Rails.configuration.auto_admin_first_user) + self.is_admin = true + self.is_active = true end end @@ -371,40 +399,20 @@ class User < ArvadosModel # add the user to the 'All users' group def create_user_group_link - # Look up the "All users" group (we expect uuid *-*-fffffffffffffff). - group = Group.where(name: 'All users').select do |g| - g[:uuid].match /-f+$/ - end.first - - if not group - logger.warn "No 'All users' group with uuid '*-*-fffffffffffffff'." - raise "No 'All users' group with uuid '*-*-fffffffffffffff' is found" - else - logger.info { "\"All users\" group uuid: " + group[:uuid] } - - group_perms = Link.where(tail_uuid: self.uuid, - head_uuid: group[:uuid], - link_class: 'permission', - name: 'can_read') - - if !group_perms.any? - group_perm = Link.create(tail_uuid: self.uuid, - head_uuid: group[:uuid], - link_class: 'permission', - name: 'can_read') - logger.info { "group permission: " + group_perm[:uuid] } - else - group_perm = group_perms.first - end - - return group_perm - end + return (Link.where(tail_uuid: self.uuid, + head_uuid: all_users_group[:uuid], + link_class: 'permission', + name: 'can_read').first or + Link.create(tail_uuid: self.uuid, + head_uuid: all_users_group[:uuid], + link_class: 'permission', + name: 'can_read')) end # Give the special "System group" permission to manage this user and # all of this user's stuff. - # def add_system_group_permission_link + return true if uuid == system_user_uuid act_as_system_user do Link.create(link_class: 'permission', name: 'can_manage', @@ -421,6 +429,49 @@ class User < ArvadosModel end end + # Automatically setup new user during creation + def auto_setup_new_user + return true if !Rails.configuration.auto_setup_new_users + return true if !self.email + return true if self.uuid == system_user_uuid + return true if self.uuid == anonymous_user_uuid + + if Rails.configuration.auto_setup_new_users_with_vm_uuid || + Rails.configuration.auto_setup_new_users_with_repository + username = self.email.partition('@')[0] if self.email + return true if !username + + blacklisted_usernames = Rails.configuration.auto_setup_name_blacklist + if blacklisted_usernames.include?(username) + return true + elsif !(/^[a-zA-Z][-._a-zA-Z0-9]{0,30}[a-zA-Z0-9]$/.match(username)) + return true + else + return true if !(username = derive_unique_username username) + end + end + + # setup user + setup_repo_vm_links(username, + Rails.configuration.auto_setup_new_users_with_vm_uuid, + Rails.configuration.default_openid_prefix) + end + + # Find a username that starts with the given string and does not collide + # with any existing repository name or VM login name + def derive_unique_username username + while true + if Repository.where(name: username).empty? + login_collisions = Link.where(link_class: 'permission', + name: 'can_login').select do |perm| + perm.properties['username'] == username + end + return username if login_collisions.empty? + end + username = username + SecureRandom.random_number(10).to_s + end + end + # Send notification if the user saved profile for the first time def send_profile_created_notification if self.prefs_changed?