From 21a5d6a0b5801a0b9d6a61380a396a2c9687f17e Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Mon, 12 Jul 2021 16:45:06 -0500 Subject: [PATCH] Share validation logic --- synapse/api/auth.py | 37 ++++++++++++++++++++++++++++++---- synapse/rest/client/v1/room.py | 27 +++++++------------------ 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/synapse/api/auth.py b/synapse/api/auth.py index 307f5f9a9463..42476a18e504 100644 --- a/synapse/api/auth.py +++ b/synapse/api/auth.py @@ -240,6 +240,37 @@ async def get_user_by_req( except KeyError: raise MissingClientTokenError() + async def validate_appservice_can_control_user_id( + self, app_service: ApplicationService, user_id: str + ): + """Validates that the app service is allowed to control + the given user. + + Args: + app_service: The app service that controls the user + user_id: The author MXID that the app service is controlling + + Raises: + AuthError: If the application service is not allowed to control the user + (user namespace regex does not match, wrong homeserver, etc) + or if the user has not been registered yet. + """ + + # It's ok if the app service is trying to use the sender from their registration + if app_service.sender == user_id: + pass + # Check to make sure the app service is allowed to control the user + elif not app_service.is_interested_in_user(user_id): + raise AuthError( + 403, + "Application service cannot masquerade as this user (%s)." % user_id, + ) + # Check to make sure the user is already registered on the homeserver + elif not (await self.store.get_user_by_id(user_id)): + raise AuthError( + 403, "Application service has not registered this user (%s)" % user_id + ) + async def _get_appservice_user_id( self, request: Request ) -> Tuple[Optional[str], Optional[ApplicationService]]: @@ -261,13 +292,11 @@ async def _get_appservice_user_id( return app_service.sender, app_service user_id = request.args[b"user_id"][0].decode("utf8") + await self.validate_appservice_can_control_user_id(app_service, user_id) + if app_service.sender == user_id: return app_service.sender, app_service - if not app_service.is_interested_in_user(user_id): - raise AuthError(403, "Application service cannot masquerade as this user.") - if not (await self.store.get_user_by_id(user_id)): - raise AuthError(403, "Application service has not registered this user") return user_id, app_service async def get_user_by_access_token( diff --git a/synapse/rest/client/v1/room.py b/synapse/rest/client/v1/room.py index 7ff4ad6bf5c7..ebf4e3223089 100644 --- a/synapse/rest/client/v1/room.py +++ b/synapse/rest/client/v1/room.py @@ -381,7 +381,7 @@ def _create_insertion_event_dict( return insertion_event - async def _create_requester_from_app_service( + async def _create_requester_for_user_id_from_app_service( self, user_id: str, app_service: ApplicationService ) -> Requester: """Creates a new requester for the given user_id @@ -396,20 +396,7 @@ async def _create_requester_from_app_service( Requester object """ - # It's ok if the app service is trying to use the sender from their registration - if app_service.sender == user_id: - pass - # Check to make sure the app service is allowed to control the user - elif not app_service.is_interested_in_user(user_id): - raise AuthError( - 403, - "Application service cannot masquerade as this user (%s)." % user_id, - ) - # Check to make sure the user is already registered on the homeserver - elif not (await self.store.get_user_by_id(user_id)): - raise AuthError( - 403, "Application service has not registered this user (%s)" % user_id - ) + await self.auth.validate_appservice_can_control_user_id(app_service, user_id) return create_requester(user_id, app_service=app_service) @@ -478,7 +465,7 @@ async def on_POST(self, request, room_id): if event_dict["type"] == EventTypes.Member: membership = event_dict["content"].get("membership", None) event_id, _ = await self.room_member_handler.update_membership( - await self._create_requester_from_app_service( + await self._create_requester_for_user_id_from_app_service( state_event["sender"], requester.app_service ), target=UserID.from_string(event_dict["state_key"]), @@ -500,7 +487,7 @@ async def on_POST(self, request, room_id): event, _, ) = await self.event_creation_handler.create_and_send_nonmember_event( - await self._create_requester_from_app_service( + await self._create_requester_for_user_id_from_app_service( state_event["sender"], requester.app_service ), event_dict, @@ -550,7 +537,7 @@ async def on_POST(self, request, room_id): base_insertion_event, _, ) = await self.event_creation_handler.create_and_send_nonmember_event( - await self._create_requester_from_app_service( + await self._create_requester_for_user_id_from_app_service( base_insertion_event_dict["sender"], requester.app_service, ), @@ -602,7 +589,7 @@ async def on_POST(self, request, room_id): } event, context = await self.event_creation_handler.create_event( - await self._create_requester_from_app_service( + await self._create_requester_for_user_id_from_app_service( ev["sender"], requester.app_service ), event_dict, @@ -634,7 +621,7 @@ async def on_POST(self, request, room_id): # where topological_ordering is just depth. for (event, context) in reversed(events_to_persist): ev = await self.event_creation_handler.handle_new_client_event( - await self._create_requester_from_app_service( + await self._create_requester_for_user_id_from_app_service( event["sender"], requester.app_service ), event=event,