選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

331 行
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. import platform
  18. from http import HTTPStatus
  19. from typing import TYPE_CHECKING, Optional, Tuple
  20. from synapse.api.errors import Codes, NotFoundError, SynapseError
  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.oidc import OIDCTokenRevocationRestServlet
  48. from synapse.rest.admin.registration_tokens import (
  49. ListRegistrationTokensRestServlet,
  50. NewRegistrationTokenRestServlet,
  51. RegistrationTokenRestServlet,
  52. )
  53. from synapse.rest.admin.rooms import (
  54. BlockRoomRestServlet,
  55. DeleteRoomStatusByDeleteIdRestServlet,
  56. DeleteRoomStatusByRoomIdRestServlet,
  57. ForwardExtremitiesRestServlet,
  58. JoinRoomAliasServlet,
  59. ListRoomRestServlet,
  60. MakeRoomAdminRestServlet,
  61. RoomEventContextServlet,
  62. RoomMembersRestServlet,
  63. RoomMessagesRestServlet,
  64. RoomRestServlet,
  65. RoomRestV2Servlet,
  66. RoomStateRestServlet,
  67. RoomTimestampToEventRestServlet,
  68. )
  69. from synapse.rest.admin.server_notice_servlet import SendServerNoticeServlet
  70. from synapse.rest.admin.statistics import (
  71. LargestRoomsStatistics,
  72. UserMediaStatisticsRestServlet,
  73. )
  74. from synapse.rest.admin.username_available import UsernameAvailableRestServlet
  75. from synapse.rest.admin.users import (
  76. AccountDataRestServlet,
  77. AccountValidityRenewServlet,
  78. DeactivateAccountRestServlet,
  79. PushersRestServlet,
  80. RateLimitRestServlet,
  81. ResetPasswordRestServlet,
  82. SearchUsersRestServlet,
  83. ShadowBanRestServlet,
  84. UserAdminServlet,
  85. UserByExternalId,
  86. UserByThreePid,
  87. UserMembershipRestServlet,
  88. UserRegisterServlet,
  89. UserRestServletV2,
  90. UsersRestServletV2,
  91. UserTokenRestServlet,
  92. WhoisRestServlet,
  93. )
  94. from synapse.types import JsonDict, RoomStreamToken
  95. from synapse.util import SYNAPSE_VERSION
  96. if TYPE_CHECKING:
  97. from synapse.server import HomeServer
  98. logger = logging.getLogger(__name__)
  99. class VersionServlet(RestServlet):
  100. PATTERNS = admin_patterns("/server_version$")
  101. def __init__(self, hs: "HomeServer"):
  102. self.res = {
  103. "server_version": SYNAPSE_VERSION,
  104. "python_version": platform.python_version(),
  105. }
  106. def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
  107. return HTTPStatus.OK, self.res
  108. class PurgeHistoryRestServlet(RestServlet):
  109. PATTERNS = admin_patterns(
  110. "/purge_history/(?P<room_id>[^/]*)(/(?P<event_id>[^/]*))?$"
  111. )
  112. def __init__(self, hs: "HomeServer"):
  113. self.pagination_handler = hs.get_pagination_handler()
  114. self.store = hs.get_datastores().main
  115. self.auth = hs.get_auth()
  116. async def on_POST(
  117. self, request: SynapseRequest, room_id: str, event_id: Optional[str]
  118. ) -> Tuple[int, JsonDict]:
  119. await assert_requester_is_admin(self.auth, request)
  120. body = parse_json_object_from_request(request, allow_empty_body=True)
  121. delete_local_events = bool(body.get("delete_local_events", False))
  122. # establish the topological ordering we should keep events from. The
  123. # user can provide an event_id in the URL or the request body, or can
  124. # provide a timestamp in the request body.
  125. if event_id is None:
  126. event_id = body.get("purge_up_to_event_id")
  127. if event_id is not None:
  128. event = await self.store.get_event(event_id)
  129. if event.room_id != room_id:
  130. raise SynapseError(HTTPStatus.BAD_REQUEST, "Event is for wrong room.")
  131. # RoomStreamToken expects [int] not Optional[int]
  132. assert event.internal_metadata.stream_ordering is not None
  133. room_token = RoomStreamToken(
  134. event.depth, event.internal_metadata.stream_ordering
  135. )
  136. token = await room_token.to_string(self.store)
  137. logger.info("[purge] purging up to token %s (event_id %s)", token, event_id)
  138. elif "purge_up_to_ts" in body:
  139. ts = body["purge_up_to_ts"]
  140. if type(ts) is not int: # noqa: E721
  141. raise SynapseError(
  142. HTTPStatus.BAD_REQUEST,
  143. "purge_up_to_ts must be an int",
  144. errcode=Codes.BAD_JSON,
  145. )
  146. stream_ordering = await self.store.find_first_stream_ordering_after_ts(ts)
  147. r = await self.store.get_room_event_before_stream_ordering(
  148. room_id, stream_ordering
  149. )
  150. if not r:
  151. logger.warning(
  152. "[purge] purging events not possible: No event found "
  153. "(received_ts %i => stream_ordering %i)",
  154. ts,
  155. stream_ordering,
  156. )
  157. raise SynapseError(
  158. HTTPStatus.NOT_FOUND,
  159. "there is no event to be purged",
  160. errcode=Codes.NOT_FOUND,
  161. )
  162. (stream, topo, _event_id) = r
  163. token = "t%d-%d" % (topo, stream)
  164. logger.info(
  165. "[purge] purging up to token %s (received_ts %i => "
  166. "stream_ordering %i)",
  167. token,
  168. ts,
  169. stream_ordering,
  170. )
  171. else:
  172. raise SynapseError(
  173. HTTPStatus.BAD_REQUEST,
  174. "must specify purge_up_to_event_id or purge_up_to_ts",
  175. errcode=Codes.BAD_JSON,
  176. )
  177. purge_id = self.pagination_handler.start_purge_history(
  178. room_id, token, delete_local_events=delete_local_events
  179. )
  180. return HTTPStatus.OK, {"purge_id": purge_id}
  181. class PurgeHistoryStatusRestServlet(RestServlet):
  182. PATTERNS = admin_patterns("/purge_history_status/(?P<purge_id>[^/]*)$")
  183. def __init__(self, hs: "HomeServer"):
  184. self.pagination_handler = hs.get_pagination_handler()
  185. self.auth = hs.get_auth()
  186. async def on_GET(
  187. self, request: SynapseRequest, purge_id: str
  188. ) -> Tuple[int, JsonDict]:
  189. await assert_requester_is_admin(self.auth, request)
  190. purge_status = self.pagination_handler.get_purge_status(purge_id)
  191. if purge_status is None:
  192. raise NotFoundError("purge id '%s' not found" % purge_id)
  193. return HTTPStatus.OK, purge_status.asdict()
  194. ########################################################################################
  195. #
  196. # please don't add more servlets here: this file is already long and unwieldy. Put
  197. # them in separate files within the 'admin' package.
  198. #
  199. ########################################################################################
  200. class AdminRestResource(JsonResource):
  201. """The REST resource which gets mounted at /_synapse/admin"""
  202. def __init__(self, hs: "HomeServer"):
  203. JsonResource.__init__(self, hs, canonical_json=False)
  204. register_servlets(hs, self)
  205. def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None:
  206. """
  207. Register all the admin servlets.
  208. """
  209. # Admin servlets aren't registered on workers.
  210. if hs.config.worker.worker_app is not None:
  211. return
  212. register_servlets_for_client_rest_resource(hs, http_server)
  213. BlockRoomRestServlet(hs).register(http_server)
  214. ListRoomRestServlet(hs).register(http_server)
  215. RoomStateRestServlet(hs).register(http_server)
  216. RoomRestServlet(hs).register(http_server)
  217. RoomRestV2Servlet(hs).register(http_server)
  218. RoomMembersRestServlet(hs).register(http_server)
  219. DeleteRoomStatusByDeleteIdRestServlet(hs).register(http_server)
  220. DeleteRoomStatusByRoomIdRestServlet(hs).register(http_server)
  221. JoinRoomAliasServlet(hs).register(http_server)
  222. VersionServlet(hs).register(http_server)
  223. if not hs.config.experimental.msc3861.enabled:
  224. UserAdminServlet(hs).register(http_server)
  225. UserMembershipRestServlet(hs).register(http_server)
  226. if not hs.config.experimental.msc3861.enabled:
  227. UserTokenRestServlet(hs).register(http_server)
  228. UserRestServletV2(hs).register(http_server)
  229. UsersRestServletV2(hs).register(http_server)
  230. UserMediaStatisticsRestServlet(hs).register(http_server)
  231. LargestRoomsStatistics(hs).register(http_server)
  232. EventReportDetailRestServlet(hs).register(http_server)
  233. EventReportsRestServlet(hs).register(http_server)
  234. AccountDataRestServlet(hs).register(http_server)
  235. PushersRestServlet(hs).register(http_server)
  236. MakeRoomAdminRestServlet(hs).register(http_server)
  237. ShadowBanRestServlet(hs).register(http_server)
  238. ForwardExtremitiesRestServlet(hs).register(http_server)
  239. RoomEventContextServlet(hs).register(http_server)
  240. RateLimitRestServlet(hs).register(http_server)
  241. UsernameAvailableRestServlet(hs).register(http_server)
  242. if not hs.config.experimental.msc3861.enabled:
  243. ListRegistrationTokensRestServlet(hs).register(http_server)
  244. NewRegistrationTokenRestServlet(hs).register(http_server)
  245. RegistrationTokenRestServlet(hs).register(http_server)
  246. DestinationMembershipRestServlet(hs).register(http_server)
  247. DestinationResetConnectionRestServlet(hs).register(http_server)
  248. DestinationRestServlet(hs).register(http_server)
  249. ListDestinationsRestServlet(hs).register(http_server)
  250. RoomMessagesRestServlet(hs).register(http_server)
  251. RoomTimestampToEventRestServlet(hs).register(http_server)
  252. UserByExternalId(hs).register(http_server)
  253. UserByThreePid(hs).register(http_server)
  254. DeviceRestServlet(hs).register(http_server)
  255. DevicesRestServlet(hs).register(http_server)
  256. DeleteDevicesRestServlet(hs).register(http_server)
  257. SendServerNoticeServlet(hs).register(http_server)
  258. BackgroundUpdateEnabledRestServlet(hs).register(http_server)
  259. BackgroundUpdateRestServlet(hs).register(http_server)
  260. BackgroundUpdateStartJobRestServlet(hs).register(http_server)
  261. ExperimentalFeaturesRestServlet(hs).register(http_server)
  262. if hs.config.experimental.msc3861.enabled:
  263. OIDCTokenRevocationRestServlet(hs).register(http_server)
  264. def register_servlets_for_client_rest_resource(
  265. hs: "HomeServer", http_server: HttpServer
  266. ) -> None:
  267. """Register only the servlets which need to be exposed on /_matrix/client/xxx"""
  268. WhoisRestServlet(hs).register(http_server)
  269. PurgeHistoryStatusRestServlet(hs).register(http_server)
  270. PurgeHistoryRestServlet(hs).register(http_server)
  271. # The following resources can only be run on the main process.
  272. if hs.config.worker.worker_app is None:
  273. DeactivateAccountRestServlet(hs).register(http_server)
  274. if not hs.config.experimental.msc3861.enabled:
  275. ResetPasswordRestServlet(hs).register(http_server)
  276. SearchUsersRestServlet(hs).register(http_server)
  277. if not hs.config.experimental.msc3861.enabled:
  278. UserRegisterServlet(hs).register(http_server)
  279. AccountValidityRenewServlet(hs).register(http_server)
  280. # Load the media repo ones if we're using them. Otherwise load the servlets which
  281. # don't need a media repo (typically readonly admin APIs).
  282. if hs.config.media.can_load_media_repo:
  283. register_servlets_for_media_repo(hs, http_server)
  284. else:
  285. ListMediaInRoom(hs).register(http_server)
  286. # don't add more things here: new servlets should only be exposed on
  287. # /_synapse/admin so should not go here. Instead register them in AdminRestResource.