From 7ec45434ba4c29a6d8225dc659bab8be54797e8d Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Sun, 12 Jul 2020 11:11:33 +0300 Subject: [PATCH] User: make username case insensitive (and save original styling). We want 'User' and 'UsEr' to mean the same user. Apparently that's not the default in django. This normalizes the user to ensure we enforce this. --- django_etebase/serializers.py | 7 ++++++- myauth/models.py | 13 ++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/django_etebase/serializers.py b/django_etebase/serializers.py index 3f1b084..908f126 100644 --- a/django_etebase/serializers.py +++ b/django_etebase/serializers.py @@ -382,7 +382,12 @@ class AuthenticationSignupSerializer(serializers.Serializer): user_data = validated_data.pop('user') with transaction.atomic(): - instance, _ = User.objects.get_or_create(**user_data) + try: + instance = User.objects.get_by_natural_key(user_data['username']) + except User.DoesNotExist: + # Create the user and save the casing the user chose as the first name + instance = User.objects.create_user(**user_data, first_name=user_data['username']) + if hasattr(instance, 'userinfo'): raise serializers.ValidationError('User already exists') diff --git a/myauth/models.py b/myauth/models.py index 4afc27c..4046b2f 100644 --- a/myauth/models.py +++ b/myauth/models.py @@ -1,4 +1,4 @@ -from django.contrib.auth.models import AbstractUser +from django.contrib.auth.models import AbstractUser, UserManager as DjangoUserManager from django.core import validators from django.db import models from django.utils.deconstruct import deconstructible @@ -15,9 +15,16 @@ class UnicodeUsernameValidator(validators.RegexValidator): flags = 0 +class UserManager(DjangoUserManager): + def get_by_natural_key(self, username): + return self.get(**{self.model.USERNAME_FIELD + '__iexact': username}) + + class User(AbstractUser): username_validator = UnicodeUsernameValidator() + objects = UserManager() + username = models.CharField( _('username'), max_length=150, @@ -28,3 +35,7 @@ class User(AbstractUser): 'unique': _("A user with that username already exists."), }, ) + + @classmethod + def normalize_username(cls, username): + return super().normalize_username(username).lower()