Include user membership on events (#17282)
Some checks are pending
Build docker images / build (push) Waiting to run
Deploy the documentation / Calculate variables for GitHub Pages deployment (push) Waiting to run
Deploy the documentation / GitHub Pages (push) Blocked by required conditions
Build release artifacts / Calculate list of debian distros (push) Waiting to run
Build release artifacts / Build .deb packages (push) Blocked by required conditions
Build release artifacts / Build wheels on ${{ matrix.os }} for ${{ matrix.arch }} (aarch64, ${{ startsWith(github.ref, 'refs/pull/') }}, ubuntu-20.04) (push) Waiting to run
Build release artifacts / Build wheels on ${{ matrix.os }} for ${{ matrix.arch }} (x86_64, ${{ startsWith(github.ref, 'refs/pull/') }}, macos-11) (push) Waiting to run
Build release artifacts / Build wheels on ${{ matrix.os }} for ${{ matrix.arch }} (x86_64, ${{ startsWith(github.ref, 'refs/pull/') }}, ubuntu-20.04) (push) Waiting to run
Build release artifacts / Build sdist (push) Waiting to run
Build release artifacts / Attach assets to release (push) Blocked by required conditions
Tests / linting-done (push) Blocked by required conditions
Tests / calculate-test-jobs (push) Blocked by required conditions
Tests / Typechecking (push) Blocked by required conditions
Tests / lint-crlf (push) Waiting to run
Tests / lint-newsfile (push) Waiting to run
Tests / lint-pydantic (push) Blocked by required conditions
Tests / lint-clippy (push) Blocked by required conditions
Tests / lint-clippy-nightly (push) Blocked by required conditions
Tests / lint-rustfmt (push) Blocked by required conditions
Tests / check-sampleconfig (push) Blocked by required conditions
Tests / check-schema-delta (push) Blocked by required conditions
Tests / check-lockfile (push) Waiting to run
Tests / lint (push) Blocked by required conditions
Tests / changes (push) Waiting to run
Tests / trial (push) Blocked by required conditions
Tests / trial-olddeps (push) Blocked by required conditions
Tests / trial-pypy (all, pypy-3.8) (push) Blocked by required conditions
Tests / sytest (push) Blocked by required conditions
Tests / export-data (push) Blocked by required conditions
Tests / portdb (11, 3.8) (push) Blocked by required conditions
Tests / portdb (15, 3.11) (push) Blocked by required conditions
Tests / complement (monolith, Postgres) (push) Blocked by required conditions
Tests / complement (monolith, SQLite) (push) Blocked by required conditions
Tests / complement (workers, Postgres) (push) Blocked by required conditions
Tests / cargo-test (push) Blocked by required conditions
Tests / cargo-bench (push) Blocked by required conditions
Tests / tests-done (push) Blocked by required conditions

MSC4115 has now completed FCP, so we can enable it by default and switch
to the stable identifier.
This commit is contained in:
Richard van der Hoff 2024-06-13 22:45:54 +01:00 committed by GitHub
parent c12ee0d5ba
commit 2c36a679ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 8 additions and 45 deletions

View file

@ -0,0 +1 @@
Include user membership in events served to clients, per MSC4115.

View file

@ -105,8 +105,6 @@ experimental_features:
# Expose a room summary for public rooms # Expose a room summary for public rooms
msc3266_enabled: true msc3266_enabled: true
msc4115_membership_on_events: true
server_notices: server_notices:
system_mxid_localpart: _server system_mxid_localpart: _server
system_mxid_display_name: "Server Alert" system_mxid_display_name: "Server Alert"

View file

@ -223,7 +223,6 @@ test_packages=(
./tests/msc3930 ./tests/msc3930
./tests/msc3902 ./tests/msc3902
./tests/msc3967 ./tests/msc3967
./tests/msc4115
) )
# Enable dirty runs, so tests will reuse the same container where possible. # Enable dirty runs, so tests will reuse the same container where possible.

View file

@ -238,7 +238,7 @@ class EventUnsignedContentFields:
"""Fields found inside the 'unsigned' data on events""" """Fields found inside the 'unsigned' data on events"""
# Requesting user's membership, per MSC4115 # Requesting user's membership, per MSC4115
MSC4115_MEMBERSHIP: Final = "io.element.msc4115.membership" MEMBERSHIP: Final = "membership"
class RoomTypes: class RoomTypes:

View file

