return simplejson.load(urllib.urlopen(url))
except simplejson.JSONDecodeError:
return None
+
+
+# Authentication backends
+BACKENDS = {
+ 'twitter': TwitterAuth,
+ 'facebook': FacebookAuth,
+ 'google': GoogleAuth,
+ 'yahoo': YahooAuth,
+ 'orkut': OrkutAuth,
+ 'openid': OpenIdAuth,
+}
+
+def get_backend(name, *args, **kwargs):
+ """Return auth backend instance *if* it's registered, None in other case"""
+ return BACKENDS.get(name, lambda *args, **kwargs: None)(*args, **kwargs)
timestamp = models.IntegerField()
salt = models.CharField(max_length=40)
+ def __unicode__(self):
+ """Unicode representation"""
+ return self.server_url
+
class Association(models.Model):
"""OpenId account association"""
issued = models.IntegerField()
lifetime = models.IntegerField()
assoc_type = models.CharField(max_length=64)
+
+ def __unicode__(self):
+ """Unicode representation"""
+ return '%s %s' % (self.handle, self.issued)
from django.dispatch import Signal
# Pre save signal
-# This signal is sent when user instance values is about to be
-# updated with new values from services provided. This way custom
-# actions can be attached and values updated if needed before the
-# saving time.
+# This signal is sent when user instance is about to be updated with
+# new values from services provided. This way custom actions can be
+# attached and values updated if needed before the saving time.
#
# Handlers must return True if any value was updated/changed,
# otherwise must return any non True value.
if expired: # clear expired associations
Association.objects.filter(pk__in=expired).delete()
- if associations:
+ if associations: # return most recet association
associations.sort(key=lambda x: x.issued, reverse=True)
return associations[0]
def useNonce(self, server_url, timestamp, salt):
- """Generate one use number and return if it was created"""
+ """Generate one use number and return *if* it was created"""
if abs(timestamp - time.time()) > SKEW:
return False
return Nonce.objects.get_or_create(server_url=server_url,
from django.contrib.auth import login, REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import login_required
-from .auth import TwitterAuth, FacebookAuth, OpenIdAuth, GoogleAuth, \
- YahooAuth, OrkutAuth
-
-
-# Authentication backends
-BACKENDS = {
- 'twitter': TwitterAuth,
- 'facebook': FacebookAuth,
- 'google': GoogleAuth,
- 'yahoo': YahooAuth,
- 'openid': OpenIdAuth,
- 'orkut': OrkutAuth,
-}
+from .auth import get_backend
def auth(request, backend):
def complete(request, backend):
"""Authentication complete process"""
- if backend not in BACKENDS:
+ backend = get_backend(backend, request, request.path)
+ if not backend:
return HttpResponseServerError('Incorrect authentication service')
- backend = BACKENDS[backend](request, request.path)
user = backend.auth_complete()
if user and getattr(user, 'is_active', True):
login(request, user)
@login_required
def associate_complete(request, backend):
"""Authentication complete process"""
- if backend not in BACKENDS:
+ backend = get_backend(backend, request, request.path)
+ if not backend:
return HttpResponseServerError('Incorrect authentication service')
- backend = BACKENDS[backend](request, request.path)
backend.auth_complete(user=request.user)
url = request.session.pop(REDIRECT_FIELD_NAME, '') or \
getattr(settings, 'LOGIN_REDIRECT_URL', '')
def auth_process(request, backend, complete_url_name, default_final_url):
"""Authenticate using social backend"""
- if backend not in BACKENDS:
+ redirect = reverse(complete_url_name, args=(backend,))
+ backend = get_backend(backend, request, redirect)
+ if not backend:
return HttpResponseServerError('Incorrect authentication service')
request.session[REDIRECT_FIELD_NAME] = request.GET.get(REDIRECT_FIELD_NAME,
default_final_url)
- redirect = reverse(complete_url_name, args=(backend,))
- backend = BACKENDS[backend](request, redirect)
if backend.uses_redirect:
return HttpResponseRedirect(backend.auth_url())
else: