From 281c4e41a51312eed71a7254539b98e4ed2ba0c3 Mon Sep 17 00:00:00 2001
From: Ben Adida <ben@adida.net>
Date: Sun, 7 Nov 2010 16:12:01 -0800
Subject: [PATCH] tweaked oauth login to be multi-server capable, added linked
 auth

---
 auth/auth_systems/__init__.py           |   3 +-
 auth/auth_systems/linkedin.py           |  91 ++++++++++++++++++++++++
 auth/auth_systems/oauthclient/client.py |  35 +++++----
 auth/auth_systems/twitter.py            |  12 +++-
 auth/media/login-icons/linkedin.png     | Bin 0 -> 20289 bytes
 settings.py.sample                      |   4 ++
 6 files changed, 130 insertions(+), 15 deletions(-)
 create mode 100644 auth/auth_systems/linkedin.py
 create mode 100644 auth/media/login-icons/linkedin.png

diff --git a/auth/auth_systems/__init__.py b/auth/auth_systems/__init__.py
index 8f13235..39f5ef1 100644
--- a/auth/auth_systems/__init__.py
+++ b/auth/auth_systems/__init__.py
@@ -1,8 +1,9 @@
 
 AUTH_SYSTEMS = {}
 
-import twitter, password, cas, facebook, google, yahoo
+import twitter, password, cas, facebook, google, yahoo, linkedin
 AUTH_SYSTEMS['twitter'] = twitter
+AUTH_SYSTEMS['linkedin'] = linkedin
 AUTH_SYSTEMS['password'] = password
 AUTH_SYSTEMS['cas'] = cas
 AUTH_SYSTEMS['facebook'] = facebook
