Skip to content
Snippets Groups Projects
Verified Commit dfaff270 authored by Eliot Berriot's avatar Eliot Berriot
Browse files

See #170: apply proper special chars and username blacklist to channel names

parent 581c531f
No related branches found
No related tags found
No related merge requests found
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 ...@@ -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): ...@@ -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): ...@@ -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 ...@@ -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): ...@@ -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)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment