devices.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2015, 2016 OpenMarket Ltd
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. import logging
  16. from twisted.internet import defer
  17. from synapse.api import errors
  18. from synapse.http.servlet import (
  19. RestServlet,
  20. assert_params_in_dict,
  21. parse_json_object_from_request,
  22. )
  23. from ._base import client_patterns, interactive_auth_handler
  24. logger = logging.getLogger(__name__)
  25. class DevicesRestServlet(RestServlet):
  26. PATTERNS = client_patterns("/devices$")
  27. def __init__(self, hs):
  28. """
  29. Args:
  30. hs (synapse.server.HomeServer): server
  31. """
  32. super(DevicesRestServlet, self).__init__()
  33. self.hs = hs
  34. self.auth = hs.get_auth()
  35. self.device_handler = hs.get_device_handler()
  36. @defer.inlineCallbacks
  37. def on_GET(self, request):
  38. requester = yield self.auth.get_user_by_req(request, allow_guest=True)
  39. devices = yield self.device_handler.get_devices_by_user(
  40. requester.user.to_string()
  41. )
  42. return (200, {"devices": devices})
  43. class DeleteDevicesRestServlet(RestServlet):
  44. """
  45. API for bulk deletion of devices. Accepts a JSON object with a devices
  46. key which lists the device_ids to delete. Requires user interactive auth.
  47. """
  48. PATTERNS = client_patterns("/delete_devices")
  49. def __init__(self, hs):
  50. super(DeleteDevicesRestServlet, self).__init__()
  51. self.hs = hs
  52. self.auth = hs.get_auth()
  53. self.device_handler = hs.get_device_handler()
  54. self.auth_handler = hs.get_auth_handler()
  55. @interactive_auth_handler
  56. @defer.inlineCallbacks
  57. def on_POST(self, request):
  58. requester = yield self.auth.get_user_by_req(request)
  59. try:
  60. body = parse_json_object_from_request(request)
  61. except errors.SynapseError as e:
  62. if e.errcode == errors.Codes.NOT_JSON:
  63. # DELETE
  64. # deal with older clients which didn't pass a JSON dict
  65. # the same as those that pass an empty dict
  66. body = {}
  67. else:
  68. raise e
  69. assert_params_in_dict(body, ["devices"])
  70. yield self.auth_handler.validate_user_via_ui_auth(
  71. requester, body, self.hs.get_ip_from_request(request)
  72. )
  73. yield self.device_handler.delete_devices(
  74. requester.user.to_string(), body["devices"]
  75. )
  76. return (200, {})
  77. class DeviceRestServlet(RestServlet):
  78. PATTERNS = client_patterns("/devices/(?P<device_id>[^/]*)$")
  79. def __init__(self, hs):
  80. """
  81. Args:
  82. hs (synapse.server.HomeServer): server
  83. """
  84. super(DeviceRestServlet, self).__init__()
  85. self.hs = hs
  86. self.auth = hs.get_auth()
  87. self.device_handler = hs.get_device_handler()
  88. self.auth_handler = hs.get_auth_handler()
  89. @defer.inlineCallbacks
  90. def on_GET(self, request, device_id):
  91. requester = yield self.auth.get_user_by_req(request, allow_guest=True)
  92. device = yield self.device_handler.get_device(
  93. requester.user.to_string(), device_id
  94. )
  95. return (200, device)
  96. @interactive_auth_handler
  97. @defer.inlineCallbacks
  98. def on_DELETE(self, request, device_id):
  99. requester = yield self.auth.get_user_by_req(request)
  100. try:
  101. body = parse_json_object_from_request(request)
  102. except errors.SynapseError as e:
  103. if e.errcode == errors.Codes.NOT_JSON:
  104. # deal with older clients which didn't pass a JSON dict
  105. # the same as those that pass an empty dict
  106. body = {}
  107. else:
  108. raise
  109. yield self.auth_handler.validate_user_via_ui_auth(
  110. requester, body, self.hs.get_ip_from_request(request)
  111. )
  112. yield self.device_handler.delete_device(requester.user.to_string(), device_id)
  113. return (200, {})
  114. @defer.inlineCallbacks
  115. def on_PUT(self, request, device_id):
  116. requester = yield self.auth.get_user_by_req(request, allow_guest=True)
  117. body = parse_json_object_from_request(request)
  118. yield self.device_handler.update_device(
  119. requester.user.to_string(), device_id, body
  120. )
  121. return (200, {})
  122. def register_servlets(hs, http_server):
  123. DeleteDevicesRestServlet(hs).register(http_server)
  124. DevicesRestServlet(hs).register(http_server)
  125. DeviceRestServlet(hs).register(http_server)