1
from django.http import HttpResponse, HttpResponseRedirect, Http404
2
from django.shortcuts import render_to_response as render
3
from django.template import RequestContext
4
from django.conf import settings
7
from openid.consumer.consumer import Consumer, \
8
SUCCESS, CANCEL, FAILURE, SETUP_NEEDED
9
from openid.consumer.discover import DiscoveryFailure
10
from util import OpenID, DjangoOpenIDStore, from_openid_response
12
from django.utils.html import escape
14
def get_url_host(request):
15
if request.is_secure():
19
host = escape(request.META['HTTP_HOST'])
20
return '%s://%s' % (protocol, host)
22
def get_full_url(request):
23
if request.is_secure():
27
host = escape(request.META['HTTP_HOST'])
28
return get_url_host(request) + request.get_full_path()
30
def is_valid_after_url(after):
32
# /openid/?after=/welcome/
33
# For security reasons we want to restrict the after= bit to being a local
34
# path, not a complete URL.
35
if not after.startswith('/'):
44
def begin(request, sreg=None, extension_args=None):
45
extension_args = extension_args or {}
47
extension_args['sreg.optional'] = sreg
49
settings, 'OPENID_TRUST_ROOT', get_url_host(request) + '/'
51
redirect_to = getattr(
52
settings, 'OPENID_REDIRECT_TO',
53
# If not explicitly set, assume current URL with complete/ appended
54
get_full_url(request).split('?')[0] + 'complete/'
57
if request.GET.get('after') and is_valid_after_url(request.GET['after']):
58
if '?' in redirect_to:
62
redirect_to += join + 'after=' + urllib.urlencode(request.GET['after'])
64
user_url = request.POST.get('openid_url', None)
66
return render('openid_signin.html')
68
consumer = Consumer(request.session, DjangoOpenIDStore())
70
auth_request = consumer.begin(user_url)
71
except DiscoveryFailure:
72
raise Http404, "Discovery failure"
74
# Add extension args (for things like simple registration)
75
for name, value in extension_args.items():
76
namespace, key = name.split('.', 1)
77
auth_request.addExtensionArg(namespace, key, value)
79
redirect_url = auth_request.redirectURL(trust_root, redirect_to)
80
return HttpResponseRedirect(redirect_url)
82
def complete(request):
83
consumer = Consumer(request.session, DjangoOpenIDStore())
84
openid_response = consumer.complete(dict(request.GET.items()))
85
if openid_response.status == SUCCESS:
86
return success(request, openid_response.identity_url, openid_response)
87
elif openid_response.status == CANCEL:
88
return failure(request, 'The request was cancelled')
89
elif openid_response.status == FAILURE:
90
return failure(request, openid_response.message)
91
elif openid_response.status == SETUP_NEEDED:
92
return failure(request, 'Setup needed')
94
assert False, "Bad openid status: %s" % openid_response.status
96
def success(request, identity_url, openid_response):
97
if 'openids' not in request.session.keys():
98
request.session['openids'] = []
100
# Eliminate any duplicates
101
request.session['openids'] = [
102
o for o in request.session['openids'] if o.openid != identity_url
104
request.session['openids'].append(from_openid_response(openid_response))
106
after = request.GET.get('after', '').strip()
107
if not after or not is_valid_after_url(after):
108
after = getattr(settings, 'OPENID_REDIRECT_AFTER', '/')
110
return HttpResponseRedirect(after)
112
def failure(request, message):
113
return render('openid_failure.html', {
115
}) # , context_instance = RequestContext(request))
117
def signout(request):
118
request.session.openids = []
119
request.session.openid = None
120
next = request.GET.get('next', '/')
121
return HttpResponseRedirect(next)