Add a module callback to set username at registration (#11790)

This is in the context of mainlining the Tchap fork of Synapse. Currently in Tchap usernames are derived from the user's email address (extracted from the UIA results, more specifically the m.login.email.identity step).
This change also exports the check_username method from the registration handler as part of the module API, so that a module can check if the username it's trying to generate is correct and doesn't conflict with an existing one, and fallback gracefully if not.

Co-authored-by: David Robertson <davidr@element.io>
This commit is contained in:
Brendan Abolivier 2022-01-26 14:21:13 +00:00 committed by GitHub
parent 2897fb6b4f
commit 2d3bd9aa67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 231 additions and 3 deletions

View file

@ -71,6 +71,7 @@ from synapse.handlers.account_validity import (
from synapse.handlers.auth import (
CHECK_3PID_AUTH_CALLBACK,
CHECK_AUTH_CALLBACK,
GET_USERNAME_FOR_REGISTRATION_CALLBACK,
ON_LOGGED_OUT_CALLBACK,
AuthHandler,
)
@ -177,6 +178,7 @@ class ModuleApi:
self._presence_stream = hs.get_event_sources().sources.presence
self._state = hs.get_state_handler()
self._clock: Clock = hs.get_clock()
self._registration_handler = hs.get_registration_handler()
self._send_email_handler = hs.get_send_email_handler()
self.custom_template_dir = hs.config.server.custom_template_directory
@ -310,6 +312,9 @@ class ModuleApi:
auth_checkers: Optional[
Dict[Tuple[str, Tuple[str, ...]], CHECK_AUTH_CALLBACK]
] = None,
get_username_for_registration: Optional[
GET_USERNAME_FOR_REGISTRATION_CALLBACK
] = None,
) -> None:
"""Registers callbacks for password auth provider capabilities.
@ -319,6 +324,7 @@ class ModuleApi:
check_3pid_auth=check_3pid_auth,
on_logged_out=on_logged_out,
auth_checkers=auth_checkers,
get_username_for_registration=get_username_for_registration,
)
def register_background_update_controller_callbacks(
@ -1202,6 +1208,22 @@ class ModuleApi:
"""
return await defer_to_thread(self._hs.get_reactor(), f, *args, **kwargs)
async def check_username(self, username: str) -> None:
"""Checks if the provided username uses the grammar defined in the Matrix
specification, and is already being used by an existing user.
Added in Synapse v1.52.0.
Args:
username: The username to check. This is the local part of the user's full
Matrix user ID, i.e. it's "alice" if the full user ID is "@alice:foo.com".
Raises:
SynapseError with the errcode "M_USER_IN_USE" if the username is already in
use.
"""
await self._registration_handler.check_username(username)
class PublicRoomListManager:
"""Contains methods for adding to, removing from and querying whether a room