~django-openid-auth/django-openid-auth/trunk

« back to all changes in this revision

Viewing changes to django_openidconsumer/views.py

  • Committer: swillison
  • Date: 2007-04-15 19:20:10 UTC
  • Revision ID: svn-v3-trunk0:3bcd880a-622a-0410-974b-89bbab7935c3:trunk:9
Initial checkin

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
5
 
 
6
import md5, time
 
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
 
11
 
 
12
from django.utils.html import escape
 
13
 
 
14
def get_url_host(request):
 
15
    if request.is_secure():
 
16
        protocol = 'https'
 
17
    else:
 
18
        protocol = 'http'
 
19
    host = escape(request.META['HTTP_HOST'])
 
20
    return '%s://%s' % (protocol, host)
 
21
 
 
22
def get_full_url(request):
 
23
    if request.is_secure():
 
24
        protocol = 'https'
 
25
    else:
 
26
        protocol = 'http'
 
27
    host = escape(request.META['HTTP_HOST'])
 
28
    return get_url_host(request) + request.get_full_path()
 
29
 
 
30
def is_valid_after_url(after):
 
31
    # When we allow this:
 
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('/'):
 
36
        return False
 
37
    if '://' in after:
 
38
        return False
 
39
    for c in after:
 
40
        if c.isspace():
 
41
            return False
 
42
    return True
 
43
 
 
44
def begin(request, sreg=None, extension_args=None):
 
45
    extension_args = extension_args or {}
 
46
    if sreg:
 
47
        extension_args['sreg.optional'] = sreg
 
48
    trust_root = getattr(
 
49
        settings, 'OPENID_TRUST_ROOT', get_url_host(request) + '/'
 
50
    )
 
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/'
 
55
    )
 
56
    
 
57
    if request.GET.get('after') and is_valid_after_url(request.GET['after']):
 
58
        if '?' in redirect_to:
 
59
            join = '&'
 
60
        else:
 
61
            join = '?'
 
62
        redirect_to += join + 'after=' + urllib.urlencode(request.GET['after'])
 
63
    
 
64
    user_url = request.POST.get('openid_url', None)    
 
65
    if not user_url:
 
66
        return render('openid_signin.html')
 
67
    
 
68
    consumer = Consumer(request.session, DjangoOpenIDStore())
 
69
    try:
 
70
        auth_request = consumer.begin(user_url)
 
71
    except DiscoveryFailure:
 
72
        raise Http404, "Discovery failure"
 
73
    
 
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)
 
78
    
 
79
    redirect_url = auth_request.redirectURL(trust_root, redirect_to)
 
80
    return HttpResponseRedirect(redirect_url)
 
81
 
 
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')
 
93
    else:
 
94
        assert False, "Bad openid status: %s" % openid_response.status
 
95
 
 
96
def success(request, identity_url, openid_response):
 
97
    if 'openids' not in request.session.keys():
 
98
        request.session['openids'] = []
 
99
    
 
100
    # Eliminate any duplicates
 
101
    request.session['openids'] = [
 
102
        o for o in request.session['openids'] if o.openid != identity_url
 
103
    ]
 
104
    request.session['openids'].append(from_openid_response(openid_response))
 
105
    
 
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', '/')
 
109
    
 
110
    return HttpResponseRedirect(after)
 
111
 
 
112
def failure(request, message):
 
113
    return render('openid_failure.html', {
 
114
        'message': message
 
115
    }) # , context_instance = RequestContext(request))
 
116
 
 
117
def signout(request):
 
118
    request.session.openids = []
 
119
    request.session.openid = None
 
120
    next = request.GET.get('next', '/')
 
121
    return HttpResponseRedirect(next)