Permalink
Browse files

Merge pull request #53 from akshar-raaj/add_more_providers

Add more providers
  • Loading branch information...
2 parents 59279dc + 6682962 commit b0b1acb180dd955edcc9b9b9d086470b8c332de6 @shabda shabda committed Sep 25, 2013
View
@@ -25,6 +25,8 @@ In particular it allows logging in via
#. Facebook
#. Yahoo(Essentially openid)
#. OpenId
+#. Github
+#. Foursquare
Libs you need to install
See requirements.txt
@@ -38,6 +40,8 @@ The API Keys are available from
* https://developer.yahoo.com/dashboard/createKey.html
* https://www.google.com/accounts/ManageDomains
* http://twitter.com/oauth_clients
+* https://github.com/settings/applications/new
+* https://developer.foursquare.com/overview/auth.html
How it works.
--------------
@@ -51,6 +55,9 @@ How it works.
used for authentication. (It is an autorisation framework, not an authentication one),
In practice it works pretty well. Once you have an access_token, and a name, essentially
authenticated.
+* **Github**:We use Github Oauth for authentication. As like Twitter, it works
+ pretty well.
+* **Foursquare**:We use Oauth2.0 for authenticating via foursquare.
References
----------
@@ -60,11 +67,13 @@ References
#. http://code.google.com/apis/accounts/docs/OpenID.html
#. http://apiwiki.twitter.com/OAuth-FAQ
#. http://developers.facebook.com/connect.php
+#. http://develop.github.com/p/oauth.html
+#. https://developer.foursquare.com/overview/auth.html
Limitations
------------
-As with all APIs, we are limited by the amout of data which the API provider
+As with all APIs, we are limited by the amount of data which the API provider
provides us. For example, both Yahoo and Google provide extremely limited data
about the autheticated subscriber. Twitter and Facebook provide a lot of details,
but not the email. Different Openid providers are free to provide [different
@@ -95,11 +104,13 @@ Urls
* /twitter_login/ AND /twitter_login/done/
* /facebook_login/done/ We dont have a start url here, as the starting tokens are
set in a popup.
+* /github_login/ AND /github_login/done/
+* /foursquare_login/ AND /foursquare_login/done/
Implementation
---------------
#. Install required libraries.
#. Get tokens and populate in localsettings.py
-#. Set the token callback urls correctly at Twitter and Facebook.
+#. Set the token callback urls correctly at Twitter, Facebook, Github and Foursquare.
#. Set the authentication_backends to the providers you are using.
@@ -32,6 +32,13 @@
LINKEDIN_CONSUMER_KEY = ''
LINKEDIN_CONSUMER_SECRET = ''
+GITHUB_CLIENT_ID = ''
+GITHUB_CLIENT_SECRET = ''
+
+FOURSQUARE_CONSUMER_KEY = ''
+FOURSQUARE_CONSUMER_SECRET = ''
+FOURSQUARE_REGISTERED_REDIRECT_URI = ''
+
## if any of this information is desired for your app
FACEBOOK_EXTENDED_PERMISSIONS = (
#'publish_stream',
@@ -92,4 +99,6 @@
'socialauth.auth_backends.TwitterBackend',
'socialauth.auth_backends.FacebookBackend',
'socialauth.auth_backends.LinkedInBackend',
+ 'socialauth.auth_backends.GithubBackend',
+ 'socialauth.auth_backends.FoursquareBackend',
)
View
@@ -1,5 +1,5 @@
from socialauth.models import AuthMeta, OpenidProfile, TwitterUserProfile, \
-FacebookUserProfile, LinkedInUserProfile
+FacebookUserProfile, LinkedInUserProfile, GithubUserProfile, FoursquareUserProfile
from django.contrib import admin
@@ -8,3 +8,5 @@
admin.site.register(TwitterUserProfile)
admin.site.register(FacebookUserProfile)
admin.site.register(LinkedInUserProfile)
+admin.site.register(GithubUserProfile)
+admin.site.register(FoursquareUserProfile)
@@ -7,10 +7,11 @@
import urllib
from socialauth.lib import oauthtwitter2 as oauthtwitter
from socialauth.models import OpenidProfile as UserAssociation, \
-TwitterUserProfile, FacebookUserProfile, LinkedInUserProfile, AuthMeta
+TwitterUserProfile, FacebookUserProfile, LinkedInUserProfile, AuthMeta, GithubUserProfile, FoursquareUserProfile
from socialauth.lib.linkedin import *
import random
+from cgi import parse_qs
TWITTER_CONSUMER_KEY = getattr(settings, 'TWITTER_CONSUMER_KEY', '')
TWITTER_CONSUMER_SECRET = getattr(settings, 'TWITTER_CONSUMER_SECRET', '')
@@ -325,3 +326,47 @@ def get_user(self, user_id):
return User.objects.get(pk=user_id)
except:
return None
+
+class GithubBackend:
+ def authenticate(self, github_access_token, user=None):
+ response_qs = parse_qs(github_access_token)
+ github_access_token = response_qs['access_token'][0]
+ try:
+ github_user = GithubUserProfile.objects.get(access_token=github_access_token)
+ return github_user.user
+ except GithubUserProfile.DoesNotExist:
+ github_user_count = GithubUserProfile.objects.all().count()
+ username = "GithubUser:" + str(github_user_count+1)
+ user = User(username=username)
+ user.save()
+ github_user = GithubUserProfile(user=user, access_token=github_access_token)
+ github_user.save()
+ AuthMeta(user=user, provider='Github').save()
+ return github_user.user
+
+ def get_user(self, user_id):
+ try:
+ return User.objects.get(pk=user_id)
+ except:
+ return None
+
+class FoursquareBackend:
+ def authenticate(self, foursquare_access_token):
+ try:
+ foursquare_profile = FoursquareUserProfile.objects.get(access_token=foursquare_access_token)
+ return foursquare_profile.user
+ except FoursquareUserProfile.DoesNotExist:
+ foursquare_user_count = FoursquareUserProfile.objects.all().count()
+ username = "FoursquareUser:" + str(foursquare_user_count+1)
+ user = User(username=username)
+ user.save()
+ foursquare_user = FoursquareUserProfile(user=user, access_token=foursquare_access_token)
+ foursquare_user.save()
+ AuthMeta(user=user, provider='Foursquare').save()
+ return foursquare_user.user
+
+ def get_user(self, user_id):
+ try:
+ return User.objects.get(pk=user_id)
+ except:
+ return None
@@ -0,0 +1,42 @@
+from oauth import oauth
+from django.conf import settings
+import httplib
+
+FOURSQUARE_AUTHENTICATION_URL = 'https://foursquare.com/oauth2/authenticate'
+FOURSQUARE_ACCESS_TOKEN_URL = 'https://foursquare.com/oauth2/access_token'
+FOURSQUARE_CONSUMER_KEY = getattr(settings, 'FOURSQUARE_CONSUMER_KEY')
+FOURSQUARE_CONSUMER_SECRET = getattr(settings, 'FOURSQUARE_CONSUMER_SECRET')
+REGISTERED_REDIRECT_URI = getattr(settings, 'FOURSQUARE_REGISTERED_REDIRECT_URI')
+
+def get_http_connection():
+ return httplib.HTTPSConnection('foursquare.com')
+
+def get_response_body(oauth_request):
+ http_conn = get_http_connection()
+ http_conn.request('GET', oauth_request.to_url())
+ response = http_conn.getresponse().read()
+ return response
+
+
+class FourSquareClient(object):
+ def __init__(self):
+ self.consumer = oauth.OAuthConsumer(FOURSQUARE_CONSUMER_KEY, FOURSQUARE_CONSUMER_SECRET)
+
+ def get_authentication_url(self):
+ parameters = {}
+ parameters['client_id'] = FOURSQUARE_CONSUMER_KEY
+ parameters['response_type'] = 'code'
+ parameters['redirect_uri'] = REGISTERED_REDIRECT_URI
+ oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, http_url=FOURSQUARE_AUTHENTICATION_URL, parameters=parameters)
+ return oauth_request.to_url()
+
+ def get_access_token(self, foursquare_code):
+ parameters = {}
+ parameters['client_id'] = FOURSQUARE_CONSUMER_KEY
+ parameters['client_secret'] = FOURSQUARE_CONSUMER_SECRET
+ parameters['grant_type'] = 'authorization_code'
+ parameters['redirect_uri'] = REGISTERED_REDIRECT_URI
+ parameters['code'] = foursquare_code
+ oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, http_url=FOURSQUARE_ACCESS_TOKEN_URL, parameters=parameters)
+ access_token_response = get_response_body(oauth_request)
+ return access_token_response
View
@@ -0,0 +1,31 @@
+from django.conf import settings
+from oauth.oauth import OAuthConsumer, OAuthRequest
+import httplib
+
+GITHUB_CLIENT_ID = getattr(settings, 'GITHUB_CLIENT_ID')
+GITHUB_CLIENT_SECRET = getattr(settings, 'GITHUB_CLIENT_SECRET')
+GITHUB_AUTHORIZE_URL = 'https://github.com/login/oauth/authorize'
+GITHUB_ACCESS_TOKEN_URL = 'https://github.com/login/oauth/access_token'
+
+def get_response_from_url(to_url):
+ conn = httplib.HTTPSConnection('github.com')
+ conn.request('GET', to_url)
+ return conn.getresponse().read()
+
+class GithubClient(object):
+ def __init__(self):
+ self.consumer = OAuthConsumer(GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET)
+
+ def get_authorize_url(self):
+ parameters = {'client_id':GITHUB_CLIENT_ID}
+ oauth_request = OAuthRequest.from_consumer_and_token(self.consumer, http_url=GITHUB_AUTHORIZE_URL, parameters=parameters)
+ return oauth_request.to_url()
+
+ def get_access_token(self, code):
+ parameters = {}
+ parameters['client_id'] = GITHUB_CLIENT_ID
+ parameters['client_secret'] = GITHUB_CLIENT_SECRET
+ parameters['code'] = code
+ oauth_request = OAuthRequest.from_consumer_and_token(self.consumer, http_url=GITHUB_ACCESS_TOKEN_URL, parameters=parameters)
+ access_token = get_response_from_url(oauth_request.to_url())
+ return access_token
View
@@ -91,3 +91,17 @@ class FacebookUserProfile(models.Model):
def __unicode__(self):
return "%s's profile" % self.user
+
+class GithubUserProfile(models.Model):
+ user = models.ForeignKey(User)
+ access_token = models.CharField(max_length=100, blank=True, null=True, editable=False)
+
+ def __unicode__(self):
+ return "%s's profile" % self.user
+
+class FoursquareUserProfile(models.Model):
+ user = models.ForeignKey(User)
+ access_token = models.CharField(max_length=255, blank=True, null=True, editable=False)
+
+ def __unicode__(self):
+ return "%s's profile" % self.user
View
@@ -21,6 +21,10 @@
url(r'^openid/complete/$', complete, name='socialauth_openid_complete'),
url(r'^openid/signout/$', signout, name='openid_signout'),
url(r'^openid/done/$', 'openid_done', name='openid_openid_done'),
+ url(r'^github_login/$', 'github_login', name='github_login'),
+ url(r'github_login/done/$', 'github_login_done', name='github_login_done'),
+ url(r'^foursquare_login/$', 'foursquare_login', name='foursquare_login'),
+ url(r'^foursquare_login/done/$', 'foursquare_login_done', name='foursquare_login_done'),
)
#Other views.
View
@@ -18,6 +18,8 @@
from socialauth.lib import oauthtwitter2 as oauthtwitter
from socialauth.lib.linkedin import *
+from socialauth.lib.github import GithubClient
+from socialauth.lib import foursquare
LINKEDIN_CONSUMER_KEY = getattr(settings, 'LINKEDIN_CONSUMER_KEY', '')
LINKEDIN_CONSUMER_SECRET = getattr(settings, 'LINKEDIN_CONSUMER_SECRET', '')
@@ -34,6 +36,7 @@
FACEBOOK_SECRET_KEY = getattr(settings, 'FACEBOOK_SECRET_KEY', '')
+
def del_dict_key(src_dict, key):
if key in src_dict:
del src_dict[key]
@@ -308,3 +311,51 @@ def social_logout(request):
response.delete_cookie("fbs_" + FACEBOOK_APP_ID)
return response
+
+def github_login(request):
+ github_client = GithubClient()
+ authorize_url = github_client.get_authorize_url()
+ return HttpResponseRedirect(authorize_url)
+
+def github_login_done(request):
+ try:
+ code = request.GET['code']
+ except:
+ """Either github did not respond properly
+ or someone is playing with this url"""
+ return HttpResponseRedirect(LOGIN_URL)
+ github_client = GithubClient()
+ access_token = github_client.get_access_token(code)
+ try:
+ user = authenticate(github_access_token=access_token)
+ except:
+ user = None
+ if user:
+ login(request, user)
+ return HttpResponseRedirect(LOGIN_REDIRECT_URL)
+ return HttpResponseRedirect(LOGIN_URL)
+
+def foursquare_login(request):
+ foursquare_client = foursquare.FourSquareClient()
+ return HttpResponseRedirect(foursquare_client.get_authentication_url())
+
+def foursquare_login_done(request):
+ try:
+ code = request.GET.get('code')
+ except:
+ """Some error ocurred.
+ Rediect to login page"""
+ return HttpResponseRedirect(LOGIN_URL)
+ request.session['foursquare_code'] = code
+ foursquare_client = foursquare.FourSquareClient()
+ access_token_response = foursquare_client.get_access_token(request.session['foursquare_code'])
+ import json
+ access_token = json.loads(access_token_response)['access_token']
+ try:
+ user = authenticate(foursquare_access_token=access_token)
+ except:
+ user=None
+ if user:
+ login(request, user)
+ return HttpResponseRedirect(LOGIN_REDIRECT_URL)
+ return HttpResponseRedirect(LOGIN_URL)

0 comments on commit b0b1acb

Please sign in to comment.