Fixed #3185 -- Made values for login, logout and post-login redirect URLs
configurable. This is a combined patch from Vasily Sulatskov, Marc Fargas and Collin Grady. git-svn-id: http://code.djangoproject.com/svn/django/trunk@5072 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
d744a660c4
commit
5dfe74f221
|
@ -312,6 +312,12 @@ BANNED_IPS = ()
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
|
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
|
||||||
|
|
||||||
|
LOGIN_URL = '/accounts/login/'
|
||||||
|
|
||||||
|
LOGOUT_URL = '/accounts/logout/'
|
||||||
|
|
||||||
|
LOGIN_REDIRECT_URL = '/accounts/profile/'
|
||||||
|
|
||||||
###########
|
###########
|
||||||
# TESTING #
|
# TESTING #
|
||||||
###########
|
###########
|
||||||
|
|
|
@ -2,7 +2,6 @@ from django.core.exceptions import ImproperlyConfigured
|
||||||
|
|
||||||
SESSION_KEY = '_auth_user_id'
|
SESSION_KEY = '_auth_user_id'
|
||||||
BACKEND_SESSION_KEY = '_auth_user_backend'
|
BACKEND_SESSION_KEY = '_auth_user_backend'
|
||||||
LOGIN_URL = '/accounts/login/'
|
|
||||||
REDIRECT_FIELD_NAME = 'next'
|
REDIRECT_FIELD_NAME = 'next'
|
||||||
|
|
||||||
def load_backend(path):
|
def load_backend(path):
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
from django.contrib.auth import LOGIN_URL, REDIRECT_FIELD_NAME
|
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from urllib import quote
|
from urllib import quote
|
||||||
|
|
||||||
def user_passes_test(test_func, login_url=LOGIN_URL):
|
def user_passes_test(test_func, login_url=None):
|
||||||
"""
|
"""
|
||||||
Decorator for views that checks that the user passes the given test,
|
Decorator for views that checks that the user passes the given test,
|
||||||
redirecting to the log-in page if necessary. The test should be a callable
|
redirecting to the log-in page if necessary. The test should be a callable
|
||||||
that takes the user object and returns True if the user passes.
|
that takes the user object and returns True if the user passes.
|
||||||
"""
|
"""
|
||||||
|
if not login_url:
|
||||||
|
from django.conf import settings
|
||||||
|
login_url = settings.LOGIN_URL
|
||||||
def _dec(view_func):
|
def _dec(view_func):
|
||||||
def _checklogin(request, *args, **kwargs):
|
def _checklogin(request, *args, **kwargs):
|
||||||
if test_func(request.user):
|
if test_func(request.user):
|
||||||
|
@ -27,7 +30,7 @@ login_required.__doc__ = (
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
def permission_required(perm, login_url=LOGIN_URL):
|
def permission_required(perm, login_url=None):
|
||||||
"""
|
"""
|
||||||
Decorator for views that checks whether a user has a particular permission
|
Decorator for views that checks whether a user has a particular permission
|
||||||
enabled, redirecting to the log-in page if necessary.
|
enabled, redirecting to the log-in page if necessary.
|
||||||
|
|
|
@ -6,7 +6,7 @@ from django.template import RequestContext
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth import LOGIN_URL, REDIRECT_FIELD_NAME
|
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||||
|
|
||||||
def login(request, template_name='registration/login.html'):
|
def login(request, template_name='registration/login.html'):
|
||||||
"Displays the login form and handles the login action."
|
"Displays the login form and handles the login action."
|
||||||
|
@ -17,7 +17,8 @@ def login(request, template_name='registration/login.html'):
|
||||||
if not errors:
|
if not errors:
|
||||||
# Light security check -- make sure redirect_to isn't garbage.
|
# Light security check -- make sure redirect_to isn't garbage.
|
||||||
if not redirect_to or '://' in redirect_to or ' ' in redirect_to:
|
if not redirect_to or '://' in redirect_to or ' ' in redirect_to:
|
||||||
redirect_to = '/accounts/profile/'
|
from django.conf import settings
|
||||||
|
redirect_to = settings.LOGIN_REDIRECT_URL
|
||||||
from django.contrib.auth import login
|
from django.contrib.auth import login
|
||||||
login(request, manipulator.get_user())
|
login(request, manipulator.get_user())
|
||||||
request.session.delete_test_cookie()
|
request.session.delete_test_cookie()
|
||||||
|
@ -41,12 +42,18 @@ def logout(request, next_page=None, template_name='registration/logged_out.html'
|
||||||
# Redirect to this page until the session has been cleared.
|
# Redirect to this page until the session has been cleared.
|
||||||
return HttpResponseRedirect(next_page or request.path)
|
return HttpResponseRedirect(next_page or request.path)
|
||||||
|
|
||||||
def logout_then_login(request, login_url=LOGIN_URL):
|
def logout_then_login(request, login_url=None):
|
||||||
"Logs out the user if he is logged in. Then redirects to the log-in page."
|
"Logs out the user if he is logged in. Then redirects to the log-in page."
|
||||||
|
if not login_url:
|
||||||
|
from django.conf import settings
|
||||||
|
login_url = settings.LOGIN_URL
|
||||||
return logout(request, login_url)
|
return logout(request, login_url)
|
||||||
|
|
||||||
def redirect_to_login(next, login_url=LOGIN_URL):
|
def redirect_to_login(next, login_url=None):
|
||||||
"Redirects the user to the login page, passing the given 'next' page"
|
"Redirects the user to the login page, passing the given 'next' page"
|
||||||
|
if not login_url:
|
||||||
|
from django.conf import settings
|
||||||
|
login_url = settings.LOGIN_URL
|
||||||
return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, next))
|
return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, next))
|
||||||
|
|
||||||
def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html',
|
def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html',
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<form {% if photos_optional or photos_required %}enctype="multipart/form-data" {% endif %}action="/comments/post/" method="post">
|
<form {% if photos_optional or photos_required %}enctype="multipart/form-data" {% endif %}action="/comments/post/" method="post">
|
||||||
|
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
<p>{% trans "Username:" %} <strong>{{ user.username }}</strong> (<a href="/accounts/logout/">{% trans "Log out" %}</a>)</p>
|
<p>{% trans "Username:" %} <strong>{{ user.username }}</strong> (<a href="{{ logout_url }}">{% trans "Log out" %}</a>)</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p><label for="id_username">{% trans "Username:" %}</label> <input type="text" name="username" id="id_username" /><br />{% trans "Password:" %} <input type="password" name="password" id="id_password" /> (<a href="/accounts/password_reset/">{% trans "Forgotten your password?" %}</a>)</p>
|
<p><label for="id_username">{% trans "Username:" %}</label> <input type="text" name="username" id="id_username" /><br />{% trans "Password:" %} <input type="password" name="password" id="id_password" /> (<a href="/accounts/password_reset/">{% trans "Forgotten your password?" %}</a>)</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -25,6 +25,7 @@ class CommentFormNode(template.Node):
|
||||||
self.is_public = is_public
|
self.is_public = is_public
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
|
from django.conf import settings
|
||||||
from django.utils.text import normalize_newlines
|
from django.utils.text import normalize_newlines
|
||||||
import base64
|
import base64
|
||||||
context.push()
|
context.push()
|
||||||
|
@ -64,6 +65,7 @@ class CommentFormNode(template.Node):
|
||||||
if self.rating_options:
|
if self.rating_options:
|
||||||
context['rating_range'], context['rating_choices'] = Comment.objects.get_rating_options(self.rating_options)
|
context['rating_range'], context['rating_choices'] = Comment.objects.get_rating_options(self.rating_options)
|
||||||
context['hash'] = Comment.objects.get_security_hash(context['options'], context['photo_options'], context['rating_options'], context['target'])
|
context['hash'] = Comment.objects.get_security_hash(context['options'], context['photo_options'], context['rating_options'], context['target'])
|
||||||
|
context['logout_url'] = settings.LOGOUT_URL
|
||||||
default_form = loader.get_template(COMMENT_FORM)
|
default_form = loader.get_template(COMMENT_FORM)
|
||||||
output = default_form.render(context)
|
output = default_form.render(context)
|
||||||
context.pop()
|
context.pop()
|
||||||
|
|
|
@ -387,14 +387,15 @@ introduced in Python 2.4::
|
||||||
|
|
||||||
``login_required`` does the following:
|
``login_required`` does the following:
|
||||||
|
|
||||||
* If the user isn't logged in, redirect to ``/accounts/login/``, passing
|
* If the user isn't logged in, redirect to ``settings.LOGIN_URL``
|
||||||
the current absolute URL in the query string as ``next``. For example:
|
(``/accounts/login/`` by default), passing the current absolute URL
|
||||||
|
in the query string as ``next``. For example:
|
||||||
``/accounts/login/?next=/polls/3/``.
|
``/accounts/login/?next=/polls/3/``.
|
||||||
* If the user is logged in, execute the view normally. The view code is
|
* If the user is logged in, execute the view normally. The view code is
|
||||||
free to assume the user is logged in.
|
free to assume the user is logged in.
|
||||||
|
|
||||||
Note that you'll need to map the appropriate Django view to ``/accounts/login/``.
|
Note that you'll need to map the appropriate Django view to ``settings.LOGIN_URL``.
|
||||||
To do this, add the following line to your URLconf::
|
For example, using the defaults, add the following line to your URLconf::
|
||||||
|
|
||||||
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
|
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
|
||||||
|
|
||||||
|
@ -405,9 +406,9 @@ Here's what ``django.contrib.auth.views.login`` does:
|
||||||
|
|
||||||
* If called via ``POST``, it tries to log the user in. If login is
|
* If called via ``POST``, it tries to log the user in. If login is
|
||||||
successful, the view redirects to the URL specified in ``next``. If
|
successful, the view redirects to the URL specified in ``next``. If
|
||||||
``next`` isn't provided, it redirects to ``/accounts/profile/`` (which is
|
``next`` isn't provided, it redirects to ``settings.LOGIN_REDIRECT_URL``
|
||||||
currently hard-coded). If login isn't successful, it redisplays the login
|
(which defaults to ``/accounts/profile/``). If login isn't successful,
|
||||||
form.
|
it redisplays the login form.
|
||||||
|
|
||||||
It's your responsibility to provide the login form in a template called
|
It's your responsibility to provide the login form in a template called
|
||||||
``registration/login.html`` by default. This template gets passed three
|
``registration/login.html`` by default. This template gets passed three
|
||||||
|
@ -487,7 +488,7 @@ Logs a user out, then redirects to the login page.
|
||||||
**Optional arguments:**
|
**Optional arguments:**
|
||||||
|
|
||||||
* ``login_url``: The URL of the login page to redirect to. This
|
* ``login_url``: The URL of the login page to redirect to. This
|
||||||
will default to ``/accounts/login/`` if not supplied.
|
will default to ``settings.LOGIN_URL`` if not supplied.
|
||||||
|
|
||||||
``django.contrib.auth.views.password_change``
|
``django.contrib.auth.views.password_change``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -569,7 +570,7 @@ successful login.
|
||||||
**Optional arguments:**
|
**Optional arguments:**
|
||||||
|
|
||||||
* ``login_url``: The URL of the login page to redirect to. This
|
* ``login_url``: The URL of the login page to redirect to. This
|
||||||
will default to ``/accounts/login/`` if not supplied.
|
will default to ``settings.LOGIN_URL`` if not supplied.
|
||||||
|
|
||||||
Built-in manipulators
|
Built-in manipulators
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -636,7 +637,7 @@ Note that ``user_passes_test`` does not automatically check that the ``User``
|
||||||
is not anonymous.
|
is not anonymous.
|
||||||
|
|
||||||
``user_passes_test()`` takes an optional ``login_url`` argument, which lets you
|
``user_passes_test()`` takes an optional ``login_url`` argument, which lets you
|
||||||
specify the URL for your login page (``/accounts/login/`` by default).
|
specify the URL for your login page (``settings.LOGIN_URL`` by default).
|
||||||
|
|
||||||
Example in Python 2.3 syntax::
|
Example in Python 2.3 syntax::
|
||||||
|
|
||||||
|
@ -680,7 +681,7 @@ parameter. Example::
|
||||||
my_view = permission_required('polls.can_vote', login_url='/loginpage/')(my_view)
|
my_view = permission_required('polls.can_vote', login_url='/loginpage/')(my_view)
|
||||||
|
|
||||||
As in the ``login_required`` decorator, ``login_url`` defaults to
|
As in the ``login_required`` decorator, ``login_url`` defaults to
|
||||||
``'/accounts/login/'``.
|
``settings.LOGIN_URL``.
|
||||||
|
|
||||||
Limiting access to generic views
|
Limiting access to generic views
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
|
@ -562,6 +562,21 @@ strings for translation, but the translation won't happen at runtime -- so
|
||||||
you'll have to remember to wrap the languages in the *real* ``gettext()`` in
|
you'll have to remember to wrap the languages in the *real* ``gettext()`` in
|
||||||
any code that uses ``LANGUAGES`` at runtime.
|
any code that uses ``LANGUAGES`` at runtime.
|
||||||
|
|
||||||
|
LOGIN_URL
|
||||||
|
---------
|
||||||
|
|
||||||
|
Default: ``'/accounts/login/'``
|
||||||
|
|
||||||
|
The URL where requests are redirected for login, specially when using the
|
||||||
|
`@login_required`_ decorator.
|
||||||
|
|
||||||
|
LOGOUT_URL
|
||||||
|
----------
|
||||||
|
|
||||||
|
Default: ``'/accounts/logout/'``
|
||||||
|
|
||||||
|
LOGIN_URL counterpart.
|
||||||
|
|
||||||
MANAGERS
|
MANAGERS
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
@ -620,6 +635,16 @@ locales have different formats. For example, U.S. English would say
|
||||||
See `allowed date format strings`_. See also DATE_FORMAT, DATETIME_FORMAT,
|
See `allowed date format strings`_. See also DATE_FORMAT, DATETIME_FORMAT,
|
||||||
TIME_FORMAT and YEAR_MONTH_FORMAT.
|
TIME_FORMAT and YEAR_MONTH_FORMAT.
|
||||||
|
|
||||||
|
LOGIN_REDIRECT_URL
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Default: ``'/accounts/profile/'``
|
||||||
|
|
||||||
|
The URL where requests are redirected after login when the
|
||||||
|
``contrib.auth.login`` view gets no ``next`` parameter.
|
||||||
|
|
||||||
|
This is used by the `@login_required`_ decorator, for example.
|
||||||
|
|
||||||
PREPEND_WWW
|
PREPEND_WWW
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
@ -1012,6 +1037,8 @@ Also, it's an error to call ``configure()`` more than once, or to call
|
||||||
It boils down to this: Use exactly one of either ``configure()`` or
|
It boils down to this: Use exactly one of either ``configure()`` or
|
||||||
``DJANGO_SETTINGS_MODULE``. Not both, and not neither.
|
``DJANGO_SETTINGS_MODULE``. Not both, and not neither.
|
||||||
|
|
||||||
|
.. _@login_required: ../authentication/#the-login-required-decorator
|
||||||
|
|
||||||
Error reporting via e-mail
|
Error reporting via e-mail
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue