forked from MirrorHub/synapse
Merge branch 'develop' of github.com:matrix-org/synapse into anoa/dm_room_upgrade
This commit is contained in:
commit
4026d555fa
32 changed files with 557 additions and 124 deletions
|
@ -18,7 +18,7 @@ instructions that may be required are listed later in this document.
|
||||||
|
|
||||||
.. code:: bash
|
.. code:: bash
|
||||||
|
|
||||||
pip install --upgrade --process-dependency-links matrix-synapse
|
pip install --upgrade matrix-synapse
|
||||||
|
|
||||||
# restart synapse
|
# restart synapse
|
||||||
synctl restart
|
synctl restart
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Synapse will now take advantage of native UPSERT functionality in PostgreSQL 9.5+ and SQLite 3.24+.
|
Synapse will now take advantage of native UPSERT functionality in PostgreSQL 9.5+.
|
||||||
|
|
1
changelog.d/4466.misc
Normal file
1
changelog.d/4466.misc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Synapse will now take advantage of native UPSERT functionality in PostgreSQL 9.5+ and SQLite 3.24+.
|
1
changelog.d/4468.misc
Normal file
1
changelog.d/4468.misc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Move SRV logic into the Agent layer
|
1
changelog.d/4470.misc
Normal file
1
changelog.d/4470.misc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Add infrastructure to support different event formats
|
1
changelog.d/4471.misc
Normal file
1
changelog.d/4471.misc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Synapse will now take advantage of native UPSERT functionality in PostgreSQL 9.5+.
|
1
changelog.d/4476.misc
Normal file
1
changelog.d/4476.misc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Fix quoting for allowed_local_3pids example config
|
1
changelog.d/4485.misc
Normal file
1
changelog.d/4485.misc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Remove deprecated --process-dependency-links option from UPGRADE.rst
|
1
changelog.d/4487.misc
Normal file
1
changelog.d/4487.misc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Fix idna and ipv6 literal handling in MatrixFederationAgent
|
1
changelog.d/4488.feature
Normal file
1
changelog.d/4488.feature
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Implement MSC1708 (.well-known routing for server-server federation)
|
|
@ -84,11 +84,11 @@ class RegistrationConfig(Config):
|
||||||
#
|
#
|
||||||
# allowed_local_3pids:
|
# allowed_local_3pids:
|
||||||
# - medium: email
|
# - medium: email
|
||||||
# pattern: ".*@matrix\\.org"
|
# pattern: '.*@matrix\\.org'
|
||||||
# - medium: email
|
# - medium: email
|
||||||
# pattern: ".*@vector\\.im"
|
# pattern: '.*@vector\\.im'
|
||||||
# - medium: msisdn
|
# - medium: msisdn
|
||||||
# pattern: "\\+44"
|
# pattern: '\\+44'
|
||||||
|
|
||||||
# If set, allows registration by anyone who also has the shared
|
# If set, allows registration by anyone who also has the shared
|
||||||
# secret, even if registration is otherwise disabled.
|
# secret, even if registration is otherwise disabled.
|
||||||
|
|
|
@ -18,7 +18,11 @@ from distutils.util import strtobool
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from synapse.api.constants import KNOWN_ROOM_VERSIONS, EventFormatVersions
|
from synapse.api.constants import (
|
||||||
|
KNOWN_EVENT_FORMAT_VERSIONS,
|
||||||
|
KNOWN_ROOM_VERSIONS,
|
||||||
|
EventFormatVersions,
|
||||||
|
)
|
||||||
from synapse.util.caches import intern_dict
|
from synapse.util.caches import intern_dict
|
||||||
from synapse.util.frozenutils import freeze
|
from synapse.util.frozenutils import freeze
|
||||||
|
|
||||||
|
@ -256,3 +260,21 @@ def room_version_to_event_format(room_version):
|
||||||
raise RuntimeError("Unrecognized room version %s" % (room_version,))
|
raise RuntimeError("Unrecognized room version %s" % (room_version,))
|
||||||
|
|
||||||
return EventFormatVersions.V1
|
return EventFormatVersions.V1
|
||||||
|
|
||||||
|
|
||||||
|
def event_type_from_format_version(format_version):
|
||||||
|
"""Returns the python type to use to construct an Event object for the
|
||||||
|
given event format version.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
format_version (int): The event format version
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
type: A type that can be initialized as per the initializer of
|
||||||
|
`FrozenEvent`
|
||||||
|
"""
|
||||||
|
if format_version not in KNOWN_EVENT_FORMAT_VERSIONS:
|
||||||
|
raise Exception(
|
||||||
|
"No event format %r" % (format_version,)
|
||||||
|
)
|
||||||
|
return FrozenEvent
|
||||||
|
|
|
@ -15,12 +15,39 @@
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
from synapse.api.constants import RoomVersions
|
||||||
from synapse.types import EventID
|
from synapse.types import EventID
|
||||||
from synapse.util.stringutils import random_string
|
from synapse.util.stringutils import random_string
|
||||||
|
|
||||||
from . import EventBase, FrozenEvent, _event_dict_property
|
from . import EventBase, FrozenEvent, _event_dict_property
|
||||||
|
|
||||||
|
|
||||||
|
def get_event_builder(room_version, key_values={}, internal_metadata_dict={}):
|
||||||
|
"""Generate an event builder appropriate for the given room version
|
||||||
|
|
||||||
|
Args:
|
||||||
|
room_version (str): Version of the room that we're creating an
|
||||||
|
event builder for
|
||||||
|
key_values (dict): Fields used as the basis of the new event
|
||||||
|
internal_metadata_dict (dict): Used to create the `_EventInternalMetadata`
|
||||||
|
object.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
EventBuilder
|
||||||
|
"""
|
||||||
|
if room_version in {
|
||||||
|
RoomVersions.V1,
|
||||||
|
RoomVersions.V2,
|
||||||
|
RoomVersions.VDH_TEST,
|
||||||
|
RoomVersions.STATE_V2_TEST,
|
||||||
|
}:
|
||||||
|
return EventBuilder(key_values, internal_metadata_dict)
|
||||||
|
else:
|
||||||
|
raise Exception(
|
||||||
|
"No event format defined for version %r" % (room_version,)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EventBuilder(EventBase):
|
class EventBuilder(EventBase):
|
||||||
def __init__(self, key_values={}, internal_metadata_dict={}):
|
def __init__(self, key_values={}, internal_metadata_dict={}):
|
||||||
signatures = copy.deepcopy(key_values.pop("signatures", {}))
|
signatures = copy.deepcopy(key_values.pop("signatures", {}))
|
||||||
|
@ -58,7 +85,29 @@ class EventBuilderFactory(object):
|
||||||
|
|
||||||
return e_id.to_string()
|
return e_id.to_string()
|
||||||
|
|
||||||
def new(self, key_values={}):
|
def new(self, room_version, key_values={}):
|
||||||
|
"""Generate an event builder appropriate for the given room version
|
||||||
|
|
||||||
|
Args:
|
||||||
|
room_version (str): Version of the room that we're creating an
|
||||||
|
event builder for
|
||||||
|
key_values (dict): Fields used as the basis of the new event
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
EventBuilder
|
||||||
|
"""
|
||||||
|
|
||||||
|
# There's currently only the one event version defined
|
||||||
|
if room_version not in {
|
||||||
|
RoomVersions.V1,
|
||||||
|
RoomVersions.V2,
|
||||||
|
RoomVersions.VDH_TEST,
|
||||||
|
RoomVersions.STATE_V2_TEST,
|
||||||
|
}:
|
||||||
|
raise Exception(
|
||||||
|
"No event format defined for version %r" % (room_version,)
|
||||||
|
)
|
||||||
|
|
||||||
key_values["event_id"] = self.create_event_id()
|
key_values["event_id"] = self.create_event_id()
|
||||||
|
|
||||||
time_now = int(self.clock.time_msec())
|
time_now = int(self.clock.time_msec())
|
||||||
|
|
|
@ -23,7 +23,7 @@ from twisted.internet.defer import DeferredList
|
||||||
from synapse.api.constants import MAX_DEPTH, EventTypes, Membership
|
from synapse.api.constants import MAX_DEPTH, EventTypes, Membership
|
||||||
from synapse.api.errors import Codes, SynapseError
|
from synapse.api.errors import Codes, SynapseError
|
||||||
from synapse.crypto.event_signing import check_event_content_hash
|
from synapse.crypto.event_signing import check_event_content_hash
|
||||||
from synapse.events import FrozenEvent
|
from synapse.events import event_type_from_format_version
|
||||||
from synapse.events.utils import prune_event
|
from synapse.events.utils import prune_event
|
||||||
from synapse.http.servlet import assert_params_in_dict
|
from synapse.http.servlet import assert_params_in_dict
|
||||||
from synapse.types import get_domain_from_id
|
from synapse.types import get_domain_from_id
|
||||||
|
@ -302,11 +302,12 @@ def _is_invite_via_3pid(event):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def event_from_pdu_json(pdu_json, outlier=False):
|
def event_from_pdu_json(pdu_json, event_format_version, outlier=False):
|
||||||
"""Construct a FrozenEvent from an event json received over federation
|
"""Construct a FrozenEvent from an event json received over federation
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
pdu_json (object): pdu as received over federation
|
pdu_json (object): pdu as received over federation
|
||||||
|
event_format_version (int): The event format version
|
||||||
outlier (bool): True to mark this event as an outlier
|
outlier (bool): True to mark this event as an outlier
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -330,8 +331,8 @@ def event_from_pdu_json(pdu_json, outlier=False):
|
||||||
elif depth > MAX_DEPTH:
|
elif depth > MAX_DEPTH:
|
||||||
raise SynapseError(400, "Depth too large", Codes.BAD_JSON)
|
raise SynapseError(400, "Depth too large", Codes.BAD_JSON)
|
||||||
|
|
||||||
event = FrozenEvent(
|
event = event_type_from_format_version(event_format_version)(
|
||||||
pdu_json
|
pdu_json,
|
||||||
)
|
)
|
||||||
|
|
||||||
event.internal_metadata.outlier = outlier
|
event.internal_metadata.outlier = outlier
|
||||||
|
|
|
@ -170,13 +170,13 @@ class FederationClient(FederationBase):
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
@log_function
|
@log_function
|
||||||
def backfill(self, dest, context, limit, extremities):
|
def backfill(self, dest, room_id, limit, extremities):
|
||||||
"""Requests some more historic PDUs for the given context from the
|
"""Requests some more historic PDUs for the given context from the
|
||||||
given destination server.
|
given destination server.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
dest (str): The remote home server to ask.
|
dest (str): The remote home server to ask.
|
||||||
context (str): The context to backfill.
|
room_id (str): The room_id to backfill.
|
||||||
limit (int): The maximum number of PDUs to return.
|
limit (int): The maximum number of PDUs to return.
|
||||||
extremities (list): List of PDU id and origins of the first pdus
|
extremities (list): List of PDU id and origins of the first pdus
|
||||||
we have seen from the context
|
we have seen from the context
|
||||||
|
@ -191,12 +191,15 @@ class FederationClient(FederationBase):
|
||||||
return
|
return
|
||||||
|
|
||||||
transaction_data = yield self.transport_layer.backfill(
|
transaction_data = yield self.transport_layer.backfill(
|
||||||
dest, context, extremities, limit)
|
dest, room_id, extremities, limit)
|
||||||
|
|
||||||
logger.debug("backfill transaction_data=%s", repr(transaction_data))
|
logger.debug("backfill transaction_data=%s", repr(transaction_data))
|
||||||
|
|
||||||
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
|
format_ver = room_version_to_event_format(room_version)
|
||||||
|
|
||||||
pdus = [
|
pdus = [
|
||||||
event_from_pdu_json(p, outlier=False)
|
event_from_pdu_json(p, format_ver, outlier=False)
|
||||||
for p in transaction_data["pdus"]
|
for p in transaction_data["pdus"]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -240,6 +243,8 @@ class FederationClient(FederationBase):
|
||||||
|
|
||||||
pdu_attempts = self.pdu_destination_tried.setdefault(event_id, {})
|
pdu_attempts = self.pdu_destination_tried.setdefault(event_id, {})
|
||||||
|
|
||||||
|
format_ver = room_version_to_event_format(room_version)
|
||||||
|
|
||||||
signed_pdu = None
|
signed_pdu = None
|
||||||
for destination in destinations:
|
for destination in destinations:
|
||||||
now = self._clock.time_msec()
|
now = self._clock.time_msec()
|
||||||
|
@ -255,7 +260,7 @@ class FederationClient(FederationBase):
|
||||||
logger.debug("transaction_data %r", transaction_data)
|
logger.debug("transaction_data %r", transaction_data)
|
||||||
|
|
||||||
pdu_list = [
|
pdu_list = [
|
||||||
event_from_pdu_json(p, outlier=outlier)
|
event_from_pdu_json(p, format_ver, outlier=outlier)
|
||||||
for p in transaction_data["pdus"]
|
for p in transaction_data["pdus"]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -349,12 +354,16 @@ class FederationClient(FederationBase):
|
||||||
destination, room_id, event_id=event_id,
|
destination, room_id, event_id=event_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
|
format_ver = room_version_to_event_format(room_version)
|
||||||
|
|
||||||
pdus = [
|
pdus = [
|
||||||
event_from_pdu_json(p, outlier=True) for p in result["pdus"]
|
event_from_pdu_json(p, format_ver, outlier=True)
|
||||||
|
for p in result["pdus"]
|
||||||
]
|
]
|
||||||
|
|
||||||
auth_chain = [
|
auth_chain = [
|
||||||
event_from_pdu_json(p, outlier=True)
|
event_from_pdu_json(p, format_ver, outlier=True)
|
||||||
for p in result.get("auth_chain", [])
|
for p in result.get("auth_chain", [])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -362,8 +371,6 @@ class FederationClient(FederationBase):
|
||||||
ev.event_id for ev in itertools.chain(pdus, auth_chain)
|
ev.event_id for ev in itertools.chain(pdus, auth_chain)
|
||||||
])
|
])
|
||||||
|
|
||||||
room_version = yield self.store.get_room_version(room_id)
|
|
||||||
|
|
||||||
signed_pdus = yield self._check_sigs_and_hash_and_fetch(
|
signed_pdus = yield self._check_sigs_and_hash_and_fetch(
|
||||||
destination,
|
destination,
|
||||||
[p for p in pdus if p.event_id not in seen_events],
|
[p for p in pdus if p.event_id not in seen_events],
|
||||||
|
@ -462,13 +469,14 @@ class FederationClient(FederationBase):
|
||||||
destination, room_id, event_id,
|
destination, room_id, event_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
|
format_ver = room_version_to_event_format(room_version)
|
||||||
|
|
||||||
auth_chain = [
|
auth_chain = [
|
||||||
event_from_pdu_json(p, outlier=True)
|
event_from_pdu_json(p, format_ver, outlier=True)
|
||||||
for p in res["auth_chain"]
|
for p in res["auth_chain"]
|
||||||
]
|
]
|
||||||
|
|
||||||
room_version = yield self.store.get_room_version(room_id)
|
|
||||||
|
|
||||||
signed_auth = yield self._check_sigs_and_hash_and_fetch(
|
signed_auth = yield self._check_sigs_and_hash_and_fetch(
|
||||||
destination, auth_chain,
|
destination, auth_chain,
|
||||||
outlier=True, room_version=room_version,
|
outlier=True, room_version=room_version,
|
||||||
|
@ -605,7 +613,7 @@ class FederationClient(FederationBase):
|
||||||
pdu_dict.pop("origin_server_ts", None)
|
pdu_dict.pop("origin_server_ts", None)
|
||||||
pdu_dict.pop("unsigned", None)
|
pdu_dict.pop("unsigned", None)
|
||||||
|
|
||||||
builder = self.event_builder_factory.new(pdu_dict)
|
builder = self.event_builder_factory.new(room_version, pdu_dict)
|
||||||
add_hashes_and_signatures(
|
add_hashes_and_signatures(
|
||||||
builder,
|
builder,
|
||||||
self.hs.hostname,
|
self.hs.hostname,
|
||||||
|
@ -621,7 +629,7 @@ class FederationClient(FederationBase):
|
||||||
"make_" + membership, destinations, send_request,
|
"make_" + membership, destinations, send_request,
|
||||||
)
|
)
|
||||||
|
|
||||||
def send_join(self, destinations, pdu):
|
def send_join(self, destinations, pdu, event_format_version):
|
||||||
"""Sends a join event to one of a list of homeservers.
|
"""Sends a join event to one of a list of homeservers.
|
||||||
|
|
||||||
Doing so will cause the remote server to add the event to the graph,
|
Doing so will cause the remote server to add the event to the graph,
|
||||||
|
@ -631,6 +639,7 @@ class FederationClient(FederationBase):
|
||||||
destinations (str): Candidate homeservers which are probably
|
destinations (str): Candidate homeservers which are probably
|
||||||
participating in the room.
|
participating in the room.
|
||||||
pdu (BaseEvent): event to be sent
|
pdu (BaseEvent): event to be sent
|
||||||
|
event_format_version (int): The event format version
|
||||||
|
|
||||||
Return:
|
Return:
|
||||||
Deferred: resolves to a dict with members ``origin`` (a string
|
Deferred: resolves to a dict with members ``origin`` (a string
|
||||||
|
@ -676,12 +685,12 @@ class FederationClient(FederationBase):
|
||||||
logger.debug("Got content: %s", content)
|
logger.debug("Got content: %s", content)
|
||||||
|
|
||||||
state = [
|
state = [
|
||||||
event_from_pdu_json(p, outlier=True)
|
event_from_pdu_json(p, event_format_version, outlier=True)
|
||||||
for p in content.get("state", [])
|
for p in content.get("state", [])
|
||||||
]
|
]
|
||||||
|
|
||||||
auth_chain = [
|
auth_chain = [
|
||||||
event_from_pdu_json(p, outlier=True)
|
event_from_pdu_json(p, event_format_version, outlier=True)
|
||||||
for p in content.get("auth_chain", [])
|
for p in content.get("auth_chain", [])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -759,7 +768,10 @@ class FederationClient(FederationBase):
|
||||||
|
|
||||||
logger.debug("Got response to send_invite: %s", pdu_dict)
|
logger.debug("Got response to send_invite: %s", pdu_dict)
|
||||||
|
|
||||||
pdu = event_from_pdu_json(pdu_dict)
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
|
format_ver = room_version_to_event_format(room_version)
|
||||||
|
|
||||||
|
pdu = event_from_pdu_json(pdu_dict, format_ver)
|
||||||
|
|
||||||
# Check signatures are correct.
|
# Check signatures are correct.
|
||||||
pdu = yield self._check_sigs_and_hash(pdu)
|
pdu = yield self._check_sigs_and_hash(pdu)
|
||||||
|
@ -837,13 +849,14 @@ class FederationClient(FederationBase):
|
||||||
content=send_content,
|
content=send_content,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
|
format_ver = room_version_to_event_format(room_version)
|
||||||
|
|
||||||
auth_chain = [
|
auth_chain = [
|
||||||
event_from_pdu_json(e)
|
event_from_pdu_json(e, format_ver)
|
||||||
for e in content["auth_chain"]
|
for e in content["auth_chain"]
|
||||||
]
|
]
|
||||||
|
|
||||||
room_version = yield self.store.get_room_version(room_id)
|
|
||||||
|
|
||||||
signed_auth = yield self._check_sigs_and_hash_and_fetch(
|
signed_auth = yield self._check_sigs_and_hash_and_fetch(
|
||||||
destination, auth_chain, outlier=True, room_version=room_version,
|
destination, auth_chain, outlier=True, room_version=room_version,
|
||||||
)
|
)
|
||||||
|
@ -887,13 +900,14 @@ class FederationClient(FederationBase):
|
||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
|
format_ver = room_version_to_event_format(room_version)
|
||||||
|
|
||||||
events = [
|
events = [
|
||||||
event_from_pdu_json(e)
|
event_from_pdu_json(e, format_ver)
|
||||||
for e in content.get("events", [])
|
for e in content.get("events", [])
|
||||||
]
|
]
|
||||||
|
|
||||||
room_version = yield self.store.get_room_version(room_id)
|
|
||||||
|
|
||||||
signed_events = yield self._check_sigs_and_hash_and_fetch(
|
signed_events = yield self._check_sigs_and_hash_and_fetch(
|
||||||
destination, events, outlier=False, room_version=room_version,
|
destination, events, outlier=False, room_version=room_version,
|
||||||
)
|
)
|
||||||
|
|
|
@ -34,6 +34,7 @@ from synapse.api.errors import (
|
||||||
SynapseError,
|
SynapseError,
|
||||||
)
|
)
|
||||||
from synapse.crypto.event_signing import compute_event_signature
|
from synapse.crypto.event_signing import compute_event_signature
|
||||||
|
from synapse.events import room_version_to_event_format
|
||||||
from synapse.federation.federation_base import FederationBase, event_from_pdu_json
|
from synapse.federation.federation_base import FederationBase, event_from_pdu_json
|
||||||
from synapse.federation.persistence import TransactionActions
|
from synapse.federation.persistence import TransactionActions
|
||||||
from synapse.federation.units import Edu, Transaction
|
from synapse.federation.units import Edu, Transaction
|
||||||
|
@ -178,14 +179,13 @@ class FederationServer(FederationBase):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# In future we will actually use the room version to parse the
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
# PDU into an event.
|
format_ver = room_version_to_event_format(room_version)
|
||||||
yield self.store.get_room_version(room_id)
|
|
||||||
except NotFoundError:
|
except NotFoundError:
|
||||||
logger.info("Ignoring PDU for unknown room_id: %s", room_id)
|
logger.info("Ignoring PDU for unknown room_id: %s", room_id)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
event = event_from_pdu_json(p)
|
event = event_from_pdu_json(p, format_ver)
|
||||||
pdus_by_room.setdefault(room_id, []).append(event)
|
pdus_by_room.setdefault(room_id, []).append(event)
|
||||||
|
|
||||||
pdu_results = {}
|
pdu_results = {}
|
||||||
|
@ -370,7 +370,9 @@ class FederationServer(FederationBase):
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def on_invite_request(self, origin, content, room_version):
|
def on_invite_request(self, origin, content, room_version):
|
||||||
pdu = event_from_pdu_json(content)
|
format_ver = room_version_to_event_format(room_version)
|
||||||
|
|
||||||
|
pdu = event_from_pdu_json(content, format_ver)
|
||||||
origin_host, _ = parse_server_name(origin)
|
origin_host, _ = parse_server_name(origin)
|
||||||
yield self.check_server_matches_acl(origin_host, pdu.room_id)
|
yield self.check_server_matches_acl(origin_host, pdu.room_id)
|
||||||
ret_pdu = yield self.handler.on_invite_request(origin, pdu)
|
ret_pdu = yield self.handler.on_invite_request(origin, pdu)
|
||||||
|
@ -378,9 +380,12 @@ class FederationServer(FederationBase):
|
||||||
defer.returnValue({"event": ret_pdu.get_pdu_json(time_now)})
|
defer.returnValue({"event": ret_pdu.get_pdu_json(time_now)})
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def on_send_join_request(self, origin, content):
|
def on_send_join_request(self, origin, content, room_id):
|
||||||
logger.debug("on_send_join_request: content: %s", content)
|
logger.debug("on_send_join_request: content: %s", content)
|
||||||
pdu = event_from_pdu_json(content)
|
|
||||||
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
|
format_ver = room_version_to_event_format(room_version)
|
||||||
|
pdu = event_from_pdu_json(content, format_ver)
|
||||||
|
|
||||||
origin_host, _ = parse_server_name(origin)
|
origin_host, _ = parse_server_name(origin)
|
||||||
yield self.check_server_matches_acl(origin_host, pdu.room_id)
|
yield self.check_server_matches_acl(origin_host, pdu.room_id)
|
||||||
|
@ -410,9 +415,12 @@ class FederationServer(FederationBase):
|
||||||
})
|
})
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def on_send_leave_request(self, origin, content):
|
def on_send_leave_request(self, origin, content, room_id):
|
||||||
logger.debug("on_send_leave_request: content: %s", content)
|
logger.debug("on_send_leave_request: content: %s", content)
|
||||||
pdu = event_from_pdu_json(content)
|
|
||||||
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
|
format_ver = room_version_to_event_format(room_version)
|
||||||
|
pdu = event_from_pdu_json(content, format_ver)
|
||||||
|
|
||||||
origin_host, _ = parse_server_name(origin)
|
origin_host, _ = parse_server_name(origin)
|
||||||
yield self.check_server_matches_acl(origin_host, pdu.room_id)
|
yield self.check_server_matches_acl(origin_host, pdu.room_id)
|
||||||
|
@ -458,13 +466,14 @@ class FederationServer(FederationBase):
|
||||||
origin_host, _ = parse_server_name(origin)
|
origin_host, _ = parse_server_name(origin)
|
||||||
yield self.check_server_matches_acl(origin_host, room_id)
|
yield self.check_server_matches_acl(origin_host, room_id)
|
||||||
|
|
||||||
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
|
format_ver = room_version_to_event_format(room_version)
|
||||||
|
|
||||||
auth_chain = [
|
auth_chain = [
|
||||||
event_from_pdu_json(e)
|
event_from_pdu_json(e, format_ver)
|
||||||
for e in content["auth_chain"]
|
for e in content["auth_chain"]
|
||||||
]
|
]
|
||||||
|
|
||||||
room_version = yield self.store.get_room_version(room_id)
|
|
||||||
|
|
||||||
signed_auth = yield self._check_sigs_and_hash_and_fetch(
|
signed_auth = yield self._check_sigs_and_hash_and_fetch(
|
||||||
origin, auth_chain, outlier=True, room_version=room_version,
|
origin, auth_chain, outlier=True, room_version=room_version,
|
||||||
)
|
)
|
||||||
|
|
|
@ -469,7 +469,7 @@ class FederationSendLeaveServlet(BaseFederationServlet):
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def on_PUT(self, origin, content, query, room_id, event_id):
|
def on_PUT(self, origin, content, query, room_id, event_id):
|
||||||
content = yield self.handler.on_send_leave_request(origin, content)
|
content = yield self.handler.on_send_leave_request(origin, content, room_id)
|
||||||
defer.returnValue((200, content))
|
defer.returnValue((200, content))
|
||||||
|
|
||||||
|
|
||||||
|
@ -487,7 +487,7 @@ class FederationSendJoinServlet(BaseFederationServlet):
|
||||||
def on_PUT(self, origin, content, query, context, event_id):
|
def on_PUT(self, origin, content, query, context, event_id):
|
||||||
# TODO(paul): assert that context/event_id parsed from path actually
|
# TODO(paul): assert that context/event_id parsed from path actually
|
||||||
# match those given in content
|
# match those given in content
|
||||||
content = yield self.handler.on_send_join_request(origin, content)
|
content = yield self.handler.on_send_join_request(origin, content, context)
|
||||||
defer.returnValue((200, content))
|
defer.returnValue((200, content))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1061,7 +1061,7 @@ class FederationHandler(BaseHandler):
|
||||||
"""
|
"""
|
||||||
logger.debug("Joining %s to %s", joinee, room_id)
|
logger.debug("Joining %s to %s", joinee, room_id)
|
||||||
|
|
||||||
origin, event = yield self._make_and_verify_event(
|
origin, event, event_format_version = yield self._make_and_verify_event(
|
||||||
target_hosts,
|
target_hosts,
|
||||||
room_id,
|
room_id,
|
||||||
joinee,
|
joinee,
|
||||||
|
@ -1091,7 +1091,9 @@ class FederationHandler(BaseHandler):
|
||||||
target_hosts.insert(0, origin)
|
target_hosts.insert(0, origin)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
ret = yield self.federation_client.send_join(target_hosts, event)
|
ret = yield self.federation_client.send_join(
|
||||||
|
target_hosts, event, event_format_version,
|
||||||
|
)
|
||||||
|
|
||||||
origin = ret["origin"]
|
origin = ret["origin"]
|
||||||
state = ret["state"]
|
state = ret["state"]
|
||||||
|
@ -1164,13 +1166,18 @@ class FederationHandler(BaseHandler):
|
||||||
"""
|
"""
|
||||||
event_content = {"membership": Membership.JOIN}
|
event_content = {"membership": Membership.JOIN}
|
||||||
|
|
||||||
builder = self.event_builder_factory.new({
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
"type": EventTypes.Member,
|
|
||||||
"content": event_content,
|
builder = self.event_builder_factory.new(
|
||||||
"room_id": room_id,
|
room_version,
|
||||||
"sender": user_id,
|
{
|
||||||
"state_key": user_id,
|
"type": EventTypes.Member,
|
||||||
})
|
"content": event_content,
|
||||||
|
"room_id": room_id,
|
||||||
|
"sender": user_id,
|
||||||
|
"state_key": user_id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
event, context = yield self.event_creation_handler.create_new_client_event(
|
event, context = yield self.event_creation_handler.create_new_client_event(
|
||||||
|
@ -1304,7 +1311,7 @@ class FederationHandler(BaseHandler):
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def do_remotely_reject_invite(self, target_hosts, room_id, user_id):
|
def do_remotely_reject_invite(self, target_hosts, room_id, user_id):
|
||||||
origin, event = yield self._make_and_verify_event(
|
origin, event, event_format_version = yield self._make_and_verify_event(
|
||||||
target_hosts,
|
target_hosts,
|
||||||
room_id,
|
room_id,
|
||||||
user_id,
|
user_id,
|
||||||
|
@ -1336,7 +1343,7 @@ class FederationHandler(BaseHandler):
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def _make_and_verify_event(self, target_hosts, room_id, user_id, membership,
|
def _make_and_verify_event(self, target_hosts, room_id, user_id, membership,
|
||||||
content={}, params=None):
|
content={}, params=None):
|
||||||
origin, pdu, _ = yield self.federation_client.make_membership_event(
|
origin, event, format_ver = yield self.federation_client.make_membership_event(
|
||||||
target_hosts,
|
target_hosts,
|
||||||
room_id,
|
room_id,
|
||||||
user_id,
|
user_id,
|
||||||
|
@ -1345,9 +1352,7 @@ class FederationHandler(BaseHandler):
|
||||||
params=params,
|
params=params,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug("Got response to make_%s: %s", membership, pdu)
|
logger.debug("Got response to make_%s: %s", membership, event)
|
||||||
|
|
||||||
event = pdu
|
|
||||||
|
|
||||||
# We should assert some things.
|
# We should assert some things.
|
||||||
# FIXME: Do this in a nicer way
|
# FIXME: Do this in a nicer way
|
||||||
|
@ -1355,7 +1360,7 @@ class FederationHandler(BaseHandler):
|
||||||
assert(event.user_id == user_id)
|
assert(event.user_id == user_id)
|
||||||
assert(event.state_key == user_id)
|
assert(event.state_key == user_id)
|
||||||
assert(event.room_id == room_id)
|
assert(event.room_id == room_id)
|
||||||
defer.returnValue((origin, event))
|
defer.returnValue((origin, event, format_ver))
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
@log_function
|
@log_function
|
||||||
|
@ -1364,13 +1369,17 @@ class FederationHandler(BaseHandler):
|
||||||
leave event for the room and return that. We do *not* persist or
|
leave event for the room and return that. We do *not* persist or
|
||||||
process it until the other server has signed it and sent it back.
|
process it until the other server has signed it and sent it back.
|
||||||
"""
|
"""
|
||||||
builder = self.event_builder_factory.new({
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
"type": EventTypes.Member,
|
builder = self.event_builder_factory.new(
|
||||||
"content": {"membership": Membership.LEAVE},
|
room_version,
|
||||||
"room_id": room_id,
|
{
|
||||||
"sender": user_id,
|
"type": EventTypes.Member,
|
||||||
"state_key": user_id,
|
"content": {"membership": Membership.LEAVE},
|
||||||
})
|
"room_id": room_id,
|
||||||
|
"sender": user_id,
|
||||||
|
"state_key": user_id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
event, context = yield self.event_creation_handler.create_new_client_event(
|
event, context = yield self.event_creation_handler.create_new_client_event(
|
||||||
builder=builder,
|
builder=builder,
|
||||||
|
@ -2266,14 +2275,16 @@ class FederationHandler(BaseHandler):
|
||||||
}
|
}
|
||||||
|
|
||||||
if (yield self.auth.check_host_in_room(room_id, self.hs.hostname)):
|
if (yield self.auth.check_host_in_room(room_id, self.hs.hostname)):
|
||||||
builder = self.event_builder_factory.new(event_dict)
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
|
builder = self.event_builder_factory.new(room_version, event_dict)
|
||||||
|
|
||||||
EventValidator().validate_new(builder)
|
EventValidator().validate_new(builder)
|
||||||
event, context = yield self.event_creation_handler.create_new_client_event(
|
event, context = yield self.event_creation_handler.create_new_client_event(
|
||||||
builder=builder
|
builder=builder
|
||||||
)
|
)
|
||||||
|
|
||||||
event, context = yield self.add_display_name_to_third_party_invite(
|
event, context = yield self.add_display_name_to_third_party_invite(
|
||||||
event_dict, event, context
|
room_version, event_dict, event, context
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -2304,14 +2315,18 @@ class FederationHandler(BaseHandler):
|
||||||
Returns:
|
Returns:
|
||||||
Deferred: resolves (to None)
|
Deferred: resolves (to None)
|
||||||
"""
|
"""
|
||||||
builder = self.event_builder_factory.new(event_dict)
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
|
|
||||||
|
# NB: event_dict has a particular specced format we might need to fudge
|
||||||
|
# if we change event formats too much.
|
||||||
|
builder = self.event_builder_factory.new(room_version, event_dict)
|
||||||
|
|
||||||
event, context = yield self.event_creation_handler.create_new_client_event(
|
event, context = yield self.event_creation_handler.create_new_client_event(
|
||||||
builder=builder,
|
builder=builder,
|
||||||
)
|
)
|
||||||
|
|
||||||
event, context = yield self.add_display_name_to_third_party_invite(
|
event, context = yield self.add_display_name_to_third_party_invite(
|
||||||
event_dict, event, context
|
room_version, event_dict, event, context
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -2331,7 +2346,8 @@ class FederationHandler(BaseHandler):
|
||||||
yield member_handler.send_membership_event(None, event, context)
|
yield member_handler.send_membership_event(None, event, context)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def add_display_name_to_third_party_invite(self, event_dict, event, context):
|
def add_display_name_to_third_party_invite(self, room_version, event_dict,
|
||||||
|
event, context):
|
||||||
key = (
|
key = (
|
||||||
EventTypes.ThirdPartyInvite,
|
EventTypes.ThirdPartyInvite,
|
||||||
event.content["third_party_invite"]["signed"]["token"]
|
event.content["third_party_invite"]["signed"]["token"]
|
||||||
|
@ -2355,7 +2371,7 @@ class FederationHandler(BaseHandler):
|
||||||
# auth checks. If we need the invite and don't have it then the
|
# auth checks. If we need the invite and don't have it then the
|
||||||
# auth check code will explode appropriately.
|
# auth check code will explode appropriately.
|
||||||
|
|
||||||
builder = self.event_builder_factory.new(event_dict)
|
builder = self.event_builder_factory.new(room_version, event_dict)
|
||||||
EventValidator().validate_new(builder)
|
EventValidator().validate_new(builder)
|
||||||
event, context = yield self.event_creation_handler.create_new_client_event(
|
event, context = yield self.event_creation_handler.create_new_client_event(
|
||||||
builder=builder,
|
builder=builder,
|
||||||
|
|
|
@ -278,7 +278,15 @@ class EventCreationHandler(object):
|
||||||
"""
|
"""
|
||||||
yield self.auth.check_auth_blocking(requester.user.to_string())
|
yield self.auth.check_auth_blocking(requester.user.to_string())
|
||||||
|
|
||||||
builder = self.event_builder_factory.new(event_dict)
|
if event_dict["type"] == EventTypes.Create and event_dict["state_key"] == "":
|
||||||
|
room_version = event_dict["content"]["room_version"]
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
room_version = yield self.store.get_room_version(event_dict["room_id"])
|
||||||
|
except NotFoundError:
|
||||||
|
raise AuthError(403, "Unknown room")
|
||||||
|
|
||||||
|
builder = self.event_builder_factory.new(room_version, event_dict)
|
||||||
|
|
||||||
self.validator.validate_new(builder)
|
self.validator.validate_new(builder)
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,16 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
import attr
|
||||||
|
from netaddr import IPAddress
|
||||||
from zope.interface import implementer
|
from zope.interface import implementer
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.internet.endpoints import HostnameEndpoint, wrapClientTLS
|
from twisted.internet.endpoints import HostnameEndpoint, wrapClientTLS
|
||||||
from twisted.web.client import URI, Agent, HTTPConnectionPool
|
from twisted.web.client import URI, Agent, HTTPConnectionPool
|
||||||
|
from twisted.web.http_headers import Headers
|
||||||
from twisted.web.iweb import IAgent
|
from twisted.web.iweb import IAgent
|
||||||
|
|
||||||
from synapse.http.endpoint import parse_server_name
|
|
||||||
from synapse.http.federation.srv_resolver import SrvResolver, pick_server_from_list
|
from synapse.http.federation.srv_resolver import SrvResolver, pick_server_from_list
|
||||||
from synapse.util.logcontext import make_deferred_yieldable
|
from synapse.util.logcontext import make_deferred_yieldable
|
||||||
|
|
||||||
|
@ -85,35 +87,35 @@ class MatrixFederationAgent(object):
|
||||||
response from being received (including problems that prevent the request
|
response from being received (including problems that prevent the request
|
||||||
from being sent).
|
from being sent).
|
||||||
"""
|
"""
|
||||||
|
parsed_uri = URI.fromBytes(uri, defaultPort=-1)
|
||||||
|
res = yield self._route_matrix_uri(parsed_uri)
|
||||||
|
|
||||||
parsed_uri = URI.fromBytes(uri)
|
# set up the TLS connection params
|
||||||
server_name_bytes = parsed_uri.netloc
|
#
|
||||||
host, port = parse_server_name(server_name_bytes.decode("ascii"))
|
|
||||||
|
|
||||||
# XXX disabling TLS is really only supported here for the benefit of the
|
# XXX disabling TLS is really only supported here for the benefit of the
|
||||||
# unit tests. We should make the UTs cope with TLS rather than having to make
|
# unit tests. We should make the UTs cope with TLS rather than having to make
|
||||||
# the code support the unit tests.
|
# the code support the unit tests.
|
||||||
if self._tls_client_options_factory is None:
|
if self._tls_client_options_factory is None:
|
||||||
tls_options = None
|
tls_options = None
|
||||||
else:
|
else:
|
||||||
tls_options = self._tls_client_options_factory.get_options(host)
|
tls_options = self._tls_client_options_factory.get_options(
|
||||||
|
res.tls_server_name.decode("ascii")
|
||||||
|
)
|
||||||
|
|
||||||
if port is not None:
|
# make sure that the Host header is set correctly
|
||||||
target = (host, port)
|
if headers is None:
|
||||||
|
headers = Headers()
|
||||||
else:
|
else:
|
||||||
service_name = b"_matrix._tcp.%s" % (server_name_bytes, )
|
headers = headers.copy()
|
||||||
server_list = yield self._srv_resolver.resolve_service(service_name)
|
|
||||||
if not server_list:
|
if not headers.hasHeader(b'host'):
|
||||||
target = (host, 8448)
|
headers.addRawHeader(b'host', res.host_header)
|
||||||
logger.debug("No SRV record for %s, using %s", host, target)
|
|
||||||
else:
|
|
||||||
target = pick_server_from_list(server_list)
|
|
||||||
|
|
||||||
class EndpointFactory(object):
|
class EndpointFactory(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def endpointForURI(_uri):
|
def endpointForURI(_uri):
|
||||||
logger.info("Connecting to %s:%s", target[0], target[1])
|
logger.info("Connecting to %s:%s", res.target_host, res.target_port)
|
||||||
ep = HostnameEndpoint(self._reactor, host=target[0], port=target[1])
|
ep = HostnameEndpoint(self._reactor, res.target_host, res.target_port)
|
||||||
if tls_options is not None:
|
if tls_options is not None:
|
||||||
ep = wrapClientTLS(tls_options, ep)
|
ep = wrapClientTLS(tls_options, ep)
|
||||||
return ep
|
return ep
|
||||||
|
@ -123,3 +125,111 @@ class MatrixFederationAgent(object):
|
||||||
agent.request(method, uri, headers, bodyProducer)
|
agent.request(method, uri, headers, bodyProducer)
|
||||||
)
|
)
|
||||||
defer.returnValue(res)
|
defer.returnValue(res)
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def _route_matrix_uri(self, parsed_uri):
|
||||||
|
"""Helper for `request`: determine the routing for a Matrix URI
|
||||||
|
|
||||||
|
Args:
|
||||||
|
parsed_uri (twisted.web.client.URI): uri to route. Note that it should be
|
||||||
|
parsed with URI.fromBytes(uri, defaultPort=-1) to set the `port` to -1
|
||||||
|
if there is no explicit port given.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Deferred[_RoutingResult]
|
||||||
|
"""
|
||||||
|
# check for an IP literal
|
||||||
|
try:
|
||||||
|
ip_address = IPAddress(parsed_uri.host.decode("ascii"))
|
||||||
|
except Exception:
|
||||||
|
# not an IP address
|
||||||
|
ip_address = None
|
||||||
|
|
||||||
|
if ip_address:
|
||||||
|
port = parsed_uri.port
|
||||||
|
if port == -1:
|
||||||
|
port = 8448
|
||||||
|
defer.returnValue(_RoutingResult(
|
||||||
|
host_header=parsed_uri.netloc,
|
||||||
|
tls_server_name=parsed_uri.host,
|
||||||
|
target_host=parsed_uri.host,
|
||||||
|
target_port=port,
|
||||||
|
))
|
||||||
|
|
||||||
|
if parsed_uri.port != -1:
|
||||||
|
# there is an explicit port
|
||||||
|
defer.returnValue(_RoutingResult(
|
||||||
|
host_header=parsed_uri.netloc,
|
||||||
|
tls_server_name=parsed_uri.host,
|
||||||
|
target_host=parsed_uri.host,
|
||||||
|
target_port=parsed_uri.port,
|
||||||
|
))
|
||||||
|
|
||||||
|
# try a SRV lookup
|
||||||
|
service_name = b"_matrix._tcp.%s" % (parsed_uri.host,)
|
||||||
|
server_list = yield self._srv_resolver.resolve_service(service_name)
|
||||||
|
|
||||||
|
if not server_list:
|
||||||
|
target_host = parsed_uri.host
|
||||||
|
port = 8448
|
||||||
|
logger.debug(
|
||||||
|
"No SRV record for %s, using %s:%i",
|
||||||
|
parsed_uri.host.decode("ascii"), target_host.decode("ascii"), port,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
target_host, port = pick_server_from_list(server_list)
|
||||||
|
logger.debug(
|
||||||
|
"Picked %s:%i from SRV records for %s",
|
||||||
|
target_host.decode("ascii"), port, parsed_uri.host.decode("ascii"),
|
||||||
|
)
|
||||||
|
|
||||||
|
defer.returnValue(_RoutingResult(
|
||||||
|
host_header=parsed_uri.netloc,
|
||||||
|
tls_server_name=parsed_uri.host,
|
||||||
|
target_host=target_host,
|
||||||
|
target_port=port,
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
@attr.s
|
||||||
|
class _RoutingResult(object):
|
||||||
|
"""The result returned by `_route_matrix_uri`.
|
||||||
|
|
||||||
|
Contains the parameters needed to direct a federation connection to a particular
|
||||||
|
server.
|
||||||
|
|
||||||
|
Where a SRV record points to several servers, this object contains a single server
|
||||||
|
chosen from the list.
|
||||||
|
"""
|
||||||
|
|
||||||
|
host_header = attr.ib()
|
||||||
|
"""
|
||||||
|
The value we should assign to the Host header (host:port from the matrix
|
||||||
|
URI, or .well-known).
|
||||||
|
|
||||||
|
:type: bytes
|
||||||
|
"""
|
||||||
|
|
||||||
|
tls_server_name = attr.ib()
|
||||||
|
"""
|
||||||
|
The server name we should set in the SNI (typically host, without port, from the
|
||||||
|
matrix URI or .well-known)
|
||||||
|
|
||||||
|
:type: bytes
|
||||||
|
"""
|
||||||
|
|
||||||
|
target_host = attr.ib()
|
||||||
|
"""
|
||||||
|
The hostname (or IP literal) we should route the TCP connection to (the target of the
|
||||||
|
SRV record, or the hostname from the URL/.well-known)
|
||||||
|
|
||||||
|
:type: bytes
|
||||||
|
"""
|
||||||
|
|
||||||
|
target_port = attr.ib()
|
||||||
|
"""
|
||||||
|
The port we should route the TCP connection to (the target of the SRV record, or
|
||||||
|
the port from the URL/.well-known, or 8448)
|
||||||
|
|
||||||
|
:type: int
|
||||||
|
"""
|
||||||
|
|
|
@ -255,7 +255,6 @@ class MatrixFederationHttpClient(object):
|
||||||
|
|
||||||
headers_dict = {
|
headers_dict = {
|
||||||
b"User-Agent": [self.version_string_bytes],
|
b"User-Agent": [self.version_string_bytes],
|
||||||
b"Host": [destination_bytes],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
with limiter:
|
with limiter:
|
||||||
|
|
|
@ -17,7 +17,7 @@ import logging
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.events import FrozenEvent
|
from synapse.events import event_type_from_format_version
|
||||||
from synapse.events.snapshot import EventContext
|
from synapse.events.snapshot import EventContext
|
||||||
from synapse.http.servlet import parse_json_object_from_request
|
from synapse.http.servlet import parse_json_object_from_request
|
||||||
from synapse.replication.http._base import ReplicationEndpoint
|
from synapse.replication.http._base import ReplicationEndpoint
|
||||||
|
@ -70,6 +70,7 @@ class ReplicationFederationSendEventsRestServlet(ReplicationEndpoint):
|
||||||
|
|
||||||
event_payloads.append({
|
event_payloads.append({
|
||||||
"event": event.get_pdu_json(),
|
"event": event.get_pdu_json(),
|
||||||
|
"event_format_version": event.format_version,
|
||||||
"internal_metadata": event.internal_metadata.get_dict(),
|
"internal_metadata": event.internal_metadata.get_dict(),
|
||||||
"rejected_reason": event.rejected_reason,
|
"rejected_reason": event.rejected_reason,
|
||||||
"context": serialized_context,
|
"context": serialized_context,
|
||||||
|
@ -94,9 +95,12 @@ class ReplicationFederationSendEventsRestServlet(ReplicationEndpoint):
|
||||||
event_and_contexts = []
|
event_and_contexts = []
|
||||||
for event_payload in event_payloads:
|
for event_payload in event_payloads:
|
||||||
event_dict = event_payload["event"]
|
event_dict = event_payload["event"]
|
||||||
|
format_ver = content["event_format_version"]
|
||||||
internal_metadata = event_payload["internal_metadata"]
|
internal_metadata = event_payload["internal_metadata"]
|
||||||
rejected_reason = event_payload["rejected_reason"]
|
rejected_reason = event_payload["rejected_reason"]
|
||||||
event = FrozenEvent(event_dict, internal_metadata, rejected_reason)
|
|
||||||
|
EventType = event_type_from_format_version(format_ver)
|
||||||
|
event = EventType(event_dict, internal_metadata, rejected_reason)
|
||||||
|
|
||||||
context = yield EventContext.deserialize(
|
context = yield EventContext.deserialize(
|
||||||
self.store, event_payload["context"],
|
self.store, event_payload["context"],
|
||||||
|
|
|
@ -17,7 +17,7 @@ import logging
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.events import FrozenEvent
|
from synapse.events import event_type_from_format_version
|
||||||
from synapse.events.snapshot import EventContext
|
from synapse.events.snapshot import EventContext
|
||||||
from synapse.http.servlet import parse_json_object_from_request
|
from synapse.http.servlet import parse_json_object_from_request
|
||||||
from synapse.replication.http._base import ReplicationEndpoint
|
from synapse.replication.http._base import ReplicationEndpoint
|
||||||
|
@ -74,6 +74,7 @@ class ReplicationSendEventRestServlet(ReplicationEndpoint):
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"event": event.get_pdu_json(),
|
"event": event.get_pdu_json(),
|
||||||
|
"event_format_version": event.format_version,
|
||||||
"internal_metadata": event.internal_metadata.get_dict(),
|
"internal_metadata": event.internal_metadata.get_dict(),
|
||||||
"rejected_reason": event.rejected_reason,
|
"rejected_reason": event.rejected_reason,
|
||||||
"context": serialized_context,
|
"context": serialized_context,
|
||||||
|
@ -90,9 +91,12 @@ class ReplicationSendEventRestServlet(ReplicationEndpoint):
|
||||||
content = parse_json_object_from_request(request)
|
content = parse_json_object_from_request(request)
|
||||||
|
|
||||||
event_dict = content["event"]
|
event_dict = content["event"]
|
||||||
|
format_ver = content["event_format_version"]
|
||||||
internal_metadata = content["internal_metadata"]
|
internal_metadata = content["internal_metadata"]
|
||||||
rejected_reason = content["rejected_reason"]
|
rejected_reason = content["rejected_reason"]
|
||||||
event = FrozenEvent(event_dict, internal_metadata, rejected_reason)
|
|
||||||
|
EventType = event_type_from_format_version(format_ver)
|
||||||
|
event = EventType(event_dict, internal_metadata, rejected_reason)
|
||||||
|
|
||||||
requester = Requester.deserialize(self.store, content["requester"])
|
requester = Requester.deserialize(self.store, content["requester"])
|
||||||
context = yield EventContext.deserialize(self.store, content["context"])
|
context = yield EventContext.deserialize(self.store, content["context"])
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
import struct
|
import struct
|
||||||
import threading
|
import threading
|
||||||
from sqlite3 import sqlite_version_info
|
|
||||||
|
|
||||||
from synapse.storage.prepare_database import prepare_database
|
from synapse.storage.prepare_database import prepare_database
|
||||||
|
|
||||||
|
@ -34,10 +33,14 @@ class Sqlite3Engine(object):
|
||||||
@property
|
@property
|
||||||
def can_native_upsert(self):
|
def can_native_upsert(self):
|
||||||
"""
|
"""
|
||||||
Do we support native UPSERTs? This requires SQLite3 3.24+, plus some
|
Do we support native UPSERTs?
|
||||||
more work we haven't done yet to tell what was inserted vs updated.
|
|
||||||
"""
|
"""
|
||||||
return sqlite_version_info >= (3, 24, 0)
|
# SQLite3 3.24+ supports them, but empirically the unit tests don't work
|
||||||
|
# when its enabled.
|
||||||
|
# FIXME: Figure out what is wrong so we can re-enable native upserts
|
||||||
|
|
||||||
|
# return self.module.sqlite_version_info >= (3, 24, 0)
|
||||||
|
return False
|
||||||
|
|
||||||
def check_database(self, txn):
|
def check_database(self, txn):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -23,7 +23,7 @@ from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.api.constants import EventFormatVersions
|
from synapse.api.constants import EventFormatVersions
|
||||||
from synapse.api.errors import NotFoundError
|
from synapse.api.errors import NotFoundError
|
||||||
from synapse.events import FrozenEvent
|
from synapse.events import FrozenEvent, event_type_from_format_version # noqa: F401
|
||||||
# these are only included to make the type annotations work
|
# these are only included to make the type annotations work
|
||||||
from synapse.events.snapshot import EventContext # noqa: F401
|
from synapse.events.snapshot import EventContext # noqa: F401
|
||||||
from synapse.events.utils import prune_event
|
from synapse.events.utils import prune_event
|
||||||
|
@ -412,11 +412,7 @@ class EventsWorkerStore(SQLBaseStore):
|
||||||
# of a event format version, so it must be a V1 event.
|
# of a event format version, so it must be a V1 event.
|
||||||
format_version = EventFormatVersions.V1
|
format_version = EventFormatVersions.V1
|
||||||
|
|
||||||
# TODO: When we implement new event formats we'll need to use a
|
original_ev = event_type_from_format_version(format_version)(
|
||||||
# different event python type
|
|
||||||
assert format_version == EventFormatVersions.V1
|
|
||||||
|
|
||||||
original_ev = FrozenEvent(
|
|
||||||
event_dict=d,
|
event_dict=d,
|
||||||
internal_metadata_dict=internal_metadata,
|
internal_metadata_dict=internal_metadata,
|
||||||
rejected_reason=rejected_reason,
|
rejected_reason=rejected_reason,
|
||||||
|
|
|
@ -131,6 +131,10 @@ class MatrixFederationAgentTests(TestCase):
|
||||||
request = http_server.requests[0]
|
request = http_server.requests[0]
|
||||||
self.assertEqual(request.method, b'GET')
|
self.assertEqual(request.method, b'GET')
|
||||||
self.assertEqual(request.path, b'/foo/bar')
|
self.assertEqual(request.path, b'/foo/bar')
|
||||||
|
self.assertEqual(
|
||||||
|
request.requestHeaders.getRawHeaders(b'host'),
|
||||||
|
[b'testserv:8448']
|
||||||
|
)
|
||||||
content = request.content.read()
|
content = request.content.read()
|
||||||
self.assertEqual(content, b'')
|
self.assertEqual(content, b'')
|
||||||
|
|
||||||
|
@ -162,11 +166,7 @@ class MatrixFederationAgentTests(TestCase):
|
||||||
"""
|
"""
|
||||||
Test the behaviour when the server name contains an explicit IP (with no port)
|
Test the behaviour when the server name contains an explicit IP (with no port)
|
||||||
"""
|
"""
|
||||||
|
# there will be a getaddrinfo on the IP
|
||||||
# the SRV lookup will return an empty list (XXX: why do we even do an SRV lookup?)
|
|
||||||
self.mock_resolver.resolve_service.side_effect = lambda _: []
|
|
||||||
|
|
||||||
# then there will be a getaddrinfo on the IP
|
|
||||||
self.reactor.lookups["1.2.3.4"] = "1.2.3.4"
|
self.reactor.lookups["1.2.3.4"] = "1.2.3.4"
|
||||||
|
|
||||||
test_d = self._make_get_request(b"matrix://1.2.3.4/foo/bar")
|
test_d = self._make_get_request(b"matrix://1.2.3.4/foo/bar")
|
||||||
|
@ -174,10 +174,6 @@ class MatrixFederationAgentTests(TestCase):
|
||||||
# Nothing happened yet
|
# Nothing happened yet
|
||||||
self.assertNoResult(test_d)
|
self.assertNoResult(test_d)
|
||||||
|
|
||||||
self.mock_resolver.resolve_service.assert_called_once_with(
|
|
||||||
b"_matrix._tcp.1.2.3.4",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Make sure treq is trying to connect
|
# Make sure treq is trying to connect
|
||||||
clients = self.reactor.tcpClients
|
clients = self.reactor.tcpClients
|
||||||
self.assertEqual(len(clients), 1)
|
self.assertEqual(len(clients), 1)
|
||||||
|
@ -195,6 +191,92 @@ class MatrixFederationAgentTests(TestCase):
|
||||||
request = http_server.requests[0]
|
request = http_server.requests[0]
|
||||||
self.assertEqual(request.method, b'GET')
|
self.assertEqual(request.method, b'GET')
|
||||||
self.assertEqual(request.path, b'/foo/bar')
|
self.assertEqual(request.path, b'/foo/bar')
|
||||||
|
self.assertEqual(
|
||||||
|
request.requestHeaders.getRawHeaders(b'host'),
|
||||||
|
[b'1.2.3.4'],
|
||||||
|
)
|
||||||
|
|
||||||
|
# finish the request
|
||||||
|
request.finish()
|
||||||
|
self.reactor.pump((0.1,))
|
||||||
|
self.successResultOf(test_d)
|
||||||
|
|
||||||
|
def test_get_ipv6_address(self):
|
||||||
|
"""
|
||||||
|
Test the behaviour when the server name contains an explicit IPv6 address
|
||||||
|
(with no port)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# there will be a getaddrinfo on the IP
|
||||||
|
self.reactor.lookups["::1"] = "::1"
|
||||||
|
|
||||||
|
test_d = self._make_get_request(b"matrix://[::1]/foo/bar")
|
||||||
|
|
||||||
|
# Nothing happened yet
|
||||||
|
self.assertNoResult(test_d)
|
||||||
|
|
||||||
|
# Make sure treq is trying to connect
|
||||||
|
clients = self.reactor.tcpClients
|
||||||
|
self.assertEqual(len(clients), 1)
|
||||||
|
(host, port, client_factory, _timeout, _bindAddress) = clients[0]
|
||||||
|
self.assertEqual(host, '::1')
|
||||||
|
self.assertEqual(port, 8448)
|
||||||
|
|
||||||
|
# make a test server, and wire up the client
|
||||||
|
http_server = self._make_connection(
|
||||||
|
client_factory,
|
||||||
|
expected_sni=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(len(http_server.requests), 1)
|
||||||
|
request = http_server.requests[0]
|
||||||
|
self.assertEqual(request.method, b'GET')
|
||||||
|
self.assertEqual(request.path, b'/foo/bar')
|
||||||
|
self.assertEqual(
|
||||||
|
request.requestHeaders.getRawHeaders(b'host'),
|
||||||
|
[b'[::1]'],
|
||||||
|
)
|
||||||
|
|
||||||
|
# finish the request
|
||||||
|
request.finish()
|
||||||
|
self.reactor.pump((0.1,))
|
||||||
|
self.successResultOf(test_d)
|
||||||
|
|
||||||
|
def test_get_ipv6_address_with_port(self):
|
||||||
|
"""
|
||||||
|
Test the behaviour when the server name contains an explicit IPv6 address
|
||||||
|
(with explicit port)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# there will be a getaddrinfo on the IP
|
||||||
|
self.reactor.lookups["::1"] = "::1"
|
||||||
|
|
||||||
|
test_d = self._make_get_request(b"matrix://[::1]:80/foo/bar")
|
||||||
|
|
||||||
|
# Nothing happened yet
|
||||||
|
self.assertNoResult(test_d)
|
||||||
|
|
||||||
|
# Make sure treq is trying to connect
|
||||||
|
clients = self.reactor.tcpClients
|
||||||
|
self.assertEqual(len(clients), 1)
|
||||||
|
(host, port, client_factory, _timeout, _bindAddress) = clients[0]
|
||||||
|
self.assertEqual(host, '::1')
|
||||||
|
self.assertEqual(port, 80)
|
||||||
|
|
||||||
|
# make a test server, and wire up the client
|
||||||
|
http_server = self._make_connection(
|
||||||
|
client_factory,
|
||||||
|
expected_sni=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(len(http_server.requests), 1)
|
||||||
|
request = http_server.requests[0]
|
||||||
|
self.assertEqual(request.method, b'GET')
|
||||||
|
self.assertEqual(request.path, b'/foo/bar')
|
||||||
|
self.assertEqual(
|
||||||
|
request.requestHeaders.getRawHeaders(b'host'),
|
||||||
|
[b'[::1]:80'],
|
||||||
|
)
|
||||||
|
|
||||||
# finish the request
|
# finish the request
|
||||||
request.finish()
|
request.finish()
|
||||||
|
@ -235,6 +317,10 @@ class MatrixFederationAgentTests(TestCase):
|
||||||
request = http_server.requests[0]
|
request = http_server.requests[0]
|
||||||
self.assertEqual(request.method, b'GET')
|
self.assertEqual(request.method, b'GET')
|
||||||
self.assertEqual(request.path, b'/foo/bar')
|
self.assertEqual(request.path, b'/foo/bar')
|
||||||
|
self.assertEqual(
|
||||||
|
request.requestHeaders.getRawHeaders(b'host'),
|
||||||
|
[b'testserv'],
|
||||||
|
)
|
||||||
|
|
||||||
# finish the request
|
# finish the request
|
||||||
request.finish()
|
request.finish()
|
||||||
|
@ -246,7 +332,7 @@ class MatrixFederationAgentTests(TestCase):
|
||||||
Test the behaviour when there is a single SRV record
|
Test the behaviour when there is a single SRV record
|
||||||
"""
|
"""
|
||||||
self.mock_resolver.resolve_service.side_effect = lambda _: [
|
self.mock_resolver.resolve_service.side_effect = lambda _: [
|
||||||
Server(host="srvtarget", port=8443)
|
Server(host=b"srvtarget", port=8443)
|
||||||
]
|
]
|
||||||
self.reactor.lookups["srvtarget"] = "1.2.3.4"
|
self.reactor.lookups["srvtarget"] = "1.2.3.4"
|
||||||
|
|
||||||
|
@ -276,6 +362,100 @@ class MatrixFederationAgentTests(TestCase):
|
||||||
request = http_server.requests[0]
|
request = http_server.requests[0]
|
||||||
self.assertEqual(request.method, b'GET')
|
self.assertEqual(request.method, b'GET')
|
||||||
self.assertEqual(request.path, b'/foo/bar')
|
self.assertEqual(request.path, b'/foo/bar')
|
||||||
|
self.assertEqual(
|
||||||
|
request.requestHeaders.getRawHeaders(b'host'),
|
||||||
|
[b'testserv'],
|
||||||
|
)
|
||||||
|
|
||||||
|
# finish the request
|
||||||
|
request.finish()
|
||||||
|
self.reactor.pump((0.1,))
|
||||||
|
self.successResultOf(test_d)
|
||||||
|
|
||||||
|
def test_idna_servername(self):
|
||||||
|
"""test the behaviour when the server name has idna chars in"""
|
||||||
|
|
||||||
|
self.mock_resolver.resolve_service.side_effect = lambda _: []
|
||||||
|
|
||||||
|
# hostnameendpoint does the lookup on the unicode value (getaddrinfo encodes
|
||||||
|
# it back to idna)
|
||||||
|
self.reactor.lookups[u"bücher.com"] = "1.2.3.4"
|
||||||
|
|
||||||
|
# this is idna for bücher.com
|
||||||
|
test_d = self._make_get_request(b"matrix://xn--bcher-kva.com/foo/bar")
|
||||||
|
|
||||||
|
# Nothing happened yet
|
||||||
|
self.assertNoResult(test_d)
|
||||||
|
|
||||||
|
self.mock_resolver.resolve_service.assert_called_once_with(
|
||||||
|
b"_matrix._tcp.xn--bcher-kva.com",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Make sure treq is trying to connect
|
||||||
|
clients = self.reactor.tcpClients
|
||||||
|
self.assertEqual(len(clients), 1)
|
||||||
|
(host, port, client_factory, _timeout, _bindAddress) = clients[0]
|
||||||
|
self.assertEqual(host, '1.2.3.4')
|
||||||
|
self.assertEqual(port, 8448)
|
||||||
|
|
||||||
|
# make a test server, and wire up the client
|
||||||
|
http_server = self._make_connection(
|
||||||
|
client_factory,
|
||||||
|
expected_sni=b'xn--bcher-kva.com',
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(len(http_server.requests), 1)
|
||||||
|
request = http_server.requests[0]
|
||||||
|
self.assertEqual(request.method, b'GET')
|
||||||
|
self.assertEqual(request.path, b'/foo/bar')
|
||||||
|
self.assertEqual(
|
||||||
|
request.requestHeaders.getRawHeaders(b'host'),
|
||||||
|
[b'xn--bcher-kva.com'],
|
||||||
|
)
|
||||||
|
|
||||||
|
# finish the request
|
||||||
|
request.finish()
|
||||||
|
self.reactor.pump((0.1,))
|
||||||
|
self.successResultOf(test_d)
|
||||||
|
|
||||||
|
def test_idna_srv_target(self):
|
||||||
|
"""test the behaviour when the target of a SRV record has idna chars"""
|
||||||
|
|
||||||
|
self.mock_resolver.resolve_service.side_effect = lambda _: [
|
||||||
|
Server(host=b"xn--trget-3qa.com", port=8443) # târget.com
|
||||||
|
]
|
||||||
|
self.reactor.lookups[u"târget.com"] = "1.2.3.4"
|
||||||
|
|
||||||
|
test_d = self._make_get_request(b"matrix://xn--bcher-kva.com/foo/bar")
|
||||||
|
|
||||||
|
# Nothing happened yet
|
||||||
|
self.assertNoResult(test_d)
|
||||||
|
|
||||||
|
self.mock_resolver.resolve_service.assert_called_once_with(
|
||||||
|
b"_matrix._tcp.xn--bcher-kva.com",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Make sure treq is trying to connect
|
||||||
|
clients = self.reactor.tcpClients
|
||||||
|
self.assertEqual(len(clients), 1)
|
||||||
|
(host, port, client_factory, _timeout, _bindAddress) = clients[0]
|
||||||
|
self.assertEqual(host, '1.2.3.4')
|
||||||
|
self.assertEqual(port, 8443)
|
||||||
|
|
||||||
|
# make a test server, and wire up the client
|
||||||
|
http_server = self._make_connection(
|
||||||
|
client_factory,
|
||||||
|
expected_sni=b'xn--bcher-kva.com',
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(len(http_server.requests), 1)
|
||||||
|
request = http_server.requests[0]
|
||||||
|
self.assertEqual(request.method, b'GET')
|
||||||
|
self.assertEqual(request.path, b'/foo/bar')
|
||||||
|
self.assertEqual(
|
||||||
|
request.requestHeaders.getRawHeaders(b'host'),
|
||||||
|
[b'xn--bcher-kva.com'],
|
||||||
|
)
|
||||||
|
|
||||||
# finish the request
|
# finish the request
|
||||||
request.finish()
|
request.finish()
|
||||||
|
|
|
@ -49,7 +49,6 @@ class FederationClientTests(HomeserverTestCase):
|
||||||
return hs
|
return hs
|
||||||
|
|
||||||
def prepare(self, reactor, clock, homeserver):
|
def prepare(self, reactor, clock, homeserver):
|
||||||
|
|
||||||
self.cl = MatrixFederationHttpClient(self.hs)
|
self.cl = MatrixFederationHttpClient(self.hs)
|
||||||
self.reactor.lookups["testserv"] = "1.2.3.4"
|
self.reactor.lookups["testserv"] = "1.2.3.4"
|
||||||
|
|
||||||
|
@ -95,6 +94,7 @@ class FederationClientTests(HomeserverTestCase):
|
||||||
|
|
||||||
# that should have made it send the request to the transport
|
# that should have made it send the request to the transport
|
||||||
self.assertRegex(transport.value(), b"^GET /foo/bar")
|
self.assertRegex(transport.value(), b"^GET /foo/bar")
|
||||||
|
self.assertRegex(transport.value(), b"Host: testserv:8008")
|
||||||
|
|
||||||
# Deferred is still without a result
|
# Deferred is still without a result
|
||||||
self.assertNoResult(test_d)
|
self.assertNoResult(test_d)
|
||||||
|
|
|
@ -18,7 +18,7 @@ from mock import Mock
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.api.constants import EventTypes, Membership
|
from synapse.api.constants import EventTypes, Membership, RoomVersions
|
||||||
from synapse.types import RoomID, UserID
|
from synapse.types import RoomID, UserID
|
||||||
|
|
||||||
from tests import unittest
|
from tests import unittest
|
||||||
|
@ -52,6 +52,7 @@ class RedactionTestCase(unittest.TestCase):
|
||||||
content = {"membership": membership}
|
content = {"membership": membership}
|
||||||
content.update(extra_content)
|
content.update(extra_content)
|
||||||
builder = self.event_builder_factory.new(
|
builder = self.event_builder_factory.new(
|
||||||
|
RoomVersions.V1,
|
||||||
{
|
{
|
||||||
"type": EventTypes.Member,
|
"type": EventTypes.Member,
|
||||||
"sender": user.to_string(),
|
"sender": user.to_string(),
|
||||||
|
@ -74,6 +75,7 @@ class RedactionTestCase(unittest.TestCase):
|
||||||
self.depth += 1
|
self.depth += 1
|
||||||
|
|
||||||
builder = self.event_builder_factory.new(
|
builder = self.event_builder_factory.new(
|
||||||
|
RoomVersions.V1,
|
||||||
{
|
{
|
||||||
"type": EventTypes.Message,
|
"type": EventTypes.Message,
|
||||||
"sender": user.to_string(),
|
"sender": user.to_string(),
|
||||||
|
@ -94,6 +96,7 @@ class RedactionTestCase(unittest.TestCase):
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def inject_redaction(self, room, event_id, user, reason):
|
def inject_redaction(self, room, event_id, user, reason):
|
||||||
builder = self.event_builder_factory.new(
|
builder = self.event_builder_factory.new(
|
||||||
|
RoomVersions.V1,
|
||||||
{
|
{
|
||||||
"type": EventTypes.Redaction,
|
"type": EventTypes.Redaction,
|
||||||
"sender": user.to_string(),
|
"sender": user.to_string(),
|
||||||
|
|
|
@ -18,7 +18,7 @@ from mock import Mock
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.api.constants import EventTypes, Membership
|
from synapse.api.constants import EventTypes, Membership, RoomVersions
|
||||||
from synapse.types import RoomID, UserID
|
from synapse.types import RoomID, UserID
|
||||||
|
|
||||||
from tests import unittest
|
from tests import unittest
|
||||||
|
@ -50,6 +50,7 @@ class RoomMemberStoreTestCase(unittest.TestCase):
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def inject_room_member(self, room, user, membership, replaces_state=None):
|
def inject_room_member(self, room, user, membership, replaces_state=None):
|
||||||
builder = self.event_builder_factory.new(
|
builder = self.event_builder_factory.new(
|
||||||
|
RoomVersions.V1,
|
||||||
{
|
{
|
||||||
"type": EventTypes.Member,
|
"type": EventTypes.Member,
|
||||||
"sender": user.to_string(),
|
"sender": user.to_string(),
|
||||||
|
|
|
@ -17,7 +17,7 @@ import logging
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.api.constants import EventTypes, Membership
|
from synapse.api.constants import EventTypes, Membership, RoomVersions
|
||||||
from synapse.storage.state import StateFilter
|
from synapse.storage.state import StateFilter
|
||||||
from synapse.types import RoomID, UserID
|
from synapse.types import RoomID, UserID
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ class StateStoreTestCase(tests.unittest.TestCase):
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def inject_state_event(self, room, sender, typ, state_key, content):
|
def inject_state_event(self, room, sender, typ, state_key, content):
|
||||||
builder = self.event_builder_factory.new(
|
builder = self.event_builder_factory.new(
|
||||||
|
RoomVersions.V1,
|
||||||
{
|
{
|
||||||
"type": typ,
|
"type": typ,
|
||||||
"sender": sender.to_string(),
|
"sender": sender.to_string(),
|
||||||
|
|
|
@ -17,6 +17,7 @@ import logging
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.internet.defer import succeed
|
from twisted.internet.defer import succeed
|
||||||
|
|
||||||
|
from synapse.api.constants import RoomVersions
|
||||||
from synapse.events import FrozenEvent
|
from synapse.events import FrozenEvent
|
||||||
from synapse.visibility import filter_events_for_server
|
from synapse.visibility import filter_events_for_server
|
||||||
|
|
||||||
|
@ -124,6 +125,7 @@ class FilterEventsForServerTestCase(tests.unittest.TestCase):
|
||||||
def inject_visibility(self, user_id, visibility):
|
def inject_visibility(self, user_id, visibility):
|
||||||
content = {"history_visibility": visibility}
|
content = {"history_visibility": visibility}
|
||||||
builder = self.event_builder_factory.new(
|
builder = self.event_builder_factory.new(
|
||||||
|
RoomVersions.V1,
|
||||||
{
|
{
|
||||||
"type": "m.room.history_visibility",
|
"type": "m.room.history_visibility",
|
||||||
"sender": user_id,
|
"sender": user_id,
|
||||||
|
@ -144,6 +146,7 @@ class FilterEventsForServerTestCase(tests.unittest.TestCase):
|
||||||
content = {"membership": membership}
|
content = {"membership": membership}
|
||||||
content.update(extra_content)
|
content.update(extra_content)
|
||||||
builder = self.event_builder_factory.new(
|
builder = self.event_builder_factory.new(
|
||||||
|
RoomVersions.V1,
|
||||||
{
|
{
|
||||||
"type": "m.room.member",
|
"type": "m.room.member",
|
||||||
"sender": user_id,
|
"sender": user_id,
|
||||||
|
@ -165,6 +168,7 @@ class FilterEventsForServerTestCase(tests.unittest.TestCase):
|
||||||
if content is None:
|
if content is None:
|
||||||
content = {"body": "testytest"}
|
content = {"body": "testytest"}
|
||||||
builder = self.event_builder_factory.new(
|
builder = self.event_builder_factory.new(
|
||||||
|
RoomVersions.V1,
|
||||||
{
|
{
|
||||||
"type": "m.room.message",
|
"type": "m.room.message",
|
||||||
"sender": user_id,
|
"sender": user_id,
|
||||||
|
|
|
@ -26,7 +26,7 @@ from six.moves.urllib import parse as urlparse
|
||||||
|
|
||||||
from twisted.internet import defer, reactor
|
from twisted.internet import defer, reactor
|
||||||
|
|
||||||
from synapse.api.constants import EventTypes
|
from synapse.api.constants import EventTypes, RoomVersions
|
||||||
from synapse.api.errors import CodeMessageException, cs_error
|
from synapse.api.errors import CodeMessageException, cs_error
|
||||||
from synapse.config.server import ServerConfig
|
from synapse.config.server import ServerConfig
|
||||||
from synapse.federation.transport import server
|
from synapse.federation.transport import server
|
||||||
|
@ -624,6 +624,7 @@ def create_room(hs, room_id, creator_id):
|
||||||
event_creation_handler = hs.get_event_creation_handler()
|
event_creation_handler = hs.get_event_creation_handler()
|
||||||
|
|
||||||
builder = event_builder_factory.new(
|
builder = event_builder_factory.new(
|
||||||
|
RoomVersions.V1,
|
||||||
{
|
{
|
||||||
"type": EventTypes.Create,
|
"type": EventTypes.Create,
|
||||||
"state_key": "",
|
"state_key": "",
|
||||||
|
|
Loading…
Reference in a new issue