Compare commits
8 commits
develop
...
madlittlem
Author | SHA1 | Date | |
---|---|---|---|
2370dcadf6 | |||
d10625eb18 | |||
f421a2df2d | |||
4bb5fd33a3 | |||
e093481966 | |||
9f45d09fe7 | |||
66f085911c | |||
39efad1b8f |
1
changelog.d/11243.feature
Normal file
1
changelog.d/11243.feature
Normal file
|
@ -0,0 +1 @@
|
|||
Add experimental room version `org.matrix.msc2716v4` to allow events to be created without `prev_events` (only `auth_events`).
|
|
@ -81,6 +81,8 @@ class RoomVersion:
|
|||
msc2716_historical = attr.ib(type=bool)
|
||||
# MSC2716: Adds support for redacting "insertion", "chunk", and "marker" events
|
||||
msc2716_redactions = attr.ib(type=bool)
|
||||
# MSC2716: Adds support for events with no `prev_events` but with some `auth_events`
|
||||
msc2716_empty_prev_events = attr.ib(type=bool)
|
||||
|
||||
|
||||
class RoomVersions:
|
||||
|
@ -99,6 +101,7 @@ class RoomVersions:
|
|||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
msc2716_empty_prev_events=False,
|
||||
)
|
||||
V2 = RoomVersion(
|
||||
"2",
|
||||
|
@ -115,6 +118,7 @@ class RoomVersions:
|
|||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
msc2716_empty_prev_events=False,
|
||||
)
|
||||
V3 = RoomVersion(
|
||||
"3",
|
||||
|
@ -131,6 +135,7 @@ class RoomVersions:
|
|||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
msc2716_empty_prev_events=False,
|
||||
)
|
||||
V4 = RoomVersion(
|
||||
"4",
|
||||
|
@ -147,6 +152,7 @@ class RoomVersions:
|
|||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
msc2716_empty_prev_events=False,
|
||||
)
|
||||
V5 = RoomVersion(
|
||||
"5",
|
||||
|
@ -163,6 +169,7 @@ class RoomVersions:
|
|||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
msc2716_empty_prev_events=False,
|
||||
)
|
||||
V6 = RoomVersion(
|
||||
"6",
|
||||
|
@ -179,6 +186,7 @@ class RoomVersions:
|
|||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
msc2716_empty_prev_events=False,
|
||||
)
|
||||
MSC2176 = RoomVersion(
|
||||
"org.matrix.msc2176",
|
||||
|
@ -195,6 +203,7 @@ class RoomVersions:
|
|||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
msc2716_empty_prev_events=False,
|
||||
)
|
||||
V7 = RoomVersion(
|
||||
"7",
|
||||
|
@ -211,6 +220,7 @@ class RoomVersions:
|
|||
msc2403_knocking=True,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
msc2716_empty_prev_events=False,
|
||||
)
|
||||
V8 = RoomVersion(
|
||||
"8",
|
||||
|
@ -227,6 +237,7 @@ class RoomVersions:
|
|||
msc2403_knocking=True,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
msc2716_empty_prev_events=False,
|
||||
)
|
||||
V9 = RoomVersion(
|
||||
"9",
|
||||
|
@ -243,6 +254,7 @@ class RoomVersions:
|
|||
msc2403_knocking=True,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
msc2716_empty_prev_events=False,
|
||||
)
|
||||
MSC2716v3 = RoomVersion(
|
||||
"org.matrix.msc2716v3",
|
||||
|
@ -259,6 +271,24 @@ class RoomVersions:
|
|||
msc2403_knocking=True,
|
||||
msc2716_historical=True,
|
||||
msc2716_redactions=True,
|
||||
msc2716_empty_prev_events=False,
|
||||
)
|
||||
MSC2716v4 = RoomVersion(
|
||||
"org.matrix.msc2716v4",
|
||||
RoomDisposition.UNSTABLE,
|
||||
EventFormatVersions.V3,
|
||||
StateResolutionVersions.V2,
|
||||
enforce_key_validity=True,
|
||||
special_case_aliases_auth=False,
|
||||
strict_canonicaljson=True,
|
||||
limit_notifications_power_levels=True,
|
||||
msc2176_redaction_rules=False,
|
||||
msc3083_join_rules=False,
|
||||
msc3375_redaction_rules=False,
|
||||
msc2403_knocking=True,
|
||||
msc2716_historical=True,
|
||||
msc2716_redactions=True,
|
||||
msc2716_empty_prev_events=True,
|
||||
)
|
||||
|
||||
|
||||
|
@ -276,6 +306,7 @@ KNOWN_ROOM_VERSIONS: Dict[str, RoomVersion] = {
|
|||
RoomVersions.V8,
|
||||
RoomVersions.V9,
|
||||
RoomVersions.MSC2716v3,
|
||||
RoomVersions.MSC2716v4,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -918,6 +918,7 @@ class EventCreationHandler:
|
|||
full_state_ids_at_event = None
|
||||
if auth_event_ids is not None:
|
||||
# If auth events are provided, prev events must be also.
|
||||
# prev_event_ids could be an empty array though.
|
||||
assert prev_event_ids is not None
|
||||
|
||||
# Copy the full auth state before it stripped down
|
||||
|
@ -949,14 +950,24 @@ class EventCreationHandler:
|
|||
else:
|
||||
prev_event_ids = await self.store.get_prev_events_for_room(builder.room_id)
|
||||
|
||||
# we now ought to have some prev_events (unless it's a create event).
|
||||
#
|
||||
# do a quick sanity check here, rather than waiting until we've created the
|
||||
# Do a quick sanity check here, rather than waiting until we've created the
|
||||
# event and then try to auth it (which fails with a somewhat confusing "No
|
||||
# create event in auth events")
|
||||
assert (
|
||||
builder.type == EventTypes.Create or len(prev_event_ids) > 0
|
||||
), "Attempting to create an event with no prev_events"
|
||||
room_version_obj = await self.store.get_room_version(builder.room_id)
|
||||
if room_version_obj.msc2716_empty_prev_events:
|
||||
# We allow events with no `prev_events` but it better have some `auth_events`
|
||||
assert (
|
||||
builder.type == EventTypes.Create
|
||||
or len(prev_event_ids) > 0
|
||||
# Allow an event to have empty list of prev_event_ids
|
||||
# only if it has auth_event_ids.
|
||||
or auth_event_ids
|
||||
), "Attempting to create a non-m.room.create event with no prev_events or auth_event_ids"
|
||||
else:
|
||||
# we now ought to have some prev_events (unless it's a create event).
|
||||
assert (
|
||||
builder.type == EventTypes.Create or len(prev_event_ids) > 0
|
||||
), "Attempting to create a non-m.room.create event with no prev_events"
|
||||
|
||||
event = await builder.build(
|
||||
prev_event_ids=prev_event_ids,
|
||||
|
|
|
@ -644,7 +644,8 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
|||
if block_invite:
|
||||
raise SynapseError(403, "Invites have been disabled on this server")
|
||||
|
||||
if prev_event_ids:
|
||||
# An empty prev_events list is allowed by room version "org.matrix.msc2716v4"
|
||||
if prev_event_ids is not None:
|
||||
return await self._local_membership_update(
|
||||
requester=requester,
|
||||
target=target,
|
||||
|
|
|
@ -15,6 +15,7 @@ import logging
|
|||
from typing import Tuple
|
||||
|
||||
from synapse.api.constants import EventTypes
|
||||
from synapse.api.room_versions import RoomVersions
|
||||
from synapse.events import EventBase
|
||||
from synapse.events.snapshot import EventContext
|
||||
from synapse.rest import admin
|
||||
|
@ -23,6 +24,7 @@ from synapse.types import create_requester
|
|||
from synapse.util.stringutils import random_string
|
||||
|
||||
from tests import unittest
|
||||
from tests.test_utils.event_injection import create_event
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -156,6 +158,80 @@ class EventCreationTestCase(unittest.HomeserverTestCase):
|
|||
self.assertEqual(len(events), 2)
|
||||
self.assertEqual(events[0].event_id, events[1].event_id)
|
||||
|
||||
def test_create_empty_prev_events_in_msc2716_room_version(self):
|
||||
"""Try to create an event without any prev_events (only auth_events).
|
||||
|
||||
This is currently only supported in the experimental MSC2716v4+ room versions.
|
||||
"""
|
||||
room_id = self.helper.create_room_as(
|
||||
self.user_id,
|
||||
tok=self.access_token,
|
||||
room_version=RoomVersions.MSC2716v4.identifier,
|
||||
)
|
||||
|
||||
# Create a member event we can use as an auth_event
|
||||
memberEvent, memberEventContext = self.get_success(
|
||||
create_event(
|
||||
self.hs,
|
||||
room_id=room_id,
|
||||
type="m.room.member",
|
||||
sender=self.requester.user.to_string(),
|
||||
state_key=self.requester.user.to_string(),
|
||||
content={"membership": "join"},
|
||||
)
|
||||
)
|
||||
self.get_success(
|
||||
self.persist_event_storage.persist_event(memberEvent, memberEventContext)
|
||||
)
|
||||
|
||||
# Try to create the event with empty prev_events (only auth_events)
|
||||
event, _ = self.get_success(
|
||||
self.handler.create_event(
|
||||
self.requester,
|
||||
{
|
||||
"type": EventTypes.Message,
|
||||
"room_id": room_id,
|
||||
"sender": self.requester.user.to_string(),
|
||||
"content": {"msgtype": "m.text", "body": random_string(5)},
|
||||
},
|
||||
# Empty prev_events is the key thing we're testing here
|
||||
prev_event_ids=[],
|
||||
auth_event_ids=[memberEvent.event_id],
|
||||
)
|
||||
)
|
||||
self.assertIsNotNone(event)
|
||||
|
||||
def test_reject_empty_prev_events_and_auth_events_in_msc2716_room_version(
|
||||
self,
|
||||
):
|
||||
"""Try to create an event without any prev_events or auth_events.
|
||||
Expect an exception to be raised.
|
||||
|
||||
This is currently only supported in the experimental MSC2716v4 room versions.
|
||||
"""
|
||||
room_id = self.helper.create_room_as(
|
||||
self.user_id,
|
||||
tok=self.access_token,
|
||||
room_version=RoomVersions.MSC2716v4.identifier,
|
||||
)
|
||||
|
||||
# Try to create the event with empty prev_events and empty auth_events
|
||||
self.get_failure(
|
||||
self.handler.create_event(
|
||||
self.requester,
|
||||
{
|
||||
"type": EventTypes.Message,
|
||||
"room_id": room_id,
|
||||
"sender": self.requester.user.to_string(),
|
||||
"content": {"msgtype": "m.text", "body": random_string(5)},
|
||||
},
|
||||
prev_event_ids=[],
|
||||
# The event should be rejected when there are no auth_events
|
||||
auth_event_ids=[],
|
||||
),
|
||||
AssertionError,
|
||||
)
|
||||
|
||||
|
||||
class ServerAclValidationTestCase(unittest.HomeserverTestCase):
|
||||
servlets = [
|
||||
|
|
Loading…
Reference in a new issue