2010-03-02 03:58:53 +08:00
|
|
|
import re
|
2008-08-02 00:13:12 +08:00
|
|
|
from django.conf import settings
|
2008-06-26 12:11:53 +08:00
|
|
|
from django.contrib.auth import REDIRECT_FIELD_NAME
|
2010-03-02 03:58:53 +08:00
|
|
|
# Avoid shadowing the login() view below.
|
|
|
|
from django.contrib.auth import login as auth_login
|
2008-06-26 12:11:53 +08:00
|
|
|
from django.contrib.auth.decorators import login_required
|
2006-05-02 09:31:56 +08:00
|
|
|
from django.contrib.auth.forms import AuthenticationForm
|
2008-08-16 01:42:13 +08:00
|
|
|
from django.contrib.auth.forms import PasswordResetForm, SetPasswordForm, PasswordChangeForm
|
2008-08-01 04:47:53 +08:00
|
|
|
from django.contrib.auth.tokens import default_token_generator
|
2009-10-27 08:36:34 +08:00
|
|
|
from django.views.decorators.csrf import csrf_protect
|
2008-08-13 07:31:31 +08:00
|
|
|
from django.core.urlresolvers import reverse
|
2008-07-19 07:54:34 +08:00
|
|
|
from django.shortcuts import render_to_response, get_object_or_404
|
2007-08-15 06:08:11 +08:00
|
|
|
from django.contrib.sites.models import Site, RequestSite
|
2008-08-01 04:47:53 +08:00
|
|
|
from django.http import HttpResponseRedirect, Http404
|
2008-06-26 12:11:53 +08:00
|
|
|
from django.template import RequestContext
|
2008-08-01 04:47:53 +08:00
|
|
|
from django.utils.http import urlquote, base36_to_int
|
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
|
|
|
from django.utils.translation import ugettext as _
|
2008-07-19 07:54:34 +08:00
|
|
|
from django.contrib.auth.models import User
|
2008-08-16 01:10:14 +08:00
|
|
|
from django.views.decorators.cache import never_cache
|
2006-05-02 09:31:56 +08:00
|
|
|
|
Fixed #9977 - CsrfMiddleware gets template tag added, session dependency removed, and turned on by default.
This is a large change to CSRF protection for Django. It includes:
* removing the dependency on the session framework.
* deprecating CsrfResponseMiddleware, and replacing with a core template tag.
* turning on CSRF protection by default by adding CsrfViewMiddleware to
the default value of MIDDLEWARE_CLASSES.
* protecting all contrib apps (whatever is in settings.py)
using a decorator.
For existing users of the CSRF functionality, it should be a seamless update,
but please note that it includes DEPRECATION of features in Django 1.1,
and there are upgrade steps which are detailed in the docs.
Many thanks to 'Glenn' and 'bthomas', who did a lot of the thinking and work
on the patch, and to lots of other people including Simon Willison and
Russell Keith-Magee who refined the ideas.
Details of the rationale for these changes is found here:
http://code.djangoproject.com/wiki/CsrfProtection
As of this commit, the CSRF code is mainly in 'contrib'. The code will be
moved to core in a separate commit, to make the changeset as readable as
possible.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@11660 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2009-10-27 07:23:07 +08:00
|
|
|
@csrf_protect
|
|
|
|
@never_cache
|
2009-10-12 23:32:24 +08:00
|
|
|
def login(request, template_name='registration/login.html',
|
|
|
|
redirect_field_name=REDIRECT_FIELD_NAME,
|
|
|
|
authentication_form=AuthenticationForm):
|
2010-03-02 03:58:53 +08:00
|
|
|
"""Displays the login form and handles the login action."""
|
|
|
|
|
2007-09-15 03:25:37 +08:00
|
|
|
redirect_to = request.REQUEST.get(redirect_field_name, '')
|
2010-03-02 03:58:53 +08:00
|
|
|
|
2008-07-19 07:54:34 +08:00
|
|
|
if request.method == "POST":
|
2009-10-12 23:32:24 +08:00
|
|
|
form = authentication_form(data=request.POST)
|
2008-07-19 07:54:34 +08:00
|
|
|
if form.is_valid():
|
2006-05-02 09:31:56 +08:00
|
|
|
# Light security check -- make sure redirect_to isn't garbage.
|
2010-03-02 03:58:53 +08:00
|
|
|
if not redirect_to or ' ' in redirect_to:
|
2007-04-25 16:49:57 +08:00
|
|
|
redirect_to = settings.LOGIN_REDIRECT_URL
|
2010-03-02 03:58:53 +08:00
|
|
|
|
|
|
|
# Heavier security check -- redirects to http://example.com should
|
|
|
|
# not be allowed, but things like /view/?param=http://example.com
|
|
|
|
# should be allowed. This regex checks if there is a '//' *before* a
|
|
|
|
# question mark.
|
|
|
|
elif '//' in redirect_to and re.match(r'[^\?]*//', redirect_to):
|
|
|
|
redirect_to = settings.LOGIN_REDIRECT_URL
|
|
|
|
|
|
|
|
# Okay, security checks complete. Log the user in.
|
|
|
|
auth_login(request, form.get_user())
|
|
|
|
|
2008-06-19 00:13:14 +08:00
|
|
|
if request.session.test_cookie_worked():
|
|
|
|
request.session.delete_test_cookie()
|
2010-03-02 03:58:53 +08:00
|
|
|
|
2006-05-02 09:31:56 +08:00
|
|
|
return HttpResponseRedirect(redirect_to)
|
2010-03-02 03:58:53 +08:00
|
|
|
|
2006-05-02 09:31:56 +08:00
|
|
|
else:
|
2009-10-12 23:32:24 +08:00
|
|
|
form = authentication_form(request)
|
2010-03-02 03:58:53 +08:00
|
|
|
|
2006-05-02 09:31:56 +08:00
|
|
|
request.session.set_test_cookie()
|
2010-03-02 03:58:53 +08:00
|
|
|
|
2007-08-15 06:08:11 +08:00
|
|
|
if Site._meta.installed:
|
|
|
|
current_site = Site.objects.get_current()
|
|
|
|
else:
|
2007-08-15 06:26:34 +08:00
|
|
|
current_site = RequestSite(request)
|
2010-03-02 03:58:53 +08:00
|
|
|
|
2006-06-06 13:16:05 +08:00
|
|
|
return render_to_response(template_name, {
|
2008-07-19 07:54:34 +08:00
|
|
|
'form': form,
|
2007-09-15 03:25:37 +08:00
|
|
|
redirect_field_name: redirect_to,
|
2009-04-02 00:37:48 +08:00
|
|
|
'site': current_site,
|
2007-08-15 06:08:11 +08:00
|
|
|
'site_name': current_site.name,
|
2006-05-02 09:31:56 +08:00
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
2009-04-02 01:02:32 +08:00
|
|
|
def logout(request, next_page=None, template_name='registration/logged_out.html', redirect_field_name=REDIRECT_FIELD_NAME):
|
2006-05-02 09:31:56 +08:00
|
|
|
"Logs out the user and displays 'You are logged out' message."
|
2006-06-29 00:37:02 +08:00
|
|
|
from django.contrib.auth import logout
|
2006-07-24 07:14:36 +08:00
|
|
|
logout(request)
|
|
|
|
if next_page is None:
|
2009-04-02 01:02:32 +08:00
|
|
|
redirect_to = request.REQUEST.get(redirect_field_name, '')
|
|
|
|
if redirect_to:
|
|
|
|
return HttpResponseRedirect(redirect_to)
|
|
|
|
else:
|
|
|
|
return render_to_response(template_name, {
|
|
|
|
'title': _('Logged out')
|
|
|
|
}, context_instance=RequestContext(request))
|
2006-05-02 09:31:56 +08:00
|
|
|
else:
|
|
|
|
# Redirect to this page until the session has been cleared.
|
|
|
|
return HttpResponseRedirect(next_page or request.path)
|
|
|
|
|
2007-04-25 16:49:57 +08:00
|
|
|
def logout_then_login(request, login_url=None):
|
2006-05-02 09:31:56 +08:00
|
|
|
"Logs out the user if he is logged in. Then redirects to the log-in page."
|
2007-04-25 16:49:57 +08:00
|
|
|
if not login_url:
|
|
|
|
login_url = settings.LOGIN_URL
|
2006-05-02 09:31:56 +08:00
|
|
|
return logout(request, login_url)
|
|
|
|
|
2007-09-15 03:25:37 +08:00
|
|
|
def redirect_to_login(next, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
|
2006-05-02 09:31:56 +08:00
|
|
|
"Redirects the user to the login page, passing the given 'next' page"
|
2007-04-25 16:49:57 +08:00
|
|
|
if not login_url:
|
|
|
|
login_url = settings.LOGIN_URL
|
2008-06-26 12:11:53 +08:00
|
|
|
return HttpResponseRedirect('%s?%s=%s' % (login_url, urlquote(redirect_field_name), urlquote(next)))
|
2006-05-02 09:31:56 +08:00
|
|
|
|
2008-08-01 04:47:53 +08:00
|
|
|
# 4 views for password reset:
|
|
|
|
# - password_reset sends the mail
|
|
|
|
# - password_reset_done shows a success message for the above
|
|
|
|
# - password_reset_confirm checks the link the user clicked and
|
|
|
|
# prompts for a new password
|
|
|
|
# - password_reset_complete shows a success message for the above
|
|
|
|
|
Fixed #9977 - CsrfMiddleware gets template tag added, session dependency removed, and turned on by default.
This is a large change to CSRF protection for Django. It includes:
* removing the dependency on the session framework.
* deprecating CsrfResponseMiddleware, and replacing with a core template tag.
* turning on CSRF protection by default by adding CsrfViewMiddleware to
the default value of MIDDLEWARE_CLASSES.
* protecting all contrib apps (whatever is in settings.py)
using a decorator.
For existing users of the CSRF functionality, it should be a seamless update,
but please note that it includes DEPRECATION of features in Django 1.1,
and there are upgrade steps which are detailed in the docs.
Many thanks to 'Glenn' and 'bthomas', who did a lot of the thinking and work
on the patch, and to lots of other people including Simon Willison and
Russell Keith-Magee who refined the ideas.
Details of the rationale for these changes is found here:
http://code.djangoproject.com/wiki/CsrfProtection
As of this commit, the CSRF code is mainly in 'contrib'. The code will be
moved to core in a separate commit, to make the changeset as readable as
possible.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@11660 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2009-10-27 07:23:07 +08:00
|
|
|
@csrf_protect
|
2006-07-28 01:48:35 +08:00
|
|
|
def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html',
|
2008-07-19 07:54:34 +08:00
|
|
|
email_template_name='registration/password_reset_email.html',
|
2008-08-23 11:26:01 +08:00
|
|
|
password_reset_form=PasswordResetForm, token_generator=default_token_generator,
|
|
|
|
post_reset_redirect=None):
|
|
|
|
if post_reset_redirect is None:
|
|
|
|
post_reset_redirect = reverse('django.contrib.auth.views.password_reset_done')
|
2008-07-19 07:54:34 +08:00
|
|
|
if request.method == "POST":
|
|
|
|
form = password_reset_form(request.POST)
|
|
|
|
if form.is_valid():
|
2008-08-01 04:47:53 +08:00
|
|
|
opts = {}
|
|
|
|
opts['use_https'] = request.is_secure()
|
|
|
|
opts['token_generator'] = token_generator
|
2006-05-02 09:31:56 +08:00
|
|
|
if is_admin_site:
|
2008-08-01 04:47:53 +08:00
|
|
|
opts['domain_override'] = request.META['HTTP_HOST']
|
2006-05-02 09:31:56 +08:00
|
|
|
else:
|
2008-08-01 04:47:53 +08:00
|
|
|
opts['email_template_name'] = email_template_name
|
|
|
|
if not Site._meta.installed:
|
|
|
|
opts['domain_override'] = RequestSite(request).domain
|
|
|
|
form.save(**opts)
|
2008-08-23 11:26:01 +08:00
|
|
|
return HttpResponseRedirect(post_reset_redirect)
|
2008-07-19 07:54:34 +08:00
|
|
|
else:
|
|
|
|
form = password_reset_form()
|
|
|
|
return render_to_response(template_name, {
|
|
|
|
'form': form,
|
|
|
|
}, context_instance=RequestContext(request))
|
2006-05-02 09:31:56 +08:00
|
|
|
|
2006-06-06 13:16:05 +08:00
|
|
|
def password_reset_done(request, template_name='registration/password_reset_done.html'):
|
|
|
|
return render_to_response(template_name, context_instance=RequestContext(request))
|
2006-05-02 09:31:56 +08:00
|
|
|
|
Fixed #9977 - CsrfMiddleware gets template tag added, session dependency removed, and turned on by default.
This is a large change to CSRF protection for Django. It includes:
* removing the dependency on the session framework.
* deprecating CsrfResponseMiddleware, and replacing with a core template tag.
* turning on CSRF protection by default by adding CsrfViewMiddleware to
the default value of MIDDLEWARE_CLASSES.
* protecting all contrib apps (whatever is in settings.py)
using a decorator.
For existing users of the CSRF functionality, it should be a seamless update,
but please note that it includes DEPRECATION of features in Django 1.1,
and there are upgrade steps which are detailed in the docs.
Many thanks to 'Glenn' and 'bthomas', who did a lot of the thinking and work
on the patch, and to lots of other people including Simon Willison and
Russell Keith-Magee who refined the ideas.
Details of the rationale for these changes is found here:
http://code.djangoproject.com/wiki/CsrfProtection
As of this commit, the CSRF code is mainly in 'contrib'. The code will be
moved to core in a separate commit, to make the changeset as readable as
possible.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@11660 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2009-10-27 07:23:07 +08:00
|
|
|
# Doesn't need csrf_protect since no-one can guess the URL
|
2008-08-01 04:47:53 +08:00
|
|
|
def password_reset_confirm(request, uidb36=None, token=None, template_name='registration/password_reset_confirm.html',
|
2008-08-23 11:26:01 +08:00
|
|
|
token_generator=default_token_generator, set_password_form=SetPasswordForm,
|
|
|
|
post_reset_redirect=None):
|
2008-08-01 04:47:53 +08:00
|
|
|
"""
|
|
|
|
View that checks the hash in a password reset link and presents a
|
|
|
|
form for entering a new password.
|
|
|
|
"""
|
|
|
|
assert uidb36 is not None and token is not None # checked by URLconf
|
2008-08-23 11:26:01 +08:00
|
|
|
if post_reset_redirect is None:
|
|
|
|
post_reset_redirect = reverse('django.contrib.auth.views.password_reset_complete')
|
2008-08-01 04:47:53 +08:00
|
|
|
try:
|
|
|
|
uid_int = base36_to_int(uidb36)
|
|
|
|
except ValueError:
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
user = get_object_or_404(User, id=uid_int)
|
|
|
|
context_instance = RequestContext(request)
|
|
|
|
|
|
|
|
if token_generator.check_token(user, token):
|
|
|
|
context_instance['validlink'] = True
|
|
|
|
if request.method == 'POST':
|
|
|
|
form = set_password_form(user, request.POST)
|
|
|
|
if form.is_valid():
|
|
|
|
form.save()
|
2008-08-23 11:26:01 +08:00
|
|
|
return HttpResponseRedirect(post_reset_redirect)
|
2008-08-01 04:47:53 +08:00
|
|
|
else:
|
|
|
|
form = set_password_form(None)
|
|
|
|
else:
|
|
|
|
context_instance['validlink'] = False
|
|
|
|
form = None
|
2009-10-12 23:32:24 +08:00
|
|
|
context_instance['form'] = form
|
2008-08-01 04:47:53 +08:00
|
|
|
return render_to_response(template_name, context_instance=context_instance)
|
|
|
|
|
|
|
|
def password_reset_complete(request, template_name='registration/password_reset_complete.html'):
|
2008-08-02 00:13:12 +08:00
|
|
|
return render_to_response(template_name, context_instance=RequestContext(request,
|
|
|
|
{'login_url': settings.LOGIN_URL}))
|
2008-08-01 04:47:53 +08:00
|
|
|
|
Fixed #9977 - CsrfMiddleware gets template tag added, session dependency removed, and turned on by default.
This is a large change to CSRF protection for Django. It includes:
* removing the dependency on the session framework.
* deprecating CsrfResponseMiddleware, and replacing with a core template tag.
* turning on CSRF protection by default by adding CsrfViewMiddleware to
the default value of MIDDLEWARE_CLASSES.
* protecting all contrib apps (whatever is in settings.py)
using a decorator.
For existing users of the CSRF functionality, it should be a seamless update,
but please note that it includes DEPRECATION of features in Django 1.1,
and there are upgrade steps which are detailed in the docs.
Many thanks to 'Glenn' and 'bthomas', who did a lot of the thinking and work
on the patch, and to lots of other people including Simon Willison and
Russell Keith-Magee who refined the ideas.
Details of the rationale for these changes is found here:
http://code.djangoproject.com/wiki/CsrfProtection
As of this commit, the CSRF code is mainly in 'contrib'. The code will be
moved to core in a separate commit, to make the changeset as readable as
possible.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@11660 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2009-10-27 07:23:07 +08:00
|
|
|
@csrf_protect
|
|
|
|
@login_required
|
2008-08-23 11:26:01 +08:00
|
|
|
def password_change(request, template_name='registration/password_change_form.html',
|
2009-10-12 23:32:24 +08:00
|
|
|
post_change_redirect=None, password_change_form=PasswordChangeForm):
|
2008-08-23 11:26:01 +08:00
|
|
|
if post_change_redirect is None:
|
|
|
|
post_change_redirect = reverse('django.contrib.auth.views.password_change_done')
|
2008-07-19 07:54:34 +08:00
|
|
|
if request.method == "POST":
|
2009-10-12 23:32:24 +08:00
|
|
|
form = password_change_form(user=request.user, data=request.POST)
|
2008-07-19 07:54:34 +08:00
|
|
|
if form.is_valid():
|
|
|
|
form.save()
|
2008-08-23 11:26:01 +08:00
|
|
|
return HttpResponseRedirect(post_change_redirect)
|
2008-07-19 07:54:34 +08:00
|
|
|
else:
|
2009-10-12 23:32:24 +08:00
|
|
|
form = password_change_form(user=request.user)
|
2008-07-19 07:54:34 +08:00
|
|
|
return render_to_response(template_name, {
|
|
|
|
'form': form,
|
|
|
|
}, context_instance=RequestContext(request))
|
2006-05-02 09:31:56 +08:00
|
|
|
|
2006-06-06 13:16:05 +08:00
|
|
|
def password_change_done(request, template_name='registration/password_change_done.html'):
|
|
|
|
return render_to_response(template_name, context_instance=RequestContext(request))
|