|
@@ -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):
|