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

Add the ability to enable/disable registrations when in the OIDC flow #14978

Merged
merged 6 commits into from
Mar 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/14978.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add the ability to enable/disable registrations when in the OIDC flow.
6 changes: 6 additions & 0 deletions docs/usage/configuration/config_documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -3100,6 +3100,11 @@ Options for each entry include:
match a pre-existing account instead of failing. This could be used if
switching from password logins to OIDC. Defaults to false.

* `enable_registration`: set to 'false' to disable automatic registration of new
users. This allows the OIDC SSO flow to be limited to sign in only, rather than
automatically registering users that have a valid SSO login but do not have
a pre-registered account. Defaults to true.

* `user_mapping_provider`: Configuration for how attributes returned from a OIDC
provider are mapped onto a matrix user. This setting has the following
sub-properties:
Expand Down Expand Up @@ -3216,6 +3221,7 @@ oidc_providers:
userinfo_endpoint: "https://accounts.example.com/userinfo"
jwks_uri: "https://accounts.example.com/.well-known/jwks.json"
skip_verification: true
enable_registration: true
user_mapping_provider:
config:
subject_claim: "id"
Expand Down
5 changes: 5 additions & 0 deletions synapse/config/oidc.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ def oidc_enabled(self) -> bool:
"type": "array",
"items": SsoAttributeRequirement.JSON_SCHEMA,
},
"enable_registration": {"type": "boolean"},
},
}

Expand Down Expand Up @@ -306,6 +307,7 @@ def _parse_oidc_config_dict(
user_mapping_provider_class=user_mapping_provider_class,
user_mapping_provider_config=user_mapping_provider_config,
attribute_requirements=attribute_requirements,
enable_registration=oidc_config.get("enable_registration", True),
)


Expand Down Expand Up @@ -405,3 +407,6 @@ class OidcProviderConfig:

# required attributes to require in userinfo to allow login/registration
attribute_requirements: List[SsoAttributeRequirement]

# Whether automatic registrations are enabled in the ODIC flow. Defaults to True
enable_registration: bool
1 change: 1 addition & 0 deletions synapse/handlers/oidc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,7 @@ async def grandfather_existing_users() -> Optional[str]:
grandfather_existing_users,
extra_attributes,
auth_provider_session_id=sid,
registration_enabled=self._config.enable_registration,
)

def _remote_id_from_userinfo(self, userinfo: UserInfo) -> str:
Expand Down
17 changes: 15 additions & 2 deletions synapse/handlers/sso.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ async def complete_sso_login_request(
grandfather_existing_users: Callable[[], Awaitable[Optional[str]]],
extra_login_attributes: Optional[JsonDict] = None,
auth_provider_session_id: Optional[str] = None,
registration_enabled: bool = True,
) -> None:
"""
Given an SSO ID, retrieve the user ID for it and possibly register the user.
Expand Down Expand Up @@ -435,6 +436,10 @@ async def complete_sso_login_request(

auth_provider_session_id: An optional session ID from the IdP.

registration_enabled: An optional boolean to enable/disable automatic
registrations of new users. If false and the user does not exist then the
flow is aborted. Defaults to true.

Raises:
MappingException if there was a problem mapping the response to a user.
RedirectException: if the mapping provider needs to redirect the user
Expand Down Expand Up @@ -462,8 +467,16 @@ async def complete_sso_login_request(
auth_provider_id, remote_user_id, user_id
)

# Otherwise, generate a new user.
if not user_id:
if not user_id and not registration_enabled:
logger.info(
"User does not exist and registration are disabled for IdP '%s' and remote_user_id '%s'",
auth_provider_id,
remote_user_id,
)
raise MappingException(
"User does not exist and registrations are disabled"
)
elif not user_id: # Otherwise, generate a new user.
attributes = await self._call_attribute_mapper(sso_to_matrix_id_mapper)

next_step_url = self._get_url_for_next_new_user_step(
Expand Down
17 changes: 16 additions & 1 deletion tests/handlers/test_oidc.py
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,7 @@ def test_extra_attributes(self) -> None:
auth_provider_session_id=None,
)

@override_config({"oidc_config": DEFAULT_CONFIG})
@override_config({"oidc_config": {**DEFAULT_CONFIG, "enable_registration": True}})
def test_map_userinfo_to_user(self) -> None:
"""Ensure that mapping the userinfo returned from a provider to an MXID works properly."""
userinfo: dict = {
Expand Down Expand Up @@ -975,6 +975,21 @@ def test_map_userinfo_to_user(self) -> None:
"Mapping provider does not support de-duplicating Matrix IDs",
)

@override_config({"oidc_config": {**DEFAULT_CONFIG, "enable_registration": False}})
def test_map_userinfo_to_user_does_not_register_new_user(self) -> None:
"""Ensures new users are not registered if the enabled registration flag is disabled."""
userinfo: dict = {
"sub": "test_user",
"username": "test_user",
}
request, _ = self.start_authorization(userinfo)
self.get_success(self.handler.handle_oidc_callback(request))
self.complete_sso_login.assert_not_called()
self.assertRenderedError(
"mapping_error",
"User does not exist and registrations are disabled",
)

@override_config({"oidc_config": {**DEFAULT_CONFIG, "allow_existing_users": True}})
def test_map_userinfo_to_existing_user(self) -> None:
"""Existing users can log in with OpenID Connect when allow_existing_users is True."""
Expand Down