Sign federation transactions

This commit is contained in:
Mark Haines 2014-09-24 17:25:41 +01:00
parent bf4b224fcf
commit 52ca867670
8 changed files with 73 additions and 10 deletions

View File

@ -25,6 +25,8 @@ from .persistence import PduActions, TransactionActions
from synapse.util.logutils import log_function from synapse.util.logutils import log_function
from syutil.crypto.jsonsign import sign_json
import logging import logging
@ -489,7 +491,7 @@ class _TransactionQueue(object):
""" """
def __init__(self, hs, transaction_actions, transport_layer): def __init__(self, hs, transaction_actions, transport_layer):
self.signing_key = hs.config.signing_key[0]
self.server_name = hs.hostname self.server_name = hs.hostname
self.transaction_actions = transaction_actions self.transaction_actions = transaction_actions
self.transport_layer = transport_layer self.transport_layer = transport_layer
@ -604,6 +606,9 @@ class _TransactionQueue(object):
# Actually send the transaction # Actually send the transaction
server_name = self.server_name
signing_key = self.signing_key
# FIXME (erikj): This is a bit of a hack to make the Pdu age # FIXME (erikj): This is a bit of a hack to make the Pdu age
# keys work # keys work
def cb(transaction): def cb(transaction):
@ -613,6 +618,8 @@ class _TransactionQueue(object):
if "age_ts" in p: if "age_ts" in p:
p["age"] = now - int(p["age_ts"]) p["age"] = now - int(p["age_ts"])
transaction = sign_json(transaction, server_name, signing_key)
return transaction return transaction
code, response = yield self.transport_layer.send_transaction( code, response = yield self.transport_layer.send_transaction(

View File

@ -19,7 +19,7 @@ from tests import unittest
# python imports # python imports
from mock import Mock, ANY from mock import Mock, ANY
from ..utils import MockHttpResource, MockClock from ..utils import MockHttpResource, MockClock, MockKey
from synapse.server import HomeServer from synapse.server import HomeServer
from synapse.federation import initialize_http_replication from synapse.federation import initialize_http_replication
@ -64,6 +64,8 @@ class FederationTestCase(unittest.TestCase):
self.mock_persistence.get_received_txn_response.return_value = ( self.mock_persistence.get_received_txn_response.return_value = (
defer.succeed(None) defer.succeed(None)
) )
self.mock_config = Mock()
self.mock_config.signing_key = [MockKey()]
self.clock = MockClock() self.clock = MockClock()
hs = HomeServer("test", hs = HomeServer("test",
resource_for_federation=self.mock_resource, resource_for_federation=self.mock_resource,
@ -71,6 +73,7 @@ class FederationTestCase(unittest.TestCase):
db_pool=None, db_pool=None,
datastore=self.mock_persistence, datastore=self.mock_persistence,
clock=self.clock, clock=self.clock,
config=self.mock_config,
) )
self.federation = initialize_http_replication(hs) self.federation = initialize_http_replication(hs)
self.distributor = hs.get_distributor() self.distributor = hs.get_distributor()

View File

@ -26,12 +26,16 @@ from synapse.federation.units import Pdu
from mock import NonCallableMock, ANY from mock import NonCallableMock, ANY
from ..utils import get_mock_call_args from ..utils import get_mock_call_args, MockKey
class FederationTestCase(unittest.TestCase): class FederationTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
self.mock_config = NonCallableMock()
self.mock_config.signing_key = [MockKey()]
self.hostname = "test" self.hostname = "test"
hs = HomeServer( hs = HomeServer(
self.hostname, self.hostname,
@ -48,6 +52,7 @@ class FederationTestCase(unittest.TestCase):
"room_member_handler", "room_member_handler",
"federation_handler", "federation_handler",
]), ]),
config=self.mock_config,
) )
self.datastore = hs.get_datastore() self.datastore = hs.get_datastore()

View File

