Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add more providers #53

Merged
merged 15 commits into from
This page is out of date. Refresh to see the latest.
View
15 README.rst
@@ -16,6 +16,8 @@ In particular it allows logging in via
#. Facebook
#. Yahoo(Essentially openid)
#. OpenId
+#. Github
+#. Foursquare
Libs you need to install
See requirements.txt
@@ -29,6 +31,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.
--------------
@@ -42,6 +46,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
----------
@@ -51,11 +58,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
@@ -86,11 +95,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.
View
9 example_project/localsettings.example.py
@@ -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
4 socialauth/admin.py
@@ -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)
View
47 socialauth/auth_backends.py
@@ -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
View
42 socialauth/lib/foursquare.py
@@ -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
31 socialauth/lib/github.py
@@ -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
14 socialauth/models.py
@@ -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
4 socialauth/urls.py
@@ -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
51 socialauth/views.py
@@ -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)
Something went wrong with that request. Please try again.