-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Allow OIDC for existing users #8180
Allow OIDC for existing users #8180
Conversation
@OmmyZhang Can you merge develop in again? We had a broken test that got fixed an hour or so ago. Sorry about that! 👍 |
This replaces #8178 (just to cross-link). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please could you separate this into two PRs: one for the gitlab fix, and the other for the existing users?
@richvdh Sure! |
I think the changes for GitLab are already up as #7658. |
Great. Now things are easier. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for this! A few comments.
synapse/handlers/oidc_handler.py
Outdated
raise MappingException( | ||
"mxid '{}' is already taken".format(user_id.to_string()) | ||
if self._merge_with_existing_users: | ||
registered_user_id = user_id.to_string() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is not a given that the registered user id is the same as the id we looked up (note: "_case_insensitive".) get_users_by_id_case_insensitive
returns a dict of potiental matches. please use it.
synapse/handlers/oidc_handler.py
Outdated
if self._merge_with_existing_users: | ||
registered_user_id = user_id.to_string() | ||
else: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the docstring on this method says:
If a user already exists with the mxid we've mapped, raise an exception.
Please update it.
changelog.d/8180.feature
Outdated
@@ -0,0 +1 @@ | |||
This adds config option that allows merging OpenID Connect users with existing users. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This adds config option that allows merging OpenID Connect users with existing users. | |
Add a configuration option that allows existing users to log in with OpenID Connect. Contributed by @BBBSnowball and @OmmyZhang. |
synapse/config/oidc_config.py
Outdated
@@ -158,6 +161,10 @@ def generate_config_section(self, config_dir_path, server_name, **kwargs): | |||
# | |||
#skip_verification: true | |||
|
|||
# if user already exists, add oidc token to that account instead of failing. Defaults to false. | |||
# | |||
#merge_with_existing_users: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't seem a great name for this option. How about allow_existing_users
?
synapse/config/oidc_config.py
Outdated
# if user already exists, add oidc token to that account instead of failing. Defaults to false. | ||
# | ||
#merge_with_existing_users: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/matrix-org/synapse/blob/develop/docs/code_style.md#configuration-file-format says:
For boolean (on/off) options, convention is that this example should be the opposite to the default (so the comment will end with "Uncomment the following to enable [or disable] ."
please could you follow the conventions.
…ging-oidc-with-existing-users
@richvdh thanks for your suggestions. Now it's updated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is close! Just a couple more details to work out!
if self._allow_existing_users: | ||
registered_user_id = next(iter(matches)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can matches have multiple items? Should we still error in that case? It feels arbitrary to choose the first one. At the very least I think we should log something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there can't be more than one item as the same (case insensitive) usernames are not allowed. This is also why we need get_users_by_id_case_insensitive
.
synapse/synapse/handlers/register.py
Lines 111 to 116 in efb6b66
users = await self.store.get_users_by_id_case_insensitive(user_id) | |
if users: | |
if not guest_access_token: | |
raise SynapseError( | |
400, "User ID already taken.", errcode=Codes.USER_IN_USE | |
) |
Maybe we should log something if there're more than one, to show that something goes wrong? But it's a little strange. If we do, we should also do this in many other places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I find auth
considers more. But I still can't understand why there can be multiple matches. Maybe for backward compatibility?
synapse/synapse/handlers/auth.py
Lines 753 to 758 in efb6b66
elif user_id in user_infos: | |
# multiple matches, but one is exact | |
result = (user_id, user_infos[user_id]) | |
else: | |
# multiple matches, none of them exact | |
logger.warning( |
If a user already exists with the mxid we've mapped and allow_existing_users | ||
is disabled , raise an exception. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a user already exists with the mxid we've mapped and allow_existing_users | |
is disabled , raise an exception. | |
If a user already exists with the mxid we've mapped and allow_existing_users | |
is disabled, raise an exception. |
@@ -158,6 +159,10 @@ def generate_config_section(self, config_dir_path, server_name, **kwargs): | |||
# | |||
#skip_verification: true | |||
|
|||
# Uncomment to add oidc token to the account instead of failing when user already exists. Defaults to false. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this comment is very descriptive -- what's the token that's being added? Why would I turn this on?
# Uncomment to add oidc token to the account instead of failing when user already exists. Defaults to false. | |
# Uncomment to allow a user logging in via OIDC to match a pre-existing account instead | |
# of failing. This could be used if switching from password logins to OIDC. Defaults to false. |
Sorry I have to create a new PR as I realized that this branch can't be auto-updated after I delete my repository and re-fork from #8345 will replace this one. |
Allows merging oidc with existing users and allows always using userinfo endpoint.
a patch by @BBBSnowball
fix #7633 and #8155