Commit 83746113 by Michael Nelson

Adds a signal on successful login that includes the request and the sreg_response.

parent 2284d64b
# django-openid-auth - OpenID integration for django.contrib.auth
#
# Copyright (C) 2007 Simon Willison
# Copyright (C) 2008-2010 Canonical Ltd.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
import django.dispatch
oauth_login_complete = django.dispatch.Signal(providing_args=[
'request', 'sreg_response'])
......@@ -33,6 +33,7 @@ import unittest
from django.conf import settings
from django.contrib.auth.models import User, Group
from django.http import HttpRequest
from django.test import TestCase
from openid.extensions import ax, sreg
from openid.fetchers import (
......@@ -44,6 +45,7 @@ from openid.store.memstore import MemoryStore
from django_openid_auth import teams
from django_openid_auth.models import UserOpenID
from django_openid_auth.views import sanitise_redirect_url
from django_openid_auth.signals import oauth_login_complete
ET = importElementTree()
......@@ -518,6 +520,33 @@ class RelyingPartyTests(TestCase):
response = self.complete(openid_response)
return User.objects.get(username=user.username)
def test_login_complete_signals_login(self):
# An oauth_login_complete signal is emitted including the
# request and sreg_response.
user = User.objects.create_user('someuser', 'someone@example.com')
useropenid = UserOpenID(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
useropenid.save()
response = self.client.post('/openid/login/',
{'openid_identifier': 'http://example.com/identity'})
openid_request = self.provider.parseFormPost(response.content)
openid_response = openid_request.answer(True)
# Use a closure to test whether the signal handler was called.
self.signal_handler_called = False
def login_callback(sender, **kwargs):
self.assertTrue(kwargs.has_key('request'))
self.assertTrue(kwargs.has_key('sreg_response'))
self.assertTrue(isinstance(kwargs['request'], HttpRequest))
self.signal_handler_called = True
oauth_login_complete.connect(login_callback)
response = self.complete(openid_response)
self.assertTrue(self.signal_handler_called)
oauth_login_complete.disconnect(login_callback)
class HelperFunctionsTest(TestCase):
def test_sanitise_redirect_url(self):
......
......@@ -52,6 +52,8 @@ from openid.extensions import sreg, ax
from django_openid_auth import teams
from django_openid_auth.forms import OpenIDLoginForm
from django_openid_auth.models import UserOpenID
from django_openid_auth.signals import oauth_login_complete
from django_openid_auth.store import DjangoOpenIDStore
......@@ -60,7 +62,7 @@ next_url_re = re.compile('^/[-\w/]+$')
def is_valid_next_url(next):
# When we allow this:
# /openid/?next=/welcome/
# For security reasons we want to restrict the next= bit to being a local
# For security reasons we want to restrict the next= bit to being a local
# path, not a complete URL.
return bool(next_url_re.match(next))
......@@ -73,7 +75,7 @@ def sanitise_redirect_url(redirect_to):
is_valid = False
elif '//' in redirect_to:
# Allow the redirect URL to be external if it's a permitted domain
allowed_domains = getattr(settings,
allowed_domains = getattr(settings,
"ALLOWED_EXTERNAL_OPENID_REDIRECT_DOMAINS", [])
s, netloc, p, q, f = urlsplit(redirect_to)
# allow it if netloc is blank or if the domain is allowed
......@@ -239,7 +241,15 @@ def login_complete(request, redirect_field_name=REDIRECT_FIELD_NAME,
if user is not None:
if user.is_active:
auth_login(request, user)
return HttpResponseRedirect(sanitise_redirect_url(redirect_to))
response = HttpResponseRedirect(sanitise_redirect_url(redirect_to))
# Notify any listeners that we successfully logged in.
sreg_response = sreg.SRegResponse.fromSuccessResponse(
openid_response)
oauth_login_complete.send(sender=UserOpenID, request=request,
sreg_response=sreg_response)
return response
else:
return render_failure(request, 'Disabled account')
else:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment