]> git.parisson.com Git - django-social-auth.git/commitdiff
added linkedin support
authorVadym Zakovinko <vp@zakovinko.com>
Mon, 28 Feb 2011 17:07:19 +0000 (19:07 +0200)
committerVadym Zakovinko <vp@zakovinko.com>
Mon, 28 Feb 2011 17:11:09 +0000 (19:11 +0200)
.gitignore
example/settings.py
example/templates/home.html
social_auth/backends/linkedin.py [new file with mode: 0644]

index f951e966d4a00f1aa2c9b8f5a469560c6ef0e82d..095d624c4b76152b19cf5599a82a3bff1ff94444 100644 (file)
@@ -6,3 +6,4 @@ build/
 dist/
 django_social_auth.egg-info/
 social_auth.egg-info/
+env/
index f2e7d7c8d733d2220adffb8083a700b1856507a4..8e63d8740b578c5cdb474d5fd9580d2a96b5107f 100644 (file)
@@ -67,6 +67,7 @@ AUTHENTICATION_BACKENDS = (
     'social_auth.backends.google.GoogleOAuthBackend',
     'social_auth.backends.google.GoogleBackend',
     'social_auth.backends.yahoo.YahooBackend',
+    'social_auth.backends.linkedin.LinkedinBackend',
     'social_auth.backends.OpenIDBackend',
     'social_auth.backends.contrib.livejournal.LiveJournalBackend',
     'django.contrib.auth.backends.ModelBackend',
index c040c2c3ed50a374a87203c5d823fda06b184e4e..d9dbf5149aa45842656aed31492d54978346b0e1 100644 (file)
@@ -8,6 +8,7 @@
   <ul>
     <li><a rel="nofollow" href="{% url begin "twitter" %}">Twitter</a></li>
     <li><a rel="nofollow" href="{% url begin "facebook" %}">Facebook</a></li>
+    <li><a rel="nofollow" href="{% url begin "linkedin" %}">Linkedin</a></li>
     <li><a rel="nofollow" href="{% url begin "orkut" %}">Orkut</a></li>
     <li><a rel="nofollow" href="{% url begin "google-oauth" %}">Google OAuth</a></li>
   </ul>
diff --git a/social_auth/backends/linkedin.py b/social_auth/backends/linkedin.py
new file mode 100644 (file)
index 0000000..931b8f8
--- /dev/null
@@ -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('&amp;', '&')
+            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