forked from CGM_Public/pretix_original
* Fix #294 - blacklist for slug validation * Fix #294 - blacklist for slug validation * fix for failing test
This commit is contained in:
committed by
Raphael Michel
parent
4820a8423f
commit
9662b956ed
@@ -15,6 +15,7 @@ from pretix.base.email import CustomSMTPBackend
|
|||||||
from pretix.base.i18n import I18nCharField
|
from pretix.base.i18n import I18nCharField
|
||||||
from pretix.base.models.base import LoggedModel
|
from pretix.base.models.base import LoggedModel
|
||||||
from pretix.base.settings import SettingsProxy
|
from pretix.base.settings import SettingsProxy
|
||||||
|
from pretix.base.validators import EventSlugBlacklistValidator
|
||||||
|
|
||||||
from .auth import User
|
from .auth import User
|
||||||
from .organizer import Organizer
|
from .organizer import Organizer
|
||||||
@@ -65,7 +66,8 @@ class Event(LoggedModel):
|
|||||||
RegexValidator(
|
RegexValidator(
|
||||||
regex="^[a-zA-Z0-9.-]+$",
|
regex="^[a-zA-Z0-9.-]+$",
|
||||||
message=_("The slug may only contain letters, numbers, dots and dashes."),
|
message=_("The slug may only contain letters, numbers, dots and dashes."),
|
||||||
)
|
),
|
||||||
|
EventSlugBlacklistValidator()
|
||||||
],
|
],
|
||||||
verbose_name=_("Slug"),
|
verbose_name=_("Slug"),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
|
|
||||||
from pretix.base.models.base import LoggedModel
|
from pretix.base.models.base import LoggedModel
|
||||||
from pretix.base.settings import SettingsProxy
|
from pretix.base.settings import SettingsProxy
|
||||||
|
from pretix.base.validators import OrganizerSlugBlacklistValidator
|
||||||
|
|
||||||
from .auth import User
|
from .auth import User
|
||||||
from .settings import OrganizerSetting
|
from .settings import OrganizerSetting
|
||||||
@@ -34,7 +35,8 @@ class Organizer(LoggedModel):
|
|||||||
RegexValidator(
|
RegexValidator(
|
||||||
regex="^[a-zA-Z0-9.-]+$",
|
regex="^[a-zA-Z0-9.-]+$",
|
||||||
message=_("The slug may only contain letters, numbers, dots and dashes.")
|
message=_("The slug may only contain letters, numbers, dots and dashes.")
|
||||||
)
|
),
|
||||||
|
OrganizerSlugBlacklistValidator()
|
||||||
],
|
],
|
||||||
verbose_name=_("Slug"),
|
verbose_name=_("Slug"),
|
||||||
)
|
)
|
||||||
|
|||||||
48
src/pretix/base/validators.py
Normal file
48
src/pretix/base/validators.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
class BlacklistValidator:
|
||||||
|
|
||||||
|
blacklist = []
|
||||||
|
|
||||||
|
def __call__(self, value):
|
||||||
|
# Validation logic
|
||||||
|
if value in self.blacklist:
|
||||||
|
raise ValidationError(
|
||||||
|
_('This slug has an invalid value: %(value)s.'),
|
||||||
|
code='invalid',
|
||||||
|
params={'value': value},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EventSlugBlacklistValidator(BlacklistValidator):
|
||||||
|
|
||||||
|
blacklist = [
|
||||||
|
'download',
|
||||||
|
'healthcheck',
|
||||||
|
'locale',
|
||||||
|
'control',
|
||||||
|
'redirect',
|
||||||
|
'jsi18n',
|
||||||
|
'metrics',
|
||||||
|
'_global',
|
||||||
|
'__debug__'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class OrganizerSlugBlacklistValidator(BlacklistValidator):
|
||||||
|
|
||||||
|
blacklist = [
|
||||||
|
'download',
|
||||||
|
'healthcheck',
|
||||||
|
'locale',
|
||||||
|
'control',
|
||||||
|
'pretixdroid',
|
||||||
|
'redirect',
|
||||||
|
'jsi18n',
|
||||||
|
'metrics',
|
||||||
|
'_global',
|
||||||
|
'__debug__',
|
||||||
|
'about'
|
||||||
|
]
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import datetime
|
||||||
import sys
|
import sys
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
@@ -601,6 +602,16 @@ class EventTest(TestCase):
|
|||||||
|
|
||||||
self.assertIn('presale_end', str(context.exception))
|
self.assertIn('presale_end', str(context.exception))
|
||||||
|
|
||||||
|
def test_slug_validation(self):
|
||||||
|
event = Event(
|
||||||
|
organizer=self.organizer, name='Download', slug='download',
|
||||||
|
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc)
|
||||||
|
)
|
||||||
|
with self.assertRaises(ValidationError) as context:
|
||||||
|
event.full_clean()
|
||||||
|
|
||||||
|
self.assertIn('slug', str(context.exception))
|
||||||
|
|
||||||
|
|
||||||
class CachedFileTestCase(TestCase):
|
class CachedFileTestCase(TestCase):
|
||||||
def test_file_handling(self):
|
def test_file_handling(self):
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import datetime
|
|||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from tests.base import SoupTest
|
from tests.base import SoupTest
|
||||||
@@ -469,3 +470,19 @@ class TestResendLink(EventTestMixin, SoupTest):
|
|||||||
self.assertEqual(len(mail.outbox), 1)
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
self.assertIn('DUMMY1', mail.outbox[0].body)
|
self.assertIn('DUMMY1', mail.outbox[0].body)
|
||||||
self.assertIn('DUMMY2', mail.outbox[0].body)
|
self.assertIn('DUMMY2', mail.outbox[0].body)
|
||||||
|
|
||||||
|
|
||||||
|
class EventSlugBlacklistValidatorTest(EventTestMixin, SoupTest):
|
||||||
|
def test_slug_validation(self):
|
||||||
|
event = Event(
|
||||||
|
organizer=self.orga,
|
||||||
|
name='download',
|
||||||
|
slug='download',
|
||||||
|
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc),
|
||||||
|
live=True
|
||||||
|
)
|
||||||
|
with self.assertRaises(ValidationError):
|
||||||
|
if event.full_clean():
|
||||||
|
event.save()
|
||||||
|
|
||||||
|
self.assertEqual(Event.objects.filter(name='download').count(), 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user