diff --git a/taiga/auth/serializers.py b/taiga/auth/serializers.py index d12cc71e..8fbba177 100644 --- a/taiga/auth/serializers.py +++ b/taiga/auth/serializers.py @@ -23,8 +23,8 @@ import re class BaseRegisterSerializer(serializers.Serializer): full_name = serializers.CharField(max_length=256) - email = serializers.EmailField(max_length=200) - username = serializers.CharField(max_length=30) + email = serializers.EmailField(max_length=255) + username = serializers.CharField(max_length=255) password = serializers.CharField(min_length=4) def validate_username(self, attrs, source): @@ -34,7 +34,7 @@ class BaseRegisterSerializer(serializers.Serializer): try: validator(value) except ValidationError: - raise serializers.ValidationError("Required. 30 characters or fewer. Letters, numbers " + raise serializers.ValidationError("Required. 255 characters or fewer. Letters, numbers " "and /./-/_ characters'") return attrs diff --git a/taiga/users/serializers.py b/taiga/users/serializers.py index 26382d37..2c76b154 100644 --- a/taiga/users/serializers.py +++ b/taiga/users/serializers.py @@ -14,11 +14,16 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from django.core import validators +from django.core.exceptions import ValidationError + from rest_framework import serializers from .models import User from .services import get_photo_or_gravatar_url, get_big_photo_or_gravatar_url +import re + class UserSerializer(serializers.ModelSerializer): full_name_display = serializers.SerializerMethodField("get_full_name_display") @@ -27,10 +32,25 @@ class UserSerializer(serializers.ModelSerializer): class Meta: model = User - fields = ('id', 'username', 'full_name', 'full_name_display', 'email', - 'github_id', 'color', 'bio', 'default_language', - 'default_timezone', 'is_active', 'photo', 'big_photo') - read_only_fields = ('id', 'username', 'email', 'github_id') + fields = ("id", "username", "full_name", "full_name_display", "email", + "github_id", "color", "bio", "default_language", + "default_timezone", "is_active", "photo", "big_photo") + read_only_fields = ("id", "email", "github_id") + + def validate_username(self, attrs, source): + value = attrs[source] + validator = validators.RegexValidator(re.compile('^[\w.-]+$'), "invalid username", "invalid") + + try: + validator(value) + except ValidationError: + raise serializers.ValidationError("Required. 255 characters or fewer. Letters, numbers " + "and /./-/_ characters'") + + if self.object and self.object.username != value and User.objects.filter(username=value).exists(): + raise serializers.ValidationError("Invalid username. Try with a different one.") + + return attrs def get_full_name_display(self, obj): return obj.get_full_name() if obj else "" diff --git a/tests/integration/test_auth_api.py b/tests/integration/test_auth_api.py index 09d9eab6..1cb81a9b 100644 --- a/tests/integration/test_auth_api.py +++ b/tests/integration/test_auth_api.py @@ -129,6 +129,6 @@ def test_respond_400_If_username_is_invalid(client, settings, register_form): response = client.post(reverse("auth-register"), register_form) assert response.status_code == 400 - register_form.update({"username": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-error"}) + register_form.update({"username": 300*"a"}) response = client.post(reverse("auth-register"), register_form) assert response.status_code == 400