lookupservlet.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. # Copyright 2014,2017 OpenMarket Ltd
  2. # Copyright 2019 The Matrix.org Foundation C.I.C.
  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 typing import TYPE_CHECKING
  17. import signedjson.sign
  18. from twisted.web.resource import Resource
  19. from twisted.web.server import Request
  20. from sydent.db.threepid_associations import GlobalAssociationStore
  21. from sydent.http.servlets import get_args, jsonwrap, send_cors
  22. from sydent.types import JsonDict
  23. from sydent.util import json_decoder
  24. if TYPE_CHECKING:
  25. from sydent.sydent import Sydent
  26. logger = logging.getLogger(__name__)
  27. class LookupServlet(Resource):
  28. isLeaf = True
  29. def __init__(self, syd: "Sydent") -> None:
  30. self.sydent = syd
  31. @jsonwrap
  32. def render_GET(self, request: Request) -> JsonDict:
  33. """
  34. Look up an individual threepid.
  35. ** DEPRECATED **
  36. Params: 'medium': the medium of the threepid
  37. 'address': the address of the threepid
  38. Returns: A signed association if the threepid has a corresponding mxid, otherwise the empty object.
  39. """
  40. send_cors(request)
  41. args = get_args(request, ("medium", "address"))
  42. medium = args["medium"]
  43. address = args["address"]
  44. globalAssocStore = GlobalAssociationStore(self.sydent)
  45. sgassoc = globalAssocStore.signedAssociationStringForThreepid(medium, address)
  46. if not sgassoc:
  47. return {}
  48. sgassoc = json_decoder.decode(sgassoc)
  49. if self.sydent.config.general.server_name not in sgassoc["signatures"]:
  50. # We have not yet worked out what the proper trust model should be.
  51. #
  52. # Maybe clients implicitly trust a server they talk to (and so we
  53. # should sign every assoc we return as ourselves, so they can
  54. # verify this).
  55. #
  56. # Maybe clients really want to know what server did the original
  57. # verification, and want to only know exactly who signed the assoc.
  58. #
  59. # Until we work out what we should do, sign all assocs we return as
  60. # ourself. This is vaguely ok because there actually is only one
  61. # identity server, but it happens to have two names (matrix.org and
  62. # vector.im), and so we're not really lying too much.
  63. #
  64. # We do this when we return assocs, not when we receive them over
  65. # replication, so that we can undo this decision in the future if
  66. # we wish, without having destroyed the raw underlying data.
  67. sgassoc = signedjson.sign.sign_json(
  68. sgassoc,
  69. self.sydent.config.general.server_name,
  70. self.sydent.keyring.ed25519,
  71. )
  72. return sgassoc
  73. def render_OPTIONS(self, request: Request) -> bytes:
  74. send_cors(request)
  75. return b""