summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--changelog.d/17098.feature1
-rw-r--r--docs/usage/configuration/config_documentation.md11
-rw-r--r--synapse/config/cas.py13
-rw-r--r--synapse/handlers/cas.py5
4 files changed, 30 insertions, 0 deletions
diff --git a/changelog.d/17098.feature b/changelog.d/17098.feature
new file mode 100644
index 0000000000..43e06481b2
--- /dev/null
+++ b/changelog.d/17098.feature
@@ -0,0 +1 @@
+Add the ability to allow numeric user IDs with a specific prefix when in the CAS flow. Contributed by Aurélien Grimpard.
diff --git a/docs/usage/configuration/config_documentation.md b/docs/usage/configuration/config_documentation.md
index 2257318bcc..f4edbdcc3e 100644
--- a/docs/usage/configuration/config_documentation.md
+++ b/docs/usage/configuration/config_documentation.md
@@ -3558,6 +3558,15 @@ Has the following sub-options:
    users. This allows the CAS SSO flow to be limited to sign in only, rather than
    automatically registering users that have a valid SSO login but do not have
    a pre-registered account. Defaults to true.
+* `allow_numeric_ids`: set to 'true' allow numeric user IDs (default false).
+   This allows CAS SSO flow to provide user IDs composed of numbers only.
+   These identifiers will be prefixed by the letter "u" by default.
+   The prefix can be configured using the "numeric_ids_prefix" option.
+   Be careful to choose the prefix correctly to avoid any possible conflicts
+   (e.g. user 1234 becomes u1234 when a user u1234 already exists).
+* `numeric_ids_prefix`: the prefix you wish to add in front of a numeric user ID
+   when the "allow_numeric_ids" option is set to "true".
+   By default, the prefix is the letter "u" and only alphanumeric characters are allowed.
 
    *Added in Synapse 1.93.0.*
 
@@ -3572,6 +3581,8 @@ cas_config:
     userGroup: "staff"
     department: None
   enable_registration: true
+  allow_numeric_ids: true
+  numeric_ids_prefix: "numericuser"
 ```
 ---
 ### `sso`
diff --git a/synapse/config/cas.py b/synapse/config/cas.py
index d23dcf96b2..fa59c350c1 100644
--- a/synapse/config/cas.py
+++ b/synapse/config/cas.py
@@ -66,6 +66,17 @@ class CasConfig(Config):
 
             self.cas_enable_registration = cas_config.get("enable_registration", True)
 
+            self.cas_allow_numeric_ids = cas_config.get("allow_numeric_ids")
+            self.cas_numeric_ids_prefix = cas_config.get("numeric_ids_prefix")
+            if (
+                self.cas_numeric_ids_prefix is not None
+                and self.cas_numeric_ids_prefix.isalnum() is False
+            ):
+                raise ConfigError(
+                    "Only alphanumeric characters are allowed for numeric IDs prefix",
+                    ("cas_config", "numeric_ids_prefix"),
+                )
+
             self.idp_name = cas_config.get("idp_name", "CAS")
             self.idp_icon = cas_config.get("idp_icon")
             self.idp_brand = cas_config.get("idp_brand")
@@ -77,6 +88,8 @@ class CasConfig(Config):
             self.cas_displayname_attribute = None
             self.cas_required_attributes = []
             self.cas_enable_registration = False
+            self.cas_allow_numeric_ids = False
+            self.cas_numeric_ids_prefix = "u"
 
 
 # CAS uses a legacy required attributes mapping, not the one provided by
diff --git a/synapse/handlers/cas.py b/synapse/handlers/cas.py
index 153123ee83..cc3d641b7d 100644
--- a/synapse/handlers/cas.py
+++ b/synapse/handlers/cas.py
@@ -78,6 +78,8 @@ class CasHandler:
         self._cas_displayname_attribute = hs.config.cas.cas_displayname_attribute
         self._cas_required_attributes = hs.config.cas.cas_required_attributes
         self._cas_enable_registration = hs.config.cas.cas_enable_registration
+        self._cas_allow_numeric_ids = hs.config.cas.cas_allow_numeric_ids
+        self._cas_numeric_ids_prefix = hs.config.cas.cas_numeric_ids_prefix
 
         self._http_client = hs.get_proxied_http_client()
 
@@ -188,6 +190,9 @@ class CasHandler:
         for child in root[0]:
             if child.tag.endswith("user"):
                 user = child.text
+                # if numeric user IDs are allowed and username is numeric then we add the prefix so Synapse can handle it
+                if self._cas_allow_numeric_ids and user is not None and user.isdigit():
+                    user = f"{self._cas_numeric_ids_prefix}{user}"
             if child.tag.endswith("attributes"):
                 for attribute in child:
                     # ElementTree library expands the namespace in