8bbe566b3401dde41341f8f380c18d8ea92f93d6
[redakcja.git] / apps / django_cas / views.py
1 """CAS login/logout replacement views"""
2
3 from urllib import urlencode
4 from urlparse import urljoin
5
6 from django.http import get_host, HttpResponseRedirect, HttpResponseForbidden
7 from django.conf import settings
8 from django.contrib.auth import REDIRECT_FIELD_NAME
9
10 __all__ = ['login', 'logout']
11
12 def _service_url(request, redirect_to = None):
13     """Generates application service URL for CAS"""
14
15     protocol = ('http://', 'https://')[request.is_secure()]
16     host = get_host(request)
17     service = protocol + host + request.path
18     if redirect_to:
19         if '?' in service:
20             service += '&'
21         else:
22             service += '?'
23         service += urlencode({REDIRECT_FIELD_NAME: redirect_to.encode('utf-8')})
24     return service
25
26
27 def _redirect_url(request):
28     """Redirects to referring page, or CAS_REDIRECT_URL if no referrer is
29     set.
30     """
31
32     next = request.GET.get(REDIRECT_FIELD_NAME)
33     if not next:
34         if settings.CAS_IGNORE_REFERER:
35             next = settings.CAS_REDIRECT_URL
36         else:
37             next = request.META.get('HTTP_REFERER', settings.CAS_REDIRECT_URL)
38         prefix = (('http://', 'https://')[request.is_secure()] +
39                   get_host(request))
40         if next.startswith(prefix):
41             next = next[len(prefix):]
42     return next
43
44
45 def _login_url(service):
46     """Generates CAS login URL"""
47
48     params = {'service': service}
49     if settings.CAS_EXTRA_LOGIN_PARAMS:
50         params.update(settings.CAS_EXTRA_LOGIN_PARAMS)
51     return urljoin(settings.CAS_SERVER_URL, 'login') + '?' + urlencode(params)
52
53
54 def _logout_url(request, next_page = None):
55     """Generates CAS logout URL"""
56
57     url = urljoin(settings.CAS_SERVER_URL, 'logout')
58     if next_page:
59         protocol = ('http://', 'https://')[request.is_secure()]
60         host = get_host(request)
61         url += '?' + urlencode({'url': protocol + host + next_page})
62     return url
63
64
65 def login(request, next_page = None, required = False):
66     """Forwards to CAS login URL or verifies CAS ticket"""
67
68     print "LOGIN original NEXT_PAGE:", next_page
69     print request.GET
70     if not next_page:
71         next_page = _redirect_url(request)
72     print "LOGIN redirect NEXT_PAGE:", next_page
73
74     if request.user.is_authenticated():
75         message = "You are logged in as %s." % request.user.username
76         request.user.message_set.create(message = message)
77         return HttpResponseRedirect(next_page)
78     ticket = request.GET.get('ticket')
79     service = _service_url(request, next_page)
80     print "TICKET: ", ticket
81     print "SERVICE: ", service
82     if ticket:
83         from django.contrib import auth
84         user = auth.authenticate(ticket = ticket, service = service)
85         if user is not None:
86             auth.login(request, user)
87             name = user.first_name or user.username
88             message = "Login succeeded. Welcome, %s." % name
89             user.message_set.create(message = message)
90             return HttpResponseRedirect(next_page)
91         elif settings.CAS_RETRY_LOGIN or required:
92             return HttpResponseRedirect(_login_url(service))
93         else:
94             error = "<h1>Forbidden</h1><p>Login failed.</p>"
95             return HttpResponseForbidden(error)
96
97     else:
98         return HttpResponseRedirect(_login_url(service))
99
100
101 def logout(request, next_page = None):
102     """Redirects to CAS logout page"""
103
104     from django.contrib.auth import logout
105     logout(request)
106     if not next_page:
107         next_page = _redirect_url(request)
108     if settings.CAS_LOGOUT_COMPLETELY:
109         return HttpResponseRedirect(_logout_url(request, next_page))
110     else:
111         return HttpResponseRedirect(next_page)