user.rb 2.62 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
# OAuth extension for User model
#
# * Find GitLab user based on omniauth uid and provider
# * Create new user from omniauth data
#
module Gitlab
  module OAuth
    class User
      class << self
        attr_reader :auth

        def find(auth)
          @auth = auth
          find_by_uid_and_provider
        end

        def create(auth)
          @auth = auth
          password = Devise.friendly_token[0, 8].downcase
          opts = {
            extern_uid: uid,
            provider: provider,
            name: name,
            username: username,
            email: email,
            password: password,
            password_confirmation: password,
          }

Izaak Alpert's avatar
Izaak Alpert committed
30
          user = model.build_user(opts, as: :admin)
31
          user.skip_confirmation!
32

33 34
          # Services like twitter and github does not return email via oauth
          # In this case we generate temporary email and force user to fill it later
35 36
          if user.email.blank?
            user.generate_tmp_oauth_email
37
          elsif provider != "ldap"
38 39
            # Google oauth returns email but dont return nickname
            # So we use part of email as username for new user
40 41
            # For LDAP, username is already set to the user's
            # uid/userid/sAMAccountName.
42 43 44
            email_username = email.match(/^[^@]*/)[0]
            # Strip apostrophes since they are disallowed as part of username
            user.username = email_username.gsub("'", "")
45 46
          end

47
          user.save!
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
          log.info "(OAuth) Creating user #{email} from login with extern_uid => #{uid}"

          if Gitlab.config.omniauth['block_auto_created_users'] && !ldap?
            user.block
          end

          user
        end

        private

        def find_by_uid_and_provider
          model.where(provider: provider, extern_uid: uid).last
        end

        def uid
          auth.info.uid || auth.uid
        end

        def email
          auth.info.email.downcase unless auth.info.email.nil?
        end

        def name
72
          if auth.info.name.nil?
73
            "#{auth.info.first_name} #{auth.info.last_name}".force_encoding('utf-8')
74 75
          else
            auth.info.name.to_s.force_encoding('utf-8')
76
          end
77 78 79
        end

        def username
80
          auth.info.nickname.to_s.force_encoding("utf-8")
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
        end

        def provider
          auth.provider
        end

        def log
          Gitlab::AppLogger
        end

        def model
          ::User
        end

        def raise_error(message)
          raise OmniAuth::Error, "(OAuth) " + message
        end

        def ldap?
          provider == 'ldap'
        end
      end
    end
  end
end