mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2024-09-06 20:41:59 +00:00
Update client-visibility filtering for outlier events (#12155)
Avoid trying to get the state for outliers, which isn't a sensible thing to do.
This commit is contained in:
parent
d56202b038
commit
87c230c27c
1
changelog.d/12155.misc
Normal file
1
changelog.d/12155.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Avoid trying to calculate the state at outlier events.
|
@ -81,8 +81,9 @@ async def filter_events_for_client(
|
|||||||
|
|
||||||
types = ((EventTypes.RoomHistoryVisibility, ""), (EventTypes.Member, user_id))
|
types = ((EventTypes.RoomHistoryVisibility, ""), (EventTypes.Member, user_id))
|
||||||
|
|
||||||
|
# we exclude outliers at this point, and then handle them separately later
|
||||||
event_id_to_state = await storage.state.get_state_for_events(
|
event_id_to_state = await storage.state.get_state_for_events(
|
||||||
frozenset(e.event_id for e in events),
|
frozenset(e.event_id for e in events if not e.internal_metadata.outlier),
|
||||||
state_filter=StateFilter.from_types(types),
|
state_filter=StateFilter.from_types(types),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -154,6 +155,17 @@ async def filter_events_for_client(
|
|||||||
if event.event_id in always_include_ids:
|
if event.event_id in always_include_ids:
|
||||||
return event
|
return event
|
||||||
|
|
||||||
|
# we need to handle outliers separately, since we don't have the room state.
|
||||||
|
if event.internal_metadata.outlier:
|
||||||
|
# Normally these can't be seen by clients, but we make an exception for
|
||||||
|
# for out-of-band membership events (eg, incoming invites, or rejections of
|
||||||
|
# said invite) for the user themselves.
|
||||||
|
if event.type == EventTypes.Member and event.state_key == user_id:
|
||||||
|
logger.debug("Returning out-of-band-membership event %s", event)
|
||||||
|
return event
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
state = event_id_to_state[event.event_id]
|
state = event_id_to_state[event.event_id]
|
||||||
|
|
||||||
# get the room_visibility at the time of the event.
|
# get the room_visibility at the time of the event.
|
||||||
@ -198,6 +210,9 @@ async def filter_events_for_client(
|
|||||||
|
|
||||||
# Always allow the user to see their own leave events, otherwise
|
# Always allow the user to see their own leave events, otherwise
|
||||||
# they won't see the room disappear if they reject the invite
|
# they won't see the room disappear if they reject the invite
|
||||||
|
#
|
||||||
|
# (Note this doesn't work for out-of-band invite rejections, which don't
|
||||||
|
# have prev_state populated. They are handled above in the outlier code.)
|
||||||
if membership == "leave" and (
|
if membership == "leave" and (
|
||||||
prev_membership == "join" or prev_membership == "invite"
|
prev_membership == "join" or prev_membership == "invite"
|
||||||
):
|
):
|
||||||
|
@ -13,11 +13,12 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
import logging
|
import logging
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from synapse.api.room_versions import RoomVersions
|
from synapse.api.room_versions import RoomVersions
|
||||||
from synapse.events import EventBase
|
from synapse.events import EventBase, make_event_from_dict
|
||||||
from synapse.types import JsonDict
|
from synapse.types import JsonDict, create_requester
|
||||||
from synapse.visibility import filter_events_for_server
|
from synapse.visibility import filter_events_for_client, filter_events_for_server
|
||||||
|
|
||||||
from tests import unittest
|
from tests import unittest
|
||||||
from tests.utils import create_room
|
from tests.utils import create_room
|
||||||
@ -185,3 +186,72 @@ class FilterEventsForServerTestCase(unittest.HomeserverTestCase):
|
|||||||
|
|
||||||
self.get_success(self.storage.persistence.persist_event(event, context))
|
self.get_success(self.storage.persistence.persist_event(event, context))
|
||||||
return event
|
return event
|
||||||
|
|
||||||
|
|
||||||
|
class FilterEventsForClientTestCase(unittest.FederatingHomeserverTestCase):
|
||||||
|
def test_out_of_band_invite_rejection(self):
|
||||||
|
# this is where we have received an invite event over federation, and then
|
||||||
|
# rejected it.
|
||||||
|
invite_pdu = {
|
||||||
|
"room_id": "!room:id",
|
||||||
|
"depth": 1,
|
||||||
|
"auth_events": [],
|
||||||
|
"prev_events": [],
|
||||||
|
"origin_server_ts": 1,
|
||||||
|
"sender": "@someone:" + self.OTHER_SERVER_NAME,
|
||||||
|
"type": "m.room.member",
|
||||||
|
"state_key": "@user:test",
|
||||||
|
"content": {"membership": "invite"},
|
||||||
|
}
|
||||||
|
self.add_hashes_and_signatures(invite_pdu)
|
||||||
|
invite_event_id = make_event_from_dict(invite_pdu, RoomVersions.V9).event_id
|
||||||
|
|
||||||
|
self.get_success(
|
||||||
|
self.hs.get_federation_server().on_invite_request(
|
||||||
|
self.OTHER_SERVER_NAME,
|
||||||
|
invite_pdu,
|
||||||
|
"9",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# stub out do_remotely_reject_invite so that we fall back to a locally-
|
||||||
|
# generated rejection
|
||||||
|
with patch.object(
|
||||||
|
self.hs.get_federation_handler(),
|
||||||
|
"do_remotely_reject_invite",
|
||||||
|
side_effect=Exception(),
|
||||||
|
):
|
||||||
|
reject_event_id, _ = self.get_success(
|
||||||
|
self.hs.get_room_member_handler().remote_reject_invite(
|
||||||
|
invite_event_id,
|
||||||
|
txn_id=None,
|
||||||
|
requester=create_requester("@user:test"),
|
||||||
|
content={},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
invite_event, reject_event = self.get_success(
|
||||||
|
self.hs.get_datastores().main.get_events_as_list(
|
||||||
|
[invite_event_id, reject_event_id]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# the invited user should be able to see both the invite and the rejection
|
||||||
|
self.assertEqual(
|
||||||
|
self.get_success(
|
||||||
|
filter_events_for_client(
|
||||||
|
self.hs.get_storage(), "@user:test", [invite_event, reject_event]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
[invite_event, reject_event],
|
||||||
|
)
|
||||||
|
|
||||||
|
# other users should see neither
|
||||||
|
self.assertEqual(
|
||||||
|
self.get_success(
|
||||||
|
filter_events_for_client(
|
||||||
|
self.hs.get_storage(), "@other:test", [invite_event, reject_event]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user