X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/9624ed0931aac929f0d773dfee8b9e620b9352ad..86b14bac0b6413dd033285a4357cc7edd05a22b3:/services/api/app/models/user.rb?ds=sidebyside diff --git a/services/api/app/models/user.rb b/services/api/app/models/user.rb index 04bf681161..6e7facd5d5 100644 --- a/services/api/app/models/user.rb +++ b/services/api/app/models/user.rb @@ -70,6 +70,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 @@ -104,12 +128,13 @@ class User < ArvadosModel 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, + # add any permission links from the current lookup_uuids to a Group. + Link.where('link_class = ? and tail_uuid in (?) and ' \ + '(head_uuid like ? or (name = ? and head_uuid like ?))', 'permission', + lookup_uuids, Group.uuid_like_pattern, + 'can_manage', User.uuid_like_pattern).each do |link| newgroups << [link.tail_uuid, link.head_uuid, link.name] end @@ -433,7 +458,7 @@ class User < ArvadosModel blacklisted_usernames = Rails.configuration.auto_setup_name_blacklist if blacklisted_usernames.include?(username) - return true; + return true elsif !(/^[a-zA-Z][-._a-zA-Z0-9]{0,30}[a-zA-Z0-9]$/.match(username)) return true else @@ -442,35 +467,24 @@ class User < ArvadosModel end # setup user - if !Rails.configuration.auto_setup_new_users_with_vm_uuid && - !Rails.configuration.auto_setup_new_users_with_repository - oid_login_perm = create_oid_login_perm Rails.configuration.default_openid_prefix - group_perm = create_user_group_link - else - setup_repo_vm_links(username, - Rails.configuration.auto_setup_new_users_with_vm_uuid, - Rails.configuration.default_openid_prefix) - end + 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 orig_username - username = String.new orig_username - 10000.times do |count| + 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 - if login_collisions.empty? - return username - end + return username if login_collisions.empty? end - - username = orig_username + SecureRandom.random_number(1000).to_s + username = username + SecureRandom.random_number(10).to_s end - return nil # count expired and no unused username was available end # Send notification if the user saved profile for the first time