summary refs log tree commit diff
path: root/synapse/handlers/sso.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--synapse/handlers/sso.py44
1 files changed, 24 insertions, 20 deletions
diff --git a/synapse/handlers/sso.py b/synapse/handlers/sso.py

index ee74289b6c..2795b282e5 100644 --- a/synapse/handlers/sso.py +++ b/synapse/handlers/sso.py
@@ -33,17 +33,17 @@ from typing import ( Mapping, NoReturn, Optional, + Protocol, Set, ) from urllib.parse import urlencode import attr -from typing_extensions import Protocol from twisted.web.iweb import IRequest from twisted.web.server import Request -from synapse.api.constants import LoginType +from synapse.api.constants import LoginType, ProfileFields from synapse.api.errors import Codes, NotFoundError, RedirectException, SynapseError from synapse.config.sso import SsoAttributeRequirement from synapse.handlers.device import DeviceHandler @@ -81,8 +81,7 @@ class SsoIdentityProvider(Protocol): An Identity Provider, or IdP, is an external HTTP service which authenticates a user to say whether they should be allowed to log in, or perform a given action. - Synapse supports various implementations of IdPs, including OpenID Connect, SAML, - and CAS. + Synapse supports various implementations of IdPs, including OpenID Connect. The main entry point is `handle_redirect_request`, which should return a URI to redirect the user's browser to the IdP's authentication page. @@ -97,7 +96,7 @@ class SsoIdentityProvider(Protocol): def idp_id(self) -> str: """A unique identifier for this SSO provider - Eg, "saml", "cas", "github" + Eg. "github" """ @property @@ -157,7 +156,7 @@ class UserAttributes: class UsernameMappingSession: """Data we track about SSO sessions""" - # A unique identifier for this SSO provider, e.g. "oidc" or "saml". + # A unique identifier for this SSO provider, e.g. "oidc". auth_provider_id: str # An optional session ID from the IdP. @@ -351,7 +350,7 @@ class SsoHandler: Args: auth_provider_id: A unique identifier for this SSO provider, e.g. - "oidc" or "saml". + "oidc". 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. @@ -418,7 +417,7 @@ class SsoHandler: Args: auth_provider_id: A unique identifier for this SSO provider, e.g. - "oidc" or "saml". + "oidc". remote_user_id: The unique identifier from the SSO provider. @@ -634,7 +633,7 @@ class SsoHandler: Args: auth_provider_id: A unique identifier for this SSO provider, e.g. - "oidc" or "saml". + "oidc". remote_user_id: The unique identifier from the SSO provider. @@ -704,7 +703,7 @@ class SsoHandler: including a non-empty localpart. auth_provider_id: A unique identifier for this SSO provider, e.g. - "oidc" or "saml". + "oidc". remote_user_id: The unique identifier from the SSO provider. @@ -813,9 +812,10 @@ class SsoHandler: # bail if user already has the same avatar profile = await self._profile_handler.get_profile(user_id) - if profile["avatar_url"] is not None: - server_name = profile["avatar_url"].split("/")[-2] - media_id = profile["avatar_url"].split("/")[-1] + if ProfileFields.AVATAR_URL in profile: + avatar_url_parts = profile[ProfileFields.AVATAR_URL].split("/") + server_name = avatar_url_parts[-2] + media_id = avatar_url_parts[-1] if self._is_mine_server_name(server_name): media = await self._media_repo.store.get_local_media(media_id) # type: ignore[has-type] if media is not None and upload_name == media.upload_name: @@ -855,12 +855,12 @@ class SsoHandler: Given an SSO ID, retrieve the user ID for it and complete UIA. Note that this requires that the user is mapped in the "user_external_ids" - table. This will be the case if they have ever logged in via SAML or OIDC in + table. This will be the case if they have ever logged in via OIDC in recentish synapse versions, but may not be for older users. Args: auth_provider_id: A unique identifier for this SSO provider, e.g. - "oidc" or "saml". + "oidc". remote_user_id: The unique identifier from the SSO provider. ui_auth_session_id: The ID of the user-interactive auth session. request: The request to complete. @@ -1184,16 +1184,16 @@ class SsoHandler: Args: auth_provider_id: A unique identifier for this SSO provider, e.g. - "oidc" or "saml". + "oidc". auth_provider_session_id: The session ID from the provider to logout expected_user_id: The user we're expecting to logout. If set, it will ignore sessions belonging to other users and log an error. """ # It is expected that this is the main process. - assert isinstance( - self._device_handler, DeviceHandler - ), "revoking SSO sessions can only be called on the main process" + assert isinstance(self._device_handler, DeviceHandler), ( + "revoking SSO sessions can only be called on the main process" + ) # Invalidate any running user-mapping sessions to_delete = [] @@ -1276,12 +1276,16 @@ def _check_attribute_requirement( return False # If the requirement is None, the attribute existing is enough. - if req.value is None: + if req.value is None and req.one_of is None: return True values = attributes[req.attribute] if req.value in values: return True + if req.one_of: + for value in req.one_of: + if value in values: + return True logger.info( "SSO attribute %s did not match required value '%s' (was '%s')",