Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

334 Zeilen
13 KiB

  1. # Copyright 2014-2016 OpenMarket Ltd
  2. # Copyright 2018-2019 New Vector Ltd
  3. # Copyright 2020, 2021 The Matrix.org Foundation C.I.C.
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. import logging
  17. from http import HTTPStatus
  18. from typing import TYPE_CHECKING, Optional, Tuple
  19. from synapse.api.errors import Codes, NotFoundError, SynapseError
  20. from synapse.handlers.pagination import PURGE_HISTORY_ACTION_NAME
  21. from synapse.http.server import HttpServer, JsonResource
  22. from synapse.http.servlet import RestServlet, parse_json_object_from_request
  23. from synapse.http.site import SynapseRequest
  24. from synapse.rest.admin._base import admin_patterns, assert_requester_is_admin
  25. from synapse.rest.admin.background_updates import (
  26. BackgroundUpdateEnabledRestServlet,
  27. BackgroundUpdateRestServlet,
  28. BackgroundUpdateStartJobRestServlet,
  29. )
  30. from synapse.rest.admin.devices import (
  31. DeleteDevicesRestServlet,
  32. DeviceRestServlet,
  33. DevicesRestServlet,
  34. )
  35. from synapse.rest.admin.event_reports import (
  36. EventReportDetailRestServlet,
  37. EventReportsRestServlet,
  38. )
  39. from synapse.rest.admin.experimental_features import ExperimentalFeaturesRestServlet
  40. from synapse.rest.admin.federation import (
  41. DestinationMembershipRestServlet,
  42. DestinationResetConnectionRestServlet,
  43. DestinationRestServlet,
  44. ListDestinationsRestServlet,
  45. )
  46. from synapse.rest.admin.media import ListMediaInRoom, register_servlets_for_media_repo
  47. from synapse.rest.admin.registration_tokens import (
  48. ListRegistrationTokensRestServlet,
  49. NewRegistrationTokenRestServlet,
  50. RegistrationTokenRestServlet,
  51. )
  52. from synapse.rest.admin.rooms import (
  53. BlockRoomRestServlet,
  54. DeleteRoomStatusByDeleteIdRestServlet,
  55. DeleteRoomStatusByRoomIdRestServlet,
  56. ForwardExtremitiesRestServlet,
  57. JoinRoomAliasServlet,
  58. ListRoomRestServlet,
  59. MakeRoomAdminRestServlet,
  60. RoomEventContextServlet,
  61. RoomMembersRestServlet,
  62. RoomMessagesRestServlet,
  63. RoomRestServlet,
  64. RoomRestV2Servlet,
  65. RoomStateRestServlet,
  66. RoomTimestampToEventRestServlet,
  67. )
  68. from synapse.rest.admin.server_notice_servlet import SendServerNoticeServlet
  69. from synapse.rest.admin.statistics import (
  70. LargestRoomsStatistics,
  71. UserMediaStatisticsRestServlet,
  72. )
  73. from synapse.rest.admin.username_available import UsernameAvailableRestServlet
  74. from synapse.rest.admin.users import (
  75. AccountDataRestServlet,
  76. AccountValidityRenewServlet,
  77. DeactivateAccountRestServlet,
  78. PushersRestServlet,
  79. RateLimitRestServlet,
  80. ResetPasswordRestServlet,
  81. SearchUsersRestServlet,
  82. ShadowBanRestServlet,
  83. UserAdminServlet,
  84. UserByExternalId,
  85. UserByThreePid,
  86. UserMembershipRestServlet,
  87. UserRegisterServlet,
  88. UserRestServletV2,
  89. UsersRestServletV2,
  90. UserTokenRestServlet,
  91. WhoisRestServlet,
  92. )
  93. from synapse.types import JsonDict, RoomStreamToken, TaskStatus
  94. from synapse.util import SYNAPSE_VERSION
  95. if TYPE_CHECKING:
  96. from synapse.server import HomeServer
  97. logger = logging.getLogger(__name__)
  98. class VersionServlet(RestServlet):
  99. PATTERNS = admin_patterns("/server_version$")
  100. def __init__(self, hs: "HomeServer"):
  101. self.res = {"server_version": SYNAPSE_VERSION}
  102. def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
  103. return HTTPStatus.OK, self.res
  104. class PurgeHistoryRestServlet(RestServlet):
  105. PATTERNS = admin_patterns(
  106. "/purge_history/(?P<room_id>[^/]*)(/(?P<event_id>[^/]*))?$"
  107. )
  108. def __init__(self, hs: "HomeServer"):
  109. self.pagination_handler = hs.get_pagination_handler()
  110. self.store = hs.get_datastores().main
  111. self.auth = hs.get_auth()
  112. async def on_POST(
  113. self, request: SynapseRequest, room_id: str, event_id: Optional[str]
  114. ) -> Tuple[int, JsonDict]:
  115. await assert_requester_is_admin(self.auth, request)
  116. body = parse_json_object_from_request(request, allow_empty_body=True)
  117. delete_local_events = bool(body.get("delete_local_events", False))
  118. # establish the topological ordering we should keep events from. The
  119. # user can provide an event_id in the URL or the request body, or can
  120. # provide a timestamp in the request body.
  121. if event_id is None:
  122. event_id = body.get("purge_up_to_event_id")
  123. if event_id is not None:
  124. event = await self.store.get_event(event_id)
  125. if event.room_id != room_id:
  126. raise SynapseError(HTTPStatus.BAD_REQUEST, "Event is for wrong room.")
  127. # RoomStreamToken expects [int] not Optional[int]
  128. assert event.internal_metadata.stream_ordering is not None
  129. room_token = RoomStreamToken(
  130. event.depth, event.internal_metadata.stream_ordering
  131. )
  132. token = await room_token.to_string(self.store)
  133. logger.info("[purge] purging up to token %s (event_id %s)", token, event_id)
  134. elif "purge_up_to_ts" in body:
  135. ts = body["purge_up_to_ts"]
  136. if type(ts) is not int: # noqa: E721
  137. raise SynapseError(
  138. HTTPStatus.BAD_REQUEST,
  139. "purge_up_to_ts must be an int",
  140. errcode=Codes.BAD_JSON,
  141. )
  142. stream_ordering = await self.store.find_first_stream_ordering_after_ts(ts)
  143. r = await self.store.get_room_event_before_stream_ordering(
  144. room_id, stream_ordering
  145. )
  146. if not r:
  147. logger.warning(
  148. "[purge] purging events not possible: No event found "
  149. "(received_ts %i => stream_ordering %i)",
  150. ts,
  151. stream_ordering,
  152. )
  153. raise SynapseError(
  154. HTTPStatus.NOT_FOUND,
  155. "there is no event to be purged",
  156. errcode=Codes.NOT_FOUND,
  157. )
  158. (stream, topo, _event_id) = r
  159. token = "t%d-%d" % (topo, stream)
  160. logger.info(
  161. "[purge] purging up to token %s (received_ts %i => "
  162. "stream_ordering %i)",
  163. token,
  164. ts,
  165. stream_ordering,
  166. )
  167. else:
  168. raise SynapseError(
  169. HTTPStatus.BAD_REQUEST,
  170. "must specify purge_up_to_event_id or purge_up_to_ts",
  171. errcode=Codes.BAD_JSON,
  172. )
  173. purge_id = await self.pagination_handler.start_purge_history(
  174. room_id, token, delete_local_events=delete_local_events
  175. )
  176. return HTTPStatus.OK, {"purge_id": purge_id}
  177. class PurgeHistoryStatusRestServlet(RestServlet):
  178. PATTERNS = admin_patterns("/purge_history_status/(?P<purge_id>[^/]*)$")
  179. def __init__(self, hs: "HomeServer"):
  180. self.pagination_handler = hs.get_pagination_handler()
  181. self.auth = hs.get_auth()
  182. async def on_GET(
  183. self, request: SynapseRequest, purge_id: str
  184. ) -> Tuple[int, JsonDict]:
  185. await assert_requester_is_admin(self.auth, request)
  186. purge_task = await self.pagination_handler.get_delete_task(purge_id)
  187. if purge_task is None or purge_task.action != PURGE_HISTORY_ACTION_NAME:
  188. raise NotFoundError("purge id '%s' not found" % purge_id)
  189. result: JsonDict = {
  190. "status": purge_task.status
  191. if purge_task.status == TaskStatus.COMPLETE
  192. or purge_task.status == TaskStatus.FAILED
  193. else "active",
  194. }
  195. if purge_task.error:
  196. result["error"] = purge_task.error
  197. return HTTPStatus.OK, result
  198. ########################################################################################
  199. #
  200. # please don't add more servlets here: this file is already long and unwieldy. Put
  201. # them in separate files within the 'admin' package.
  202. #
  203. ########################################################################################
  204. class AdminRestResource(JsonResource):
  205. """The REST resource which gets mounted at /_synapse/admin"""
  206. def __init__(self, hs: "HomeServer"):
  207. JsonResource.__init__(self, hs, canonical_json=False)
  208. register_servlets(hs, self)
  209. def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None:
  210. """
  211. Register all the admin servlets.
  212. """
  213. # Admin servlets aren't registered on workers.
  214. if hs.config.worker.worker_app is not None:
  215. return
  216. register_servlets_for_client_rest_resource(hs, http_server)
  217. BlockRoomRestServlet(hs).register(http_server)
  218. ListRoomRestServlet(hs).register(http_server)
  219. RoomStateRestServlet(hs).register(http_server)
  220. RoomRestServlet(hs).register(http_server)
  221. RoomRestV2Servlet(hs).register(http_server)
  222. RoomMembersRestServlet(hs).register(http_server)
  223. DeleteRoomStatusByDeleteIdRestServlet(hs).register(http_server)
  224. DeleteRoomStatusByRoomIdRestServlet(hs).register(http_server)
  225. JoinRoomAliasServlet(hs).register(http_server)
  226. VersionServlet(hs).register(http_server)
  227. if not hs.config.experimental.msc3861.enabled:
  228. UserAdminServlet(hs).register(http_server)
  229. UserMembershipRestServlet(hs).register(http_server)
  230. if not hs.config.experimental.msc3861.enabled:
  231. UserTokenRestServlet(hs).register(http_server)
  232. UserRestServletV2(hs).register(http_server)
  233. UsersRestServletV2(hs).register(http_server)
  234. UserMediaStatisticsRestServlet(hs).register(http_server)
  235. LargestRoomsStatistics(hs).register(http_server)
  236. EventReportDetailRestServlet(hs).register(http_server)
  237. EventReportsRestServlet(hs).register(http_server)
  238. AccountDataRestServlet(hs).register(http_server)
  239. PushersRestServlet(hs).register(http_server)
  240. MakeRoomAdminRestServlet(hs).register(http_server)
  241. ShadowBanRestServlet(hs).register(http_server)
  242. ForwardExtremitiesRestServlet(hs).register(http_server)
  243. RoomEventContextServlet(hs).register(http_server)
  244. RateLimitRestServlet(hs).register(http_server)
  245. UsernameAvailableRestServlet(hs).register(http_server)
  246. if not hs.config.experimental.msc3861.enabled:
  247. ListRegistrationTokensRestServlet(hs).register(http_server)
  248. NewRegistrationTokenRestServlet(hs).register(http_server)
  249. RegistrationTokenRestServlet(hs).register(http_server)
  250. DestinationMembershipRestServlet(hs).register(http_server)
  251. DestinationResetConnectionRestServlet(hs).register(http_server)
  252. DestinationRestServlet(hs).register(http_server)
  253. ListDestinationsRestServlet(hs).register(http_server)
  254. RoomMessagesRestServlet(hs).register(http_server)
  255. RoomTimestampToEventRestServlet(hs).register(http_server)
  256. UserByExternalId(hs).register(http_server)
  257. UserByThreePid(hs).register(http_server)
  258. DeviceRestServlet(hs).register(http_server)
  259. DevicesRestServlet(hs).register(http_server)
  260. DeleteDevicesRestServlet(hs).register(http_server)
  261. SendServerNoticeServlet(hs).register(http_server)
  262. BackgroundUpdateEnabledRestServlet(hs).register(http_server)
  263. BackgroundUpdateRestServlet(hs).register(http_server)
  264. BackgroundUpdateStartJobRestServlet(hs).register(http_server)
  265. ExperimentalFeaturesRestServlet(hs).register(http_server)
  266. def register_servlets_for_client_rest_resource(
  267. hs: "HomeServer", http_server: HttpServer
  268. ) -> None:
  269. """Register only the servlets which need to be exposed on /_matrix/client/xxx"""
  270. WhoisRestServlet(hs).register(http_server)
  271. PurgeHistoryStatusRestServlet(hs).register(http_server)
  272. PurgeHistoryRestServlet(hs).register(http_server)
  273. # The following resources can only be run on the main process.
  274. if hs.config.worker.worker_app is None:
  275. DeactivateAccountRestServlet(hs).register(http_server)
  276. if not hs.config.experimental.msc3861.enabled:
  277. ResetPasswordRestServlet(hs).register(http_server)
  278. SearchUsersRestServlet(hs).register(http_server)
  279. if not hs.config.experimental.msc3861.enabled:
  280. UserRegisterServlet(hs).register(http_server)
  281. AccountValidityRenewServlet(hs).register(http_server)
  282. # Load the media repo ones if we're using them. Otherwise load the servlets which
  283. # don't need a media repo (typically readonly admin APIs).
  284. if hs.config.media.can_load_media_repo:
  285. register_servlets_for_media_repo(hs, http_server)
  286. else:
  287. ListMediaInRoom(hs).register(http_server)
  288. # don't add more things here: new servlets should only be exposed on
  289. # /_synapse/admin so should not go here. Instead register them in AdminRestResource.