Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Implement MSC2176: Updated redaction rules #8984

Merged
merged 8 commits into from
Jan 5, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 146 additions & 48 deletions tests/events/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
)

Expand All @@ -55,54 +61,80 @@ def test_minimal(self):
)

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):
# MSC2176 now redact the membership and prev_states keys.
clokep marked this conversation as resolved.
Show resolved Hide resolved
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"}},
{
Expand All @@ -114,11 +146,35 @@ def test_content(self):
},
)

# 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",
Expand All @@ -129,6 +185,68 @@ def test_content(self):
},
)

# Create events get nothing redacted.
clokep marked this conversation as resolved.
Show resolved Hide resolved
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(
Expand All @@ -146,8 +264,7 @@ def test_alias_event(self):
},
)

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"]}},
{
Expand All @@ -159,45 +276,26 @@ def test_msc2432_alias_event(self):
room_version=RoomVersions.V6,
)

def test_msc2176_event(self):
"""Assert behaviour modified by MSC2432."""
# membership and prev_state are now redacted.
self.run_test(
{"type": "other_type", "membership": True, "prev_state": True},
{"type": "other_type", "content": {}, "signatures": {}, "unsigned": {}},
room_version=RoomVersions.MSC2176,
)
def test_redacts(self):
"""Redaction events have no special behaviour until MSC2174/MSC2176."""

# Create events get nothing redacted.
self.run_test(
{"type": "m.room.create", "content": {"not_a_real_key": True}},
{"type": "m.room.redaction", "content": {"redacts": "$test2:domain"}},
{
"type": "m.room.create",
"content": {"not_a_real_key": True},
"type": "m.room.redaction",
"content": {},
"signatures": {},
"unsigned": {},
},
room_version=RoomVersions.MSC2176,
room_version=RoomVersions.V6,
)

# Redaction events keep the redacts content key from MSC2174.
clokep marked this conversation as resolved.
Show resolved Hide resolved
self.run_test(
{"type": "m.room.redaction", "content": {"redacts": True}},
{"type": "m.room.redaction", "content": {"redacts": "$test2:domain"}},
{
"type": "m.room.redaction",
"content": {"redacts": True},
"signatures": {},
"unsigned": {},
},
room_version=RoomVersions.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},
"content": {"redacts": "$test2:domain"},
"signatures": {},
"unsigned": {},
},
Expand Down