/usr/lib/python3/dist-packages/social/backends/linkedin.py is in python3-social-auth 0.2.13-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | """
LinkedIn OAuth1 and OAuth2 backend, docs at:
http://psa.matiasaguirre.net/docs/backends/linkedin.html
"""
from social.backends.oauth import BaseOAuth1, BaseOAuth2
class BaseLinkedinAuth(object):
EXTRA_DATA = [('id', 'id'),
('first-name', 'first_name', True),
('last-name', 'last_name', True),
('firstName', 'first_name', True),
('lastName', 'last_name', True)]
USER_DETAILS = 'https://api.linkedin.com/v1/people/~:({0})'
def get_user_details(self, response):
"""Return user details from Linkedin account"""
fullname, first_name, last_name = self.get_user_names(
first_name=response['firstName'],
last_name=response['lastName']
)
email = response.get('emailAddress', '')
return {'username': first_name + last_name,
'fullname': fullname,
'first_name': first_name,
'last_name': last_name,
'email': email}
def user_details_url(self):
# use set() since LinkedIn fails when values are duplicated
fields_selectors = list(set(['first-name', 'id', 'last-name'] +
self.setting('FIELD_SELECTORS', [])))
# user sort to ease the tests URL mocking
fields_selectors.sort()
fields_selectors = ','.join(fields_selectors)
return self.USER_DETAILS.format(fields_selectors)
def user_data_headers(self):
lang = self.setting('FORCE_PROFILE_LANGUAGE')
if lang:
return {
'Accept-Language': lang if lang is not True
else self.strategy.get_language()
}
class LinkedinOAuth(BaseLinkedinAuth, BaseOAuth1):
"""Linkedin OAuth authentication backend"""
name = 'linkedin'
SCOPE_SEPARATOR = '+'
AUTHORIZATION_URL = 'https://www.linkedin.com/uas/oauth/authenticate'
REQUEST_TOKEN_URL = 'https://api.linkedin.com/uas/oauth/requestToken'
ACCESS_TOKEN_URL = 'https://api.linkedin.com/uas/oauth/accessToken'
def user_data(self, access_token, *args, **kwargs):
"""Return user data provided"""
return self.get_json(
self.user_details_url(),
params={'format': 'json'},
auth=self.oauth_auth(access_token),
headers=self.user_data_headers()
)
def unauthorized_token(self):
"""Makes first request to oauth. Returns an unauthorized Token."""
scope = self.get_scope() or ''
if scope:
scope = '?scope=' + self.SCOPE_SEPARATOR.join(scope)
return self.request(self.REQUEST_TOKEN_URL + scope,
params=self.request_token_extra_arguments(),
auth=self.oauth_auth()).text
class LinkedinOAuth2(BaseLinkedinAuth, BaseOAuth2):
name = 'linkedin-oauth2'
SCOPE_SEPARATOR = ' '
AUTHORIZATION_URL = 'https://www.linkedin.com/uas/oauth2/authorization'
ACCESS_TOKEN_URL = 'https://www.linkedin.com/uas/oauth2/accessToken'
ACCESS_TOKEN_METHOD = 'POST'
REDIRECT_STATE = False
def user_data(self, access_token, *args, **kwargs):
return self.get_json(
self.user_details_url(),
params={'oauth2_access_token': access_token,
'format': 'json'},
headers=self.user_data_headers()
)
def request_access_token(self, *args, **kwargs):
# LinkedIn expects a POST request with querystring parameters, despite
# the spec http://tools.ietf.org/html/rfc6749#section-4.1.3
kwargs['params'] = kwargs.pop('data')
return super(LinkedinOAuth2, self).request_access_token(
*args, **kwargs
)
|