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

Commit fe69e7f

Browse files
authored
Handle "registration_enabled" parameter for CAS (#16262)
Similar to OIDC, CAS providers can now disable registration such that only existing users are able to login via SSO.
1 parent 32fb264 commit fe69e7f

File tree

5 files changed

+30
-0
lines changed

5 files changed

+30
-0
lines changed

changelog.d/16262.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add the ability to enable/disable registrations when in the CAS flow. Contributed by Aurélien Grimpard.

docs/usage/configuration/config_documentation.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3430,6 +3430,12 @@ Has the following sub-options:
34303430
and the values must match the given value. Alternately if the given value
34313431
is `None` then any value is allowed (the attribute just must exist).
34323432
All of the listed attributes must match for the login to be permitted.
3433+
* `enable_registration`: set to 'false' to disable automatic registration of new
3434+
users. This allows the CAS SSO flow to be limited to sign in only, rather than
3435+
automatically registering users that have a valid SSO login but do not have
3436+
a pre-registered account. Defaults to true.
3437+
3438+
*Added in Synapse 1.93.0.*
34333439

34343440
Example configuration:
34353441
```yaml
@@ -3441,6 +3447,7 @@ cas_config:
34413447
required_attributes:
34423448
userGroup: "staff"
34433449
department: None
3450+
enable_registration: true
34443451
```
34453452
---
34463453
### `sso`

synapse/config/cas.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
5757
required_attributes
5858
)
5959

60+
self.cas_enable_registration = cas_config.get("enable_registration", True)
61+
6062
self.idp_name = cas_config.get("idp_name", "CAS")
6163
self.idp_icon = cas_config.get("idp_icon")
6264
self.idp_brand = cas_config.get("idp_brand")
@@ -67,6 +69,7 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
6769
self.cas_protocol_version = None
6870
self.cas_displayname_attribute = None
6971
self.cas_required_attributes = []
72+
self.cas_enable_registration = False
7073

7174

7275
# CAS uses a legacy required attributes mapping, not the one provided by

synapse/handlers/cas.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def __init__(self, hs: "HomeServer"):
7070
self._cas_protocol_version = hs.config.cas.cas_protocol_version
7171
self._cas_displayname_attribute = hs.config.cas.cas_displayname_attribute
7272
self._cas_required_attributes = hs.config.cas.cas_required_attributes
73+
self._cas_enable_registration = hs.config.cas.cas_enable_registration
7374

7475
self._http_client = hs.get_proxied_http_client()
7576

@@ -395,4 +396,5 @@ async def grandfather_existing_users() -> Optional[str]:
395396
client_redirect_url,
396397
cas_response_to_user_attributes,
397398
grandfather_existing_users,
399+
registration_enabled=self._cas_enable_registration,
398400
)

tests/handlers/test_cas.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,23 @@ def test_required_attributes(self) -> None:
197197
auth_provider_session_id=None,
198198
)
199199

200+
@override_config({"cas_config": {"enable_registration": False}})
201+
def test_map_cas_user_does_not_register_new_user(self) -> None:
202+
"""Ensures new users are not registered if the enabled registration flag is disabled."""
203+
204+
# stub out the auth handler
205+
auth_handler = self.hs.get_auth_handler()
206+
auth_handler.complete_sso_login = AsyncMock() # type: ignore[method-assign]
207+
208+
cas_response = CasResponse("test_user", {})
209+
request = _mock_request()
210+
self.get_success(
211+
self.handler._handle_cas_response(request, cas_response, "redirect_uri", "")
212+
)
213+
214+
# check that the auth handler was not called as expected
215+
auth_handler.complete_sso_login.assert_not_called()
216+
200217

201218
def _mock_request() -> Mock:
202219
"""Returns a mock which will stand in as a SynapseRequest"""

0 commit comments

Comments
 (0)