diff options
| -rw-r--r-- | pydis_site/apps/api/serializers.py | 31 | ||||
| -rw-r--r-- | pydis_site/apps/api/tests/test_filters.py | 2 | 
2 files changed, 27 insertions, 6 deletions
diff --git a/pydis_site/apps/api/serializers.py b/pydis_site/apps/api/serializers.py index a3779094..2186b02c 100644 --- a/pydis_site/apps/api/serializers.py +++ b/pydis_site/apps/api/serializers.py @@ -1,4 +1,5 @@  """Converters from Django models to data interchange formats and back.""" +from datetime import timedelta  from typing import Any  from django.db.models.query import QuerySet @@ -210,6 +211,8 @@ CHANNEL_SCOPE_FIELDS = (  )  MENTIONS_FIELDS = ('guild_pings', 'dm_pings') +MAX_TIMEOUT_DURATION = timedelta(days=28) +  def _create_meta_extra_kwargs(*, for_filter: bool) -> dict[str, dict[str, bool]]:      """Create the extra kwargs for the Meta classes of the Filter and FilterList serializers.""" @@ -236,17 +239,24 @@ class FilterSerializer(ModelSerializer):      def validate(self, data: dict) -> dict:          """Perform infraction data + allowed and disallowed lists validation.""" +        infraction_type = get_field_value(data, 'infraction_type') +        infraction_duration = get_field_value(data, 'infraction_duration')          if ( -            ( -                get_field_value(data, 'infraction_reason') -                or get_field_value(data, 'infraction_duration') -            ) -            and get_field_value(data, 'infraction_type') == 'NONE' +            (get_field_value(data, 'infraction_reason') or infraction_duration) +            and infraction_type == 'NONE'          ):              raise ValidationError(                  "Infraction type is required with infraction duration or reason."              ) +        if ( +            infraction_type == 'TIMEOUT' +            and (not infraction_duration or infraction_duration > MAX_TIMEOUT_DURATION) +        ): +            raise ValidationError( +                f"A timeout cannot be longer than {MAX_TIMEOUT_DURATION.days} days." +            ) +          common_channels = (              set(get_field_value(data, 'disabled_channels'))              & set(get_field_value(data, 'enabled_channels')) @@ -328,8 +338,9 @@ class FilterListSerializer(ModelSerializer):      def validate(self, data: dict) -> dict:          """Perform infraction data + allow and disallowed lists validation.""" +        infraction_duration = data.get('infraction_duration')          if ( -            data.get('infraction_reason') or data.get('infraction_duration') +            data.get('infraction_reason') or infraction_duration          ) and not data.get('infraction_type'):              raise ValidationError("Infraction type is required with infraction duration or reason") @@ -345,6 +356,14 @@ class FilterListSerializer(ModelSerializer):                  )          if ( +            data.get('infraction_type') == 'TIMEOUT' +            and (not infraction_duration or infraction_duration > MAX_TIMEOUT_DURATION) +        ): +            raise ValidationError( +                f"A timeout cannot be longer than {MAX_TIMEOUT_DURATION.days} days." +            ) + +        if (              data.get('disabled_categories') is not None              and data.get('enabled_categories') is not None          ): diff --git a/pydis_site/apps/api/tests/test_filters.py b/pydis_site/apps/api/tests/test_filters.py index 3d3be51e..ebc4a2cf 100644 --- a/pydis_site/apps/api/tests/test_filters.py +++ b/pydis_site/apps/api/tests/test_filters.py @@ -274,6 +274,7 @@ class FilterValidationTests(AuthenticatedAPITestCase):              ({"infraction_reason": "hi"}, {}, 400),              ({"infraction_duration": timedelta(seconds=10)}, {}, 400),              ({"infraction_reason": "hi"}, {"infraction_type": "NOTE"}, 200), +            ({"infraction_type": "TIMEOUT", "infraction_duration": timedelta(days=30)}, {}, 400),              ({"infraction_duration": timedelta(seconds=10)}, {"infraction_type": "TIMEOUT"}, 200),              ({"enabled_channels": ["admins"]}, {}, 200),              ({"disabled_channels": ["123"]}, {}, 200), @@ -313,6 +314,7 @@ class FilterValidationTests(AuthenticatedAPITestCase):          cases = (              ({"infraction_reason": "hi"}, 400),              ({"infraction_duration": timedelta(seconds=10)}, 400), +            ({"infraction_type": "TIMEOUT", "infraction_duration": timedelta(days=30)}, 400),              ({"infraction_reason": "hi", "infraction_type": "NOTE"}, 200),              ({"infraction_duration": timedelta(seconds=10), "infraction_type": "TIMEOUT"}, 200),              ({"enabled_channels": ["admins"]}, 200), ({"disabled_channels": ["123"]}, 200),  |