Browse Source

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.
tags/v1.93.0rc1
Aurélien Grimpard 8 months ago
committed by GitHub
parent
commit
fe69e7f617
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 0 deletions
  1. +1
    -0
      changelog.d/16262.feature
  2. +7
    -0
      docs/usage/configuration/config_documentation.md
  3. +3
    -0
      synapse/config/cas.py
  4. +2
    -0
      synapse/handlers/cas.py
  5. +17
    -0
      tests/handlers/test_cas.py

+ 1
- 0
changelog.d/16262.feature View File

@@ -0,0 +1 @@
Add the ability to enable/disable registrations when in the CAS flow. Contributed by Aurélien Grimpard.

+ 7
- 0
docs/usage/configuration/config_documentation.md View File

@@ -3430,6 +3430,12 @@ Has the following sub-options:
and the values must match the given value. Alternately if the given value
is `None` then any value is allowed (the attribute just must exist).
All of the listed attributes must match for the login to be permitted.
* `enable_registration`: set to 'false' to disable automatic registration of new
users. This allows the CAS 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.

*Added in Synapse 1.93.0.*

Example configuration:
```yaml
@@ -3441,6 +3447,7 @@ cas_config:
required_attributes:
userGroup: "staff"
department: None
enable_registration: true
```
---
### `sso`


+ 3
- 0
synapse/config/cas.py View File

@@ -57,6 +57,8 @@ class CasConfig(Config):
required_attributes
)

self.cas_enable_registration = cas_config.get("enable_registration", True)

self.idp_name = cas_config.get("idp_name", "CAS")
self.idp_icon = cas_config.get("idp_icon")
self.idp_brand = cas_config.get("idp_brand")
@@ -67,6 +69,7 @@ class CasConfig(Config):
self.cas_protocol_version = None
self.cas_displayname_attribute = None
self.cas_required_attributes = []
self.cas_enable_registration = False


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


+ 2
- 0
synapse/handlers/cas.py View File

@@ -70,6 +70,7 @@ class CasHandler:
self._cas_protocol_version = hs.config.cas.cas_protocol_version
self._cas_displayname_attribute = hs.config.cas.cas_displayname_attribute
self._cas_required_attributes = hs.config.cas.cas_required_attributes
self._cas_enable_registration = hs.config.cas.cas_enable_registration

self._http_client = hs.get_proxied_http_client()

@@ -395,4 +396,5 @@ class CasHandler:
client_redirect_url,
cas_response_to_user_attributes,
grandfather_existing_users,
registration_enabled=self._cas_enable_registration,
)

+ 17
- 0
tests/handlers/test_cas.py View File

@@ -197,6 +197,23 @@ class CasHandlerTestCase(HomeserverTestCase):
auth_provider_session_id=None,
)

@override_config({"cas_config": {"enable_registration": False}})
def test_map_cas_user_does_not_register_new_user(self) -> None:
"""Ensures new users are not registered if the enabled registration flag is disabled."""

# stub out the auth handler
auth_handler = self.hs.get_auth_handler()
auth_handler.complete_sso_login = AsyncMock() # type: ignore[method-assign]

cas_response = CasResponse("test_user", {})
request = _mock_request()
self.get_success(
self.handler._handle_cas_response(request, cas_response, "redirect_uri", "")
)

# check that the auth handler was not called as expected
auth_handler.complete_sso_login.assert_not_called()


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


Loading…
Cancel
Save