1
by Ivan Sagalaev
Scipio. Initial commit. |
1 |
# -*- coding:utf-8 -*-
|
2 |
from django.views.decorators.http import require_POST |
|
3 |
from django import http |
|
4 |
from django.utils.translation import ugettext as _ |
|
5 |
from django.utils import simplejson |
|
9
by Ivan Sagalaev
Починка вывода login-страницы при ошибках валидации OpenID URL |
6 |
from django.shortcuts import redirect, render_to_response |
7 |
from django.template import RequestContext |
|
1
by Ivan Sagalaev
Scipio. Initial commit. |
8 |
from django.contrib import auth |
9 |
||
16
by Ivan Sagalaev
Реорганизация utils в пакет. |
10 |
from scipio import models, forms, signals |
11 |
from scipio.utils import mimeparse |
|
1
by Ivan Sagalaev
Scipio. Initial commit. |
12 |
|
13 |
def _post_redirect(request): |
|
14 |
return request.POST.get('redirect', request.META.get('HTTP_REFERER', '/')) |
|
15 |
||
16 |
def login(request): |
|
34
by Ivan Sagalaev
Stylistic fixes in comments for settings. |
17 |
"""
|
18 |
Shows and processes an OpenID login form. The successful response from the
|
|
19 |
view is a redirect to user's OpenID server. The server will then return the
|
|
20 |
user back to `complete` view.
|
|
21 |
||
22 |
Requires a template "scipio/login.html".
|
|
23 |
"""
|
|
1
by Ivan Sagalaev
Scipio. Initial commit. |
24 |
if request.method == 'POST': |
25 |
form = forms.AuthForm(request.session, request.POST) |
|
26 |
if form.is_valid(): |
|
3
by Ivan Sagalaev
Авторизация не должна автоматически логинить юзера. |
27 |
after_auth_redirect = form.auth_redirect(_post_redirect(request), {'op': 'login'}) |
1
by Ivan Sagalaev
Scipio. Initial commit. |
28 |
return redirect(after_auth_redirect) |
29 |
return_url = _post_redirect(request) |
|
30 |
else: |
|
31 |
form = forms.AuthForm(request.session) |
|
32 |
return_url = request.GET.get('redirect', '/') |
|
9
by Ivan Sagalaev
Починка вывода login-страницы при ошибках валидации OpenID URL |
33 |
return render_to_response('scipio/login.html', |
34 |
{'form': form, 'redirect': return_url}, |
|
35 |
context_instance = RequestContext(request), |
|
36 |
)
|
|
1
by Ivan Sagalaev
Scipio. Initial commit. |
37 |
|
38 |
def complete(request, message=_('Authentication failed')): |
|
34
by Ivan Sagalaev
Stylistic fixes in comments for settings. |
39 |
"""
|
40 |
Completes authentication process after user returns from the OpenID server.
|
|
41 |
||
42 |
If authentication is successful sends a signal about it which an
|
|
43 |
application can catch and return some HttpResponse. If no HttpResponse
|
|
44 |
returned from signal handlers the view just redirect a user to the original
|
|
45 |
page from which authentication had started.
|
|
46 |
"""
|
|
1
by Ivan Sagalaev
Scipio. Initial commit. |
47 |
user = auth.authenticate(session=request.session, query=request.GET, return_path=request.path) |
48 |
if not user: |
|
49 |
return http.HttpResponseForbidden(message) |
|
2
by Ivan Sagalaev
str для ключей data при передаче в сигнал |
50 |
data = dict((str(k[7:]), v) for k, v in request.GET.items() if k.startswith('scipio.')) |
3
by Ivan Sagalaev
Авторизация не должна автоматически логинить юзера. |
51 |
results = signals.authenticated.send(request, user=user, **data) |
39
by Ivan Sagalaev
Treat results from a signal call as a list of tuple of (callback, result) |
52 |
for callback, result in results: |
53 |
if isinstance(result, http.HttpResponse): |
|
54 |
response = result |
|
1
by Ivan Sagalaev
Scipio. Initial commit. |
55 |
break
|
56 |
else: |
|
34
by Ivan Sagalaev
Stylistic fixes in comments for settings. |
57 |
response = redirect(request.GET.get('redirect', '/')) |
58 |
return response |
|
1
by Ivan Sagalaev
Scipio. Initial commit. |
59 |
|
3
by Ivan Sagalaev
Авторизация не должна автоматически логинить юзера. |
60 |
def complete_login(sender, user, op=None, **kwargs): |
34
by Ivan Sagalaev
Stylistic fixes in comments for settings. |
61 |
"""
|
62 |
A default handler for login completion that actually athenticates a Django
|
|
63 |
user and persists it in a session.
|
|
64 |
"""
|
|
3
by Ivan Sagalaev
Авторизация не должна автоматически логинить юзера. |
65 |
if op == 'login': |
66 |
auth.login(sender, user) |
|
67 |
signals.authenticated.connect(complete_login) |
|
68 |
||
1
by Ivan Sagalaev
Scipio. Initial commit. |
69 |
@require_POST
|
70 |
def logout(request): |
|
34
by Ivan Sagalaev
Stylistic fixes in comments for settings. |
71 |
"""
|
72 |
Processes logout form by logging out Django user.
|
|
73 |
"""
|
|
1
by Ivan Sagalaev
Scipio. Initial commit. |
74 |
auth.logout(request) |
75 |
return redirect(_post_redirect(request)) |
|
76 |
||
77 |
def openid_whitelist(request): |
|
34
by Ivan Sagalaev
Stylistic fixes in comments for settings. |
78 |
"""
|
79 |
Shows current list of white-listed users to share it with whoever wants to
|
|
80 |
know users trusted by this site.
|
|
81 |
||
82 |
The list is available in three formats (text, xml, json). The format is
|
|
83 |
negotiated by HTTP spec using Accept header.
|
|
84 |
"""
|
|
1
by Ivan Sagalaev
Scipio. Initial commit. |
85 |
if request.method == 'POST': |
86 |
try: |
|
87 |
profile = models.Profile.objects.get(pk=int(request.POST['id'])) |
|
88 |
profile.spamer = False |
|
89 |
profile.save() |
|
11
by Ivan Sagalaev
Сигнал whitelist |
90 |
signals.whitelist.send(sender=profile) |
1
by Ivan Sagalaev
Scipio. Initial commit. |
91 |
return redirect(_post_redirect(request)) |
14
by maniac
Ссылка на Profile через models.Profile в openid_whitelist |
92 |
except (models.Profile.DoesNotExist, ValueError, KeyError): |
1
by Ivan Sagalaev
Scipio. Initial commit. |
93 |
return http.HttpResponseBadRequest() |
94 |
else: |
|
14
by maniac
Ссылка на Profile через models.Profile в openid_whitelist |
95 |
openids = (p.openid for p in models.Profile.objects.filter(spamer=False) if p.openid) |
1
by Ivan Sagalaev
Scipio. Initial commit. |
96 |
MIMETYPES = ['application/xml', 'text/xml', 'application/json', 'text/plain'] |
97 |
accept = request.META.get('HTTP_ACCEPT', '') |
|
98 |
try: |
|
99 |
mimetype = mimeparse.best_match(MIMETYPES, accept) |
|
100 |
except ValueError: |
|
101 |
mimetype = 'text/plain' |
|
102 |
if mimetype.endswith('/xml'): |
|
103 |
try: |
|
104 |
import xml.etree.ElementTree as ET |
|
105 |
except ImportError: |
|
106 |
import elementtree.ElementTree as ET |
|
107 |
root = ET.Element('whitelist') |
|
108 |
for openid in openids: |
|
109 |
ET.SubElement(root, 'openid').text = openid |
|
110 |
xml = ET.ElementTree(root) |
|
111 |
response = http.HttpResponse(mimetype=mimetype) |
|
112 |
xml.write(response, encoding='utf-8') |
|
113 |
return response |
|
114 |
if mimetype == 'application/json': |
|
115 |
response = http.HttpResponse(mimetype=mimetype) |
|
116 |
simplejson.dump(list(openids), response) |
|
117 |
return response |
|
118 |
if mimetype == 'text/plain': |
|
119 |
return http.HttpResponse((o + '\n' for o in openids), mimetype=mimetype) |
|
120 |
return http.HttpResponse('Can accept only: %s' % ', '.join(MIMETYPES), status=406) |