See #170: apply proper special chars and username blacklist to channel names
This commit is contained in:
parent
581c531fca
commit
dfaff270ab
|
@ -1,3 +1,4 @@
|
||||||
|
from django.conf import settings
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
@ -13,6 +14,7 @@ from funkwhale_api.music import models as music_models
|
||||||
from funkwhale_api.music import serializers as music_serializers
|
from funkwhale_api.music import serializers as music_serializers
|
||||||
from funkwhale_api.tags import models as tags_models
|
from funkwhale_api.tags import models as tags_models
|
||||||
from funkwhale_api.tags import serializers as tags_serializers
|
from funkwhale_api.tags import serializers as tags_serializers
|
||||||
|
from funkwhale_api.users import serializers as users_serializers
|
||||||
|
|
||||||
from . import categories
|
from . import categories
|
||||||
from . import models
|
from . import models
|
||||||
|
@ -52,7 +54,10 @@ class ChannelMetadataSerializer(serializers.Serializer):
|
||||||
|
|
||||||
class ChannelCreateSerializer(serializers.Serializer):
|
class ChannelCreateSerializer(serializers.Serializer):
|
||||||
name = serializers.CharField(max_length=music_models.MAX_LENGTHS["ARTIST_NAME"])
|
name = serializers.CharField(max_length=music_models.MAX_LENGTHS["ARTIST_NAME"])
|
||||||
username = serializers.CharField(max_length=music_models.MAX_LENGTHS["ARTIST_NAME"])
|
username = serializers.CharField(
|
||||||
|
max_length=music_models.MAX_LENGTHS["ARTIST_NAME"],
|
||||||
|
validators=[users_serializers.ASCIIUsernameValidator()],
|
||||||
|
)
|
||||||
description = common_serializers.ContentSerializer(allow_null=True)
|
description = common_serializers.ContentSerializer(allow_null=True)
|
||||||
tags = tags_serializers.TagsListField()
|
tags = tags_serializers.TagsListField()
|
||||||
content_category = serializers.ChoiceField(
|
content_category = serializers.ChoiceField(
|
||||||
|
@ -76,6 +81,9 @@ class ChannelCreateSerializer(serializers.Serializer):
|
||||||
return validated_data
|
return validated_data
|
||||||
|
|
||||||
def validate_username(self, value):
|
def validate_username(self, value):
|
||||||
|
if value.lower() in [n.lower() for n in settings.ACCOUNT_USERNAME_BLACKLIST]:
|
||||||
|
raise serializers.ValidationError("This username is already taken")
|
||||||
|
|
||||||
matching = federation_models.Actor.objects.local().filter(
|
matching = federation_models.Actor.objects.local().filter(
|
||||||
preferred_username__iexact=value
|
preferred_username__iexact=value
|
||||||
)
|
)
|
||||||
|
|
|
@ -70,7 +70,7 @@ def test_channel_serializer_create_honor_max_channels_setting(factories, prefere
|
||||||
assert serializer.is_valid(raise_exception=True)
|
assert serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
|
|
||||||
def test_channel_serializer_create_validates_username(factories):
|
def test_channel_serializer_create_validates_username_uniqueness(factories):
|
||||||
attributed_to = factories["federation.Actor"](local=True)
|
attributed_to = factories["federation.Actor"](local=True)
|
||||||
data = {
|
data = {
|
||||||
"name": "My channel",
|
"name": "My channel",
|
||||||
|
@ -83,7 +83,48 @@ def test_channel_serializer_create_validates_username(factories):
|
||||||
serializer = serializers.ChannelCreateSerializer(
|
serializer = serializers.ChannelCreateSerializer(
|
||||||
data=data, context={"actor": attributed_to}
|
data=data, context={"actor": attributed_to}
|
||||||
)
|
)
|
||||||
with pytest.raises(serializers.serializers.ValidationError, match=r".*username.*"):
|
with pytest.raises(
|
||||||
|
serializers.serializers.ValidationError, match=r".*username is already taken.*"
|
||||||
|
):
|
||||||
|
assert serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_channel_serializer_create_validates_username_chars(factories):
|
||||||
|
attributed_to = factories["federation.Actor"](local=True)
|
||||||
|
data = {
|
||||||
|
"name": "My channel",
|
||||||
|
"username": "hello world",
|
||||||
|
"description": {"text": "This is my channel", "content_type": "text/markdown"},
|
||||||
|
"tags": ["hello", "world"],
|
||||||
|
"content_category": "other",
|
||||||
|
}
|
||||||
|
|
||||||
|
serializer = serializers.ChannelCreateSerializer(
|
||||||
|
data=data, context={"actor": attributed_to}
|
||||||
|
)
|
||||||
|
with pytest.raises(
|
||||||
|
serializers.serializers.ValidationError, match=r".*Enter a valid username.*"
|
||||||
|
):
|
||||||
|
assert serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_channel_serializer_create_validates_blacklisted_username(factories, settings):
|
||||||
|
settings.ACCOUNT_USERNAME_BLACKLIST = ["forBidden"]
|
||||||
|
attributed_to = factories["federation.Actor"](local=True)
|
||||||
|
data = {
|
||||||
|
"name": "My channel",
|
||||||
|
"username": "FORBIDDEN",
|
||||||
|
"description": {"text": "This is my channel", "content_type": "text/markdown"},
|
||||||
|
"tags": ["hello", "world"],
|
||||||
|
"content_category": "other",
|
||||||
|
}
|
||||||
|
|
||||||
|
serializer = serializers.ChannelCreateSerializer(
|
||||||
|
data=data, context={"actor": attributed_to}
|
||||||
|
)
|
||||||
|
with pytest.raises(
|
||||||
|
serializers.serializers.ValidationError, match=r".*username is already taken.*"
|
||||||
|
):
|
||||||
assert serializer.is_valid(raise_exception=True)
|
assert serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue