Refs #23957 -- Required session verification per deprecation timeline.
This commit is contained in:
parent
5d383549ee
commit
849037af36
|
@ -9,11 +9,9 @@ a list of all possible variables.
|
||||||
import importlib
|
import importlib
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import warnings
|
|
||||||
|
|
||||||
from django.conf import global_settings
|
from django.conf import global_settings
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.utils.deprecation import RemovedInDjango110Warning
|
|
||||||
from django.utils.functional import LazyObject, empty
|
from django.utils.functional import LazyObject, empty
|
||||||
|
|
||||||
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
|
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
|
||||||
|
@ -118,16 +116,6 @@ class Settings(BaseSettings):
|
||||||
if not self.SECRET_KEY:
|
if not self.SECRET_KEY:
|
||||||
raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")
|
raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")
|
||||||
|
|
||||||
if ('django.contrib.auth.middleware.AuthenticationMiddleware' in self.MIDDLEWARE_CLASSES and
|
|
||||||
'django.contrib.auth.middleware.SessionAuthenticationMiddleware' not in self.MIDDLEWARE_CLASSES):
|
|
||||||
warnings.warn(
|
|
||||||
"Session verification will become mandatory in Django 1.10. "
|
|
||||||
"Please add 'django.contrib.auth.middleware.SessionAuthenticationMiddleware' "
|
|
||||||
"to your MIDDLEWARE_CLASSES setting when you are ready to opt-in after "
|
|
||||||
"reading the upgrade considerations in the 1.8 release notes.",
|
|
||||||
RemovedInDjango110Warning
|
|
||||||
)
|
|
||||||
|
|
||||||
if hasattr(time, 'tzset') and self.TIME_ZONE:
|
if hasattr(time, 'tzset') and self.TIME_ZONE:
|
||||||
# When we can, attempt to validate the timezone. If we can't find
|
# When we can, attempt to validate the timezone. If we can't find
|
||||||
# this file, no check happens and it's harmless.
|
# this file, no check happens and it's harmless.
|
||||||
|
|
|
@ -45,7 +45,6 @@ MIDDLEWARE_CLASSES = [
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
]
|
]
|
||||||
|
|
|
@ -173,8 +173,7 @@ def get_user(request):
|
||||||
backend = load_backend(backend_path)
|
backend = load_backend(backend_path)
|
||||||
user = backend.get_user(user_id)
|
user = backend.get_user(user_id)
|
||||||
# Verify the session
|
# Verify the session
|
||||||
if ('django.contrib.auth.middleware.SessionAuthenticationMiddleware'
|
if hasattr(user, 'get_session_auth_hash'):
|
||||||
in settings.MIDDLEWARE_CLASSES and hasattr(user, 'get_session_auth_hash')):
|
|
||||||
session_hash = request.session.get(HASH_SESSION_KEY)
|
session_hash = request.session.get(HASH_SESSION_KEY)
|
||||||
session_hash_verified = session_hash and constant_time_compare(
|
session_hash_verified = session_hash and constant_time_compare(
|
||||||
session_hash,
|
session_hash,
|
||||||
|
@ -196,8 +195,7 @@ def get_permission_codename(action, opts):
|
||||||
|
|
||||||
def update_session_auth_hash(request, user):
|
def update_session_auth_hash(request, user):
|
||||||
"""
|
"""
|
||||||
Updating a user's password logs out all sessions for the user if
|
Updating a user's password logs out all sessions for the user.
|
||||||
django.contrib.auth.middleware.SessionAuthenticationMiddleware is enabled.
|
|
||||||
|
|
||||||
This function takes the current request and the updated user object from
|
This function takes the current request and the updated user object from
|
||||||
which the new session hash will be derived and updates the session hash
|
which the new session hash will be derived and updates the session hash
|
||||||
|
|
|
@ -28,8 +28,8 @@ class SessionAuthenticationMiddleware(object):
|
||||||
correspond to the user's current session authentication hash. However, it
|
correspond to the user's current session authentication hash. However, it
|
||||||
caused the "Vary: Cookie" header on all responses.
|
caused the "Vary: Cookie" header on all responses.
|
||||||
|
|
||||||
Now a backwards compatibility shim that enables session verification in
|
It's now a shim to allow a single settings file to more easily support
|
||||||
auth.get_user() if this middleware is in MIDDLEWARE_CLASSES.
|
multiple versions of Django. Will be RemovedInDjango20Warning.
|
||||||
"""
|
"""
|
||||||
def process_request(self, request):
|
def process_request(self, request):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -303,9 +303,7 @@ def password_change(request,
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
# Updating the password logs out all other sessions for the user
|
# Updating the password logs out all other sessions for the user
|
||||||
# except the current one if
|
# except the current one.
|
||||||
# django.contrib.auth.middleware.SessionAuthenticationMiddleware
|
|
||||||
# is enabled.
|
|
||||||
update_session_auth_hash(request, form.user)
|
update_session_auth_hash(request, form.user)
|
||||||
return HttpResponseRedirect(post_change_redirect)
|
return HttpResponseRedirect(post_change_redirect)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -382,13 +382,6 @@ Middleware for utilizing Web server provided authentication when enabled only
|
||||||
on the login page. See :ref:`persistent-remote-user-middleware-howto` for usage
|
on the login page. See :ref:`persistent-remote-user-middleware-howto` for usage
|
||||||
details.
|
details.
|
||||||
|
|
||||||
.. class:: SessionAuthenticationMiddleware
|
|
||||||
|
|
||||||
Allows a user's sessions to be invalidated when their password changes. See
|
|
||||||
:ref:`session-invalidation-on-password-change` for details. This middleware must
|
|
||||||
appear after :class:`django.contrib.auth.middleware.AuthenticationMiddleware`
|
|
||||||
in :setting:`MIDDLEWARE_CLASSES`.
|
|
||||||
|
|
||||||
CSRF protection middleware
|
CSRF protection middleware
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
|
|
|
@ -1943,9 +1943,7 @@ The secret key is used for:
|
||||||
|
|
||||||
* All :doc:`sessions </topics/http/sessions>` if you are using
|
* All :doc:`sessions </topics/http/sessions>` if you are using
|
||||||
any other session backend than ``django.contrib.sessions.backends.cache``,
|
any other session backend than ``django.contrib.sessions.backends.cache``,
|
||||||
or if you use
|
or are using the default
|
||||||
:class:`~django.contrib.auth.middleware.SessionAuthenticationMiddleware`
|
|
||||||
and are using the default
|
|
||||||
:meth:`~django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash()`.
|
:meth:`~django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash()`.
|
||||||
* All :doc:`messages </ref/contrib/messages>` if you are using
|
* All :doc:`messages </ref/contrib/messages>` if you are using
|
||||||
:class:`~django.contrib.messages.storage.cookie.CookieStorage` or
|
:class:`~django.contrib.messages.storage.cookie.CookieStorage` or
|
||||||
|
|
|
@ -349,7 +349,9 @@ removed in Django 1.10 (please see the :ref:`deprecation timeline
|
||||||
|
|
||||||
* Session verification is enabled regardless of whether or not
|
* Session verification is enabled regardless of whether or not
|
||||||
``'django.contrib.auth.middleware.SessionAuthenticationMiddleware'`` is in
|
``'django.contrib.auth.middleware.SessionAuthenticationMiddleware'`` is in
|
||||||
``MIDDLEWARE_CLASSES``.
|
``MIDDLEWARE_CLASSES``. ``SessionAuthenticationMiddleware`` no longer has
|
||||||
|
any purpose and can be removed from ``MIDDLEWARE_CLASSES``. It's kept as
|
||||||
|
a stub until Django 2.0 as a courtesy for users who don't read this note.
|
||||||
|
|
||||||
* Private attribute ``django.db.models.Field.related`` is removed.
|
* Private attribute ``django.db.models.Field.related`` is removed.
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ Bugfixes
|
||||||
(:ticket:`23950`).
|
(:ticket:`23950`).
|
||||||
|
|
||||||
* Prevented the
|
* Prevented the
|
||||||
:class:`~django.contrib.auth.middleware.SessionAuthenticationMiddleware` from
|
``django.contrib.auth.middleware.SessionAuthenticationMiddleware`` from
|
||||||
setting a ``"Vary: Cookie"`` header on all responses (:ticket:`23939`).
|
setting a ``"Vary: Cookie"`` header on all responses (:ticket:`23939`).
|
||||||
|
|
||||||
* Fixed a crash when adding ``blank=True`` to ``TextField()`` on MySQL
|
* Fixed a crash when adding ``blank=True`` to ``TextField()`` on MySQL
|
||||||
|
|
|
@ -435,9 +435,8 @@ Minor features
|
||||||
method was added and if your :setting:`AUTH_USER_MODEL` inherits from
|
method was added and if your :setting:`AUTH_USER_MODEL` inherits from
|
||||||
:class:`~django.contrib.auth.models.AbstractBaseUser`, changing a user's
|
:class:`~django.contrib.auth.models.AbstractBaseUser`, changing a user's
|
||||||
password now invalidates old sessions if the
|
password now invalidates old sessions if the
|
||||||
:class:`~django.contrib.auth.middleware.SessionAuthenticationMiddleware` is
|
``django.contrib.auth.middleware.SessionAuthenticationMiddleware`` is
|
||||||
enabled. See :ref:`session-invalidation-on-password-change` for more details
|
enabled. See :ref:`session-invalidation-on-password-change` for more details.
|
||||||
including upgrade considerations when enabling this new middleware.
|
|
||||||
|
|
||||||
``django.contrib.formtools``
|
``django.contrib.formtools``
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -1455,7 +1454,7 @@ Miscellaneous
|
||||||
when the input is not valid UTF-8.
|
when the input is not valid UTF-8.
|
||||||
|
|
||||||
* With the addition of the
|
* With the addition of the
|
||||||
:class:`~django.contrib.auth.middleware.SessionAuthenticationMiddleware` to
|
``django.contrib.auth.middleware.SessionAuthenticationMiddleware`` to
|
||||||
the default project template (pre-1.7.2 only), a database must be created
|
the default project template (pre-1.7.2 only), a database must be created
|
||||||
before accessing a page using :djadmin:`runserver`.
|
before accessing a page using :djadmin:`runserver`.
|
||||||
|
|
||||||
|
|
|
@ -1621,7 +1621,7 @@ attribute will change from ``True`` to ``False`` in Django 1.9.
|
||||||
Using ``AuthenticationMiddleware`` without ``SessionAuthenticationMiddleware``
|
Using ``AuthenticationMiddleware`` without ``SessionAuthenticationMiddleware``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
:class:`django.contrib.auth.middleware.SessionAuthenticationMiddleware` was
|
``django.contrib.auth.middleware.SessionAuthenticationMiddleware`` was
|
||||||
added in Django 1.7. In Django 1.7.2, its functionality was moved to
|
added in Django 1.7. In Django 1.7.2, its functionality was moved to
|
||||||
``auth.get_user()`` and, for backwards compatibility, enabled only if
|
``auth.get_user()`` and, for backwards compatibility, enabled only if
|
||||||
``'django.contrib.auth.middleware.SessionAuthenticationMiddleware'`` appears in
|
``'django.contrib.auth.middleware.SessionAuthenticationMiddleware'`` appears in
|
||||||
|
|
|
@ -108,9 +108,8 @@ Django also provides :ref:`views <built-in-auth-views>` and :ref:`forms
|
||||||
<built-in-auth-forms>` that may be used to allow users to change their own
|
<built-in-auth-forms>` that may be used to allow users to change their own
|
||||||
passwords.
|
passwords.
|
||||||
|
|
||||||
Changing a user's password will log out all their sessions if the
|
Changing a user's password will log out all their sessions. See
|
||||||
:class:`~django.contrib.auth.middleware.SessionAuthenticationMiddleware` is
|
:ref:`session-invalidation-on-password-change` for details.
|
||||||
enabled. See :ref:`session-invalidation-on-password-change` for details.
|
|
||||||
|
|
||||||
Authenticating Users
|
Authenticating Users
|
||||||
--------------------
|
--------------------
|
||||||
|
@ -801,29 +800,23 @@ user to the login page or issue an HTTP 403 Forbidden response.
|
||||||
Session invalidation on password change
|
Session invalidation on password change
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. warning::
|
.. versionchanged:: 1.10
|
||||||
|
|
||||||
This protection only applies if
|
Session verification is enabled and mandatory in Django 1.10 (there's no
|
||||||
:class:`~django.contrib.auth.middleware.SessionAuthenticationMiddleware`
|
way to disable it) regardless of whether or not
|
||||||
is enabled in :setting:`MIDDLEWARE_CLASSES`. It's included if
|
``SessionAuthenticationMiddleware`` is enabled. In older
|
||||||
``settings.py`` was generated by :djadmin:`startproject` on Django ≥ 1.7.
|
versions, this protection only applies if
|
||||||
|
``django.contrib.auth.middleware.SessionAuthenticationMiddleware``
|
||||||
Session verification will become mandatory in Django 1.10 regardless of
|
is enabled in :setting:`MIDDLEWARE_CLASSES`.
|
||||||
whether or not ``SessionAuthenticationMiddleware`` is enabled. If you have
|
|
||||||
a pre-1.7 project or one generated using a template that doesn't include
|
|
||||||
``SessionAuthenticationMiddleware``, consider enabling it before then after
|
|
||||||
reading the upgrade considerations below.
|
|
||||||
|
|
||||||
If your :setting:`AUTH_USER_MODEL` inherits from
|
If your :setting:`AUTH_USER_MODEL` inherits from
|
||||||
:class:`~django.contrib.auth.models.AbstractBaseUser` or implements its own
|
:class:`~django.contrib.auth.models.AbstractBaseUser` or implements its own
|
||||||
:meth:`~django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash()`
|
:meth:`~django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash()`
|
||||||
method, authenticated sessions will include the hash returned by this function.
|
method, authenticated sessions will include the hash returned by this function.
|
||||||
In the :class:`~django.contrib.auth.models.AbstractBaseUser` case, this is an
|
In the :class:`~django.contrib.auth.models.AbstractBaseUser` case, this is an
|
||||||
HMAC of the password field. If the
|
HMAC of the password field. Django verifies that the hash sent along with each
|
||||||
:class:`~django.contrib.auth.middleware.SessionAuthenticationMiddleware` is
|
request matches the one that's computed server-side. This allows a user to log
|
||||||
enabled, Django verifies that the hash sent along with each request matches
|
out all of their sessions by changing their password.
|
||||||
the one that's computed server-side. This allows a user to log out all of their
|
|
||||||
sessions by changing their password.
|
|
||||||
|
|
||||||
The default password change views included with Django,
|
The default password change views included with Django,
|
||||||
:func:`django.contrib.auth.views.password_change` and the
|
:func:`django.contrib.auth.views.password_change` and the
|
||||||
|
@ -849,15 +842,6 @@ and wish to have similar behavior, use this function:
|
||||||
else:
|
else:
|
||||||
...
|
...
|
||||||
|
|
||||||
If you are upgrading an existing site and wish to enable this middleware without
|
|
||||||
requiring all your users to re-login afterward, you should first upgrade to
|
|
||||||
Django 1.7 and run it for a while so that as sessions are naturally recreated
|
|
||||||
as users login, they include the session hash as described above. Once you
|
|
||||||
start running your site with
|
|
||||||
:class:`~django.contrib.auth.middleware.SessionAuthenticationMiddleware`, any
|
|
||||||
users who have not logged in and had their session updated with the verification
|
|
||||||
hash will have their existing session invalidated and be required to login.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Since
|
Since
|
||||||
|
|
|
@ -66,8 +66,6 @@ and these items in your :setting:`MIDDLEWARE_CLASSES` setting:
|
||||||
:doc:`sessions </topics/http/sessions>` across requests.
|
:doc:`sessions </topics/http/sessions>` across requests.
|
||||||
2. :class:`~django.contrib.auth.middleware.AuthenticationMiddleware` associates
|
2. :class:`~django.contrib.auth.middleware.AuthenticationMiddleware` associates
|
||||||
users with requests using sessions.
|
users with requests using sessions.
|
||||||
3. :class:`~django.contrib.auth.middleware.SessionAuthenticationMiddleware`
|
|
||||||
logs users out of their other sessions after a password change.
|
|
||||||
|
|
||||||
With these settings in place, running the command ``manage.py migrate`` creates
|
With these settings in place, running the command ``manage.py migrate`` creates
|
||||||
the necessary database tables for auth related models and permissions for any
|
the necessary database tables for auth related models and permissions for any
|
||||||
|
|
|
@ -33,7 +33,6 @@ here's the default value created by :djadmin:`django-admin startproject
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
]
|
]
|
||||||
|
|
|
@ -773,7 +773,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
|
||||||
user = User.objects.get(username='super')
|
user = User.objects.get(username='super')
|
||||||
user.set_unusable_password()
|
user.set_unusable_password()
|
||||||
user.save()
|
user.save()
|
||||||
|
self.client.force_login(user)
|
||||||
response = self.client.get(reverse('admin:index'))
|
response = self.client.get(reverse('admin:index'))
|
||||||
self.assertNotContains(response, reverse('admin:password_change'),
|
self.assertNotContains(response, reverse('admin:password_change'),
|
||||||
msg_prefix='The "change password" link should not be displayed if a user does not have a usable password.')
|
msg_prefix='The "change password" link should not be displayed if a user does not have a usable password.')
|
||||||
|
|
|
@ -4,47 +4,26 @@ from django.http import HttpRequest
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
|
|
||||||
class TestSessionAuthenticationMiddleware(TestCase):
|
class TestAuthenticationMiddleware(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.user_password = 'test_password'
|
self.user = User.objects.create_user('test_user', 'test@example.com', 'test_password')
|
||||||
self.user = User.objects.create_user('test_user',
|
|
||||||
'test@example.com',
|
|
||||||
self.user_password)
|
|
||||||
|
|
||||||
self.middleware = AuthenticationMiddleware()
|
self.middleware = AuthenticationMiddleware()
|
||||||
self.assertTrue(self.client.login(
|
self.client.force_login(self.user)
|
||||||
username=self.user.username,
|
|
||||||
password=self.user_password,
|
|
||||||
))
|
|
||||||
self.request = HttpRequest()
|
self.request = HttpRequest()
|
||||||
self.request.session = self.client.session
|
self.request.session = self.client.session
|
||||||
|
|
||||||
def test_changed_password_doesnt_invalidate_session(self):
|
def test_no_password_change_doesnt_invalidate_session(self):
|
||||||
"""
|
self.request.session = self.client.session
|
||||||
Changing a user's password shouldn't invalidate the session if session
|
|
||||||
verification isn't activated.
|
|
||||||
"""
|
|
||||||
session_key = self.request.session.session_key
|
|
||||||
self.middleware.process_request(self.request)
|
self.middleware.process_request(self.request)
|
||||||
self.assertIsNotNone(self.request.user)
|
self.assertIsNotNone(self.request.user)
|
||||||
self.assertFalse(self.request.user.is_anonymous())
|
self.assertFalse(self.request.user.is_anonymous())
|
||||||
|
|
||||||
# After password change, user should remain logged in.
|
def test_changed_password_invalidates_session(self):
|
||||||
|
# After password change, user should be anonymous
|
||||||
self.user.set_password('new_password')
|
self.user.set_password('new_password')
|
||||||
self.user.save()
|
self.user.save()
|
||||||
self.middleware.process_request(self.request)
|
self.middleware.process_request(self.request)
|
||||||
self.assertIsNotNone(self.request.user)
|
self.assertIsNotNone(self.request.user)
|
||||||
self.assertFalse(self.request.user.is_anonymous())
|
self.assertTrue(self.request.user.is_anonymous())
|
||||||
self.assertEqual(session_key, self.request.session.session_key)
|
|
||||||
|
|
||||||
def test_changed_password_invalidates_session_with_middleware(self):
|
|
||||||
with self.modify_settings(
|
|
||||||
MIDDLEWARE_CLASSES={'append': ['django.contrib.auth.middleware.SessionAuthenticationMiddleware']}):
|
|
||||||
# After password change, user should be anonymous
|
|
||||||
self.user.set_password('new_password')
|
|
||||||
self.user.save()
|
|
||||||
self.middleware.process_request(self.request)
|
|
||||||
self.assertIsNotNone(self.request.user)
|
|
||||||
self.assertTrue(self.request.user.is_anonymous())
|
|
||||||
# session should be flushed
|
# session should be flushed
|
||||||
self.assertIsNone(self.request.session.session_key)
|
self.assertIsNone(self.request.session.session_key)
|
||||||
|
|
|
@ -24,7 +24,7 @@ from django.core.urlresolvers import NoReverseMatch, reverse, reverse_lazy
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.http import HttpRequest, QueryDict
|
from django.http import HttpRequest, QueryDict
|
||||||
from django.middleware.csrf import CsrfViewMiddleware, get_token
|
from django.middleware.csrf import CsrfViewMiddleware, get_token
|
||||||
from django.test import TestCase, modify_settings, override_settings
|
from django.test import TestCase, override_settings
|
||||||
from django.test.utils import patch_logger
|
from django.test.utils import patch_logger
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.http import urlquote
|
from django.utils.http import urlquote
|
||||||
|
@ -506,9 +506,6 @@ class ChangePasswordTest(AuthViewsTestCase):
|
||||||
self.assertURLEqual(response.url, '/password_reset/')
|
self.assertURLEqual(response.url, '/password_reset/')
|
||||||
|
|
||||||
|
|
||||||
@modify_settings(MIDDLEWARE_CLASSES={
|
|
||||||
'append': 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
|
||||||
})
|
|
||||||
class SessionAuthenticationTests(AuthViewsTestCase):
|
class SessionAuthenticationTests(AuthViewsTestCase):
|
||||||
def test_user_password_change_updates_session(self):
|
def test_user_password_change_updates_session(self):
|
||||||
"""
|
"""
|
||||||
|
@ -876,9 +873,6 @@ class LogoutTest(AuthViewsTestCase):
|
||||||
|
|
||||||
# Redirect in test_user_change_password will fail if session auth hash
|
# Redirect in test_user_change_password will fail if session auth hash
|
||||||
# isn't updated after password change (#21649)
|
# isn't updated after password change (#21649)
|
||||||
@modify_settings(MIDDLEWARE_CLASSES={
|
|
||||||
'append': 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
|
||||||
})
|
|
||||||
@override_settings(
|
@override_settings(
|
||||||
PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'],
|
PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'],
|
||||||
ROOT_URLCONF='auth_tests.urls_admin',
|
ROOT_URLCONF='auth_tests.urls_admin',
|
||||||
|
|
|
@ -10,8 +10,10 @@ class CustomUserAdmin(UserAdmin):
|
||||||
def log_change(self, request, object, message):
|
def log_change(self, request, object, message):
|
||||||
# LogEntry.user column doesn't get altered to expect a UUID, so set an
|
# LogEntry.user column doesn't get altered to expect a UUID, so set an
|
||||||
# integer manually to avoid causing an error.
|
# integer manually to avoid causing an error.
|
||||||
|
original_pk = request.user.pk
|
||||||
request.user.pk = 1
|
request.user.pk = 1
|
||||||
super(CustomUserAdmin, self).log_change(request, object, message)
|
super(CustomUserAdmin, self).log_change(request, object, message)
|
||||||
|
request.user.pk = original_pk
|
||||||
|
|
||||||
site.register(get_user_model(), CustomUserAdmin)
|
site.register(get_user_model(), CustomUserAdmin)
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ from django.test import (
|
||||||
override_settings, signals,
|
override_settings, signals,
|
||||||
)
|
)
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.encoding import force_text
|
|
||||||
|
|
||||||
|
|
||||||
@modify_settings(ITEMS={
|
@modify_settings(ITEMS={
|
||||||
|
@ -489,47 +488,3 @@ class TestListSettings(unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
del sys.modules['fake_settings_module']
|
del sys.modules['fake_settings_module']
|
||||||
delattr(settings_module, setting)
|
delattr(settings_module, setting)
|
||||||
|
|
||||||
|
|
||||||
class TestSessionVerification(unittest.TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.settings_module = ModuleType('fake_settings_module')
|
|
||||||
self.settings_module.SECRET_KEY = 'foo'
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
if 'fake_settings_module' in sys.modules:
|
|
||||||
del sys.modules['fake_settings_module']
|
|
||||||
|
|
||||||
def test_session_verification_deprecation_no_verification(self):
|
|
||||||
self.settings_module.MIDDLEWARE_CLASSES = ['django.contrib.auth.middleware.AuthenticationMiddleware']
|
|
||||||
sys.modules['fake_settings_module'] = self.settings_module
|
|
||||||
with warnings.catch_warnings(record=True) as warn:
|
|
||||||
warnings.filterwarnings('always')
|
|
||||||
Settings('fake_settings_module')
|
|
||||||
self.assertEqual(
|
|
||||||
force_text(warn[0].message),
|
|
||||||
"Session verification will become mandatory in Django 1.10. "
|
|
||||||
"Please add 'django.contrib.auth.middleware.SessionAuthenticationMiddleware' "
|
|
||||||
"to your MIDDLEWARE_CLASSES setting when you are ready to opt-in after "
|
|
||||||
"reading the upgrade considerations in the 1.8 release notes.",
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_session_verification_deprecation_both(self):
|
|
||||||
self.settings_module.MIDDLEWARE_CLASSES = [
|
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
||||||
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
|
||||||
]
|
|
||||||
sys.modules['fake_settings_module'] = self.settings_module
|
|
||||||
with warnings.catch_warnings(record=True) as warn:
|
|
||||||
warnings.filterwarnings('always')
|
|
||||||
Settings('fake_settings_module')
|
|
||||||
self.assertEqual(len(warn), 0)
|
|
||||||
|
|
||||||
def test_session_verification_deprecation_neither(self):
|
|
||||||
self.settings_module.MIDDLEWARE_CLASSES = []
|
|
||||||
sys.modules['fake_settings_module'] = self.settings_module
|
|
||||||
with warnings.catch_warnings(record=True) as warn:
|
|
||||||
warnings.filterwarnings('always')
|
|
||||||
Settings('fake_settings_module')
|
|
||||||
self.assertEqual(len(warn), 0)
|
|
||||||
|
|
Loading…
Reference in New Issue