mirror of
https://github.com/element-hq/synapse.git
synced 2025-05-12 00:00:40 -04:00
Do not auto-provision missing users & devices when delegating auth to MAS (#18181)
Since MAS 0.13.0, the provisionning of devices and users is done synchronously and reliably enough that we don't need to auto-provision on the Synapse side anymore. It's important to remove this behaviour if we want to start caching token introspection results.
This commit is contained in:
parent
f2ca2e31f7
commit
74be5cfdbc
1
changelog.d/18181.misc
Normal file
1
changelog.d/18181.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Stop auto-provisionning missing users & devices when delegating auth to Matrix Authentication Service. Requires MAS 0.13.0 or later.
|
@ -39,7 +39,6 @@ from synapse.api.errors import (
|
|||||||
HttpResponseException,
|
HttpResponseException,
|
||||||
InvalidClientTokenError,
|
InvalidClientTokenError,
|
||||||
OAuthInsufficientScopeError,
|
OAuthInsufficientScopeError,
|
||||||
StoreError,
|
|
||||||
SynapseError,
|
SynapseError,
|
||||||
UnrecognizedRequestError,
|
UnrecognizedRequestError,
|
||||||
)
|
)
|
||||||
@ -512,7 +511,7 @@ class MSC3861DelegatedAuth(BaseAuth):
|
|||||||
raise InvalidClientTokenError("No scope in token granting user rights")
|
raise InvalidClientTokenError("No scope in token granting user rights")
|
||||||
|
|
||||||
# Match via the sub claim
|
# Match via the sub claim
|
||||||
sub: Optional[str] = introspection_result.get_sub()
|
sub = introspection_result.get_sub()
|
||||||
if sub is None:
|
if sub is None:
|
||||||
raise InvalidClientTokenError(
|
raise InvalidClientTokenError(
|
||||||
"Invalid sub claim in the introspection result"
|
"Invalid sub claim in the introspection result"
|
||||||
@ -525,29 +524,20 @@ class MSC3861DelegatedAuth(BaseAuth):
|
|||||||
# If we could not find a user via the external_id, it either does not exist,
|
# If we could not find a user via the external_id, it either does not exist,
|
||||||
# or the external_id was never recorded
|
# or the external_id was never recorded
|
||||||
|
|
||||||
# TODO: claim mapping should be configurable
|
username = introspection_result.get_username()
|
||||||
username: Optional[str] = introspection_result.get_username()
|
if username is None:
|
||||||
if username is None or not isinstance(username, str):
|
|
||||||
raise AuthError(
|
raise AuthError(
|
||||||
500,
|
500,
|
||||||
"Invalid username claim in the introspection result",
|
"Invalid username claim in the introspection result",
|
||||||
)
|
)
|
||||||
user_id = UserID(username, self._hostname)
|
user_id = UserID(username, self._hostname)
|
||||||
|
|
||||||
# First try to find a user from the username claim
|
# Try to find a user from the username claim
|
||||||
user_info = await self.store.get_user_by_id(user_id=user_id.to_string())
|
user_info = await self.store.get_user_by_id(user_id=user_id.to_string())
|
||||||
if user_info is None:
|
if user_info is None:
|
||||||
# If the user does not exist, we should create it on the fly
|
raise AuthError(
|
||||||
# TODO: we could use SCIM to provision users ahead of time and listen
|
500,
|
||||||
# for SCIM SET events if those ever become standard:
|
"User not found",
|
||||||
# https://datatracker.ietf.org/doc/html/draft-hunt-scim-notify-00
|
|
||||||
|
|
||||||
# TODO: claim mapping should be configurable
|
|
||||||
# If present, use the name claim as the displayname
|
|
||||||
name: Optional[str] = introspection_result.get_name()
|
|
||||||
|
|
||||||
await self.store.register_user(
|
|
||||||
user_id=user_id.to_string(), create_profile_with_displayname=name
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# And record the sub as external_id
|
# And record the sub as external_id
|
||||||
@ -587,17 +577,10 @@ class MSC3861DelegatedAuth(BaseAuth):
|
|||||||
"Invalid device ID in introspection result",
|
"Invalid device ID in introspection result",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create the device on the fly if it does not exist
|
# Make sure the device exists
|
||||||
try:
|
|
||||||
await self.store.get_device(
|
await self.store.get_device(
|
||||||
user_id=user_id.to_string(), device_id=device_id
|
user_id=user_id.to_string(), device_id=device_id
|
||||||
)
|
)
|
||||||
except StoreError:
|
|
||||||
await self.store.store_device(
|
|
||||||
user_id=user_id.to_string(),
|
|
||||||
device_id=device_id,
|
|
||||||
initial_device_display_name="OIDC-native client",
|
|
||||||
)
|
|
||||||
|
|
||||||
# TODO: there is a few things missing in the requester here, which still need
|
# TODO: there is a few things missing in the requester here, which still need
|
||||||
# to be figured out, like:
|
# to be figured out, like:
|
||||||
|
@ -147,6 +147,16 @@ class MSC3861OAuthDelegation(HomeserverTestCase):
|
|||||||
|
|
||||||
return hs
|
return hs
|
||||||
|
|
||||||
|
def prepare(
|
||||||
|
self, reactor: MemoryReactor, clock: Clock, homeserver: HomeServer
|
||||||
|
) -> None:
|
||||||
|
# Provision the user and the device we use in the tests.
|
||||||
|
store = homeserver.get_datastores().main
|
||||||
|
self.get_success(store.register_user(USER_ID))
|
||||||
|
self.get_success(
|
||||||
|
store.store_device(USER_ID, DEVICE, initial_device_display_name=None)
|
||||||
|
)
|
||||||
|
|
||||||
def _assertParams(self) -> None:
|
def _assertParams(self) -> None:
|
||||||
"""Assert that the request parameters are correct."""
|
"""Assert that the request parameters are correct."""
|
||||||
params = parse_qs(self.http_client.request.call_args[1]["data"].decode("utf-8"))
|
params = parse_qs(self.http_client.request.call_args[1]["data"].decode("utf-8"))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user