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 #8537 from matrix-org/rav/simplify_locally_reject_…
Browse files Browse the repository at this point in the history
…invite

Simplify `_locally_reject_invite`
  • Loading branch information
richvdh authored Oct 15, 2020
2 parents 19b15d6 + d9dc618 commit 4433d01
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 65 deletions.
1 change: 1 addition & 0 deletions changelog.d/8537.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Factor out common code between `RoomMemberHandler._locally_reject_invite` and `EventCreationHandler.create_event`.
21 changes: 13 additions & 8 deletions synapse/events/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,32 +97,37 @@ def state_key(self):
def is_state(self):
return self._state_key is not None

async def build(self, prev_event_ids: List[str]) -> EventBase:
async def build(
self, prev_event_ids: List[str], auth_event_ids: Optional[List[str]]
) -> EventBase:
"""Transform into a fully signed and hashed event
Args:
prev_event_ids: The event IDs to use as the prev events
auth_event_ids: The event IDs to use as the auth events.
Should normally be set to None, which will cause them to be calculated
based on the room state at the prev_events.
Returns:
The signed and hashed event.
"""

state_ids = await self._state.get_current_state_ids(
self.room_id, prev_event_ids
)
auth_ids = self._auth.compute_auth_events(self, state_ids)
if auth_event_ids is None:
state_ids = await self._state.get_current_state_ids(
self.room_id, prev_event_ids
)
auth_event_ids = self._auth.compute_auth_events(self, state_ids)

format_version = self.room_version.event_format
if format_version == EventFormatVersions.V1:
# The types of auth/prev events changes between event versions.
auth_events = await self._store.add_event_hashes(
auth_ids
auth_event_ids
) # type: Union[List[str], List[Tuple[str, Dict[str, str]]]]
prev_events = await self._store.add_event_hashes(
prev_event_ids
) # type: Union[List[str], List[Tuple[str, Dict[str, str]]]]
else:
auth_events = auth_ids
auth_events = auth_event_ids
prev_events = prev_event_ids

