blob: d1eede65f0c9ecf561510cace7d6e140e9968368 (
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
|
# 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].nil?
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 }
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')
|