diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 10fe1245115648b71dbf9cea3659eb804e6396e3..684f4be0d10e902e4173ce0c084a6e96d74fc6b2 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -110,6 +110,11 @@ production: &base # - { name: 'github', app_id: 'YOUR APP ID', # app_secret: 'YOUR APP SECRET' } + ## User mapping settings + user_mapping: + name: ->(uid, name, email) { name } + username: ->(uid, name, email) { email.match(/^[^@]*/)[0] } + email: ->(uid, name, email) { email } # diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb index 0fee33dbeb0ef4548a91a9c3662de510ca76e91a..9928849721891f51bc09e98a2486837acd8451e7 100644 --- a/lib/gitlab/auth.rb +++ b/lib/gitlab/auth.rb @@ -18,30 +18,9 @@ module Gitlab end def create_from_omniauth(auth, ldap = false) - provider = auth.provider - uid = auth.info.uid || auth.uid - uid = uid.to_s.force_encoding("utf-8") - name = auth.info.name.to_s.force_encoding("utf-8") - email = auth.info.email.to_s.downcase unless auth.info.email.nil? - - ldap_prefix = ldap ? '(LDAP) ' : '' - raise OmniAuth::Error, "#{ldap_prefix}#{provider} does not provide an email"\ - " address" if auth.info.email.blank? - - log.info "#{ldap_prefix}Creating user from #{provider} login"\ - " {uid => #{uid}, name => #{name}, email => #{email}}" - password = Devise.friendly_token[0, 8].downcase - @user = User.new({ - extern_uid: uid, - provider: provider, - name: name, - username: email.match(/^[^@]*/)[0], - email: email, - password: password, - password_confirmation: password, - projects_limit: Gitlab.config.gitlab.default_projects_limit, - }, as: :admin) - @user.save! + creation_helper = UserCreationHelper.new(auth, ldap) + log.info creation_helper.creation_message + @user = User.create!(creation_helper.parameters, as: :admin) if Gitlab.config.omniauth['block_auto_created_users'] && !ldap @user.block @@ -70,5 +49,79 @@ module Gitlab def log Gitlab::AppLogger end + + class UserCreationHelper + def initialize(auth, ldap = false) + @auth = auth + @ldap = ldap + @procs = { + name_proc: ->(uid, name, email) { name } + username_proc: ->(uid, name, email) { email.match(/^[^@]*/)[0] } + email_proc: ->(uid, name, email) { email } + }.merge(Gitlab.config.user_mapping) + end + + def parameters + { + extern_uid: uid, + provider: provider, + name: name, + username: username, + email: email, + password: password, + password_confirmation: password, + projects_limit: Gitlab.config.gitlab.default_projects_limit + } + end + + def uid + (@auth.info.uid || @auth.uid).to_s.force_encoding("utf-8") + end + + def provider + @auth.info.provider + end + + def name + @procs[:name].call(uid, raw_name, raw_email) + end + + def username + @procs[:username].call(uid, raw_name, raw_email) + end + + def email + @procs[:email].call(uid, raw_name, raw_email) + end + + def password + @password ||= Devise.friendly_token[0, 8].downcase + end + + def creation_message + "#{ldap_prefix}Creating user from #{provider} login"\ + " {uid => #{uid}, name => #{name}, email => #{email}}" + end + + private + + def raw_name + @auth.info.name.to_s.force_encoding("utf-8") + end + + def raw_email + auth.info.email.nil? ? email_error : auth.info.email.to_s.downcase + end + + def ldap_prefix + ldap ? '(LDAP) ' : '' + end + + def email_error + raise OmniAuth::Error, "#{ldap_prefix}#{parameters.provider} does not"\ + " provide an email address" unless parameters.email + end + end + end end