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

Commit 756fd51

Browse files
authored
Implement config option sso.update_profile_information (#10108)
Implemented config option sso.update_profile_information to keep user's display name in sync with the SSO displayname. Signed-off-by: Johannes Kanefendt <[email protected]>
1 parent a5cd05b commit 756fd51

File tree

4 files changed

+51
-1
lines changed

4 files changed

+51
-1
lines changed

changelog.d/10108.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Implement config option `sso.update_profile_information` to sync SSO users' profile information with the identity provider each time they login. Currently only displayname is supported.

docs/sample_config.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,6 +1975,17 @@ sso:
19751975
# - https://riot.im/develop
19761976
# - https://my.custom.client/
19771977

1978+
# Uncomment to keep a user's profile fields in sync with information from
1979+
# the identity provider. Currently only syncing the displayname is
1980+
# supported. Fields are checked on every SSO login, and are updated
1981+
# if necessary.
1982+
#
1983+
# Note that enabling this option will override user profile information,
1984+
# regardless of whether users have opted-out of syncing that
1985+
# information when first signing in. Defaults to false.
1986+
#
1987+
#update_profile_information: true
1988+
19781989
# Directory in which Synapse will try to find the template files below.
19791990
# If not set, or the files named below are not found within the template
19801991
# directory, default templates from within the Synapse package will be used.

synapse/config/sso.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ def read_config(self, config, **kwargs):
7474

7575
self.sso_client_whitelist = sso_config.get("client_whitelist") or []
7676

77+
self.sso_update_profile_information = (
78+
sso_config.get("update_profile_information") or False
79+
)
80+
7781
# Attempt to also whitelist the server's login fallback, since that fallback sets
7882
# the redirect URL to itself (so it can process the login token then return
7983
# gracefully to the client). This would make it pointless to ask the user for
@@ -111,6 +115,17 @@ def generate_config_section(self, **kwargs):
111115
# - https://riot.im/develop
112116
# - https://my.custom.client/
113117
118+
# Uncomment to keep a user's profile fields in sync with information from
119+
# the identity provider. Currently only syncing the displayname is
120+
# supported. Fields are checked on every SSO login, and are updated
121+
# if necessary.
122+
#
123+
# Note that enabling this option will override user profile information,
124+
# regardless of whether users have opted-out of syncing that
125+
# information when first signing in. Defaults to false.
126+
#
127+
#update_profile_information: true
128+
114129
# Directory in which Synapse will try to find the template files below.
115130
# If not set, or the files named below are not found within the template
116131
# directory, default templates from within the Synapse package will be used.

synapse/handlers/sso.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,12 @@
4141
from synapse.http import get_request_user_agent
4242
from synapse.http.server import respond_with_html, respond_with_redirect
4343
from synapse.http.site import SynapseRequest
44-
from synapse.types import JsonDict, UserID, contains_invalid_mxid_characters
44+
from synapse.types import (
45+
JsonDict,
46+
UserID,
47+
contains_invalid_mxid_characters,
48+
create_requester,
49+
)
4550
from synapse.util.async_helpers import Linearizer
4651
from synapse.util.stringutils import random_string
4752

@@ -185,11 +190,14 @@ def __init__(self, hs: "HomeServer"):
185190
self._auth_handler = hs.get_auth_handler()
186191
self._error_template = hs.config.sso_error_template
187192
self._bad_user_template = hs.config.sso_auth_bad_user_template
193+
self._profile_handler = hs.get_profile_handler()
188194

189195
# The following template is shown after a successful user interactive
190196
# authentication session. It tells the user they can close the window.
191197
self._sso_auth_success_template = hs.config.sso_auth_success_template
192198

199+
self._sso_update_profile_information = hs.config.sso_update_profile_information
200+
193201
# a lock on the mappings
194202
self._mapping_lock = Linearizer(name="sso_user_mapping", clock=hs.get_clock())
195203

@@ -458,6 +466,21 @@ async def complete_sso_login_request(
458466
request.getClientIP(),
459467
)
460468
new_user = True
469+
elif self._sso_update_profile_information:
470+
attributes = await self._call_attribute_mapper(sso_to_matrix_id_mapper)
471+
if attributes.display_name:
472+
user_id_obj = UserID.from_string(user_id)
473+
profile_display_name = await self._profile_handler.get_displayname(
474+
user_id_obj
475+
)
476+
if profile_display_name != attributes.display_name:
477+
requester = create_requester(
478+
user_id,
479+
authenticated_entity=user_id,
480+
)
481+
await self._profile_handler.set_displayname(
482+
user_id_obj, requester, attributes.display_name, True
483+
)
461484

462485
await self._auth_handler.complete_sso_login(
463486
user_id,

0 commit comments

Comments
 (0)