@ -436,10 +436,6 @@ class ExperimentalConfig(Config):
("experimental", "msc4108_delegation_endpoint"), ("experimental", "msc4108_delegation_endpoint"),
) )
self.msc4115_membership_on_events = experimental.get(
"msc4115_membership_on_events", False
)
self.msc3916_authenticated_media_enabled = experimental.get( self.msc3916_authenticated_media_enabled = experimental.get(
"msc3916_authenticated_media_enabled", False "msc3916_authenticated_media_enabled", False
) )

View file

@ -42,7 +42,6 @@ class AdminHandler:
self._device_handler = hs.get_device_handler() self._device_handler = hs.get_device_handler()
self._storage_controllers = hs.get_storage_controllers() self._storage_controllers = hs.get_storage_controllers()
self._state_storage_controller = self._storage_controllers.state self._state_storage_controller = self._storage_controllers.state
self._hs_config = hs.config
self._msc3866_enabled = hs.config.experimental.msc3866.enabled self._msc3866_enabled = hs.config.experimental.msc3866.enabled
async def get_whois(self, user: UserID) -> JsonMapping: async def get_whois(self, user: UserID) -> JsonMapping:
@ -215,7 +214,6 @@ class AdminHandler:
self._storage_controllers, self._storage_controllers,
user_id, user_id,
events, events,
msc4115_membership_on_events=self._hs_config.experimental.msc4115_membership_on_events,
) )
writer.write_events(room_id, events) writer.write_events(room_id, events)

View file

@ -148,7 +148,6 @@ class EventHandler:
def __init__(self, hs: "HomeServer"): def __init__(self, hs: "HomeServer"):
self.store = hs.get_datastores().main self.store = hs.get_datastores().main
self._storage_controllers = hs.get_storage_controllers() self._storage_controllers = hs.get_storage_controllers()
self._config = hs.config
async def get_event( async def get_event(
self, self,
@ -194,7 +193,6 @@ class EventHandler:
user.to_string(), user.to_string(),
[event], [event],
is_peeking=is_peeking, is_peeking=is_peeking,
msc4115_membership_on_events=self._config.experimental.msc4115_membership_on_events,
) )
if not filtered: if not filtered:

View file

@ -224,7 +224,6 @@ class InitialSyncHandler:
self._storage_controllers, self._storage_controllers,
user_id, user_id,
messages, messages,
msc4115_membership_on_events=self.hs.config.experimental.msc4115_membership_on_events,
) )
start_token = now_token.copy_and_replace(StreamKeyType.ROOM, token) start_token = now_token.copy_and_replace(StreamKeyType.ROOM, token)
@ -383,7 +382,6 @@ class InitialSyncHandler:
requester.user.to_string(), requester.user.to_string(),
messages, messages,
is_peeking=is_peeking, is_peeking=is_peeking,
msc4115_membership_on_events=self.hs.config.experimental.msc4115_membership_on_events,
) )
start_token = StreamToken.START.copy_and_replace(StreamKeyType.ROOM, token) start_token = StreamToken.START.copy_and_replace(StreamKeyType.ROOM, token)
@ -498,7 +496,6 @@ class InitialSyncHandler:
requester.user.to_string(), requester.user.to_string(),
messages, messages,
is_peeking=is_peeking, is_peeking=is_peeking,
msc4115_membership_on_events=self.hs.config.experimental.msc4115_membership_on_events,
) )
start_token = now_token.copy_and_replace(StreamKeyType.ROOM, token) start_token = now_token.copy_and_replace(StreamKeyType.ROOM, token)

View file

@ -623,7 +623,6 @@ class PaginationHandler:
user_id, user_id,
events, events,
is_peeking=(member_event_id is None), is_peeking=(member_event_id is None),
msc4115_membership_on_events=self.hs.config.experimental.msc4115_membership_on_events,
) )
# if after the filter applied there are no more events # if after the filter applied there are no more events

View file

