Skip to content

Commit

Permalink
Ensure bot/infractions does not accept both expires and permanent fil…
Browse files Browse the repository at this point in the history
…ters

Expires and permanent=false are permitted and tested for. Expires_before also filters the database for permanent=false explicitly
  • Loading branch information
bast0006 committed May 30, 2021
1 parent 45dfba5 commit 7a5a032
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
29 changes: 29 additions & 0 deletions pydis_site/apps/api/tests/test_infractions.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,35 @@ def test_after_after_before_invalid(self):
self.assertIn("expires_before", errors)
self.assertIn("expires_after", errors)

def test_permanent_after_invalid(self):
url = reverse('bot:infraction-list', host='api')
target_time = datetime.datetime.utcnow() + datetime.timedelta(hours=5)
response = self.client.get(f'{url}?permanent=true&expires_after={target_time.isoformat()}')

self.assertEqual(response.status_code, 400)
errors = list(response.json())
self.assertEqual("permanent", errors[0])

def test_permanent_before_invalid(self):
url = reverse('bot:infraction-list', host='api')
target_time = datetime.datetime.utcnow() + datetime.timedelta(hours=5)
response = self.client.get(f'{url}?permanent=true&expires_before={target_time.isoformat()}')

self.assertEqual(response.status_code, 400)
errors = list(response.json())
self.assertEqual("permanent", errors[0])

def test_nonpermanent_before(self):
url = reverse('bot:infraction-list', host='api')
target_time = datetime.datetime.utcnow() + datetime.timedelta(hours=6)
response = self.client.get(
f'{url}?permanent=false&expires_before={target_time.isoformat()}'
)

self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.json()), 1)
self.assertEqual(response.json()[0]["id"], self.superstar_expires_soon.id)

def test_filter_manytypes(self):
url = reverse('bot:infraction-list', host='api')
response = self.client.get(f'{url}?types=mute,ban')
Expand Down
18 changes: 18 additions & 0 deletions pydis_site/apps/api/viewsets/bot/infraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class InfractionViewSet(
Invalid query parameters are ignored.
Only one of `type` and `types` may be provided. If both `expires_before` and `expires_after`
are provided, `expires_after` must come after `expires_before`.
If `permanent` is provided and true, `expires_before` and `expires_after` must not be provided.
#### Response format
Response is paginated but the result is returned without any pagination metadata.
Expand Down Expand Up @@ -201,6 +202,23 @@ def get_queryset(self) -> QuerySet:
'expires_after': ['cannot be before expires_before'],
})

if (
('expires_at__lte' in additional_filters or 'expires_at__gte' in additional_filters)
and 'expires_at__isnull' in additional_filters
and additional_filters['expires_at__isnull']
):
raise ValidationError({
'permanent': [
'cannot filter for permanent infractions at the'
' same time as expires_at or expires_before',
]
})

if filter_expires_before:
# Filter out permanent infractions specifically if we want ones that will expire
# before a given date
additional_filters['expires_at__isnull'] = False

filter_types = self.request.query_params.get('types')
if filter_types:
if self.request.query_params.get('type'):
Expand Down

0 comments on commit 7a5a032

Please sign in to comment.