saml: Implement group sync.

Adds support for syncing group memberships for a user when logging in
via SAML. The list of group memberships is passed by the IdP in the
zulip_groups SAML attribute in the SAMLResponse.
This commit is contained in:
Mateusz Mandera
2025-05-18 22:13:41 +02:00
committed by Tim Abbott
parent b966397d25
commit 40956ae4c5
8 changed files with 573 additions and 27 deletions

View File

@@ -165,6 +165,7 @@ def maybe_send_to_registration(
desktop_flow_otp: str | None = None,
full_name: str = "",
full_name_validated: bool = False,
group_memberships_sync_map: dict[str, bool] | None = None,
is_signup: bool = False,
mobile_flow_otp: str | None = None,
multiuse_object_key: str = "",
@@ -227,6 +228,18 @@ def maybe_send_to_registration(
expiry_seconds=EXPIRABLE_SESSION_VAR_DEFAULT_EXPIRY_SECS,
)
if group_memberships_sync_map:
set_expirable_session_var(
request.session,
"registration_group_memberships_sync_map",
orjson.dumps(group_memberships_sync_map).decode(),
expiry_seconds=EXPIRABLE_SESSION_VAR_DEFAULT_EXPIRY_SECS,
)
elif "registration_group_memberships_sync_map" in request.session: # nocoverage
# Ensure it isn't possible to leak this state across
# registration attempts.
del request.session["registration_group_memberships_sync_map"]
try:
# TODO: This should use get_realm_from_request, but a bunch of tests
# rely on mocking get_subdomain here, so they'll need to be tweaked first.
@@ -360,6 +373,7 @@ def register_remote_user(request: HttpRequest, result: ExternalAuthResult) -> Ht
"email",
"full_name",
"role",
"group_memberships_sync_map",
"mobile_flow_otp",
"desktop_flow_otp",
"is_signup",