Kaydet (Commit) 596564e8 authored tarafından Tim Graham's avatar Tim Graham

[1.8.x] Fixed #24161 -- Stored the user primary key as a serialized value in the session.

This allows using a UUIDField primary key along with the JSON session
serializer.

Thanks to Trac alias jamesbeith for the report and Simon Charette
for the initial patch.

Backport of 0f7f5bc9 from master
üst 1904022f
......@@ -53,6 +53,12 @@ def _clean_credentials(credentials):
return credentials
def _get_user_session_key(request):
# This value in the session is always serialized to a string, so we need
# to convert it back to Python whenever we access it.
return get_user_model()._meta.pk.to_python(request.session[SESSION_KEY])
def authenticate(**credentials):
"""
If the given credentials are valid, return a User object.
......@@ -93,7 +99,7 @@ def login(request, user):
session_auth_hash = user.get_session_auth_hash()
if SESSION_KEY in request.session:
if request.session[SESSION_KEY] != user.pk or (
if _get_user_session_key(request) != user.pk or (
session_auth_hash and
request.session.get(HASH_SESSION_KEY) != session_auth_hash):
# To avoid reusing another user's session, create a new, empty
......@@ -102,7 +108,7 @@ def login(request, user):
request.session.flush()
else:
request.session.cycle_key()
request.session[SESSION_KEY] = user.pk
request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
request.session[BACKEND_SESSION_KEY] = user.backend
request.session[HASH_SESSION_KEY] = session_auth_hash
if hasattr(request, 'user'):
......@@ -158,7 +164,7 @@ def get_user(request):
from .models import AnonymousUser
user = None
try:
user_id = request.session[SESSION_KEY]
user_id = _get_user_session_key(request)
backend_path = request.session[BACKEND_SESSION_KEY]
except KeyError:
pass
......
......@@ -5,9 +5,10 @@ from .invalid_models import (
CustomUserBadRequiredFields,
)
from .with_foreign_key import CustomUserWithFK, Email
from .uuid_pk import UUIDUser
__all__ = (
'CustomPermissionsUser', 'CustomUserNonUniqueUsername',
'CustomUserNonListRequiredFields', 'CustomUserBadRequiredFields',
'CustomUserWithFK', 'Email', 'IsActiveTestUser1',
'CustomUserWithFK', 'Email', 'IsActiveTestUser1', 'UUIDUser',
)
import uuid
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.tests.custom_user import RemoveGroupsAndPermissions
from django.db import models
with RemoveGroupsAndPermissions():
class UUIDUser(AbstractUser):
"""A user with a UUID as primary key"""
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
class Meta:
app_label = 'auth'
......@@ -3,7 +3,9 @@ from __future__ import unicode_literals
from datetime import date
from django.conf import settings
from django.contrib.auth import BACKEND_SESSION_KEY, authenticate, get_user
from django.contrib.auth import (
BACKEND_SESSION_KEY, SESSION_KEY, authenticate, get_user,
)
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.hashers import MD5PasswordHasher
from django.contrib.auth.models import AnonymousUser, Group, Permission, User
......@@ -13,7 +15,7 @@ from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.http import HttpRequest
from django.test import TestCase, modify_settings, override_settings
from .models import CustomPermissionsUser
from .models import CustomPermissionsUser, UUIDUser
class CountingMD5PasswordHasher(MD5PasswordHasher):
......@@ -287,6 +289,18 @@ class CustomUserModelBackendAuthenticateTest(TestCase):
self.assertEqual(test_user, authenticated_user)
@override_settings(AUTH_USER_MODEL='auth.UUIDUser')
class UUIDUserTests(TestCase):
def test_login(self):
"""
A custom user with a UUID primary key should be able to login.
"""
user = UUIDUser.objects.create_user(username='uuid', password='test')
self.assertTrue(self.client.login(username='uuid', password='test'))
self.assertEqual(UUIDUser.objects.get(pk=self.client.session[SESSION_KEY]), user)
class TestObj(object):
pass
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment