3
3
module OmniAuth
4
4
module Strategies
5
5
class LinkedIn < OmniAuth ::Strategies ::OAuth2
6
- # Give your strategy a name.
7
6
option :name , 'linkedin'
8
7
9
- # This is where you pass the options you would pass when
10
- # initializing your consumer from the OAuth gem.
11
8
option :client_options , {
12
9
:site => 'https://api.linkedin.com' ,
13
10
:authorize_url => 'https://www.linkedin.com/oauth/v2/authorization?response_type=code' ,
14
11
:token_url => 'https://www.linkedin.com/oauth/v2/accessToken'
15
12
}
16
13
17
14
option :scope , 'r_liteprofile r_emailaddress'
18
- option :fields , [ 'id' , 'first-name' , 'last-name' , 'picture-url' ]
15
+ option :fields , [ 'id' , 'first-name' , 'last-name' , 'picture-url' , 'email-address' ]
19
16
20
- # These are called after authentication has succeeded. If
21
- # possible, you should try to set the UID without making
22
- # additional calls (if the user id is returned with the token
23
- # or as a URI parameter). This may not be possible with all
24
- # providers.
25
17
uid do
26
18
raw_info [ 'id' ]
27
19
end
28
20
29
21
info do
30
22
{
31
- :email => nil ,
23
+ :email => email_address ,
32
24
:first_name => localized_field ( 'firstName' ) ,
33
25
:last_name => localized_field ( 'lastName' ) ,
34
26
:picture_url => picture_url
@@ -60,6 +52,30 @@ def raw_info
60
52
61
53
private
62
54
55
+ def email_address
56
+ if options . fields . include? 'email-address'
57
+ fetch_email_address
58
+ parse_email_address
59
+ end
60
+ end
61
+
62
+ def fetch_email_address
63
+ @email_address_response ||= access_token . get ( email_address_endpoint ) . parsed
64
+ end
65
+
66
+ def parse_email_address
67
+ return unless email_address_available?
68
+
69
+ @email_address_response [ 'elements' ] . first [ 'handle~' ] [ 'emailAddress' ]
70
+ end
71
+
72
+ def email_address_available?
73
+ @email_address_response [ 'elements' ] &&
74
+ @email_address_response [ 'elements' ] . is_a? ( Array ) &&
75
+ @email_address_response [ 'elements' ] . first &&
76
+ @email_address_response [ 'elements' ] . first [ 'handle~' ]
77
+ end
78
+
63
79
def fields_mapping
64
80
{
65
81
'id' => 'id' ,
@@ -71,7 +87,7 @@ def fields_mapping
71
87
72
88
def fields
73
89
options . fields . each . with_object ( [ ] ) do |field , result |
74
- result << fields_mapping [ field ]
90
+ result << fields_mapping [ field ] if fields_mapping . has_key? field
75
91
end
76
92
end
77
93
@@ -106,6 +122,10 @@ def picture_references
106
122
raw_info [ 'profilePicture' ] [ 'displayImage~' ] [ 'elements' ]
107
123
end
108
124
125
+ def email_address_endpoint
126
+ '/v2/emailAddress?q=members&projection=(elements*(handle~))'
127
+ end
128
+
109
129
def profile_endpoint
110
130
"/v2/me?projection=(#{ fields . join ( ',' ) } )"
111
131
end
0 commit comments