Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit a989405

Browse files
committed
add a test, and fix a bug it showed up
1 parent 5bc58bc commit a989405

File tree

3 files changed

+170
-2
lines changed

3 files changed

+170
-2
lines changed

synapse/federation/federation_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,11 +464,11 @@ async def get_room_state(
464464
)
465465

466466
valid_auth_events = await self._check_sigs_and_hash_and_fetch(
467-
destination, auth_events, room_version
467+
destination, auth_event_map.values(), room_version
468468
)
469469

470470
valid_state_events = await self._check_sigs_and_hash_and_fetch(
471-
destination, state_events, room_version
471+
destination, state_event_map.values(), room_version
472472
)
473473

474474
return valid_state_events, valid_auth_events
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# Copyright 2022 Matrix.org Federation C.I.C
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import json
16+
from unittest import mock
17+
18+
import twisted.web.client
19+
from twisted.internet import defer
20+
from twisted.internet.protocol import Protocol
21+
from twisted.python.failure import Failure
22+
from twisted.test.proto_helpers import MemoryReactor
23+
24+
from synapse.api.room_versions import RoomVersions
25+
from synapse.server import HomeServer
26+
from synapse.types import JsonDict
27+
from synapse.util import Clock
28+
29+
from tests.unittest import FederatingHomeserverTestCase
30+
31+
32+
class FederationClientTest(FederatingHomeserverTestCase):
33+
def prepare(self, reactor: MemoryReactor, clock: Clock, homeserver: HomeServer):
34+
super().prepare(reactor, clock, homeserver)
35+
36+
# mock out the Agent used by the federation client, which is easier than
37+
# catching the HTTPS connection and do the TLS stuff.
38+
self._mock_agent = mock.create_autospec(twisted.web.client.Agent, spec_set=True)
39+
homeserver.get_federation_http_client().agent = self._mock_agent
40+
41+
def test_get_room_state(self):
42+
creator = f"@creator:{self.OTHER_SERVER_NAME}"
43+
test_room_id = "!room_id"
44+
45+
# mock up some events to use in the response
46+
create_event_dict = self.add_hashes_and_signatures(
47+
{
48+
"room_id": test_room_id,
49+
"type": "m.room.create",
50+
"state_key": "",
51+
"sender": creator,
52+
"content": {"creator": creator},
53+
"prev_events": [],
54+
"auth_events": [],
55+
"origin_server_ts": 500,
56+
}
57+
)
58+
member_event_dict = self.add_hashes_and_signatures(
59+
{
60+
"room_id": test_room_id,
61+
"type": "m.room.member",
62+
"sender": creator,
63+
"state_key": creator,
64+
"content": {"membership": "join"},
65+
"prev_events": [],
66+
"auth_events": [],
67+
"origin_server_ts": 600,
68+
}
69+
)
70+
pl_event_dict = self.add_hashes_and_signatures(
71+
{
72+
"room_id": test_room_id,
73+
"type": "m.room.power_levels",
74+
"sender": creator,
75+
"state_key": "",
76+
"content": {},
77+
"prev_events": [],
78+
"auth_events": [],
79+
"origin_server_ts": 700,
80+
}
81+
)
82+
83+
# mock up the response, and have the agent return it
84+
self._mock_agent.request.return_value = defer.succeed(
85+
_mock_response(
86+
{
87+
"pdus": [
88+
create_event_dict,
89+
member_event_dict,
90+
pl_event_dict,
91+
],
92+
"auth_chain": [
93+
create_event_dict,
94+
member_event_dict,
95+
],
96+
}
97+
)
98+
)
99+
100+
# now fire off the request
101+
state_resp, auth_resp = self.get_success(
102+
self.hs.get_federation_client().get_room_state(
103+
"yet_another_server",
104+
test_room_id,
105+
"event_id",
106+
RoomVersions.V9,
107+
)
108+
)
109+
110+
# check the right call got made to the agent
111+
self._mock_agent.request.assert_called_once_with(
112+
b"GET",
113+
b"matrix://yet_another_server/_matrix/federation/v1/state/%21room_id?event_id=event_id",
114+
headers=mock.ANY,
115+
bodyProducer=None,
116+
)
117+
118+
# ... and that the response is correct.
119+
120+
# the auth_resp should be empty because all the events are also in state
121+
self.assertEqual(auth_resp, [])
122+
123+
# all of the events should be returned in state_resp, though not necessarily
124+
# in the same order. We just check the type on the assumption that if the type
125+
# is right, so is the rest of the event.
126+
self.assertCountEqual(
127+
[e.type for e in state_resp],
128+
["m.room.create", "m.room.member", "m.room.power_levels"],
129+
)
130+
131+
132+
def _mock_response(resp: JsonDict):
133+
body = json.dumps(resp).encode("utf-8")
134+
135+
def deliver_body(p: Protocol):
136+
p.dataReceived(body)
137+
p.connectionLost(Failure(twisted.web.client.ResponseDone()))
138+
139+
response = mock.Mock(
140+
code=200,
141+
phrase=b"OK",
142+
headers=twisted.web.client.Headers({"content-Type": ["application/json"]}),
143+
length=len(body),
144+
deliverBody=deliver_body,
145+
)
146+
mock.seal(response)
147+
return response

tests/unittest.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@
5151

5252
from synapse import events
5353
from synapse.api.constants import EventTypes, Membership
54+
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, RoomVersion
5455
from synapse.config.homeserver import HomeServerConfig
56+
from synapse.config.server import DEFAULT_ROOM_VERSION
57+
from synapse.crypto.event_signing import add_hashes_and_signatures
5558
from synapse.federation.transport.server import TransportLayerServer
5659
from synapse.http.server import JsonResource
5760
from synapse.http.site import SynapseRequest, SynapseSite
@@ -839,6 +842,24 @@ def make_signed_federation_request(
839842
client_ip=client_ip,
840843
)
841844

845+
def add_hashes_and_signatures(
846+
self,
847+
event_dict: JsonDict,
848+
room_version: RoomVersion = KNOWN_ROOM_VERSIONS[DEFAULT_ROOM_VERSION],
849+
) -> JsonDict:
850+
"""Adds hashes and signatures to the given event dict
851+
852+
Returns:
853+
The modified event dict, for convenience
854+
"""
855+
add_hashes_and_signatures(
856+
room_version,
857+
event_dict,
858+
signature_name=self.OTHER_SERVER_NAME,
859+
signing_key=self.OTHER_SERVER_SIGNATURE_KEY,
860+
)
861+
return event_dict
862+
842863

843864
def _auth_header_for_request(
844865
origin: str,

0 commit comments

Comments
 (0)