@ -95,7 +95,6 @@ class RelationsHandler:
self._event_handler = hs.get_event_handler() self._event_handler = hs.get_event_handler()
self._event_serializer = hs.get_event_client_serializer() self._event_serializer = hs.get_event_client_serializer()
self._event_creation_handler = hs.get_event_creation_handler() self._event_creation_handler = hs.get_event_creation_handler()
self._config = hs.config
async def get_relations( async def get_relations(
self, self,
@ -164,7 +163,6 @@ class RelationsHandler:
user_id, user_id,
events, events,
is_peeking=(member_event_id is None), is_peeking=(member_event_id is None),
msc4115_membership_on_events=self._config.experimental.msc4115_membership_on_events,
) )
# The relations returned for the requested event do include their # The relations returned for the requested event do include their
@ -610,7 +608,6 @@ class RelationsHandler:
user_id, user_id,
events, events,
is_peeking=(member_event_id is None), is_peeking=(member_event_id is None),
msc4115_membership_on_events=self._config.experimental.msc4115_membership_on_events,
) )
aggregations = await self.get_bundled_aggregations( aggregations = await self.get_bundled_aggregations(

View file

@ -1476,7 +1476,6 @@ class RoomContextHandler:
user.to_string(), user.to_string(),
events, events,
is_peeking=is_peeking, is_peeking=is_peeking,
msc4115_membership_on_events=self.hs.config.experimental.msc4115_membership_on_events,
) )
event = await self.store.get_event( event = await self.store.get_event(

View file

@ -483,7 +483,6 @@ class SearchHandler:
self._storage_controllers, self._storage_controllers,
user.to_string(), user.to_string(),
filtered_events, filtered_events,
msc4115_membership_on_events=self.hs.config.experimental.msc4115_membership_on_events,
) )
events.sort(key=lambda e: -rank_map[e.event_id]) events.sort(key=lambda e: -rank_map[e.event_id])
@ -585,7 +584,6 @@ class SearchHandler:
self._storage_controllers, self._storage_controllers,
user.to_string(), user.to_string(),
filtered_events, filtered_events,
msc4115_membership_on_events=self.hs.config.experimental.msc4115_membership_on_events,
) )
room_events.extend(events) room_events.extend(events)
@ -673,14 +671,12 @@ class SearchHandler:
self._storage_controllers, self._storage_controllers,
user.to_string(), user.to_string(),
res.events_before, res.events_before,
msc4115_membership_on_events=self.hs.config.experimental.msc4115_membership_on_events,
) )
events_after = await filter_events_for_client( events_after = await filter_events_for_client(
self._storage_controllers, self._storage_controllers,
user.to_string(), user.to_string(),
res.events_after, res.events_after,
msc4115_membership_on_events=self.hs.config.experimental.msc4115_membership_on_events,
) )
context: JsonDict = { context: JsonDict = {

View file

@ -844,7 +844,6 @@ class SyncHandler:
sync_config.user.to_string(), sync_config.user.to_string(),
recents, recents,
always_include_ids=current_state_ids, always_include_ids=current_state_ids,
msc4115_membership_on_events=self.hs_config.experimental.msc4115_membership_on_events,
) )
log_kv({"recents_after_visibility_filtering": len(recents)}) log_kv({"recents_after_visibility_filtering": len(recents)})
else: else:
@ -930,7 +929,6 @@ class SyncHandler:
sync_config.user.to_string(), sync_config.user.to_string(),
loaded_recents, loaded_recents,
always_include_ids=current_state_ids, always_include_ids=current_state_ids,
msc4115_membership_on_events=self.hs_config.experimental.msc4115_membership_on_events,
) )
loaded_recents = [] loaded_recents = []

View file

@ -721,7 +721,6 @@ class Notifier:
user.to_string(), user.to_string(),
new_events, new_events,
is_peeking=is_peeking, is_peeking=is_peeking,
msc4115_membership_on_events=self.hs.config.experimental.msc4115_membership_on_events,
) )
elif keyname == StreamKeyType.PRESENCE: elif keyname == StreamKeyType.PRESENCE:
now = self.clock.time_msec() now = self.clock.time_msec()

View file

@ -532,7 +532,6 @@ class Mailer:
self._storage_controllers, self._storage_controllers,
user_id, user_id,
results.events_before, results.events_before,
msc4115_membership_on_events=self.hs.config.experimental.msc4115_membership_on_events,
) )
the_events.append(notif_event) the_events.append(notif_event)

View file

