From 19048e366a43872aa87ed996166f8d75c00836d5 Mon Sep 17 00:00:00 2001 From: Lucas Brandstaetter <lucas@brandstaetter.tech> Date: Mon, 23 Dec 2024 02:35:00 +0100 Subject: [PATCH] Fix case-sensitivity of assembly slugs Add a validator to the assembly slug that checks if the slug is lowercase --- src/core/locale/de/LC_MESSAGES/django.po | 3 ++ src/core/locale/en/LC_MESSAGES/django.po | 3 ++ .../migrations/0170_alter_assembly_slug.py | 32 +++++++++++++++++++ src/core/models/assemblies.py | 5 +-- src/core/validators.py | 14 ++++++++ 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/core/migrations/0170_alter_assembly_slug.py diff --git a/src/core/locale/de/LC_MESSAGES/django.po b/src/core/locale/de/LC_MESSAGES/django.po index de11241f0..ff3f6a27a 100644 --- a/src/core/locale/de/LC_MESSAGES/django.po +++ b/src/core/locale/de/LC_MESSAGES/django.po @@ -2556,6 +2556,9 @@ msgstr "Das Bild muss die Abmessungen von minimal %(min_width)spx/%(min_height)s msgid "Validation__error_image_square" msgstr "Das Bild muss quadratisch sein." +msgid "Validation__error_lowercase" +msgstr "Das Feld darf nur Kleinbuchstaben enthalten." + msgid "Registration" msgstr "Registrieren" diff --git a/src/core/locale/en/LC_MESSAGES/django.po b/src/core/locale/en/LC_MESSAGES/django.po index bf783a463..14cfc2fcf 100644 --- a/src/core/locale/en/LC_MESSAGES/django.po +++ b/src/core/locale/en/LC_MESSAGES/django.po @@ -2538,6 +2538,9 @@ msgstr "The image must have the dimensions of minimal %(min_width)spx/%(min_heig msgid "Validation__error_image_square" msgstr "The image must be square" +msgid "Validation__error_lowercase" +msgstr "The field may only contain lowercase letters" + msgid "Registration" msgstr "Sign Up" diff --git a/src/core/migrations/0170_alter_assembly_slug.py b/src/core/migrations/0170_alter_assembly_slug.py new file mode 100644 index 000000000..ea803500a --- /dev/null +++ b/src/core/migrations/0170_alter_assembly_slug.py @@ -0,0 +1,32 @@ +# Generated by Django 5.1.3 on 2024-12-23 01:30 + +import core.validators +import django.core.validators +import re +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("core", "0169_team_teammember"), + ] + + operations = [ + migrations.AlterField( + model_name="assembly", + name="slug", + field=models.SlugField( + help_text="Assembly__slug__help", + validators=[ + django.core.validators.RegexValidator( + re.compile("^[-a-zA-Z0-9_]+\\Z"), + "Enter a valid “slug” consisting of letters, numbers, underscores or hyphens.", + "invalid", + ), + core.validators.validate_lower_case, + ], + verbose_name="Assembly__slug", + ), + ), + ] diff --git a/src/core/models/assemblies.py b/src/core/models/assemblies.py index c3497ff6e..2f2a97bad 100644 --- a/src/core/models/assemblies.py +++ b/src/core/models/assemblies.py @@ -10,6 +10,7 @@ from django.conf import settings from django.contrib.contenttypes.fields import GenericRelation from django.contrib.gis.db import models as gis_models from django.core.exceptions import ValidationError +from django.core.validators import validate_slug from django.db import models from django.db.models import Q, QuerySet from django.template.loader import render_to_string @@ -33,7 +34,7 @@ from core.models.tags import TaggedItemMixin, TagItem from core.models.users import PlatformUser from core.predicates import has_perms from core.utils import render_markdown_as_text -from core.validators import FileSizeValidator, ImageDimensionValidator +from core.validators import FileSizeValidator, ImageDimensionValidator, validate_lower_case @rules.predicate @@ -110,7 +111,7 @@ class Assembly(TaggedItemMixin, ActivityLogMixin, RulesModel): id = models.UUIDField(default=uuid4, primary_key=True, editable=False) conference = ConferenceReference(related_name='assemblies') - slug = models.SlugField(help_text=_('Assembly__slug__help'), verbose_name=_('Assembly__slug')) + slug = models.SlugField(help_text=_('Assembly__slug__help'), verbose_name=_('Assembly__slug'), validators=[validate_slug, validate_lower_case]) name = models.CharField(max_length=200, help_text=_('Assembly__name__help'), verbose_name=_('Assembly__name')) is_official = models.BooleanField(default=False, help_text=_('Assembly__is_official__help'), verbose_name=_('Assembly__is_official')) diff --git a/src/core/validators.py b/src/core/validators.py index d288ef9c8..cf62f4ea1 100644 --- a/src/core/validators.py +++ b/src/core/validators.py @@ -130,3 +130,17 @@ class ImageDimensionValidator: other.max_size, other.square, ) + + +def validate_lower_case(value: str) -> None: + """ + A validator function that will check if a string is lowercase + + Raises: + ValidationError: Raises a validation error if the string is not lowercase. + + Args: + value (str): The string to check + """ + if value != value.lower(): + raise ValidationError(_('Validation__error_lowercase'), code='lowercase') -- GitLab