admin.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2014-2016 OpenMarket Ltd
  3. # Copyright 2018 New Vector Ltd
  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 hashlib
  17. import hmac
  18. import logging
  19. from six.moves import http_client
  20. from twisted.internet import defer
  21. from synapse.api.constants import Membership
  22. from synapse.api.errors import AuthError, Codes, NotFoundError, SynapseError
  23. from synapse.http.servlet import (
  24. assert_params_in_dict,
  25. parse_integer,
  26. parse_json_object_from_request,
  27. parse_string,
  28. )
  29. from synapse.types import UserID, create_requester
  30. from .base import ClientV1RestServlet, client_path_patterns
  31. logger = logging.getLogger(__name__)
  32. class UsersRestServlet(ClientV1RestServlet):
  33. PATTERNS = client_path_patterns("/admin/users/(?P<user_id>[^/]*)")
  34. def __init__(self, hs):
  35. super(UsersRestServlet, self).__init__(hs)
  36. self.handlers = hs.get_handlers()
  37. @defer.inlineCallbacks
  38. def on_GET(self, request, user_id):
  39. target_user = UserID.from_string(user_id)
  40. requester = yield self.auth.get_user_by_req(request)
  41. is_admin = yield self.auth.is_server_admin(requester.user)
  42. if not is_admin:
  43. raise AuthError(403, "You are not a server admin")
  44. # To allow all users to get the users list
  45. # if not is_admin and target_user != auth_user:
  46. # raise AuthError(403, "You are not a server admin")
  47. if not self.hs.is_mine(target_user):
  48. raise SynapseError(400, "Can only users a local user")
  49. ret = yield self.handlers.admin_handler.get_users()
  50. defer.returnValue((200, ret))
  51. class UserRegisterServlet(ClientV1RestServlet):
  52. """
  53. Attributes:
  54. NONCE_TIMEOUT (int): Seconds until a generated nonce won't be accepted
  55. nonces (dict[str, int]): The nonces that we will accept. A dict of
  56. nonce to the time it was generated, in int seconds.
  57. """
  58. PATTERNS = client_path_patterns("/admin/register")
  59. NONCE_TIMEOUT = 60
  60. def __init__(self, hs):
  61. super(UserRegisterServlet, self).__init__(hs)
  62. self.handlers = hs.get_handlers()
  63. self.reactor = hs.get_reactor()
  64. self.nonces = {}
  65. self.hs = hs
  66. def _clear_old_nonces(self):
  67. """
  68. Clear out old nonces that are older than NONCE_TIMEOUT.
  69. """
  70. now = int(self.reactor.seconds())
  71. for k, v in list(self.nonces.items()):
  72. if now - v > self.NONCE_TIMEOUT:
  73. del self.nonces[k]
  74. def on_GET(self, request):
  75. """
  76. Generate a new nonce.
  77. """
  78. self._clear_old_nonces()
  79. nonce = self.hs.get_secrets().token_hex(64)
  80. self.nonces[nonce] = int(self.reactor.seconds())
  81. return (200, {"nonce": nonce.encode('ascii')})
  82. @defer.inlineCallbacks
  83. def on_POST(self, request):
  84. self._clear_old_nonces()
  85. if not self.hs.config.registration_shared_secret:
  86. raise SynapseError(400, "Shared secret registration is not enabled")
  87. body = parse_json_object_from_request(request)
  88. if "nonce" not in body:
  89. raise SynapseError(
  90. 400, "nonce must be specified", errcode=Codes.BAD_JSON,
  91. )
  92. nonce = body["nonce"]
  93. if nonce not in self.nonces:
  94. raise SynapseError(
  95. 400, "unrecognised nonce",
  96. )
  97. # Delete the nonce, so it can't be reused, even if it's invalid
  98. del self.nonces[nonce]
  99. if "username" not in body:
  100. raise SynapseError(
  101. 400, "username must be specified", errcode=Codes.BAD_JSON,
  102. )
  103. else:
  104. if (not isinstance(body['username'], str) or len(body['username']) > 512):
  105. raise SynapseError(400, "Invalid username")
  106. username = body["username"].encode("utf-8")
  107. if b"\x00" in username:
  108. raise SynapseError(400, "Invalid username")
  109. if "password" not in body:
  110. raise SynapseError(
  111. 400, "password must be specified", errcode=Codes.BAD_JSON,
  112. )
  113. else:
  114. if (not isinstance(body['password'], str) or len(body['password']) > 512):
  115. raise SynapseError(400, "Invalid password")
  116. password = body["password"].encode("utf-8")
  117. if b"\x00" in password:
  118. raise SynapseError(400, "Invalid password")
  119. admin = body.get("admin", None)
  120. got_mac = body["mac"]
  121. want_mac = hmac.new(
  122. key=self.hs.config.registration_shared_secret.encode(),
  123. digestmod=hashlib.sha1,
  124. )
  125. want_mac.update(nonce)
  126. want_mac.update(b"\x00")
  127. want_mac.update(username)
  128. want_mac.update(b"\x00")
  129. want_mac.update(password)
  130. want_mac.update(b"\x00")
  131. want_mac.update(b"admin" if admin else b"notadmin")
  132. want_mac = want_mac.hexdigest()
  133. if not hmac.compare_digest(want_mac, got_mac):
  134. raise SynapseError(
  135. 403, "HMAC incorrect",
  136. )
  137. # Reuse the parts of RegisterRestServlet to reduce code duplication
  138. from synapse.rest.client.v2_alpha.register import RegisterRestServlet
  139. register = RegisterRestServlet(self.hs)
  140. (user_id, _) = yield register.registration_handler.register(
  141. localpart=username.lower(), password=password, admin=bool(admin),
  142. generate_token=False,
  143. )
  144. result = yield register._create_registration_details(user_id, body)
  145. defer.returnValue((200, result))
  146. class WhoisRestServlet(ClientV1RestServlet):
  147. PATTERNS = client_path_patterns("/admin/whois/(?P<user_id>[^/]*)")
  148. def __init__(self, hs):
  149. super(WhoisRestServlet, self).__init__(hs)
  150. self.handlers = hs.get_handlers()
  151. @defer.inlineCallbacks
  152. def on_GET(self, request, user_id):
  153. target_user = UserID.from_string(user_id)
  154. requester = yield self.auth.get_user_by_req(request)
  155. auth_user = requester.user
  156. is_admin = yield self.auth.is_server_admin(requester.user)
  157. if not is_admin and target_user != auth_user:
  158. raise AuthError(403, "You are not a server admin")
  159. if not self.hs.is_mine(target_user):
  160. raise SynapseError(400, "Can only whois a local user")
  161. ret = yield self.handlers.admin_handler.get_whois(target_user)
  162. defer.returnValue((200, ret))
  163. class PurgeMediaCacheRestServlet(ClientV1RestServlet):
  164. PATTERNS = client_path_patterns("/admin/purge_media_cache")
  165. def __init__(self, hs):
  166. self.media_repository = hs.get_media_repository()
  167. super(PurgeMediaCacheRestServlet, self).__init__(hs)
  168. @defer.inlineCallbacks
  169. def on_POST(self, request):
  170. requester = yield self.auth.get_user_by_req(request)
  171. is_admin = yield self.auth.is_server_admin(requester.user)
  172. if not is_admin:
  173. raise AuthError(403, "You are not a server admin")
  174. before_ts = parse_integer(request, "before_ts", required=True)
  175. logger.info("before_ts: %r", before_ts)
  176. ret = yield self.media_repository.delete_old_remote_media(before_ts)
  177. defer.returnValue((200, ret))
  178. class PurgeHistoryRestServlet(ClientV1RestServlet):
  179. PATTERNS = client_path_patterns(
  180. "/admin/purge_history/(?P<room_id>[^/]*)(/(?P<event_id>[^/]+))?"
  181. )
  182. def __init__(self, hs):
  183. """
  184. Args:
  185. hs (synapse.server.HomeServer)
  186. """
  187. super(PurgeHistoryRestServlet, self).__init__(hs)
  188. self.handlers = hs.get_handlers()
  189. self.store = hs.get_datastore()
  190. @defer.inlineCallbacks
  191. def on_POST(self, request, room_id, event_id):
  192. requester = yield self.auth.get_user_by_req(request)
  193. is_admin = yield self.auth.is_server_admin(requester.user)
  194. if not is_admin:
  195. raise AuthError(403, "You are not a server admin")
  196. body = parse_json_object_from_request(request, allow_empty_body=True)
  197. delete_local_events = bool(body.get("delete_local_events", False))
  198. # establish the topological ordering we should keep events from. The
  199. # user can provide an event_id in the URL or the request body, or can
  200. # provide a timestamp in the request body.
  201. if event_id is None:
  202. event_id = body.get('purge_up_to_event_id')
  203. if event_id is not None:
  204. event = yield self.store.get_event(event_id)
  205. if event.room_id != room_id:
  206. raise SynapseError(400, "Event is for wrong room.")
  207. token = yield self.store.get_topological_token_for_event(event_id)
  208. logger.info(
  209. "[purge] purging up to token %s (event_id %s)",
  210. token, event_id,
  211. )
  212. elif 'purge_up_to_ts' in body:
  213. ts = body['purge_up_to_ts']
  214. if not isinstance(ts, int):
  215. raise SynapseError(
  216. 400, "purge_up_to_ts must be an int",
  217. errcode=Codes.BAD_JSON,
  218. )
  219. stream_ordering = (
  220. yield self.store.find_first_stream_ordering_after_ts(ts)
  221. )
  222. r = (
  223. yield self.store.get_room_event_after_stream_ordering(
  224. room_id, stream_ordering,
  225. )
  226. )
  227. if not r:
  228. logger.warn(
  229. "[purge] purging events not possible: No event found "
  230. "(received_ts %i => stream_ordering %i)",
  231. ts, stream_ordering,
  232. )
  233. raise SynapseError(
  234. 404,
  235. "there is no event to be purged",
  236. errcode=Codes.NOT_FOUND,
  237. )
  238. (stream, topo, _event_id) = r
  239. token = "t%d-%d" % (topo, stream)
  240. logger.info(
  241. "[purge] purging up to token %s (received_ts %i => "
  242. "stream_ordering %i)",
  243. token, ts, stream_ordering,
  244. )
  245. else:
  246. raise SynapseError(
  247. 400,
  248. "must specify purge_up_to_event_id or purge_up_to_ts",
  249. errcode=Codes.BAD_JSON,
  250. )
  251. purge_id = yield self.handlers.message_handler.start_purge_history(
  252. room_id, token,
  253. delete_local_events=delete_local_events,
  254. )
  255. defer.returnValue((200, {
  256. "purge_id": purge_id,
  257. }))
  258. class PurgeHistoryStatusRestServlet(ClientV1RestServlet):
  259. PATTERNS = client_path_patterns(
  260. "/admin/purge_history_status/(?P<purge_id>[^/]+)"
  261. )
  262. def __init__(self, hs):
  263. """
  264. Args:
  265. hs (synapse.server.HomeServer)
  266. """
  267. super(PurgeHistoryStatusRestServlet, self).__init__(hs)
  268. self.handlers = hs.get_handlers()
  269. @defer.inlineCallbacks
  270. def on_GET(self, request, purge_id):
  271. requester = yield self.auth.get_user_by_req(request)
  272. is_admin = yield self.auth.is_server_admin(requester.user)
  273. if not is_admin:
  274. raise AuthError(403, "You are not a server admin")
  275. purge_status = self.handlers.message_handler.get_purge_status(purge_id)
  276. if purge_status is None:
  277. raise NotFoundError("purge id '%s' not found" % purge_id)
  278. defer.returnValue((200, purge_status.asdict()))
  279. class DeactivateAccountRestServlet(ClientV1RestServlet):
  280. PATTERNS = client_path_patterns("/admin/deactivate/(?P<target_user_id>[^/]*)")
  281. def __init__(self, hs):
  282. super(DeactivateAccountRestServlet, self).__init__(hs)
  283. self._deactivate_account_handler = hs.get_deactivate_account_handler()
  284. @defer.inlineCallbacks
  285. def on_POST(self, request, target_user_id):
  286. body = parse_json_object_from_request(request, allow_empty_body=True)
  287. erase = body.get("erase", False)
  288. if not isinstance(erase, bool):
  289. raise SynapseError(
  290. http_client.BAD_REQUEST,
  291. "Param 'erase' must be a boolean, if given",
  292. Codes.BAD_JSON,
  293. )
  294. UserID.from_string(target_user_id)
  295. requester = yield self.auth.get_user_by_req(request)
  296. is_admin = yield self.auth.is_server_admin(requester.user)
  297. if not is_admin:
  298. raise AuthError(403, "You are not a server admin")
  299. yield self._deactivate_account_handler.deactivate_account(
  300. target_user_id, erase,
  301. )
  302. defer.returnValue((200, {}))
  303. class ShutdownRoomRestServlet(ClientV1RestServlet):
  304. """Shuts down a room by removing all local users from the room and blocking
  305. all future invites and joins to the room. Any local aliases will be repointed
  306. to a new room created by `new_room_user_id` and kicked users will be auto
  307. joined to the new room.
  308. """
  309. PATTERNS = client_path_patterns("/admin/shutdown_room/(?P<room_id>[^/]+)")
  310. DEFAULT_MESSAGE = (
  311. "Sharing illegal content on this server is not permitted and rooms in"
  312. " violation will be blocked."
  313. )
  314. def __init__(self, hs):
  315. super(ShutdownRoomRestServlet, self).__init__(hs)
  316. self.store = hs.get_datastore()
  317. self.state = hs.get_state_handler()
  318. self._room_creation_handler = hs.get_room_creation_handler()
  319. self.event_creation_handler = hs.get_event_creation_handler()
  320. self.room_member_handler = hs.get_room_member_handler()
  321. @defer.inlineCallbacks
  322. def on_POST(self, request, room_id):
  323. requester = yield self.auth.get_user_by_req(request)
  324. is_admin = yield self.auth.is_server_admin(requester.user)
  325. if not is_admin:
  326. raise AuthError(403, "You are not a server admin")
  327. content = parse_json_object_from_request(request)
  328. assert_params_in_dict(content, ["new_room_user_id"])
  329. new_room_user_id = content["new_room_user_id"]
  330. room_creator_requester = create_requester(new_room_user_id)
  331. message = content.get("message", self.DEFAULT_MESSAGE)
  332. room_name = content.get("room_name", "Content Violation Notification")
  333. info = yield self._room_creation_handler.create_room(
  334. room_creator_requester,
  335. config={
  336. "preset": "public_chat",
  337. "name": room_name,
  338. "power_level_content_override": {
  339. "users_default": -10,
  340. },
  341. },
  342. ratelimit=False,
  343. )
  344. new_room_id = info["room_id"]
  345. yield self.event_creation_handler.create_and_send_nonmember_event(
  346. room_creator_requester,
  347. {
  348. "type": "m.room.message",
  349. "content": {"body": message, "msgtype": "m.text"},
  350. "room_id": new_room_id,
  351. "sender": new_room_user_id,
  352. },
  353. ratelimit=False,
  354. )
  355. requester_user_id = requester.user.to_string()
  356. logger.info("Shutting down room %r", room_id)
  357. yield self.store.block_room(room_id, requester_user_id)
  358. users = yield self.state.get_current_user_in_room(room_id)
  359. kicked_users = []
  360. for user_id in users:
  361. if not self.hs.is_mine_id(user_id):
  362. continue
  363. logger.info("Kicking %r from %r...", user_id, room_id)
  364. target_requester = create_requester(user_id)
  365. yield self.room_member_handler.update_membership(
  366. requester=target_requester,
  367. target=target_requester.user,
  368. room_id=room_id,
  369. action=Membership.LEAVE,
  370. content={},
  371. ratelimit=False
  372. )
  373. yield self.room_member_handler.forget(target_requester.user, room_id)
  374. yield self.room_member_handler.update_membership(
  375. requester=target_requester,
  376. target=target_requester.user,
  377. room_id=new_room_id,
  378. action=Membership.JOIN,
  379. content={},
  380. ratelimit=False
  381. )
  382. kicked_users.append(user_id)
  383. aliases_for_room = yield self.store.get_aliases_for_room(room_id)
  384. yield self.store.update_aliases_for_room(
  385. room_id, new_room_id, requester_user_id
  386. )
  387. defer.returnValue((200, {
  388. "kicked_users": kicked_users,
  389. "local_aliases": aliases_for_room,
  390. "new_room_id": new_room_id,
  391. }))
  392. class QuarantineMediaInRoom(ClientV1RestServlet):
  393. """Quarantines all media in a room so that no one can download it via
  394. this server.
  395. """
  396. PATTERNS = client_path_patterns("/admin/quarantine_media/(?P<room_id>[^/]+)")
  397. def __init__(self, hs):
  398. super(QuarantineMediaInRoom, self).__init__(hs)
  399. self.store = hs.get_datastore()
  400. @defer.inlineCallbacks
  401. def on_POST(self, request, room_id):
  402. requester = yield self.auth.get_user_by_req(request)
  403. is_admin = yield self.auth.is_server_admin(requester.user)
  404. if not is_admin:
  405. raise AuthError(403, "You are not a server admin")
  406. num_quarantined = yield self.store.quarantine_media_ids_in_room(
  407. room_id, requester.user.to_string(),
  408. )
  409. defer.returnValue((200, {"num_quarantined": num_quarantined}))
  410. class ListMediaInRoom(ClientV1RestServlet):
  411. """Lists all of the media in a given room.
  412. """
  413. PATTERNS = client_path_patterns("/admin/room/(?P<room_id>[^/]+)/media")
  414. def __init__(self, hs):
  415. super(ListMediaInRoom, self).__init__(hs)
  416. self.store = hs.get_datastore()
  417. @defer.inlineCallbacks
  418. def on_GET(self, request, room_id):
  419. requester = yield self.auth.get_user_by_req(request)
  420. is_admin = yield self.auth.is_server_admin(requester.user)
  421. if not is_admin:
  422. raise AuthError(403, "You are not a server admin")
  423. local_mxcs, remote_mxcs = yield self.store.get_media_mxcs_in_room(room_id)
  424. defer.returnValue((200, {"local": local_mxcs, "remote": remote_mxcs}))
  425. class ResetPasswordRestServlet(ClientV1RestServlet):
  426. """Post request to allow an administrator reset password for a user.
  427. This needs user to have administrator access in Synapse.
  428. Example:
  429. http://localhost:8008/_matrix/client/api/v1/admin/reset_password/
  430. @user:to_reset_password?access_token=admin_access_token
  431. JsonBodyToSend:
  432. {
  433. "new_password": "secret"
  434. }
  435. Returns:
  436. 200 OK with empty object if success otherwise an error.
  437. """
  438. PATTERNS = client_path_patterns("/admin/reset_password/(?P<target_user_id>[^/]*)")
  439. def __init__(self, hs):
  440. self.store = hs.get_datastore()
  441. super(ResetPasswordRestServlet, self).__init__(hs)
  442. self.hs = hs
  443. self.auth = hs.get_auth()
  444. self._set_password_handler = hs.get_set_password_handler()
  445. @defer.inlineCallbacks
  446. def on_POST(self, request, target_user_id):
  447. """Post request to allow an administrator reset password for a user.
  448. This needs user to have administrator access in Synapse.
  449. """
  450. UserID.from_string(target_user_id)
  451. requester = yield self.auth.get_user_by_req(request)
  452. is_admin = yield self.auth.is_server_admin(requester.user)
  453. if not is_admin:
  454. raise AuthError(403, "You are not a server admin")
  455. params = parse_json_object_from_request(request)
  456. assert_params_in_dict(params, ["new_password"])
  457. new_password = params['new_password']
  458. logger.info("new_password: %r", new_password)
  459. yield self._set_password_handler.set_password(
  460. target_user_id, new_password, requester
  461. )
  462. defer.returnValue((200, {}))
  463. class GetUsersPaginatedRestServlet(ClientV1RestServlet):
  464. """Get request to get specific number of users from Synapse.
  465. This needs user to have administrator access in Synapse.
  466. Example:
  467. http://localhost:8008/_matrix/client/api/v1/admin/users_paginate/
  468. @admin:user?access_token=admin_access_token&start=0&limit=10
  469. Returns:
  470. 200 OK with json object {list[dict[str, Any]], count} or empty object.
  471. """
  472. PATTERNS = client_path_patterns("/admin/users_paginate/(?P<target_user_id>[^/]*)")
  473. def __init__(self, hs):
  474. self.store = hs.get_datastore()
  475. super(GetUsersPaginatedRestServlet, self).__init__(hs)
  476. self.hs = hs
  477. self.auth = hs.get_auth()
  478. self.handlers = hs.get_handlers()
  479. @defer.inlineCallbacks
  480. def on_GET(self, request, target_user_id):
  481. """Get request to get specific number of users from Synapse.
  482. This needs user to have administrator access in Synapse.
  483. """
  484. target_user = UserID.from_string(target_user_id)
  485. requester = yield self.auth.get_user_by_req(request)
  486. is_admin = yield self.auth.is_server_admin(requester.user)
  487. if not is_admin:
  488. raise AuthError(403, "You are not a server admin")
  489. # To allow all users to get the users list
  490. # if not is_admin and target_user != auth_user:
  491. # raise AuthError(403, "You are not a server admin")
  492. if not self.hs.is_mine(target_user):
  493. raise SynapseError(400, "Can only users a local user")
  494. order = "name" # order by name in user table
  495. start = parse_integer(request, "start", required=True)
  496. limit = parse_integer(request, "limit", required=True)
  497. logger.info("limit: %s, start: %s", limit, start)
  498. ret = yield self.handlers.admin_handler.get_users_paginate(
  499. order, start, limit
  500. )
  501. defer.returnValue((200, ret))
  502. @defer.inlineCallbacks
  503. def on_POST(self, request, target_user_id):
  504. """Post request to get specific number of users from Synapse..
  505. This needs user to have administrator access in Synapse.
  506. Example:
  507. http://localhost:8008/_matrix/client/api/v1/admin/users_paginate/
  508. @admin:user?access_token=admin_access_token
  509. JsonBodyToSend:
  510. {
  511. "start": "0",
  512. "limit": "10
  513. }
  514. Returns:
  515. 200 OK with json object {list[dict[str, Any]], count} or empty object.
  516. """
  517. UserID.from_string(target_user_id)
  518. requester = yield self.auth.get_user_by_req(request)
  519. is_admin = yield self.auth.is_server_admin(requester.user)
  520. if not is_admin:
  521. raise AuthError(403, "You are not a server admin")
  522. order = "name" # order by name in user table
  523. params = parse_json_object_from_request(request)
  524. assert_params_in_dict(params, ["limit", "start"])
  525. limit = params['limit']
  526. start = params['start']
  527. logger.info("limit: %s, start: %s", limit, start)
  528. ret = yield self.handlers.admin_handler.get_users_paginate(
  529. order, start, limit
  530. )
  531. defer.returnValue((200, ret))
  532. class SearchUsersRestServlet(ClientV1RestServlet):
  533. """Get request to search user table for specific users according to
  534. search term.
  535. This needs user to have administrator access in Synapse.
  536. Example:
  537. http://localhost:8008/_matrix/client/api/v1/admin/search_users/
  538. @admin:user?access_token=admin_access_token&term=alice
  539. Returns:
  540. 200 OK with json object {list[dict[str, Any]], count} or empty object.
  541. """
  542. PATTERNS = client_path_patterns("/admin/search_users/(?P<target_user_id>[^/]*)")
  543. def __init__(self, hs):
  544. self.store = hs.get_datastore()
  545. super(SearchUsersRestServlet, self).__init__(hs)
  546. self.hs = hs
  547. self.auth = hs.get_auth()
  548. self.handlers = hs.get_handlers()
  549. @defer.inlineCallbacks
  550. def on_GET(self, request, target_user_id):
  551. """Get request to search user table for specific users according to
  552. search term.
  553. This needs user to have a administrator access in Synapse.
  554. """
  555. target_user = UserID.from_string(target_user_id)
  556. requester = yield self.auth.get_user_by_req(request)
  557. is_admin = yield self.auth.is_server_admin(requester.user)
  558. if not is_admin:
  559. raise AuthError(403, "You are not a server admin")
  560. # To allow all users to get the users list
  561. # if not is_admin and target_user != auth_user:
  562. # raise AuthError(403, "You are not a server admin")
  563. if not self.hs.is_mine(target_user):
  564. raise SynapseError(400, "Can only users a local user")
  565. term = parse_string(request, "term", required=True)
  566. logger.info("term: %s ", term)
  567. ret = yield self.handlers.admin_handler.search_users(
  568. term
  569. )
  570. defer.returnValue((200, ret))
  571. def register_servlets(hs, http_server):
  572. WhoisRestServlet(hs).register(http_server)
  573. PurgeMediaCacheRestServlet(hs).register(http_server)
  574. PurgeHistoryStatusRestServlet(hs).register(http_server)
  575. DeactivateAccountRestServlet(hs).register(http_server)
  576. PurgeHistoryRestServlet(hs).register(http_server)
  577. UsersRestServlet(hs).register(http_server)
  578. ResetPasswordRestServlet(hs).register(http_server)
  579. GetUsersPaginatedRestServlet(hs).register(http_server)
  580. SearchUsersRestServlet(hs).register(http_server)
  581. ShutdownRoomRestServlet(hs).register(http_server)
  582. QuarantineMediaInRoom(hs).register(http_server)
  583. ListMediaInRoom(hs).register(http_server)
  584. UserRegisterServlet(hs).register(http_server)