From 29cceb86152f9d9daecbb8360e2e227d32ae8bc4 Mon Sep 17 00:00:00 2001
From: Dominik George <dominik.george@teckids.org>
Date: Tue, 22 Feb 2022 23:08:12 +0100
Subject: [PATCH] Allow configuring username regex

---
 CHANGELOG.rst                     |  1 +
 aleksis/core/preferences.py       |  8 ++++++++
 aleksis/core/settings.py          |  3 +++
 aleksis/core/util/auth_helpers.py | 10 ++++++++++
 4 files changed, 22 insertions(+)

diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index d3e4c84c4..b8a5948a8 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -18,6 +18,7 @@ Added
 * Create a reusable snippet for avatar content.
 * Allow to configure if additional field is required
 * Allow to configure description of additional fields
+* Allow configuring regex for allowed usernames
 
 Changed
 ~~~~~~~
diff --git a/aleksis/core/preferences.py b/aleksis/core/preferences.py
index c7ad53cec..352d5480d 100644
--- a/aleksis/core/preferences.py
+++ b/aleksis/core/preferences.py
@@ -279,6 +279,14 @@ class SignupEnabled(BooleanPreference):
     verbose_name = _("Enable signup")
 
 
+@site_preferences_registry.register
+class AllowedUsernameRegex(StringPreference):
+    section = auth
+    name = "allowed_username_regex"
+    default = ".+"
+    verbose_name = _("Regular expression for allowed usernames")
+
+
 @site_preferences_registry.register
 class InviteEnabled(BooleanPreference):
     section = auth
diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py
index 087762de8..00c0a6605 100644
--- a/aleksis/core/settings.py
+++ b/aleksis/core/settings.py
@@ -362,6 +362,9 @@ ACCOUNT_SIGNUP_EMAIL_ENTER_TWICE = True
 # Enforce uniqueness of email addresses
 ACCOUNT_UNIQUE_EMAIL = _settings.get("auth.login.registration.unique_email", True)
 
+# Configurable username validators
+ACCOUNT_USERNAME_VALIDATORS = "aleksis.core.util.auth_helpers.custom_username_validators"
+
 # Configuration for django-invitations
 
 # Use custom account adapter
diff --git a/aleksis/core/util/auth_helpers.py b/aleksis/core/util/auth_helpers.py
index 056b5156d..03f2b4bc8 100644
--- a/aleksis/core/util/auth_helpers.py
+++ b/aleksis/core/util/auth_helpers.py
@@ -3,6 +3,8 @@
 from typing import Any, Optional
 
 from django.conf import settings
+from django.contrib.auth.validators import ASCIIUsernameValidator
+from django.core.validators import RegexValidator
 from django.http import HttpRequest
 
 from allauth.account.adapter import DefaultAccountAdapter
@@ -134,3 +136,11 @@ class ClientProtectedResourceMixin(_ClientProtectedResourceMixin):
         required_scopes = set(self.get_scopes() or [])
         allowed_scopes = set(AppScopes().get_available_scopes(oauth_request.client) or [])
         return required_scopes.issubset(allowed_scopes)
+
+
+def validate_username_preference_regex(value: str):
+    regex = get_site_preferences()["auth__allowed_username_regex"]
+    return RegexValidator(regex)(value)
+
+
+custom_username_validators = [validate_username_preference_regex, ASCIIUsernameValidator()]
-- 
GitLab