From ba76fe9f49def13d85b8939ee684816e68d89492 Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Sun, 22 Jul 2018 13:05:43 +0200
Subject: [PATCH] Apply restrictions to username characters during signup

---
 api/config/settings/common.py            |  2 ++
 api/funkwhale_api/federation/views.py    |  1 +
 api/funkwhale_api/users/serializers.py   | 20 +++++++++++++++++++-
 api/tests/users/test_views.py            | 16 ++++++++++++++++
 changes/changelog.d/username.enhancement |  1 +
 5 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 changes/changelog.d/username.enhancement

diff --git a/api/config/settings/common.py b/api/config/settings/common.py
index 4a68f80f..013c7ae4 100644
--- a/api/config/settings/common.py
+++ b/api/config/settings/common.py
@@ -302,6 +302,7 @@ SESSION_COOKIE_HTTPONLY = False
 ACCOUNT_AUTHENTICATION_METHOD = "username_email"
 ACCOUNT_EMAIL_REQUIRED = True
 ACCOUNT_EMAIL_VERIFICATION = "mandatory"
+ACCOUNT_USERNAME_VALIDATORS = "funkwhale_api.users.serializers.username_validators"
 
 # Custom user app defaults
 # Select the correct user model
@@ -432,6 +433,7 @@ PLAYLISTS_MAX_TRACKS = env.int("PLAYLISTS_MAX_TRACKS", default=250)
 ACCOUNT_USERNAME_BLACKLIST = [
     "funkwhale",
     "library",
+    "instance",
     "test",
     "status",
     "root",
diff --git a/api/funkwhale_api/federation/views.py b/api/funkwhale_api/federation/views.py
index 2c01292b..29f56630 100644
--- a/api/funkwhale_api/federation/views.py
+++ b/api/funkwhale_api/federation/views.py
@@ -34,6 +34,7 @@ class FederationMixin(object):
 
 class ActorViewSet(FederationMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
     lookup_field = "user__username"
+    lookup_value_regex = ".*"
     authentication_classes = [authentication.SignatureAuthentication]
     permission_classes = []
     renderer_classes = [renderers.ActivityPubRenderer]
diff --git a/api/funkwhale_api/users/serializers.py b/api/funkwhale_api/users/serializers.py
index 4421fa3f..2f227158 100644
--- a/api/funkwhale_api/users/serializers.py
+++ b/api/funkwhale_api/users/serializers.py
@@ -1,8 +1,13 @@
+import re
+
 from django.conf import settings
+from django.core import validators
+from django.utils.deconstruct import deconstructible
+from django.utils.translation import gettext_lazy as _
+
 from rest_auth.serializers import PasswordResetSerializer as PRS
 from rest_auth.registration.serializers import RegisterSerializer as RS
 from rest_framework import serializers
-
 from versatileimagefield.serializers import VersatileImageFieldSerializer
 
 from funkwhale_api.activity import serializers as activity_serializers
@@ -10,6 +15,19 @@ from funkwhale_api.activity import serializers as activity_serializers
 from . import models
 
 
+@deconstructible
+class ASCIIUsernameValidator(validators.RegexValidator):
+    regex = r"^[\w]+$"
+    message = _(
+        "Enter a valid username. This value may contain only English letters, "
+        "numbers, and _ characters."
+    )
+    flags = re.ASCII
+
+
+username_validators = [ASCIIUsernameValidator()]
+
+
 class RegisterSerializer(RS):
     invitation = serializers.CharField(
         required=False, allow_null=True, allow_blank=True
diff --git a/api/tests/users/test_views.py b/api/tests/users/test_views.py
index 268148c2..92e9922b 100644
--- a/api/tests/users/test_views.py
+++ b/api/tests/users/test_views.py
@@ -20,6 +20,22 @@ def test_can_create_user_via_api(preferences, api_client, db):
     assert u.username == "test1"
 
 
+@pytest.mark.parametrize("username", ["wrong.name", "wrong-name", "éaeu", "wrong name"])
+def test_username_only_accepts_letters_and_underscores(
+    username, preferences, api_client, db
+):
+    url = reverse("rest_register")
+    data = {
+        "username": username,
+        "email": "test1@test.com",
+        "password1": "testtest",
+        "password2": "testtest",
+    }
+    preferences["users__registration_enabled"] = True
+    response = api_client.post(url, data)
+    assert response.status_code == 400
+
+
 def test_can_restrict_usernames(settings, preferences, db, api_client):
     url = reverse("rest_register")
     preferences["users__registration_enabled"] = True
diff --git a/changes/changelog.d/username.enhancement b/changes/changelog.d/username.enhancement
new file mode 100644
index 00000000..bf38490f
--- /dev/null
+++ b/changes/changelog.d/username.enhancement
@@ -0,0 +1 @@
+Apply restrictions to username characters during signup
-- 
GitLab