|
1 import re |
1 from django.conf import settings |
2 from django.conf import settings |
2 from django.contrib.auth import REDIRECT_FIELD_NAME |
3 from django.contrib.auth import REDIRECT_FIELD_NAME |
|
4 # Avoid shadowing the login() view below. |
|
5 from django.contrib.auth import login as auth_login |
3 from django.contrib.auth.decorators import login_required |
6 from django.contrib.auth.decorators import login_required |
4 from django.contrib.auth.forms import AuthenticationForm |
7 from django.contrib.auth.forms import AuthenticationForm |
5 from django.contrib.auth.forms import PasswordResetForm, SetPasswordForm, PasswordChangeForm |
8 from django.contrib.auth.forms import PasswordResetForm, SetPasswordForm, PasswordChangeForm |
6 from django.contrib.auth.tokens import default_token_generator |
9 from django.contrib.auth.tokens import default_token_generator |
|
10 from django.views.decorators.csrf import csrf_protect |
7 from django.core.urlresolvers import reverse |
11 from django.core.urlresolvers import reverse |
8 from django.shortcuts import render_to_response, get_object_or_404 |
12 from django.shortcuts import render_to_response, get_object_or_404 |
9 from django.contrib.sites.models import Site, RequestSite |
13 from django.contrib.sites.models import Site, RequestSite |
10 from django.http import HttpResponseRedirect, Http404 |
14 from django.http import HttpResponseRedirect, Http404 |
11 from django.template import RequestContext |
15 from django.template import RequestContext |
12 from django.utils.http import urlquote, base36_to_int |
16 from django.utils.http import urlquote, base36_to_int |
13 from django.utils.translation import ugettext as _ |
17 from django.utils.translation import ugettext as _ |
14 from django.contrib.auth.models import User |
18 from django.contrib.auth.models import User |
15 from django.views.decorators.cache import never_cache |
19 from django.views.decorators.cache import never_cache |
16 |
20 |
17 def login(request, template_name='registration/login.html', redirect_field_name=REDIRECT_FIELD_NAME): |
21 @csrf_protect |
18 "Displays the login form and handles the login action." |
22 @never_cache |
|
23 def login(request, template_name='registration/login.html', |
|
24 redirect_field_name=REDIRECT_FIELD_NAME, |
|
25 authentication_form=AuthenticationForm): |
|
26 """Displays the login form and handles the login action.""" |
|
27 |
19 redirect_to = request.REQUEST.get(redirect_field_name, '') |
28 redirect_to = request.REQUEST.get(redirect_field_name, '') |
|
29 |
20 if request.method == "POST": |
30 if request.method == "POST": |
21 form = AuthenticationForm(data=request.POST) |
31 form = authentication_form(data=request.POST) |
22 if form.is_valid(): |
32 if form.is_valid(): |
23 # Light security check -- make sure redirect_to isn't garbage. |
33 # Light security check -- make sure redirect_to isn't garbage. |
24 if not redirect_to or '//' in redirect_to or ' ' in redirect_to: |
34 if not redirect_to or ' ' in redirect_to: |
25 redirect_to = settings.LOGIN_REDIRECT_URL |
35 redirect_to = settings.LOGIN_REDIRECT_URL |
26 from django.contrib.auth import login |
36 |
27 login(request, form.get_user()) |
37 # Heavier security check -- redirects to http://example.com should |
|
38 # not be allowed, but things like /view/?param=http://example.com |
|
39 # should be allowed. This regex checks if there is a '//' *before* a |
|
40 # question mark. |
|
41 elif '//' in redirect_to and re.match(r'[^\?]*//', redirect_to): |
|
42 redirect_to = settings.LOGIN_REDIRECT_URL |
|
43 |
|
44 # Okay, security checks complete. Log the user in. |
|
45 auth_login(request, form.get_user()) |
|
46 |
28 if request.session.test_cookie_worked(): |
47 if request.session.test_cookie_worked(): |
29 request.session.delete_test_cookie() |
48 request.session.delete_test_cookie() |
|
49 |
30 return HttpResponseRedirect(redirect_to) |
50 return HttpResponseRedirect(redirect_to) |
|
51 |
31 else: |
52 else: |
32 form = AuthenticationForm(request) |
53 form = authentication_form(request) |
|
54 |
33 request.session.set_test_cookie() |
55 request.session.set_test_cookie() |
|
56 |
34 if Site._meta.installed: |
57 if Site._meta.installed: |
35 current_site = Site.objects.get_current() |
58 current_site = Site.objects.get_current() |
36 else: |
59 else: |
37 current_site = RequestSite(request) |
60 current_site = RequestSite(request) |
|
61 |
38 return render_to_response(template_name, { |
62 return render_to_response(template_name, { |
39 'form': form, |
63 'form': form, |
40 redirect_field_name: redirect_to, |
64 redirect_field_name: redirect_to, |
41 'site': current_site, |
65 'site': current_site, |
42 'site_name': current_site.name, |
66 'site_name': current_site.name, |
43 }, context_instance=RequestContext(request)) |
67 }, context_instance=RequestContext(request)) |
44 login = never_cache(login) |
|
45 |
68 |
46 def logout(request, next_page=None, template_name='registration/logged_out.html', redirect_field_name=REDIRECT_FIELD_NAME): |
69 def logout(request, next_page=None, template_name='registration/logged_out.html', redirect_field_name=REDIRECT_FIELD_NAME): |
47 "Logs out the user and displays 'You are logged out' message." |
70 "Logs out the user and displays 'You are logged out' message." |
48 from django.contrib.auth import logout |
71 from django.contrib.auth import logout |
49 logout(request) |
72 logout(request) |
76 # - password_reset_done shows a success message for the above |
99 # - password_reset_done shows a success message for the above |
77 # - password_reset_confirm checks the link the user clicked and |
100 # - password_reset_confirm checks the link the user clicked and |
78 # prompts for a new password |
101 # prompts for a new password |
79 # - password_reset_complete shows a success message for the above |
102 # - password_reset_complete shows a success message for the above |
80 |
103 |
|
104 @csrf_protect |
81 def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html', |
105 def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html', |
82 email_template_name='registration/password_reset_email.html', |
106 email_template_name='registration/password_reset_email.html', |
83 password_reset_form=PasswordResetForm, token_generator=default_token_generator, |
107 password_reset_form=PasswordResetForm, token_generator=default_token_generator, |
84 post_reset_redirect=None): |
108 post_reset_redirect=None): |
85 if post_reset_redirect is None: |
109 if post_reset_redirect is None: |
105 }, context_instance=RequestContext(request)) |
129 }, context_instance=RequestContext(request)) |
106 |
130 |
107 def password_reset_done(request, template_name='registration/password_reset_done.html'): |
131 def password_reset_done(request, template_name='registration/password_reset_done.html'): |
108 return render_to_response(template_name, context_instance=RequestContext(request)) |
132 return render_to_response(template_name, context_instance=RequestContext(request)) |
109 |
133 |
|
134 # Doesn't need csrf_protect since no-one can guess the URL |
110 def password_reset_confirm(request, uidb36=None, token=None, template_name='registration/password_reset_confirm.html', |
135 def password_reset_confirm(request, uidb36=None, token=None, template_name='registration/password_reset_confirm.html', |
111 token_generator=default_token_generator, set_password_form=SetPasswordForm, |
136 token_generator=default_token_generator, set_password_form=SetPasswordForm, |
112 post_reset_redirect=None): |
137 post_reset_redirect=None): |
113 """ |
138 """ |
114 View that checks the hash in a password reset link and presents a |
139 View that checks the hash in a password reset link and presents a |
135 else: |
160 else: |
136 form = set_password_form(None) |
161 form = set_password_form(None) |
137 else: |
162 else: |
138 context_instance['validlink'] = False |
163 context_instance['validlink'] = False |
139 form = None |
164 form = None |
140 context_instance['form'] = form |
165 context_instance['form'] = form |
141 return render_to_response(template_name, context_instance=context_instance) |
166 return render_to_response(template_name, context_instance=context_instance) |
142 |
167 |
143 def password_reset_complete(request, template_name='registration/password_reset_complete.html'): |
168 def password_reset_complete(request, template_name='registration/password_reset_complete.html'): |
144 return render_to_response(template_name, context_instance=RequestContext(request, |
169 return render_to_response(template_name, context_instance=RequestContext(request, |
145 {'login_url': settings.LOGIN_URL})) |
170 {'login_url': settings.LOGIN_URL})) |
146 |
171 |
|
172 @csrf_protect |
|
173 @login_required |
147 def password_change(request, template_name='registration/password_change_form.html', |
174 def password_change(request, template_name='registration/password_change_form.html', |
148 post_change_redirect=None): |
175 post_change_redirect=None, password_change_form=PasswordChangeForm): |
149 if post_change_redirect is None: |
176 if post_change_redirect is None: |
150 post_change_redirect = reverse('django.contrib.auth.views.password_change_done') |
177 post_change_redirect = reverse('django.contrib.auth.views.password_change_done') |
151 if request.method == "POST": |
178 if request.method == "POST": |
152 form = PasswordChangeForm(request.user, request.POST) |
179 form = password_change_form(user=request.user, data=request.POST) |
153 if form.is_valid(): |
180 if form.is_valid(): |
154 form.save() |
181 form.save() |
155 return HttpResponseRedirect(post_change_redirect) |
182 return HttpResponseRedirect(post_change_redirect) |
156 else: |
183 else: |
157 form = PasswordChangeForm(request.user) |
184 form = password_change_form(user=request.user) |
158 return render_to_response(template_name, { |
185 return render_to_response(template_name, { |
159 'form': form, |
186 'form': form, |
160 }, context_instance=RequestContext(request)) |
187 }, context_instance=RequestContext(request)) |
161 password_change = login_required(password_change) |
|
162 |
188 |
163 def password_change_done(request, template_name='registration/password_change_done.html'): |
189 def password_change_done(request, template_name='registration/password_change_done.html'): |
164 return render_to_response(template_name, context_instance=RequestContext(request)) |
190 return render_to_response(template_name, context_instance=RequestContext(request)) |