diff --git a/auth/auth_systems/linkedin.py b/auth/auth_systems/linkedin.py
new file mode 100644
index 0000000..9a939e2
--- /dev/null
+++ b/auth/auth_systems/linkedin.py
@@ -0,0 +1,91 @@
+"""
+LinkedIn Authentication
+"""
+
+from oauthclient import client
+
+from django.core.urlresolvers import reverse
+from django.http import HttpResponseRedirect
+
+from auth import utils
+
+from xml.etree import ElementTree
+
+import logging
+
+from django.conf import settings
+API_KEY = settings.LINKEDIN_API_KEY
+API_SECRET = settings.LINKEDIN_API_SECRET
+
+# some parameters to indicate that status updating is possible
+STATUS_UPDATES = False
+STATUS_UPDATE_WORDING_TEMPLATE = "Tweet %s"
+
+OAUTH_PARAMS = {
+  'root_url' : 'https://api.linkedin.com/uas',
+  'request_token_path' : '/oauth/requestToken',
+  'authorize_path' : '/oauth/authorize',
+  'authenticate_path' : '/oauth/authenticate',
+  'access_token_path': '/oauth/accessToken'
+}
+
+def _get_new_client(token=None, token_secret=None):
+  if token:
+    return client.LoginOAuthClient(API_KEY, API_SECRET, OAUTH_PARAMS, token, token_secret)
+  else:
+    return client.LoginOAuthClient(API_KEY, API_SECRET, OAUTH_PARAMS)
+
+def _get_client_by_token(token):
+  return _get_new_client(token['oauth_token'], token['oauth_token_secret'])
+
+def get_auth_url(request, redirect_url):
+  client = _get_new_client()
+  try:
+    tok = client.get_request_token()
+  except:
+    return None
+  
+  request.session['request_token'] = tok
+  url = client.get_authenticate_url(tok['oauth_token']) 
+  return url
+    
+def get_user_info_after_auth(request):
+  tok = request.session['request_token']
+  login_client = _get_client_by_token(tok)
+  access_token = login_client.get_access_token(verifier = request.GET.get('oauth_verifier', None))
+  request.session['access_token'] = access_token
+    
+  user_info_xml = ElementTree.fromstring(login_client.oauth_request('http://api.linkedin.com/v1/people/~:(id,first-name,last-name)', args={}, method='GET'))
+  
+  user_id = user_info_xml.findtext('id')
+  first_name = user_info_xml.findtext('first-name')
+  last_name = user_info_xml.findtext('last-name')
+
+  return {'type': 'linkedin', 'user_id' : user_id, 'name': "%s %s" % (first_name, last_name), 'info': {}, 'token': access_token}
+    
+
+def user_needs_intervention(user_id, user_info, token):
+  """
+  check to see if user is following the users we need
+  """
+  return None
+
+def _get_client_by_request(request):
+  access_token = request.session['access_token']
+  return _get_client_by_token(access_token)
+  
+def update_status(user_id, user_info, token, message):
+  """
+  post a message to the auth system's update stream, e.g. twitter stream
+  """
+  return
+  #twitter_client = _get_client_by_token(token)
+  #result = twitter_client.oauth_request('http://api.twitter.com/1/statuses/update.json', args={'status': message}, method='POST')
+
+def send_message(user_id, user_name, user_info, subject, body):
+  pass
+
+def send_notification(user_id, user_info, message):
+  pass
+
+
diff --git a/auth/auth_systems/oauthclient/client.py b/auth/auth_systems/oauthclient/client.py
index e1a4e18..c9e6b82 100644
--- a/auth/auth_systems/oauthclient/client.py
+++ b/auth/auth_systems/oauthclient/client.py
@@ -1,5 +1,6 @@
 '''
 Python Oauth client for Twitter
+modified to work with other oAuth logins like LinkedIn (Ben Adida)
 
 Used the SampleClient from the OAUTH.org example python client as basis.
 
@@ -13,22 +14,26 @@ import webbrowser
 import oauth as oauth
 from urlparse import urlparse
 
-class TwitterOAuthClient(oauth.OAuthClient):
-    api_root_url = 'https://twitter.com' #for testing 'http://term.ie'
-    api_root_port = "80"
+class LoginOAuthClient(oauth.OAuthClient):
 
     #set api urls
     def request_token_url(self):
-        return self.api_root_url + '/oauth/request_token'
+        return self.server_params['root_url'] + self.server_params['request_token_path']
     def authorize_url(self):
-        return self.api_root_url + '/oauth/authorize'
+        return self.server_params['root_url'] + self.server_params['authorize_path']
     def authenticate_url(self):
-      return self.api_root_url + '/oauth/authenticate'
+        return self.server_params['root_url'] + self.server_params['authenticate_path']
     def access_token_url(self):
-        return self.api_root_url + '/oauth/access_token'
+        return self.server_params['root_url'] + self.server_params['access_token_path']
 
     #oauth object
-    def __init__(self, consumer_key, consumer_secret, oauth_token=None, oauth_token_secret=None):
+    def __init__(self, consumer_key, consumer_secret, server_params, oauth_token=None, oauth_token_secret=None):
+        """
+        params should be a dictionary including
+        root_url, request_token_path, authorize_path, authenticate_path, access_token_path
+        """
+        self.server_params = server_params
+
         self.sha1_method = oauth.OAuthSignatureMethod_HMAC_SHA1()
         self.consumer = oauth.OAuthConsumer(consumer_key, consumer_secret)
         if ((oauth_token != None) and (oauth_token_secret!=None)):
@@ -97,8 +102,11 @@ class TwitterOAuthClient(oauth.OAuthClient):
     def get_authenticate_url(self, token):
         return self.authenticate_url() + '?oauth_token=' +token
 
-    def get_access_token(self,token=None):
-        r = self.oauth_request(self.access_token_url())
+    def get_access_token(self,token=None,verifier=None):
+        if verifier:
+            r = self.oauth_request(self.access_token_url(), args={'oauth_verifier': verifier})
+        else:
+            r = self.oauth_request(self.access_token_url())
         token = self.oauth_parse_response(r)
         self.token = oauth.OAuthConsumer(token['oauth_token'],token['oauth_token_secret'])
         return token
@@ -117,6 +125,9 @@ class TwitterOAuthClient(oauth.OAuthClient):
             return self.http_wrapper(req.get_normalized_http_url(),req.to_postdata())
 
         
+##
+## the code below needs to be updated to take into account not just Twitter
+##
 
 if __name__ == '__main__':
     consumer_key = ''
@@ -125,7 +136,7 @@ if __name__ == '__main__':
         consumer_key = raw_input('Please enter consumer key: ')
     while not consumer_secret:
         consumer_secret = raw_input('Please enter consumer secret: ')
-    auth_client = TwitterOAuthClient(consumer_key,consumer_secret)
+    auth_client = LoginOAuthClient(consumer_key,consumer_secret)
     tok = auth_client.get_request_token()
     token = tok['oauth_token']
     token_secret = tok['oauth_token_secret']
@@ -133,7 +144,7 @@ if __name__ == '__main__':
     webbrowser.open(url)
     print "Visit this URL to authorize your app: " + url
     response_token = raw_input('What is the oauth_token from twitter: ')
-    response_client = TwitterOAuthClient(consumer_key, consumer_secret,token, token_secret) 
+    response_client = LoginOAuthClient(consumer_key, consumer_secret,token, token_secret, server_params={})
     tok = response_client.get_access_token()
     print "Making signed request"
     #verify user access
diff --git a/auth/auth_systems/twitter.py b/auth/auth_systems/twitter.py
index 73f8bfe..56ea1ab 100644
--- a/auth/auth_systems/twitter.py
+++ b/auth/auth_systems/twitter.py
@@ -22,11 +22,19 @@ DM_TOKEN = settings.TWITTER_DM_TOKEN
 STATUS_UPDATES = True
 STATUS_UPDATE_WORDING_TEMPLATE = "Tweet %s"
 
+OAUTH_PARAMS = {
+  'root_url' : 'https://twitter.com',
+  'request_token_path' : '/oauth/request_token',
+  'authorize_path' : '/oauth/authorize',
+  'authenticate_path' : '/oauth/authenticate',
+  'access_token_path': '/oauth/access_token'
+}
+
 def _get_new_client(token=None, token_secret=None):
   if token:
-    return client.TwitterOAuthClient(API_KEY, API_SECRET, token, token_secret)
+    return client.LoginOAuthClient(API_KEY, API_SECRET, OAUTH_PARAMS, token, token_secret)
   else:
-    return client.TwitterOAuthClient(API_KEY, API_SECRET)
+    return client.LoginOAuthClient(API_KEY, API_SECRET, OAUTH_PARAMS)
 
 def _get_client_by_token(token):
   return _get_new_client(token['oauth_token'], token['oauth_token_secret'])
diff --git a/auth/media/login-icons/linkedin.png b/auth/media/login-icons/linkedin.png
new file mode 100644
index 0000000000000000000000000000000000000000..745ef3b3d2e4cb37773ae70604dae7344d7705c9
GIT binary patch
literal 20289
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

literal 0
HcmV?d00001

diff --git a/settings.py.sample b/settings.py.sample
index 7fe210b..d9d81ca 100644
--- a/settings.py.sample
+++ b/settings.py.sample
@@ -153,6 +153,10 @@ TWITTER_REASON_TO_FOLLOW = "we can direct-message you when the result has been c
 # the token for Helios to do direct messaging
 TWITTER_DM_TOKEN = {"oauth_token": "", "oauth_token_secret": "", "user_id": "", "screen_name": ""}
 
+# LinkedIn
+LINKEDIN_API_KEY = ''
+LINKEDIN_API_SECRET = ''
+
 # email server
 EMAIL_HOST = 'localhost'
 EMAIL_PORT = 1025
-- 
GitLab