server_notice_servlet.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. # Copyright 2019 New Vector Ltd
  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. from typing import TYPE_CHECKING, Optional, Tuple
  15. from synapse.api.constants import EventTypes
  16. from synapse.api.errors import NotFoundError, SynapseError
  17. from synapse.http.server import HttpServer
  18. from synapse.http.servlet import (
  19. RestServlet,
  20. assert_params_in_dict,
  21. parse_json_object_from_request,
  22. )
  23. from synapse.http.site import SynapseRequest
  24. from synapse.rest.admin import assert_requester_is_admin
  25. from synapse.rest.admin._base import admin_patterns
  26. from synapse.rest.client.transactions import HttpTransactionCache
  27. from synapse.types import JsonDict, UserID
  28. if TYPE_CHECKING:
  29. from synapse.server import HomeServer
  30. class SendServerNoticeServlet(RestServlet):
  31. """Servlet which will send a server notice to a given user
  32. POST /_synapse/admin/v1/send_server_notice
  33. {
  34. "user_id": "@target_user:server_name",
  35. "content": {
  36. "msgtype": "m.text",
  37. "body": "This is my message"
  38. }
  39. }
  40. returns:
  41. {
  42. "event_id": "$1895723857jgskldgujpious"
  43. }
  44. """
  45. def __init__(self, hs: "HomeServer"):
  46. self.hs = hs
  47. self.auth = hs.get_auth()
  48. self.server_notices_manager = hs.get_server_notices_manager()
  49. self.admin_handler = hs.get_admin_handler()
  50. self.txns = HttpTransactionCache(hs)
  51. def register(self, json_resource: HttpServer):
  52. PATTERN = "/send_server_notice"
  53. json_resource.register_paths(
  54. "POST", admin_patterns(PATTERN + "$"), self.on_POST, self.__class__.__name__
  55. )
  56. json_resource.register_paths(
  57. "PUT",
  58. admin_patterns(PATTERN + "/(?P<txn_id>[^/]*)$"),
  59. self.on_PUT,
  60. self.__class__.__name__,
  61. )
  62. async def on_POST(
  63. self, request: SynapseRequest, txn_id: Optional[str] = None
  64. ) -> Tuple[int, JsonDict]:
  65. await assert_requester_is_admin(self.auth, request)
  66. body = parse_json_object_from_request(request)
  67. assert_params_in_dict(body, ("user_id", "content"))
  68. event_type = body.get("type", EventTypes.Message)
  69. state_key = body.get("state_key")
  70. # We grab the server notices manager here as its initialisation has a check for worker processes,
  71. # but worker processes still need to initialise SendServerNoticeServlet (as it is part of the
  72. # admin api).
  73. if not self.server_notices_manager.is_enabled():
  74. raise SynapseError(400, "Server notices are not enabled on this server")
  75. target_user = UserID.from_string(body["user_id"])
  76. if not self.hs.is_mine(target_user):
  77. raise SynapseError(400, "Server notices can only be sent to local users")
  78. if not await self.admin_handler.get_user(target_user):
  79. raise NotFoundError("User not found")
  80. event = await self.server_notices_manager.send_notice(
  81. user_id=target_user.to_string(),
  82. type=event_type,
  83. state_key=state_key,
  84. event_content=body["content"],
  85. txn_id=txn_id,
  86. )
  87. return 200, {"event_id": event.event_id}
  88. def on_PUT(self, request: SynapseRequest, txn_id: str) -> Tuple[int, JsonDict]:
  89. return self.txns.fetch_or_execute_request(
  90. request, self.on_POST, request, txn_id
  91. )