@ -17,11 +17,12 @@
from tests import unittest from tests import unittest
from twisted.internet import defer, reactor from twisted.internet import defer, reactor
from mock import Mock, call, ANY from mock import Mock, call, ANY, NonCallableMock
import json import json
from tests.utils import ( from tests.utils import (
MockHttpResource, MockClock, DeferredMockCallable, SQLiteMemoryDbPool MockHttpResource, MockClock, DeferredMockCallable, SQLiteMemoryDbPool,
MockKey
) )
from synapse.server import HomeServer from synapse.server import HomeServer
@ -67,12 +68,16 @@ class PresenceStateTestCase(unittest.TestCase):
db_pool = SQLiteMemoryDbPool() db_pool = SQLiteMemoryDbPool()
yield db_pool.prepare() yield db_pool.prepare()
self.mock_config = NonCallableMock()
self.mock_config.signing_key = [MockKey()]
hs = HomeServer("test", hs = HomeServer("test",
clock=MockClock(), clock=MockClock(),
db_pool=db_pool, db_pool=db_pool,
handlers=None, handlers=None,
resource_for_federation=Mock(), resource_for_federation=Mock(),
http_client=None, http_client=None,
config=self.mock_config,
) )
hs.handlers = JustPresenceHandlers(hs) hs.handlers = JustPresenceHandlers(hs)
@ -214,6 +219,9 @@ class PresenceInvitesTestCase(unittest.TestCase):
db_pool = SQLiteMemoryDbPool() db_pool = SQLiteMemoryDbPool()
yield db_pool.prepare() yield db_pool.prepare()
self.mock_config = NonCallableMock()
self.mock_config.signing_key = [MockKey()]
hs = HomeServer("test", hs = HomeServer("test",
clock=MockClock(), clock=MockClock(),
db_pool=db_pool, db_pool=db_pool,
@ -221,6 +229,7 @@ class PresenceInvitesTestCase(unittest.TestCase):
resource_for_client=Mock(), resource_for_client=Mock(),
resource_for_federation=self.mock_federation_resource, resource_for_federation=self.mock_federation_resource,
http_client=self.mock_http_client, http_client=self.mock_http_client,
config=self.mock_config,
) )
hs.handlers = JustPresenceHandlers(hs) hs.handlers = JustPresenceHandlers(hs)
@ -503,6 +512,9 @@ class PresencePushTestCase(unittest.TestCase):
self.mock_federation_resource = MockHttpResource() self.mock_federation_resource = MockHttpResource()
self.mock_config = NonCallableMock()
self.mock_config.signing_key = [MockKey()]
hs = HomeServer("test", hs = HomeServer("test",
clock=self.clock, clock=self.clock,
db_pool=None, db_pool=None,
@ -520,6 +532,7 @@ class PresencePushTestCase(unittest.TestCase):
resource_for_client=Mock(), resource_for_client=Mock(),
resource_for_federation=self.mock_federation_resource, resource_for_federation=self.mock_federation_resource,
http_client=self.mock_http_client, http_client=self.mock_http_client,
config=self.mock_config,
) )
hs.handlers = JustPresenceHandlers(hs) hs.handlers = JustPresenceHandlers(hs)
@ -995,6 +1008,9 @@ class PresencePollingTestCase(unittest.TestCase):
self.mock_federation_resource = MockHttpResource() self.mock_federation_resource = MockHttpResource()
self.mock_config = NonCallableMock()
self.mock_config.signing_key = [MockKey()]
hs = HomeServer("test", hs = HomeServer("test",
clock=MockClock(), clock=MockClock(),
db_pool=None, db_pool=None,
@ -1009,6 +1025,7 @@ class PresencePollingTestCase(unittest.TestCase):
resource_for_client=Mock(), resource_for_client=Mock(),
resource_for_federation=self.mock_federation_resource, resource_for_federation=self.mock_federation_resource,
http_client=self.mock_http_client, http_client=self.mock_http_client,
config = self.mock_config,
) )
hs.handlers = JustPresenceHandlers(hs) hs.handlers = JustPresenceHandlers(hs)

View File

