Skip to content

Commit 09de014

Browse files
authored
🐛(back) allow ASCII characters in user sub field
All ASCII characters are allowed in a sub, we change the sub validator to reflect this.
1 parent 8d42149 commit 09de014

File tree

7 files changed

+55
-20
lines changed

7 files changed

+55
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ and this project adheres to
2525
- #1270
2626
- #1282
2727
- ♻️(backend) fallback to email identifier when no name #1298
28+
- 🐛(backend) allow ASCII characters in user sub field #1295
2829

2930
### Fixed
3031

src/backend/core/api/serializers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import magic
1414
from rest_framework import serializers
1515

16-
from core import choices, enums, models, utils
16+
from core import choices, enums, models, utils, validators
1717
from core.services.ai_services import AI_ACTIONS
1818
from core.services.converter_services import (
1919
ConversionError,
@@ -422,7 +422,7 @@ class ServerCreateDocumentSerializer(serializers.Serializer):
422422
content = serializers.CharField(required=True)
423423
# User
424424
sub = serializers.CharField(
425-
required=True, validators=[models.User.sub_validator], max_length=255
425+
required=True, validators=[validators.sub_validator], max_length=255
426426
)
427427
email = serializers.EmailField(required=True)
428428
language = serializers.ChoiceField(

src/backend/core/migrations/0024_add_is_masked_field_to_link_trace.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from django.db import migrations, models
44

5+
import core.validators
6+
57

68
class Migration(migrations.Migration):
79
dependencies = [
@@ -33,4 +35,17 @@ class Migration(migrations.Migration):
3335
verbose_name="language",
3436
),
3537
),
38+
migrations.AlterField(
39+
model_name="user",
40+
name="sub",
41+
field=models.CharField(
42+
blank=True,
43+
help_text="Required. 255 characters or fewer. ASCII characters only.",
44+
max_length=255,
45+
null=True,
46+
unique=True,
47+
validators=[core.validators.sub_validator],
48+
verbose_name="sub",
49+
),
50+
),
3651
]

src/backend/core/models.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from django.contrib.auth.base_user import AbstractBaseUser
1515
from django.contrib.postgres.fields import ArrayField
1616
from django.contrib.sites.models import Site
17-
from django.core import mail, validators
17+
from django.core import mail
1818
from django.core.cache import cache
1919
from django.core.files.base import ContentFile
2020
from django.core.files.storage import default_storage
@@ -39,6 +39,7 @@
3939
RoleChoices,
4040
get_equivalent_link_definition,
4141
)
42+
from .validators import sub_validator
4243

4344
logger = getLogger(__name__)
4445

@@ -136,22 +137,12 @@ def get_user_by_sub_or_email(self, sub, email):
136137
class User(AbstractBaseUser, BaseModel, auth_models.PermissionsMixin):
137138
"""User model to work with OIDC only authentication."""
138139

139-
sub_validator = validators.RegexValidator(
140-
regex=r"^[\w.@+-:]+\Z",
141-
message=_(
142-
"Enter a valid sub. This value may contain only letters, "
143-
"numbers, and @/./+/-/_/: characters."
144-
),
145-
)
146-
147140
sub = models.CharField(
148141
_("sub"),
149-
help_text=_(
150-
"Required. 255 characters or fewer. Letters, numbers, and @/./+/-/_/: characters only."
151-
),
142+
help_text=_("Required. 255 characters or fewer. ASCII characters only."),
152143
max_length=255,
153-
unique=True,
154144
validators=[sub_validator],
145+
unique=True,
155146
blank=True,
156147
null=True,
157148
)

src/backend/core/tests/documents/test_api_documents_create_for_owner.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def test_api_documents_create_for_owner_invalid_sub():
148148
data = {
149149
"title": "My Document",
150150
"content": "Document content",
151-
"sub": "123!!",
151+
"sub": "invalid süb",
152152
"email": "[email protected]",
153153
}
154154

@@ -163,10 +163,7 @@ def test_api_documents_create_for_owner_invalid_sub():
163163
assert not Document.objects.exists()
164164

165165
assert response.json() == {
166-
"sub": [
167-
"Enter a valid sub. This value may contain only letters, "
168-
"numbers, and @/./+/-/_/: characters."
169-
]
166+
"sub": ["Enter a valid sub. This value should be ASCII only."]
170167
}
171168

172169

src/backend/core/tests/test_models_users.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,25 @@ def test_models_users_send_mail_main_missing():
4444
user.email_user("my subject", "my message")
4545

4646
assert str(excinfo.value) == "User has no email address."
47+
48+
49+
@pytest.mark.parametrize(
50+
"sub,is_valid",
51+
[
52+
("valid_sub.@+-:=/", True),
53+
("invalid süb", False),
54+
(12345, True),
55+
],
56+
)
57+
def test_models_users_sub_validator(sub, is_valid):
58+
"""The "sub" field should be validated."""
59+
user = factories.UserFactory()
60+
user.sub = sub
61+
if is_valid:
62+
user.full_clean()
63+
else:
64+
with pytest.raises(
65+
ValidationError,
66+
match=("Enter a valid sub. This value should be ASCII only."),
67+
):
68+
user.full_clean()

src/backend/core/validators.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
"""Custom validators for the core app."""
2+
3+
from django.core.exceptions import ValidationError
4+
5+
6+
def sub_validator(value):
7+
"""Validate that the sub is ASCII only."""
8+
if not value.isascii():
9+
raise ValidationError("Enter a valid sub. This value should be ASCII only.")

0 commit comments

Comments
 (0)