Skip to content

Commit

Permalink
New class property sign_next_param = False can be used to disable the…
Browse files Browse the repository at this point in the history
… signing behaviour regarding the ?next= paramater for login and logout URLs.
  • Loading branch information
Simon Willison committed Jan 10, 2010
1 parent 75ddde0 commit fb259f9
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 32 deletions.
7 changes: 0 additions & 7 deletions django_openid/auth.py
Expand Up @@ -206,17 +206,10 @@ def show_associate(self, request, openid=None):
"Screen that offers to associate an OpenID with a user's account"
if not request.user.is_authenticated():
return self.need_authenticated_user(request)
try:
next = signed.loads(
request.REQUEST.get('next', ''), extra_key=self.salt_next
)
except ValueError:
next = ''
return self.render(request, self.show_associate_template, {
'action': urljoin(request.path, '../associate/'),
'user': request.user,
'specific_openid': openid,
'next': next and request.REQUEST.get('next', '') or None,
'openid_token': signed.dumps(
# Use user.id as part of extra_key to prevent attackers from
# creating their own openid_token for use in CSRF attack
Expand Down
57 changes: 37 additions & 20 deletions django_openid/consumer.py
Expand Up @@ -96,6 +96,7 @@ class Consumer(object):
failure_message = 'Failure: %s'
setup_needed_message = 'Setup needed'

sign_next_param = True # Set to False to disable signed ?next= URLs
salt_next = 'salt-next-token' # Adds extra saltiness to the ?next= salt
xri_enabled = False
on_complete_url = None
Expand All @@ -115,7 +116,10 @@ def __init__(self, persist_class=CookiePersist):
self.persist = persist_class()

def sign_next(self, url):
return signed.dumps(url, extra_key = self.salt_next)
if self.sign_next_param:
return signed.dumps(url, extra_key = self.salt_next)
else:
return url

def render(self, request, template, context=None):
context = context or {}
Expand Down Expand Up @@ -157,12 +161,15 @@ def do_index(self, request, extra_message=None):
do_index.urlregex = '^$'

def show_login(self, request, message=None):
try:
next = signed.loads(
request.REQUEST.get('next', ''), extra_key=self.salt_next
)
except ValueError:
next = ''
if self.sign_next_param:
try:
next = signed.loads(
request.REQUEST.get('next', ''), extra_key=self.salt_next
)
except ValueError:
next = ''
else:
next = request.REQUEST.get('next', '')
return self.render(request, self.login_template, {
'action': request.path,
'logo': self.logo_path or (request.path + 'logo/'),
Expand Down Expand Up @@ -205,12 +212,15 @@ def get_on_complete_url(self, request, on_complete_url=None):
on_complete_url = on_complete_url or self.on_complete_url or \
(request.path + 'complete/')
on_complete_url = self.ensure_absolute_url(request, on_complete_url)
try:
next = signed.loads(
request.POST.get('next', ''), extra_key=self.salt_next
)
except ValueError:
return on_complete_url
if self.sign_next_param:
try:
next = signed.loads(
request.POST.get('next', ''), extra_key=self.salt_next
)
except ValueError:
return on_complete_url
else:
next = request.POST.get('next', '')

if '?' not in on_complete_url:
on_complete_url += '?next=' + self.sign_next(next)
Expand Down Expand Up @@ -302,13 +312,20 @@ def do_debug(self, request):

def redirect_if_valid_next(self, request):
"Logic for checking if a signed ?next= token is included in request"
try:
next = signed.loads(
request.REQUEST.get('next', ''), extra_key=self.salt_next
)
return HttpResponseRedirect(next)
except ValueError:
return None
if self.sign_next_param:
try:
next = signed.loads(
request.REQUEST.get('next', ''), extra_key=self.salt_next
)
return HttpResponseRedirect(next)
except ValueError:
return None
else:
next = request.REQUEST.get('next', '')
if next.startswith('/'):
return HttpResponseRedirect(next)
else:
return None

def on_success(self, request, identity_url, openid_response):
response = self.redirect_if_valid_next(request)
Expand Down
5 changes: 4 additions & 1 deletion django_openid/demos/registration_consumer/urls.py
Expand Up @@ -2,7 +2,10 @@
from django.http import HttpResponseRedirect
from django_openid.registration import RegistrationConsumer

class NoSignNext(RegistrationConsumer):
sign_next_param = False

urlpatterns = patterns('',
(r'^$', lambda r: HttpResponseRedirect('/openid/')),
(r'^openid/(.*)', RegistrationConsumer()),
(r'^openid/(.*)', NoSignNext()),
)
3 changes: 1 addition & 2 deletions django_openid/templates/django_openid/associate.html
Expand Up @@ -10,8 +10,7 @@ <h1>Associate with your account?</h1>
<form action="{{ action }}" method="post">
<p>
<input type="hidden" name="openid_token" value="{{ openid_token }}">
{% if next %} <input type="hidden" name="next" value="{{ next }}">
{% endif %} <input type="submit" value="Associate">
<input type="submit" value="Associate">
</p>
</form>
{% endblock %}
4 changes: 2 additions & 2 deletions setup.py
Expand Up @@ -2,11 +2,11 @@

setup(
name='django-openid',
version='0.1.2',
version='0.1.3',
description='OpenID tools for Django',
author='Simon Willison',
author_email='simon@simonwillison.net',
url='http://code.google.com/p/django-openid/',
url='http://github.com/simonw/django-openid/',
packages=find_packages(),
classifiers=[
'Development Status :: 3 - Alpha',
Expand Down

0 comments on commit fb259f9

Please sign in to comment.