Skip to content

Commit f94b083

Browse files
committed
Add option to allow registrations that begin with _
This commit resolves a long-standing question dating back to Jira. > leonerd: Should this be a configuration option? We don't want to allow > new user signups beginning with `_` on matrix.org, because of clashes > with ASes; but maybe other sites wouldn't mind that? As this may result in clashes with AppService namespaces, it is disallowed by default. Homeservers which provision users from an external identity provider may find this useful. Fixes: SYN-738
1 parent 1efb826 commit f94b083

File tree

5 files changed

+46
-1
lines changed

5 files changed

+46
-1
lines changed

changelog.d/18262.feature

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add option to allow registrations that begin with `_`. Contributed by `_` (@hex5f).

docs/usage/configuration/config_documentation.md

+14
Original file line numberDiff line numberDiff line change
@@ -2887,6 +2887,20 @@ Example configuration:
28872887
inhibit_user_in_use_error: true
28882888
```
28892889
---
2890+
### `allow_underscore_prefixed_registration`
2891+
2892+
Whether users are allowed to register with a underscore-prefixed localpart.
2893+
By default, AppServices use prefixes like `_example` to namespace their
2894+
associated ghost users. If turned on, this may result in clashes or confusion.
2895+
Useful when provisioning users from an external identity provider.
2896+
2897+
Defaults to false.
2898+
2899+
Example configuration:
2900+
```yaml
2901+
allow_underscore_prefixed_registration: false
2902+
```
2903+
---
28902904
## User session management
28912905
---
28922906
### `session_lifetime`

synapse/config/registration.py

+4
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ def read_config(
162162
"disable_msisdn_registration", False
163163
)
164164

165+
self.allow_underscore_prefixed_localpart = config.get(
166+
"allow_underscore_prefixed_localpart", False
167+
)
168+
165169
session_lifetime = config.get("session_lifetime")
166170
if session_lifetime is not None:
167171
session_lifetime = self.parse_duration(session_lifetime)

synapse/handlers/register.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,10 @@ async def check_username(
159159
if not localpart:
160160
raise SynapseError(400, "User ID cannot be empty", Codes.INVALID_USERNAME)
161161

162-
if localpart[0] == "_":
162+
if (
163+
localpart[0] == "_"
164+
and not self.hs.config.registration.allow_underscore_prefixed_localpart
165+
):
163166
raise SynapseError(
164167
400, "User ID may not begin with _", Codes.INVALID_USERNAME
165168
)

tests/handlers/test_register.py

+23
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,29 @@ def test_register_not_support_user(self) -> None:
588588
d = self.store.is_support_user(user_id)
589589
self.assertFalse(self.get_success(d))
590590

591+
def test_underscore_localpart_rejected_by_default(self) -> None:
592+
for invalid_user_id in ("_", "_prefixed"):
593+
with self.subTest(invalid_user_id=invalid_user_id):
594+
self.get_failure(
595+
self.handler.register_user(localpart=invalid_user_id),
596+
SynapseError,
597+
)
598+
599+
@override_config(
600+
{
601+
"allow_underscore_prefixed_localpart": "true",
602+
}
603+
)
604+
def test_underscore_localpart_allowed_if_configured(self) -> None:
605+
for valid_user_id in ("_", "_prefixed"):
606+
with self.subTest(valid_user_id=valid_user_id):
607+
user_id = self.get_success(
608+
self.handler.register_user(
609+
localpart=valid_user_id,
610+
),
611+
)
612+
self.assertEqual(user_id, f"@{valid_user_id}:test")
613+
591614
def test_invalid_user_id(self) -> None:
592615
invalid_user_id = "^abcd"
593616
self.get_failure(

0 commit comments

Comments
 (0)