From: Matías Aguirre Date: Sun, 6 Mar 2011 14:20:57 +0000 (-0200) Subject: LinkedIn Support from Quard X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=fc1def94978fa255fb338e4a5bde6d8f07cc5e84;p=django-social-auth.git LinkedIn Support from Quard --- diff --git a/social_auth/backends/contrib/linkedin.py b/social_auth/backends/contrib/linkedin.py new file mode 100644 index 0000000..931b8f8 --- /dev/null +++ b/social_auth/backends/contrib/linkedin.py @@ -0,0 +1,77 @@ +""" +Linkedin OAuth support + +No extra configurations are needed to make this work. +""" +import urlparse +import xml +from xml.etree import ElementTree + +from social_auth.backends import ConsumerBasedOAuth, OAuthBackend, USERNAME + + +LINKEDIN_SERVER = 'linkedin.com' +LINKEDIN_REQUEST_TOKEN_URL = 'https://api.%s/uas/oauth/requestToken' % LINKEDIN_SERVER +LINKEDIN_ACCESS_TOKEN_URL = 'https://api.%s/uas/oauth/accessToken' % LINKEDIN_SERVER +LINKEDIN_AUTHORIZATION_URL = 'https://www.%s/uas/oauth/authenticate' % LINKEDIN_SERVER +LINKEDIN_CHECK_AUTH = 'https://api.%s/v1/people/~' % LINKEDIN_SERVER + + +class LinkedinBackend(OAuthBackend): + """Linkedin OAuth authentication backend""" + name = 'linkedin' + + def get_user_details(self, response): + """Return user details from Linkedin account""" + return { + 'first_name': response['first-name'], + 'last_name': response['last-name'], + 'email': '', # not supplied + } + + +class LinkedinAuth(ConsumerBasedOAuth): + """Linkedin OAuth authentication mechanism""" + AUTHORIZATION_URL = LINKEDIN_AUTHORIZATION_URL + REQUEST_TOKEN_URL = LINKEDIN_REQUEST_TOKEN_URL + ACCESS_TOKEN_URL = LINKEDIN_ACCESS_TOKEN_URL + SERVER_URL = 'api.%s' % LINKEDIN_SERVER + AUTH_BACKEND = LinkedinBackend + SETTINGS_KEY_NAME = 'LINKEDIN_CONSUMER_KEY' + SETTINGS_SECRET_NAME = 'LINKEDIN_CONSUMER_SECRET' + + def user_data(self, access_token): + """Return user data provided""" + request = self.oauth_request(access_token, LINKEDIN_CHECK_AUTH) + raw_xml = self.fetch_response(request) + try: + xml = ElementTree.fromstring(raw_xml) + data = _xml_to_dict(xml) + url = data['site-standard-profile-request']['url'] + url = url.replace('&', '&') + data['id'] = urlparse.parse_qs(url)['key'][0] + + return data + except (xml.parsers.expat.ExpatError, KeyError, IndexError): + return None + + @classmethod + def enabled(cls): + return True + + +# Backend definition +BACKENDS = { + 'linkedin': LinkedinAuth, +} + + +def _xml_to_dict(xml): + data = {} + for child in xml.getchildren(): + if child.getchildren(): + data[child.tag] = _xml_to_dict(child) + else: + data[child.tag] = child.text + + return data diff --git a/social_auth/backends/linkedin.py b/social_auth/backends/linkedin.py deleted file mode 100644 index 931b8f8..0000000 --- a/social_auth/backends/linkedin.py +++ /dev/null @@ -1,77 +0,0 @@ -""" -Linkedin OAuth support - -No extra configurations are needed to make this work. -""" -import urlparse -import xml -from xml.etree import ElementTree - -from social_auth.backends import ConsumerBasedOAuth, OAuthBackend, USERNAME - - -LINKEDIN_SERVER = 'linkedin.com' -LINKEDIN_REQUEST_TOKEN_URL = 'https://api.%s/uas/oauth/requestToken' % LINKEDIN_SERVER -LINKEDIN_ACCESS_TOKEN_URL = 'https://api.%s/uas/oauth/accessToken' % LINKEDIN_SERVER -LINKEDIN_AUTHORIZATION_URL = 'https://www.%s/uas/oauth/authenticate' % LINKEDIN_SERVER -LINKEDIN_CHECK_AUTH = 'https://api.%s/v1/people/~' % LINKEDIN_SERVER - - -class LinkedinBackend(OAuthBackend): - """Linkedin OAuth authentication backend""" - name = 'linkedin' - - def get_user_details(self, response): - """Return user details from Linkedin account""" - return { - 'first_name': response['first-name'], - 'last_name': response['last-name'], - 'email': '', # not supplied - } - - -class LinkedinAuth(ConsumerBasedOAuth): - """Linkedin OAuth authentication mechanism""" - AUTHORIZATION_URL = LINKEDIN_AUTHORIZATION_URL - REQUEST_TOKEN_URL = LINKEDIN_REQUEST_TOKEN_URL - ACCESS_TOKEN_URL = LINKEDIN_ACCESS_TOKEN_URL - SERVER_URL = 'api.%s' % LINKEDIN_SERVER - AUTH_BACKEND = LinkedinBackend - SETTINGS_KEY_NAME = 'LINKEDIN_CONSUMER_KEY' - SETTINGS_SECRET_NAME = 'LINKEDIN_CONSUMER_SECRET' - - def user_data(self, access_token): - """Return user data provided""" - request = self.oauth_request(access_token, LINKEDIN_CHECK_AUTH) - raw_xml = self.fetch_response(request) - try: - xml = ElementTree.fromstring(raw_xml) - data = _xml_to_dict(xml) - url = data['site-standard-profile-request']['url'] - url = url.replace('&', '&') - data['id'] = urlparse.parse_qs(url)['key'][0] - - return data - except (xml.parsers.expat.ExpatError, KeyError, IndexError): - return None - - @classmethod - def enabled(cls): - return True - - -# Backend definition -BACKENDS = { - 'linkedin': LinkedinAuth, -} - - -def _xml_to_dict(xml): - data = {} - for child in xml.getchildren(): - if child.getchildren(): - data[child.tag] = _xml_to_dict(child) - else: - data[child.tag] = child.text - - return data