@ -24,6 +24,7 @@ from synapse.api.constants import Membership
from synapse.handlers.room import RoomMemberHandler, RoomCreationHandler from synapse.handlers.room import RoomMemberHandler, RoomCreationHandler
from synapse.handlers.profile import ProfileHandler from synapse.handlers.profile import ProfileHandler
from synapse.server import HomeServer from synapse.server import HomeServer
from ..utils import MockKey
from mock import Mock, NonCallableMock from mock import Mock, NonCallableMock
@ -31,6 +32,8 @@ from mock import Mock, NonCallableMock
class RoomMemberHandlerTestCase(unittest.TestCase): class RoomMemberHandlerTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
self.mock_config = NonCallableMock()
self.mock_config.signing_key = [MockKey()]
self.hostname = "red" self.hostname = "red"
hs = HomeServer( hs = HomeServer(
self.hostname, self.hostname,
@ -38,7 +41,6 @@ class RoomMemberHandlerTestCase(unittest.TestCase):
ratelimiter=NonCallableMock(spec_set=[ ratelimiter=NonCallableMock(spec_set=[
"send_message", "send_message",
]), ]),
config=NonCallableMock(),
datastore=NonCallableMock(spec_set=[ datastore=NonCallableMock(spec_set=[
"persist_event", "persist_event",
"get_joined_hosts_for_room", "get_joined_hosts_for_room",
@ -57,6 +59,7 @@ class RoomMemberHandlerTestCase(unittest.TestCase):
]), ]),
auth=NonCallableMock(spec_set=["check"]), auth=NonCallableMock(spec_set=["check"]),
state_handler=NonCallableMock(spec_set=["handle_new_event"]), state_handler=NonCallableMock(spec_set=["handle_new_event"]),
config=self.mock_config,
) )
self.federation = NonCallableMock(spec_set=[ self.federation = NonCallableMock(spec_set=[

View File

@ -20,7 +20,7 @@ from twisted.internet import defer
from mock import Mock, call, ANY from mock import Mock, call, ANY
import json import json
from ..utils import MockHttpResource, MockClock, DeferredMockCallable from ..utils import MockHttpResource, MockClock, DeferredMockCallable, MockKey
from synapse.server import HomeServer from synapse.server import HomeServer
from synapse.handlers.typing import TypingNotificationHandler from synapse.handlers.typing import TypingNotificationHandler
@ -61,6 +61,9 @@ class TypingNotificationsTestCase(unittest.TestCase):
self.mock_federation_resource = MockHttpResource() self.mock_federation_resource = MockHttpResource()
self.mock_config = Mock()
self.mock_config.signing_key = [MockKey()]
hs = HomeServer("test", hs = HomeServer("test",
clock=self.clock, clock=self.clock,
db_pool=None, db_pool=None,
@ -75,6 +78,7 @@ class TypingNotificationsTestCase(unittest.TestCase):
resource_for_client=Mock(), resource_for_client=Mock(),
resource_for_federation=self.mock_federation_resource, resource_for_federation=self.mock_federation_resource,
http_client=self.mock_http_client, http_client=self.mock_http_client,
config=self.mock_config,
) )
hs.handlers = JustTypingNotificationHandlers(hs) hs.handlers = JustTypingNotificationHandlers(hs)

View File

@ -20,7 +20,7 @@ from twisted.internet import defer
from mock import Mock from mock import Mock
from ..utils import MockHttpResource from ..utils import MockHttpResource, MockKey
from synapse.api.constants import PresenceState from synapse.api.constants import PresenceState
from synapse.handlers.presence import PresenceHandler from synapse.handlers.presence import PresenceHandler
@ -45,7 +45,8 @@ class PresenceStateTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) self.mock_resource = MockHttpResource(prefix=PATH_PREFIX)
self.mock_config = Mock()
self.mock_config.signing_key = [MockKey()]
hs = HomeServer("test", hs = HomeServer("test",
db_pool=None, db_pool=None,
datastore=Mock(spec=[ datastore=Mock(spec=[
@ -55,6 +56,7 @@ class PresenceStateTestCase(unittest.TestCase):
http_client=None, http_client=None,
resource_for_client=self.mock_resource, resource_for_client=self.mock_resource,
resource_for_federation=self.mock_resource, resource_for_federation=self.mock_resource,
config=self.mock_config,
) )
hs.handlers = JustPresenceHandlers(hs) hs.handlers = JustPresenceHandlers(hs)
@ -119,6 +121,8 @@ class PresenceListTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) self.mock_resource = MockHttpResource(prefix=PATH_PREFIX)
self.mock_config = Mock()
self.mock_config.signing_key = [MockKey()]
hs = HomeServer("test", hs = HomeServer("test",
db_pool=None, db_pool=None,
@ -134,7 +138,8 @@ class PresenceListTestCase(unittest.TestCase):
]), ]),
http_client=None, http_client=None,
resource_for_client=self.mock_resource, resource_for_client=self.mock_resource,
resource_for_federation=self.mock_resource resource_for_federation=self.mock_resource,
config=self.mock_config,
) )
hs.handlers = JustPresenceHandlers(hs) hs.handlers = JustPresenceHandlers(hs)
@ -225,6 +230,9 @@ class PresenceEventStreamTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) self.mock_resource = MockHttpResource(prefix=PATH_PREFIX)
self.mock_config = Mock()
self.mock_config.signing_key = [MockKey()]
# HIDEOUS HACKERY # HIDEOUS HACKERY
# TODO(paul): This should be injected in via the HomeServer DI system # TODO(paul): This should be injected in via the HomeServer DI system
from synapse.streams.events import ( from synapse.streams.events import (
@ -255,6 +263,7 @@ class PresenceEventStreamTestCase(unittest.TestCase):
"cancel_call_later", "cancel_call_later",
"time_msec", "time_msec",
]), ]),
config=self.mock_config,
) )
hs.get_clock().time_msec.return_value = 1000000 hs.get_clock().time_msec.return_value = 1000000

View File

@ -108,6 +108,21 @@ class MockHttpResource(HttpServer):
self.callbacks.append((method, path_pattern, callback)) self.callbacks.append((method, path_pattern, callback))
class MockKey(object):
alg = "mock_alg"
version = "mock_version"
@property
def verify_key(self):
return self
def sign(self, message):
return b"\x9a\x87$"
def verify(self, message, sig):
assert sig == b"\x9a\x87$"
class MockClock(object): class MockClock(object):
now = 1000 now = 1000