|
22 | 22 | from nacl.signing import SigningKey |
23 | 23 | from signedjson.key import encode_verify_key_base64, get_verify_key |
24 | 24 |
|
| 25 | +from twisted.internet import defer |
25 | 26 | from twisted.internet.defer import Deferred, ensureDeferred |
26 | 27 |
|
27 | 28 | from synapse.api.errors import SynapseError |
@@ -577,6 +578,76 @@ def test_get_keys_from_perspectives(self): |
577 | 578 | bytes(res["key_json"]), canonicaljson.encode_canonical_json(response) |
578 | 579 | ) |
579 | 580 |
|
| 581 | + def test_get_multiple_keys_from_perspectives(self): |
| 582 | + """Check that we can correctly request multiple keys for the same server""" |
| 583 | + |
| 584 | + fetcher = PerspectivesKeyFetcher(self.hs) |
| 585 | + |
| 586 | + SERVER_NAME = "server2" |
| 587 | + |
| 588 | + testkey1 = signedjson.key.generate_signing_key("ver1") |
| 589 | + testverifykey1 = signedjson.key.get_verify_key(testkey1) |
| 590 | + testverifykey1_id = "ed25519:ver1" |
| 591 | + |
| 592 | + testkey2 = signedjson.key.generate_signing_key("ver2") |
| 593 | + testverifykey2 = signedjson.key.get_verify_key(testkey2) |
| 594 | + testverifykey2_id = "ed25519:ver2" |
| 595 | + |
| 596 | + VALID_UNTIL_TS = 200 * 1000 |
| 597 | + |
| 598 | + response1 = self.build_perspectives_response( |
| 599 | + SERVER_NAME, |
| 600 | + testkey1, |
| 601 | + VALID_UNTIL_TS, |
| 602 | + ) |
| 603 | + response2 = self.build_perspectives_response( |
| 604 | + SERVER_NAME, |
| 605 | + testkey2, |
| 606 | + VALID_UNTIL_TS, |
| 607 | + ) |
| 608 | + |
| 609 | + async def post_json(destination, path, data, **kwargs): |
| 610 | + self.assertEqual(destination, self.mock_perspective_server.server_name) |
| 611 | + self.assertEqual(path, "/_matrix/key/v2/query") |
| 612 | + |
| 613 | + # check that the request is for the expected keys |
| 614 | + q = data["server_keys"] |
| 615 | + |
| 616 | + self.assertEqual( |
| 617 | + list(q[SERVER_NAME].keys()), [testverifykey1_id, testverifykey2_id] |
| 618 | + ) |
| 619 | + return {"server_keys": [response1, response2]} |
| 620 | + |
| 621 | + self.http_client.post_json.side_effect = post_json |
| 622 | + |
| 623 | + # fire off two separate requests; they should get merged together into a |
| 624 | + # single HTTP hit. |
| 625 | + request1_d = defer.ensureDeferred( |
| 626 | + fetcher.get_keys(SERVER_NAME, [testverifykey1_id], 0) |
| 627 | + ) |
| 628 | + request2_d = defer.ensureDeferred( |
| 629 | + fetcher.get_keys(SERVER_NAME, [testverifykey2_id], 0) |
| 630 | + ) |
| 631 | + |
| 632 | + keys1 = self.get_success(request1_d) |
| 633 | + self.assertIn(testverifykey1_id, keys1) |
| 634 | + k = keys1[testverifykey1_id] |
| 635 | + self.assertEqual(k.valid_until_ts, VALID_UNTIL_TS) |
| 636 | + self.assertEqual(k.verify_key, testverifykey1) |
| 637 | + self.assertEqual(k.verify_key.alg, "ed25519") |
| 638 | + self.assertEqual(k.verify_key.version, "ver1") |
| 639 | + |
| 640 | + keys2 = self.get_success(request2_d) |
| 641 | + self.assertIn(testverifykey2_id, keys2) |
| 642 | + k = keys2[testverifykey2_id] |
| 643 | + self.assertEqual(k.valid_until_ts, VALID_UNTIL_TS) |
| 644 | + self.assertEqual(k.verify_key, testverifykey2) |
| 645 | + self.assertEqual(k.verify_key.alg, "ed25519") |
| 646 | + self.assertEqual(k.verify_key.version, "ver2") |
| 647 | + |
| 648 | + # finally, ensure that only one request was sent |
| 649 | + self.assertEqual(self.http_client.post_json.call_count, 1) |
| 650 | + |
580 | 651 | def test_get_perspectives_own_key(self): |
581 | 652 | """Check that we can get the perspectives server's own keys |
582 | 653 |
|
|
0 commit comments