old_depth = await self._store.get_max_depth_of(prev_event_ids)
Expand Down
30 changes: 23 additions & 7 deletions synapse/handlers/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,9 +437,9 @@ async def create_event(
self,
requester: Requester,
event_dict: dict,
token_id: Optional[str] = None,
txn_id: Optional[str] = None,
prev_event_ids: Optional[List[str]] = None,
auth_event_ids: Optional[List[str]] = None,
require_consent: bool = True,
) -> Tuple[EventBase, EventContext]:
"""
Expand All @@ -453,13 +453,18 @@ async def create_event(
Args:
requester
event_dict: An entire event
token_id
txn_id
prev_event_ids:
the forward extremities to use as the prev_events for the
new event.
If None, they will be requested from the database.
auth_event_ids:
The event ids to use as the auth_events for the new event.
Should normally be left as None, which will cause them to be calculated
based on the room state at the prev_events.
require_consent: Whether to check if the requester has
consented to the privacy policy.
Raises:
Expand Down Expand Up @@ -511,14 +516,17 @@ async def create_event(
if require_consent and not is_exempt:
await self.assert_accepted_privacy_policy(requester)

if token_id is not None:
builder.internal_metadata.token_id = token_id
if requester.access_token_id is not None:
builder.internal_metadata.token_id = requester.access_token_id

if txn_id is not None:
builder.internal_metadata.txn_id = txn_id

event, context = await self.create_new_client_event(
builder=builder, requester=requester, prev_event_ids=prev_event_ids,
builder=builder,
requester=requester,
prev_event_ids=prev_event_ids,
auth_event_ids=auth_event_ids,
)

# In an ideal world we wouldn't need the second part of this condition. However,
Expand Down Expand Up @@ -726,7 +734,7 @@ async def create_and_send_nonmember_event(
return event, event.internal_metadata.stream_ordering

event, context = await self.create_event(
requester, event_dict, token_id=requester.access_token_id, txn_id=txn_id
requester, event_dict, txn_id=txn_id
)

assert self.hs.is_mine_id(event.sender), "User must be our own: %s" % (
Expand Down Expand Up @@ -757,6 +765,7 @@ async def create_new_client_event(
builder: EventBuilder,
requester: Optional[Requester] = None,
prev_event_ids: Optional[List[str]] = None,
auth_event_ids: Optional[List[str]] = None,
) -> Tuple[EventBase, EventContext]:
"""Create a new event for a local client
Expand All @@ -769,6 +778,11 @@ async def create_new_client_event(
If None, they will be requested from the database.
auth_event_ids:
The event ids to use as the auth_events for the new event.
Should normally be left as None, which will cause them to be calculated
based on the room state at the prev_events.
Returns:
Tuple of created event, context
"""
Expand All @@ -790,7 +804,9 @@ async def create_new_client_event(
builder.type == EventTypes.Create or len(prev_event_ids) > 0
), "Attempting to create an event with no prev_events"

event = await builder.build(prev_event_ids=prev_event_ids)
event = await builder.build(
prev_event_ids=prev_event_ids, auth_event_ids=auth_event_ids
)
context = await self.state.compute_event_context(event)
if requester:
context.app_service = requester.app_service
Expand Down
1 change: 0 additions & 1 deletion synapse/handlers/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@ async def _upgrade_room(
"replacement_room": new_room_id,
},
},
token_id=requester.access_token_id,
)
old_room_version = await self.store.get_room_version_id(old_room_id)
await self.auth.check_from_context(
Expand Down
59 changes: 15 additions & 44 deletions synapse/handlers/room_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@
import logging
import random
from http import HTTPStatus
from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple, Union

from unpaddedbase64 import encode_base64
from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple

from synapse import types
from synapse.api.constants import MAX_DEPTH, AccountDataTypes, EventTypes, Membership
from synapse.api.constants import AccountDataTypes, EventTypes, Membership
from synapse.api.errors import (
AuthError,
Codes,
Expand All @@ -31,12 +29,8 @@
SynapseError,
)
from synapse.api.ratelimiting import Ratelimiter
from synapse.api.room_versions import EventFormatVersions
from synapse.crypto.event_signing import compute_event_reference_hash
from synapse.events import EventBase
from synapse.events.builder import create_local_event_from_event_dict
from synapse.events.snapshot import EventContext
from synapse.events.validator import EventValidator
from synapse.storage.roommember import RoomsForUser
from synapse.types import JsonDict, Requester, RoomAlias, RoomID, StateMap, UserID
from synapse.util.async_helpers import Linearizer
Expand Down Expand Up @@ -193,7 +187,6 @@ async def _local_membership_update(
# For backwards compatibility:
"membership": membership,
},
token_id=requester.access_token_id,
txn_id=txn_id,
prev_event_ids=prev_event_ids,
require_consent=require_consent,
Expand Down Expand Up @@ -1133,56 +1126,34 @@ async def _locally_reject_invite(

room_id = invite_event.room_id
target_user = invite_event.state_key
room_version = await self.store.get_room_version(room_id)

content["membership"] = Membership.LEAVE

# the auth events for the new event are the same as that of the invite, plus
# the invite itself.
#
# the prev_events are just the invite.
invite_hash = invite_event.event_id # type: Union[str, Tuple]
if room_version.event_format == EventFormatVersions.V1:
alg, h = compute_event_reference_hash(invite_event)
invite_hash = (invite_event.event_id, {alg: encode_base64(h)})

auth_events = tuple(invite_event.auth_events) + (invite_hash,)
prev_events = (invite_hash,)

# we cap depth of generated events, to ensure that they are not
# rejected by other servers (and so that they can be persisted in
# the db)
depth = min(invite_event.depth + 1, MAX_DEPTH)

event_dict = {
"depth": depth,
"auth_events": auth_events,
"prev_events": prev_events,
"type": EventTypes.Member,
"room_id": room_id,
"sender": target_user,
"content": content,
"state_key": target_user,
}

event = create_local_event_from_event_dict(
clock=self.clock,
hostname=self.hs.hostname,
signing_key=self.hs.signing_key,
room_version=room_version,
event_dict=event_dict,
# the auth events for the new event are the same as that of the invite, plus
# the invite itself.
#
# the prev_events are just the invite.
prev_event_ids = [invite_event.event_id]
auth_event_ids = invite_event.auth_event_ids() + prev_event_ids

event, context = await self.event_creation_handler.create_event(
requester,
event_dict,
txn_id=txn_id,
prev_event_ids=prev_event_ids,
auth_event_ids=auth_event_ids,
)
event.internal_metadata.outlier = True
event.internal_metadata.out_of_band_membership = True
if txn_id is not None:
event.internal_metadata.txn_id = txn_id
if requester.access_token_id is not None:
event.internal_metadata.token_id = requester.access_token_id

EventValidator().validate_new(event, self.config)

context = await self.state_handler.compute_event_context(event)
context.app_service = requester.app_service
result_event = await self.event_creation_handler.handle_new_client_event(
requester, event, context, extra_users=[UserID.from_string(target_user)],
)
Expand Down
1 change: 0 additions & 1 deletion tests/handlers/test_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ def _create_duplicate_event(self, txn_id: str) -> Tuple[EventBase, EventContext]
"sender": self.requester.user.to_string(),
"content": {"msgtype": "m.text", "body": random_string(5)},
},
token_id=self.token_id,
txn_id=txn_id,
)
)
Expand Down
2 changes: 1 addition & 1 deletion tests/handlers/test_presence.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ def _add_new_user(self, room_id, user_id):
self.store.get_latest_event_ids_in_room(room_id)
)

event = self.get_success(builder.build(prev_event_ids))
event = self.get_success(builder.build(prev_event_ids, None))

self.get_success(self.federation_handler.on_receive_pdu(hostname, event))

Expand Down
2 changes: 1 addition & 1 deletion tests/replication/test_federation_sender_shard.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def create_room_with_remote_server(self, user, token, remote_server="other_serve
}

builder = factory.for_room_version(room_version, event_dict)
join_event = self.get_success(builder.build(prev_event_ids))
join_event = self.get_success(builder.build(prev_event_ids, None))

self.get_success(federation.on_send_join_request(remote_server, join_event))
self.replicate()
Expand Down
4 changes: 2 additions & 2 deletions tests/storage/test_redaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,9 @@ def __init__(self, base_builder, event_id):
self._event_id = event_id

@defer.inlineCallbacks
def build(self, prev_event_ids):
def build(self, prev_event_ids, auth_event_ids):
built_event = yield defer.ensureDeferred(
self._base_builder.build(prev_event_ids)
self._base_builder.build(prev_event_ids, auth_event_ids)
)

built_event._event_id = self._event_id
Expand Down

0 comments on commit 4433d01

Please sign in to comment.