Welcome to mirror list, hosted at ThFree Co, Russian Federation.

auth_hash.rb « o_auth « auth « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c2b49c1c068db8419e355c7e27588b530384acf7 (plain)
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# frozen_string_literal: true

# Class to parse and transform the info provided by omniauth
#
module Gitlab
  module Auth
    module OAuth
      class AuthHash
        attr_reader :auth_hash

        def initialize(auth_hash)
          @auth_hash = auth_hash
        end

        def uid
          @uid ||= Gitlab::Utils.force_utf8(auth_hash.uid.to_s)
        end

        def provider
          @provider ||= auth_hash.provider.to_s
        end

        def name
          @name ||= get_info(:name) || "#{get_info(:first_name)} #{get_info(:last_name)}"
        end

        def username
          @username ||= username_and_email[:username].to_s
        end

        def email
          @email ||= username_and_email[:email].to_s
        end

        def password
          @password ||= Gitlab::Utils.force_utf8(::User.random_password)
        end

        def location
          location = get_info(:address)
          if location.is_a?(Hash)
            [location.locality.presence, location.country.presence].compact.join(', ')
          else
            location
          end
        end

        def has_attribute?(attribute)
          if attribute == :location
            get_info(:address).present?
          else
            get_info(attribute).present?
          end
        end

        private

        def info
          auth_hash['info']
        end

        def coerce_utf8(value)
          value.is_a?(String) ? Gitlab::Utils.force_utf8(value) : value
        end

        def get_info(key)
          coerce_utf8(info[key])
        end

        def provider_config
          Gitlab::Auth::OAuth::Provider.config_for(provider) || {}
        end

        def provider_args
          @provider_args ||= provider_config['args'].presence || {}
        end

        def get_from_auth_hash_or_info(key)
          if auth_hash.key?(key)
            coerce_utf8(auth_hash[key])
          elsif auth_hash.key?(:extra) && auth_hash.extra.key?(:raw_info) && !auth_hash.extra.raw_info[key].blank?
            coerce_utf8(auth_hash.extra.raw_info[key])
          else
            get_info(key)
          end
        end

        # Allow for configuring a custom username claim per provider from
        # the auth hash or use the canonical username or nickname fields
        def gitlab_username_claim
          provider_args.dig('gitlab_username_claim')&.to_sym
        end

        def username_claims
          [gitlab_username_claim, :username, :nickname].compact
        end

        def get_username
          username_claims.map { |claim| get_from_auth_hash_or_info(claim) }
            .find { |name| name.presence }
            &.split("@")
            &.first
        end

        def username_and_email
          @username_and_email ||= begin
            username  = get_username
            email     = get_info(:email).presence

            username ||= generate_username(email)             if email
            email    ||= generate_temporarily_email(username) if username

            {
              username: username,
              email: email
            }
          end
        end

        # Get the first part of the email address (before @)
        # In addition in removes illegal characters
        def generate_username(email)
          email.match(/^[^@]*/)[0].mb_chars.unicode_normalize(:nfkd).gsub(/[^\x00-\x7F]/, '').to_s
        end

        def generate_temporarily_email(username)
          "temp-email-for-oauth-#{username}@gitlab.localhost"
        end
      end
    end
  end
end

Gitlab::Auth::OAuth::AuthHash.prepend_mod_with('Gitlab::Auth::OAuth::AuthHash')