diff --git a/auth/auth_systems/__init__.py b/auth/auth_systems/__init__.py index 8f13235e021eb205dbbafb5892c20322cb03bd79..39f5ef14314d57671f71fec507dd80f6508f7d42 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 0000000000000000000000000000000000000000..9a939e2492d0c4edc03253134885e59e315b5f76 --- /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 e1a4e18b7ccc2c84d6cccec0f0ab21f27ba120ad..c9e6b829bb946694130cabcc6b336939864bcb3a 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 73f8bfe21b623025c89eeeebd1991d098b0d7ec6..56ea1aba862cdde73bc108448dadb1d90b8567f1 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 Binary files /dev/null and b/auth/media/login-icons/linkedin.png differ diff --git a/settings.py.sample b/settings.py.sample index 7fe210b0c311e81388d29d2e1e87efc9577035b2..d9d81ca3139200cea520aeed799c375c2a415851 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