room_member_worker.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. # Copyright 2018-2021 The Matrix.org Foundation C.I.C.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import logging
  15. from typing import TYPE_CHECKING, List, Optional, Tuple
  16. from synapse.api.errors import SynapseError
  17. from synapse.handlers.room_member import RoomMemberHandler
  18. from synapse.replication.http.membership import (
  19. ReplicationRemoteJoinRestServlet as ReplRemoteJoin,
  20. ReplicationRemoteKnockRestServlet as ReplRemoteKnock,
  21. ReplicationRemoteRejectInviteRestServlet as ReplRejectInvite,
  22. ReplicationRemoteRescindKnockRestServlet as ReplRescindKnock,
  23. ReplicationUserJoinedLeftRoomRestServlet as ReplJoinedLeft,
  24. )
  25. from synapse.types import JsonDict, Requester, UserID
  26. if TYPE_CHECKING:
  27. from synapse.server import HomeServer
  28. logger = logging.getLogger(__name__)
  29. class RoomMemberWorkerHandler(RoomMemberHandler):
  30. def __init__(self, hs: "HomeServer"):
  31. super().__init__(hs)
  32. self._remote_join_client = ReplRemoteJoin.make_client(hs)
  33. self._remote_knock_client = ReplRemoteKnock.make_client(hs)
  34. self._remote_reject_client = ReplRejectInvite.make_client(hs)
  35. self._remote_rescind_client = ReplRescindKnock.make_client(hs)
  36. self._notify_change_client = ReplJoinedLeft.make_client(hs)
  37. async def _remote_join(
  38. self,
  39. requester: Requester,
  40. remote_room_hosts: List[str],
  41. room_id: str,
  42. user: UserID,
  43. content: dict,
  44. ) -> Tuple[str, int]:
  45. """Implements RoomMemberHandler._remote_join"""
  46. if len(remote_room_hosts) == 0:
  47. raise SynapseError(404, "No known servers")
  48. ret = await self._remote_join_client(
  49. requester=requester,
  50. remote_room_hosts=remote_room_hosts,
  51. room_id=room_id,
  52. user_id=user.to_string(),
  53. content=content,
  54. )
  55. return ret["event_id"], ret["stream_id"]
  56. async def remote_reject_invite(
  57. self,
  58. invite_event_id: str,
  59. txn_id: Optional[str],
  60. requester: Requester,
  61. content: dict,
  62. ) -> Tuple[str, int]:
  63. """
  64. Rejects an out-of-band invite received from a remote user
  65. Implements RoomMemberHandler.remote_reject_invite
  66. """
  67. ret = await self._remote_reject_client(
  68. invite_event_id=invite_event_id,
  69. txn_id=txn_id,
  70. requester=requester,
  71. content=content,
  72. )
  73. return ret["event_id"], ret["stream_id"]
  74. async def remote_rescind_knock(
  75. self,
  76. knock_event_id: str,
  77. txn_id: Optional[str],
  78. requester: Requester,
  79. content: JsonDict,
  80. ) -> Tuple[str, int]:
  81. """
  82. Rescinds a local knock made on a remote room
  83. Args:
  84. knock_event_id: the knock event
  85. txn_id: optional transaction ID supplied by the client
  86. requester: user making the request, according to the access token
  87. content: additional content to include in the leave event.
  88. Normally an empty dict.
  89. Returns:
  90. A tuple containing (event_id, stream_id of the leave event)
  91. """
  92. ret = await self._remote_rescind_client(
  93. knock_event_id=knock_event_id,
  94. txn_id=txn_id,
  95. requester=requester,
  96. content=content,
  97. )
  98. return ret["event_id"], ret["stream_id"]
  99. async def remote_knock(
  100. self,
  101. remote_room_hosts: List[str],
  102. room_id: str,
  103. user: UserID,
  104. content: dict,
  105. ) -> Tuple[str, int]:
  106. """Sends a knock to a room.
  107. Implements RoomMemberHandler.remote_knock
  108. """
  109. ret = await self._remote_knock_client(
  110. remote_room_hosts=remote_room_hosts,
  111. room_id=room_id,
  112. user=user,
  113. content=content,
  114. )
  115. return ret["event_id"], ret["stream_id"]
  116. async def _user_left_room(self, target: UserID, room_id: str) -> None:
  117. """Implements RoomMemberHandler._user_left_room"""
  118. await self._notify_change_client(
  119. user_id=target.to_string(), room_id=room_id, change="left"
  120. )
  121. async def forget(self, target: UserID, room_id: str) -> None:
  122. raise RuntimeError("Cannot forget rooms on workers.")