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

Commit

Permalink
Merge pull request #4405 from matrix-org/erikj/fixup_rejecting_invites
Browse files Browse the repository at this point in the history
Store rejected remote invite events as outliers
  • Loading branch information
erikjohnston authored Jan 24, 2019
2 parents 664b7a2 + 5ee1f99 commit 80bcca6
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 39 deletions.
1 change: 1 addition & 0 deletions changelog.d/4405.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix bug when rejecting remote invites
9 changes: 7 additions & 2 deletions synapse/events/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,13 @@ def get_dict(self):
def is_outlier(self):
return getattr(self, "outlier", False)

def is_invite_from_remote(self):
return getattr(self, "invite_from_remote", False)
def is_out_of_band_membership(self):
"""Whether this is an out of band membership, like an invite or an invite
rejection. This is needed as those events are marked as outliers, but
they still need to be processed as if they're new events (e.g. updating
invite state in the database, relaying to clients, etc).
"""
return getattr(self, "out_of_band_membership", False)

def get_send_on_behalf_of(self):
"""Whether this server should send the event on behalf of another server.
Expand Down
24 changes: 20 additions & 4 deletions synapse/federation/federation_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
HttpResponseException,
SynapseError,
)
from synapse.events import builder
from synapse.crypto.event_signing import add_hashes_and_signatures
from synapse.federation.federation_base import FederationBase, event_from_pdu_json
from synapse.util import logcontext, unwrapFirstError
from synapse.util.caches.expiringcache import ExpiringCache
Expand Down Expand Up @@ -66,6 +66,8 @@ def __init__(self, hs):
self.state = hs.get_state_handler()
self.transport_layer = hs.get_federation_transport_client()

self.event_builder_factory = hs.get_event_builder_factory()

self._get_pdu_cache = ExpiringCache(
cache_name="get_pdu_cache",
clock=self._clock,
Expand Down Expand Up @@ -522,6 +524,8 @@ def make_membership_event(self, destinations, room_id, user_id, membership,
Does so by asking one of the already participating servers to create an
event with proper context.
Returns a fully signed and hashed event.
Note that this does not append any events to any graphs.
Args:
Expand All @@ -536,8 +540,9 @@ def make_membership_event(self, destinations, room_id, user_id, membership,
params (dict[str, str|Iterable[str]]): Query parameters to include in the
request.
Return:
Deferred: resolves to a tuple of (origin (str), event (object))
where origin is the remote homeserver which generated the event.
Deferred[tuple[str, FrozenEvent]]: resolves to a tuple of `origin`
and event where origin is the remote homeserver which generated
the event.
Fails with a ``SynapseError`` if the chosen remote server
returns a 300/400 code.
Expand Down Expand Up @@ -571,7 +576,18 @@ def send_request(destination):
if "prev_state" not in pdu_dict:
pdu_dict["prev_state"] = []

ev = builder.EventBuilder(pdu_dict)
# Strip off the fields that we want to clobber.
pdu_dict.pop("origin", None)
pdu_dict.pop("origin_server_ts", None)
pdu_dict.pop("unsigned", None)

builder = self.event_builder_factory.new(pdu_dict)
add_hashes_and_signatures(
builder,
self.hs.hostname,
self.hs.config.signing_key[0]
)
ev = builder.build()

defer.returnValue(
(destination, ev)
Expand Down
32 changes: 3 additions & 29 deletions synapse/handlers/federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@
StoreError,
SynapseError,
)
from synapse.crypto.event_signing import (
add_hashes_and_signatures,
compute_event_signature,
)
from synapse.crypto.event_signing import compute_event_signature
from synapse.events.validator import EventValidator
from synapse.replication.http.federation import (
ReplicationCleanRoomRestServlet,
Expand All @@ -58,7 +55,6 @@
from synapse.util import logcontext, unwrapFirstError
from synapse.util.async_helpers import Linearizer
from synapse.util.distributor import user_joined_room
from synapse.util.frozenutils import unfreeze
from synapse.util.logutils import log_function
from synapse.util.retryutils import NotRetryingDestination
from synapse.visibility import filter_events_for_server
Expand Down Expand Up @@ -1083,7 +1079,6 @@ def do_invite_join(self, target_hosts, room_id, joinee, content):
handled_events = set()

try:
event = self._sign_event(event)
# Try the host we successfully got a response to /make_join/
# request first.
try:
Expand Down Expand Up @@ -1287,7 +1282,7 @@ def on_invite_request(self, origin, pdu):
)

event.internal_metadata.outlier = True
event.internal_metadata.invite_from_remote = True
event.internal_metadata.out_of_band_membership = True

event.signatures.update(
compute_event_signature(
Expand All @@ -1313,7 +1308,7 @@ def do_remotely_reject_invite(self, target_hosts, room_id, user_id):
# Mark as outlier as we don't have any state for this event; we're not
# even in the room.
event.internal_metadata.outlier = True
event = self._sign_event(event)
event.internal_metadata.out_of_band_membership = True

# Try the host that we succesfully called /make_leave/ on first for
# the /send_leave/ request.
Expand Down Expand Up @@ -1357,27 +1352,6 @@ def _make_and_verify_event(self, target_hosts, room_id, user_id, membership,
assert(event.room_id == room_id)
defer.returnValue((origin, event))

def _sign_event(self, event):
event.internal_metadata.outlier = False

builder = self.event_builder_factory.new(
unfreeze(event.get_pdu_json())
)

builder.event_id = self.event_builder_factory.create_event_id()
builder.origin = self.hs.hostname

if not hasattr(event, "signatures"):
builder.signatures = {}

add_hashes_and_signatures(
builder,
self.hs.hostname,
self.hs.config.signing_key[0],
)

return builder.build()

@defer.inlineCallbacks
@log_function
def on_make_leave_request(self, room_id, user_id):
Expand Down
8 changes: 4 additions & 4 deletions synapse/storage/roommember.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,12 +588,12 @@ def _store_room_members_txn(self, txn, events, backfilled):
)

# We update the local_invites table only if the event is "current",
# i.e., its something that has just happened.
# The only current event that can also be an outlier is if its an
# invite that has come in across federation.
# i.e., its something that has just happened. If the event is an
# outlier it is only current if its an "out of band membership",
# like a remote invite or a rejection of a remote invite.
is_new_state = not backfilled and (
not event.internal_metadata.is_outlier()
or event.internal_metadata.is_invite_from_remote()
or event.internal_metadata.is_out_of_band_membership()
)
is_mine = self.hs.is_mine_id(event.state_key)
if is_new_state and is_mine:
Expand Down

0 comments on commit 80bcca6

Please sign in to comment.