diff --git a/synapse/handlers/oidc_handler.py b/synapse/handlers/oidc_handler.py index 57f30e5d83..eddae5071a 100644 --- a/synapse/handlers/oidc_handler.py +++ b/synapse/handlers/oidc_handler.py @@ -864,20 +864,14 @@ class OidcHandler(BaseHandler): # to be strings. remote_user_id = str(remote_user_id) - logger.info( - "Looking for existing mapping for user %s:%s", - self._auth_provider_id, - remote_user_id, - ) - - registered_user_id = await self.store.get_user_by_external_id( + # first of all, check if we already have a mapping for this user + registered_user_id = await self._sso_handler.get_sso_user_by_remote_user_id( self._auth_provider_id, remote_user_id, ) - - if registered_user_id is not None: - logger.info("Found existing mapping %s", registered_user_id) + if registered_user_id: return registered_user_id + # Otherwise, generate a new user. try: attributes = await self._user_mapping_provider.map_user_attributes( userinfo, token diff --git a/synapse/handlers/saml_handler.py b/synapse/handlers/saml_handler.py index e702137903..e523267d34 100644 --- a/synapse/handlers/saml_handler.py +++ b/synapse/handlers/saml_handler.py @@ -250,16 +250,10 @@ class SamlHandler(BaseHandler): with (await self._mapping_lock.queue(self._auth_provider_id)): # first of all, check if we already have a mapping for this user - logger.info( - "Looking for existing mapping for user %s:%s", - self._auth_provider_id, - remote_user_id, + registered_user_id = await self._sso_handler.get_sso_user_by_remote_user_id( + self._auth_provider_id, remote_user_id, ) - registered_user_id = await self.store.get_user_by_external_id( - self._auth_provider_id, remote_user_id - ) - if registered_user_id is not None: - logger.info("Found existing mapping %s", registered_user_id) + if registered_user_id: return registered_user_id # backwards-compatibility hack: see if there is an existing user with a diff --git a/synapse/handlers/sso.py b/synapse/handlers/sso.py index 3e6dc8b15b..ece704bbc2 100644 --- a/synapse/handlers/sso.py +++ b/synapse/handlers/sso.py @@ -52,3 +52,39 @@ class SsoHandler(BaseHandler): error=error, error_description=error_description ) respond_with_html(request, 400, html) + + async def get_sso_user_by_remote_user_id( + self, auth_provider_id: str, remote_user_id: str + ) -> Optional[str]: + """ + Maps the user ID of a remote IdP to a mxid for a previously seen user. + + If the user has not been seen yet, this will return None. + + Args: + auth_provider_id: A unique identifier for this SSO provider, e.g. + "oidc" or "saml". + remote_user_id: The user ID according to the remote IdP. This might + be an e-mail address, a GUID, or some other form. It must be + unique and immutable. + + Returns: + The mxid of a previously seen user. + """ + # Check if we already have a mapping for this user. + logger.info( + "Looking for existing mapping for user %s:%s", + auth_provider_id, + remote_user_id, + ) + registered_user_id = await self.store.get_user_by_external_id( + auth_provider_id, remote_user_id, + ) + + # A match was found, return the user ID. + if registered_user_id is not None: + logger.info("Found existing mapping %s", registered_user_id) + return registered_user_id + + # No match. + return None