Implement MSC2176: Updated redaction rules (#8984)

An experimental room version ("org.matrix.msc2176") contains
the new redaction rules for testing.
This commit is contained in:
Patrick Cloke 2021-01-05 07:41:48 -05:00 committed by GitHub
parent 111b673fc1
commit 9dde9c9f01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 206 additions and 30 deletions

View file

@ -34,11 +34,17 @@ def MockEvent(**kwargs):
class PruneEventTestCase(unittest.TestCase):
""" Asserts that a new event constructed with `evdict` will look like
`matchdict` when it is redacted. """
def run_test(self, evdict, matchdict, **kwargs):
self.assertEquals(
"""
Asserts that a new event constructed with `evdict` will look like
`matchdict` when it is redacted.
Args:
evdict: The dictionary to build the event from.
matchdict: The expected resulting dictionary.
kwargs: Additional keyword arguments used to create the event.
"""
self.assertEqual(
prune_event(make_event_from_dict(evdict, **kwargs)).get_dict(), matchdict
)
@ -55,54 +61,80 @@ class PruneEventTestCase(unittest.TestCase):
)
def test_basic_keys(self):
"""Ensure that the keys that should be untouched are kept."""
# Note that some of the values below don't really make sense, but the
# pruning of events doesn't worry about the values of any fields (with
# the exception of the content field).
self.run_test(
{
"event_id": "$3:domain",
"type": "A",
"room_id": "!1:domain",
"sender": "@2:domain",
"event_id": "$3:domain",
"state_key": "B",
"content": {"other_key": "foo"},
"hashes": "hashes",
"signatures": {"domain": {"algo:1": "sigs"}},
"depth": 4,
"prev_events": "prev_events",
"prev_state": "prev_state",
"auth_events": "auth_events",
"origin": "domain",
"origin_server_ts": 1234,
"membership": "join",
# Also include a key that should be removed.
"other_key": "foo",
},
{
"event_id": "$3:domain",
"type": "A",
"room_id": "!1:domain",
"sender": "@2:domain",
"event_id": "$3:domain",
"state_key": "B",
"hashes": "hashes",
"depth": 4,
"prev_events": "prev_events",
"prev_state": "prev_state",
"auth_events": "auth_events",
"origin": "domain",
"origin_server_ts": 1234,
"membership": "join",
"content": {},
"signatures": {},
"signatures": {"domain": {"algo:1": "sigs"}},
"unsigned": {},
},
)
def test_unsigned_age_ts(self):
# As of MSC2176 we now redact the membership and prev_states keys.
self.run_test(
{"type": "B", "event_id": "$test:domain", "unsigned": {"age_ts": 20}},
{
"type": "B",
"event_id": "$test:domain",
"content": {},
"signatures": {},
"unsigned": {"age_ts": 20},
},
{"type": "A", "prev_state": "prev_state", "membership": "join"},
{"type": "A", "content": {}, "signatures": {}, "unsigned": {}},
room_version=RoomVersions.MSC2176,
)
def test_unsigned(self):
"""Ensure that unsigned properties get stripped (except age_ts and replaces_state)."""
self.run_test(
{
"type": "B",
"event_id": "$test:domain",
"unsigned": {"other_key": "here"},
"unsigned": {
"age_ts": 20,
"replaces_state": "$test2:domain",
"other_key": "foo",
},
},
{
"type": "B",
"event_id": "$test:domain",
"content": {},
"signatures": {},
"unsigned": {},
"unsigned": {"age_ts": 20, "replaces_state": "$test2:domain"},
},
)
def test_content(self):
"""The content dictionary should be stripped in most cases."""
self.run_test(
{"type": "C", "event_id": "$test:domain", "content": {"things": "here"}},
{
@ -114,11 +146,35 @@ class PruneEventTestCase(unittest.TestCase):
},
)
# Some events keep a single content key/value.
EVENT_KEEP_CONTENT_KEYS = [
("member", "membership", "join"),
("join_rules", "join_rule", "invite"),
("history_visibility", "history_visibility", "shared"),
]
for event_type, key, value in EVENT_KEEP_CONTENT_KEYS:
self.run_test(
{
"type": "m.room." + event_type,
"event_id": "$test:domain",
"content": {key: value, "other_key": "foo"},
},
{
"type": "m.room." + event_type,
"event_id": "$test:domain",
"content": {key: value},
"signatures": {},
"unsigned": {},
},
)
def test_create(self):
"""Create events are partially redacted until MSC2176."""
self.run_test(
{
"type": "m.room.create",
"event_id": "$test:domain",
"content": {"creator": "@2:domain", "other_field": "here"},
"content": {"creator": "@2:domain", "other_key": "foo"},
},
{
"type": "m.room.create",
@ -129,6 +185,68 @@ class PruneEventTestCase(unittest.TestCase):
},
)
# After MSC2176, create events get nothing redacted.
self.run_test(
{"type": "m.room.create", "content": {"not_a_real_key": True}},
{
"type": "m.room.create",
"content": {"not_a_real_key": True},
"signatures": {},
"unsigned": {},
},
room_version=RoomVersions.MSC2176,
)
def test_power_levels(self):
"""Power level events keep a variety of content keys."""
self.run_test(
{
"type": "m.room.power_levels",
"event_id": "$test:domain",
"content": {
"ban": 1,
"events": {"m.room.name": 100},
"events_default": 2,
"invite": 3,
"kick": 4,
"redact": 5,
"state_default": 6,
"users": {"@admin:domain": 100},
"users_default": 7,
"other_key": 8,
},
},
{
"type": "m.room.power_levels",
"event_id": "$test:domain",
"content": {
"ban": 1,
"events": {"m.room.name": 100},
"events_default": 2,
# Note that invite is not here.
"kick": 4,
"redact": 5,
"state_default": 6,
"users": {"@admin:domain": 100},
"users_default": 7,
},
"signatures": {},
"unsigned": {},
},
)
# After MSC2176, power levels events keep the invite key.
self.run_test(
{"type": "m.room.power_levels", "content": {"invite": 75}},
{
"type": "m.room.power_levels",
"content": {"invite": 75},
"signatures": {},
"unsigned": {},
},
room_version=RoomVersions.MSC2176,
)
def test_alias_event(self):
"""Alias events have special behavior up through room version 6."""
self.run_test(
@ -146,8 +264,7 @@ class PruneEventTestCase(unittest.TestCase):
},
)
def test_msc2432_alias_event(self):
"""After MSC2432, alias events have no special behavior."""
# After MSC2432, alias events have no special behavior.
self.run_test(
{"type": "m.room.aliases", "content": {"aliases": ["test"]}},
{
@ -159,6 +276,32 @@ class PruneEventTestCase(unittest.TestCase):
room_version=RoomVersions.V6,
)
def test_redacts(self):
"""Redaction events have no special behaviour until MSC2174/MSC2176."""
self.run_test(
{"type": "m.room.redaction", "content": {"redacts": "$test2:domain"}},
{
"type": "m.room.redaction",
"content": {},
"signatures": {},
"unsigned": {},
},
room_version=RoomVersions.V6,
)
# After MSC2174, redaction events keep the redacts content key.
self.run_test(
{"type": "m.room.redaction", "content": {"redacts": "$test2:domain"}},
{
"type": "m.room.redaction",
"content": {"redacts": "$test2:domain"},
"signatures": {},
"unsigned": {},
},
room_version=RoomVersions.MSC2176,
)
class SerializeEventTestCase(unittest.TestCase):
def serialize(self, ev, fields):