Skip to content
This repository was archived by the owner on Mar 26, 2024. It is now read-only.

Commit 9368691

Browse files
clokepFizzadar
authored andcommitted
Add + as an allowed character for Matrix IDs (MSC4009) (matrix-org#15911)
1 parent bc38545 commit 9368691

File tree

7 files changed

+17
-39
lines changed

7 files changed

+17
-39
lines changed

changelog.d/15911.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Allow `+` in Matrix IDs, per [MSC4009](https://github.com/matrix-org/matrix-spec-proposals/pull/4009).

synapse/config/experimental.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -395,9 +395,6 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
395395
# Check that none of the other config options conflict with MSC3861 when enabled
396396
self.msc3861.check_config_conflicts(self.root)
397397

398-
# MSC4009: E.164 Matrix IDs
399-
self.msc4009_e164_mxids = experimental.get("msc4009_e164_mxids", False)
400-
401398
# MSC4010: Do not allow setting m.push_rules account data.
402399
self.msc4010_push_rules_account_data = experimental.get(
403400
"msc4010_push_rules_account_data", False

synapse/handlers/register.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,10 @@ async def check_username(
143143
assigned_user_id: Optional[str] = None,
144144
inhibit_user_in_use_error: bool = False,
145145
) -> None:
146-
if types.contains_invalid_mxid_characters(
147-
localpart, self.hs.config.experimental.msc4009_e164_mxids
148-
):
149-
extra_chars = (
150-
"=_-./+" if self.hs.config.experimental.msc4009_e164_mxids else "=_-./"
151-
)
146+
if types.contains_invalid_mxid_characters(localpart):
152147
raise SynapseError(
153148
400,
154-
f"User ID can only contain characters a-z, 0-9, or '{extra_chars}'",
149+
"User ID can only contain characters a-z, 0-9, or '=_-./+'",
155150
Codes.INVALID_USERNAME,
156151
)
157152

synapse/handlers/saml.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
from synapse.http.site import SynapseRequest
2828
from synapse.module_api import ModuleApi
2929
from synapse.types import (
30+
MXID_LOCALPART_ALLOWED_CHARACTERS,
3031
UserID,
3132
map_username_to_mxid_localpart,
32-
mxid_localpart_allowed_characters,
3333
)
3434
from synapse.util.iterutils import chunk_seq
3535

@@ -371,7 +371,7 @@ def expire_sessions(self) -> None:
371371

372372

373373
DOT_REPLACE_PATTERN = re.compile(
374-
"[^%s]" % (re.escape("".join(mxid_localpart_allowed_characters)),)
374+
"[^%s]" % (re.escape("".join(MXID_LOCALPART_ALLOWED_CHARACTERS)),)
375375
)
376376

377377

synapse/handlers/sso.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,6 @@ def __init__(self, hs: "HomeServer"):
225225

226226
self._consent_at_registration = hs.config.consent.user_consent_at_registration
227227

228-
self._e164_mxids = hs.config.experimental.msc4009_e164_mxids
229-
230228
def register_identity_provider(self, p: SsoIdentityProvider) -> None:
231229
p_id = p.idp_id
232230
assert p_id not in self._identity_providers
@@ -713,7 +711,7 @@ async def _register_mapped_user(
713711
# Since the localpart is provided via a potentially untrusted module,
714712
# ensure the MXID is valid before registering.
715713
if not attributes.localpart or contains_invalid_mxid_characters(
716-
attributes.localpart, self._e164_mxids
714+
attributes.localpart
717715
):
718716
raise MappingException("localpart is invalid: %s" % (attributes.localpart,))
719717

@@ -946,7 +944,7 @@ async def check_username_availability(
946944
localpart,
947945
)
948946

949-
if contains_invalid_mxid_characters(localpart, self._e164_mxids):
947+
if contains_invalid_mxid_characters(localpart):
950948
raise SynapseError(400, "localpart is invalid: %s" % (localpart,))
951949
user_id = UserID(localpart, self._server_name).to_string()
952950
user_infos = await self._store.get_users_by_id_case_insensitive(user_id)

synapse/types/__init__.py

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -348,22 +348,15 @@ class EventID(DomainSpecificString):
348348
SIGIL = "$"
349349

350350

351-
mxid_localpart_allowed_characters = set(
352-
"_-./=" + string.ascii_lowercase + string.digits
351+
MXID_LOCALPART_ALLOWED_CHARACTERS = set(
352+
"_-./=+" + string.ascii_lowercase + string.digits
353353
)
354-
# MSC4007 adds the + to the allowed characters.
355-
#
356-
# TODO If this was accepted, update the SSO code to support this, see the callers
357-
# of map_username_to_mxid_localpart.
358-
extended_mxid_localpart_allowed_characters = mxid_localpart_allowed_characters | {"+"}
359354

360355
# Guest user IDs are purely numeric.
361356
GUEST_USER_ID_PATTERN = re.compile(r"^\d+$")
362357

363358

364-
def contains_invalid_mxid_characters(
365-
localpart: str, use_extended_character_set: bool
366-
) -> bool:
359+
def contains_invalid_mxid_characters(localpart: str) -> bool:
367360
"""Check for characters not allowed in an mxid or groupid localpart
368361
369362
Args:
@@ -374,12 +367,7 @@ def contains_invalid_mxid_characters(
374367
Returns:
375368
True if there are any naughty characters
376369
"""
377-
allowed_characters = (
378-
extended_mxid_localpart_allowed_characters
379-
if use_extended_character_set
380-
else mxid_localpart_allowed_characters
381-
)
382-
return any(c not in allowed_characters for c in localpart)
370+
return any(c not in MXID_LOCALPART_ALLOWED_CHARACTERS for c in localpart)
383371

384372

385373
UPPER_CASE_PATTERN = re.compile(b"[A-Z_]")
@@ -396,7 +384,7 @@ def contains_invalid_mxid_characters(
396384
# bytes rather than strings
397385
#
398386
NON_MXID_CHARACTER_PATTERN = re.compile(
399-
("[^%s]" % (re.escape("".join(mxid_localpart_allowed_characters - {"="})),)).encode(
387+
("[^%s]" % (re.escape("".join(MXID_LOCALPART_ALLOWED_CHARACTERS - {"="})),)).encode(
400388
"ascii"
401389
)
402390
)

tests/handlers/test_register.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -588,17 +588,16 @@ def test_register_not_support_user(self) -> None:
588588
self.assertFalse(self.get_success(d))
589589

590590
def test_invalid_user_id(self) -> None:
591-
invalid_user_id = "+abcd"
591+
invalid_user_id = "^abcd"
592592
self.get_failure(
593593
self.handler.register_user(localpart=invalid_user_id), SynapseError
594594
)
595595

596-
@override_config({"experimental_features": {"msc4009_e164_mxids": True}})
597-
def text_extended_user_ids(self) -> None:
598-
"""+ should be allowed according to MSC4009."""
599-
valid_user_id = "+1234"
596+
def test_special_chars(self) -> None:
597+
"""Ensure that characters which are allowed in Matrix IDs work."""
598+
valid_user_id = "a1234_-./=+"
600599
user_id = self.get_success(self.handler.register_user(localpart=valid_user_id))
601-
self.assertEqual(user_id, valid_user_id)
600+
self.assertEqual(user_id, f"@{valid_user_id}:test")
602601

603602
def test_invalid_user_id_length(self) -> None:
604603
invalid_user_id = "x" * 256

0 commit comments

Comments
 (0)