@ -82,7 +82,6 @@ async def filter_events_for_client(
is_peeking: bool = False, is_peeking: bool = False,
always_include_ids: FrozenSet[str] = frozenset(), always_include_ids: FrozenSet[str] = frozenset(),
filter_send_to_client: bool = True, filter_send_to_client: bool = True,
msc4115_membership_on_events: bool = False,
) -> List[EventBase]: ) -> List[EventBase]:
""" """
Check which events a user is allowed to see. If the user can see the event but its Check which events a user is allowed to see. If the user can see the event but its
@ -101,12 +100,10 @@ async def filter_events_for_client(
filter_send_to_client: Whether we're checking an event that's going to be filter_send_to_client: Whether we're checking an event that's going to be
sent to a client. This might not always be the case since this function can sent to a client. This might not always be the case since this function can
also be called to check whether a user can see the state at a given point. also be called to check whether a user can see the state at a given point.
msc4115_membership_on_events: Whether to include the requesting user's
membership in the "unsigned" data, per MSC4115.
Returns: Returns:
The filtered events. If `msc4115_membership_on_events` is true, the `unsigned` The filtered events. The `unsigned` data is annotated with the membership state
data is annotated with the membership state of `user_id` at each event. of `user_id` at each event.
""" """
# Filter out events that have been soft failed so that we don't relay them # Filter out events that have been soft failed so that we don't relay them
# to clients. # to clients.
@ -159,9 +156,6 @@ async def filter_events_for_client(
if filtered is None: if filtered is None:
return None return None
if not msc4115_membership_on_events:
return filtered
# Annotate the event with the user's membership after the event. # Annotate the event with the user's membership after the event.
# #
# Normally we just look in `state_after_event`, but if the event is an outlier # Normally we just look in `state_after_event`, but if the event is an outlier
@ -186,7 +180,7 @@ async def filter_events_for_client(
# Copy the event before updating the unsigned data: this shouldn't be persisted # Copy the event before updating the unsigned data: this shouldn't be persisted
# to the cache! # to the cache!
cloned = clone_event(filtered) cloned = clone_event(filtered)
cloned.unsigned[EventUnsignedContentFields.MSC4115_MEMBERSHIP] = user_membership cloned.unsigned[EventUnsignedContentFields.MEMBERSHIP] = user_membership
return cloned return cloned

View file

@ -167,7 +167,6 @@ class RetentionTestCase(unittest.HomeserverTestCase):
storage_controllers, storage_controllers,
self.user_id, self.user_id,
events, events,
msc4115_membership_on_events=True,
) )
) )

View file

@ -336,7 +336,6 @@ class FilterEventsForClientTestCase(HomeserverTestCase):
self.hs.get_storage_controllers(), self.hs.get_storage_controllers(),
"@joiner:test", "@joiner:test",
events_to_filter, events_to_filter,
msc4115_membership_on_events=True,
) )
) )
resident_filtered_events = self.get_success( resident_filtered_events = self.get_success(
@ -344,7 +343,6 @@ class FilterEventsForClientTestCase(HomeserverTestCase):
self.hs.get_storage_controllers(), self.hs.get_storage_controllers(),
"@resident:test", "@resident:test",
events_to_filter, events_to_filter,
msc4115_membership_on_events=True,
) )
) )
@ -357,7 +355,7 @@ class FilterEventsForClientTestCase(HomeserverTestCase):
self.assertEqual( self.assertEqual(
["join", "join", "leave"], ["join", "join", "leave"],
[ [
e.unsigned[EventUnsignedContentFields.MSC4115_MEMBERSHIP] e.unsigned[EventUnsignedContentFields.MEMBERSHIP]
for e in joiner_filtered_events for e in joiner_filtered_events
], ],
) )
@ -379,7 +377,7 @@ class FilterEventsForClientTestCase(HomeserverTestCase):
self.assertEqual( self.assertEqual(
["join", "join", "join", "join", "join"], ["join", "join", "join", "join", "join"],
[ [
e.unsigned[EventUnsignedContentFields.MSC4115_MEMBERSHIP] e.unsigned[EventUnsignedContentFields.MEMBERSHIP]
for e in resident_filtered_events for e in resident_filtered_events
], ],
) )
@ -441,7 +439,6 @@ class FilterEventsOutOfBandEventsForClientTestCase(
self.hs.get_storage_controllers(), self.hs.get_storage_controllers(),
"@user:test", "@user:test",
[invite_event, reject_event], [invite_event, reject_event],
msc4115_membership_on_events=True,
) )
) )
self.assertEqual( self.assertEqual(
@ -451,7 +448,7 @@ class FilterEventsOutOfBandEventsForClientTestCase(
self.assertEqual( self.assertEqual(
["invite", "leave"], ["invite", "leave"],
[ [
e.unsigned[EventUnsignedContentFields.MSC4115_MEMBERSHIP] e.unsigned[EventUnsignedContentFields.MEMBERSHIP]
for e in filtered_events for e in filtered_events
], ],
) )
@ -463,7 +460,6 @@ class FilterEventsOutOfBandEventsForClientTestCase(
self.hs.get_storage_controllers(), self.hs.get_storage_controllers(),
"@other:test", "@other:test",
[invite_event, reject_event], [invite_event, reject_event],
msc4115_membership_on_events=True,
) )
), ),
[], [],