test_userdir.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import json
  2. import signedjson.key
  3. import signedjson.sign
  4. from mock import Mock
  5. from tests.utils import make_request, make_sydent
  6. from twisted.trial import unittest
  7. class UserdirTestCase(unittest.TestCase):
  8. def setUp(self):
  9. # Create a new sydent
  10. config = {
  11. "userdir": {
  12. "userdir.allowed_homeservers": "fake.server"
  13. }
  14. }
  15. # Use this keypair to sign and verify payloads.
  16. self.signing_key = signedjson.key.decode_signing_key_base64(
  17. "ed25519", "0", "b29eXMMAYCFvFEtq9mLI42aivMtcg4Hl0wK89a+Vb6c",
  18. )
  19. self.public_key_base64 = "+vB8mTaooD/MA8YYZM8t9+vnGhP1937q2icrqPV9JTs"
  20. self.sydent = make_sydent(test_config=config)
  21. # Mock the _getKeysForServer function so tests don't fail on fetching keys.
  22. self.sydent.sig_verifier._getKeysForServer = Mock()
  23. pubkey_res = {"ed25519:0": {"key": self.public_key_base64}}
  24. self.sydent.sig_verifier._getKeysForServer.return_value = pubkey_res
  25. self.sydent.run()
  26. def test_replicate_profile_and_lookup(self):
  27. """Tests that a user can send profile updates via the corresponding replication
  28. endpoint and that the user directory is populated correctly."""
  29. # Create two profiles. Jane Doe is an extra profile we're not going to look up to
  30. # ensure filtering is applied.
  31. john_update = {
  32. "display_name": "John Doe",
  33. "avatar_url": "mxc://fake.server/someavatar",
  34. }
  35. jane_update = {
  36. "display_name": "Jane Doe",
  37. "avatar_url": "mxc://fake.server/someotheravatar",
  38. }
  39. self._update_profiles(
  40. batchnum=1,
  41. batch={
  42. "@john:fake.server": john_update,
  43. "@jane:fake.server": jane_update,
  44. },
  45. )
  46. # Check that John's profile exists and is returned by a lookup.
  47. self._query_profile_for_search_terms("John", john_update)
  48. # Check that updating the profile of a user to None removes that profile from the
  49. # user directory.
  50. self._update_profiles(
  51. batchnum=2,
  52. batch={
  53. "@john:fake.server": None,
  54. },
  55. )
  56. self._query_profile_for_search_terms("John", None)
  57. # Check that updating a profile but not increasing the batch number doesn't
  58. # update the user directory.
  59. self._update_profiles(
  60. batchnum=2,
  61. batch={
  62. "@john:fake.server": john_update,
  63. },
  64. )
  65. self._query_profile_for_search_terms("John", None)
  66. def _update_profiles(self, batchnum, batch):
  67. """Send the given profile updates."""
  68. # Build and sign the request body.
  69. profile_update = {
  70. "batchnum": batchnum,
  71. "batch": batch,
  72. "origin_server": "fake.server",
  73. }
  74. signed_update = signedjson.sign.sign_json(
  75. profile_update, "fake.server", self.signing_key,
  76. )
  77. # Send the profile updates.
  78. request, channel = make_request(
  79. self.sydent.reactor,
  80. "POST",
  81. "/_matrix/identity/api/v1/replicate_profiles",
  82. json.dumps(signed_update),
  83. )
  84. request.render(self.sydent.servlets.profileReplicationServlet)
  85. self.assertEqual(channel.code, 200, channel.json_body)
  86. def _query_profile_for_search_terms(self, search_terms, expected_result):
  87. """Query the profile matching the given search terms and checks that it returns
  88. the expected result."""
  89. # Get a signed body.
  90. signed_search_request = signedjson.sign.sign_json(
  91. {"search_term": search_terms}, "fake.server", self.signing_key,
  92. )
  93. # Send the request.
  94. request, channel = make_request(
  95. self.sydent.reactor,
  96. "POST",
  97. "/_matrix/identity/api/v1/user_directory/search",
  98. json.dumps(signed_search_request),
  99. )
  100. request.render(self.sydent.servlets.userDirectorySearchServlet)
  101. self.assertEqual(channel.code, 200, channel.json_body)
  102. # Check if the response matches the expected result.
  103. results = channel.json_body["results"]
  104. if expected_result is None:
  105. self.assertEqual(len(channel.json_body["results"]), 0)
  106. else:
  107. self.assertEqual(len(channel.json_body["results"]), 1)
  108. self.assertDictContainsSubset(expected_result, results[0])