Implement redaction for v1 to v11 events

This commit is contained in:
2025-10-26 22:38:22 -04:00
parent 17d5a6458e
commit da82f492e8
4 changed files with 63 additions and 16 deletions

View File

@@ -174,7 +174,7 @@ async def make_join(room, user):
return jsonify({
"event": globals.hash_and_sign_event(join),
"event": globals.hash_and_sign_event(join, int(room_ver)),
"room_version": room_ver
})

View File

@@ -223,12 +223,12 @@ def v3(request, room) -> dict:
del event["signatures"]
# m.room.create doesn't have prev_events or auth_events
events["m.room.create"] = globals.hash_and_sign_event(events["m.room.create"])
events["m.room.create"] = globals.hash_and_sign_event(events["m.room.create"], ver)
hash_map["m.room.create"] = globals.make_ref_hash(events["m.room.create"], ver)
events["m.room.member"]["auth_events"] = [hash_map["m.room.create"]]
events["m.room.member"]["prev_events"] = [hash_map["m.room.create"]]
events["m.room.member"] = globals.hash_and_sign_event(events["m.room.member"])
events["m.room.member"] = globals.hash_and_sign_event(events["m.room.member"], ver)
hash_map["m.room.member"] = globals.make_ref_hash(events["m.room.member"], ver)
events["m.room.power_levels"]["auth_events"] = [
@@ -238,7 +238,7 @@ def v3(request, room) -> dict:
events["m.room.power_levels"]["prev_events"] = [hash_map["m.room.member"]]
if ver == 10:
events["m.room.power_levels"]["content"]["users"][f"@vona:{config.server_name}"] = 100
events["m.room.power_levels"] = globals.hash_and_sign_event(events["m.room.power_levels"])
events["m.room.power_levels"] = globals.hash_and_sign_event(events["m.room.power_levels"], ver)
hash_map["m.room.power_levels"] = globals.make_ref_hash(events["m.room.power_levels"], ver)
events["m.room.join_rules"]["auth_events"] = [
@@ -247,7 +247,7 @@ def v3(request, room) -> dict:
hash_map["m.room.power_levels"],
]
events["m.room.join_rules"]["prev_events"] = [hash_map["m.room.power_levels"]]
events["m.room.join_rules"] = globals.hash_and_sign_event(events["m.room.join_rules"])
events["m.room.join_rules"] = globals.hash_and_sign_event(events["m.room.join_rules"], ver)
hash_map["m.room.join_rules"] = globals.make_ref_hash(events["m.room.join_rules"], ver)
events["m.room.guest_access"]["auth_events"] = [
@@ -256,7 +256,7 @@ def v3(request, room) -> dict:
hash_map["m.room.power_levels"],
]
events["m.room.guest_access"]["prev_events"] = [hash_map["m.room.join_rules"]]
events["m.room.guest_access"] = globals.hash_and_sign_event(events["m.room.guest_access"])
events["m.room.guest_access"] = globals.hash_and_sign_event(events["m.room.guest_access"], ver)
hash_map["m.room.guest_access"] = globals.make_ref_hash(events["m.room.guest_access"], ver)
events["m.room.history_visibility"]["auth_events"] = [
@@ -265,7 +265,7 @@ def v3(request, room) -> dict:
hash_map["m.room.power_levels"],
]
events["m.room.history_visibility"]["prev_events"] = [hash_map["m.room.guest_access"]]
events["m.room.history_visibility"] = globals.hash_and_sign_event(events["m.room.history_visibility"])
events["m.room.history_visibility"] = globals.hash_and_sign_event(events["m.room.history_visibility"], ver)
new_state = []

View File

@@ -8,6 +8,7 @@ import base64
import random
import httpx
import json
import copy
import re
version = "1.5.0"
@@ -171,9 +172,10 @@ def make_auth_header(
def redact_event(
event: dict,
for_event_id: bool = False,
room_ver: int = 1,
):
# Returns a redacted event as per
# the algorithm for v1/v2 rooms.
# the algorithm for v1 to v11 rooms.
allowed_keys = [
"event_id",
@@ -185,16 +187,18 @@ def redact_event(
"hashes",
"depth",
"prev_events",
"prev_state",
"auth_events",
"origin",
"origin_server_ts",
"membership",
]
if not for_event_id:
allowed_keys.append("signatures")
if room_ver < 11:
allowed_keys.append("origin")
allowed_keys.append("membership")
allowed_keys.append("prev_state")
redacted_event = {k: v for k, v in event.items() if k in allowed_keys}
if "type" in redacted_event and "content" in redacted_event:
@@ -218,23 +222,59 @@ def redact_event(
"m.room.history_visibility": ["history_visibility"],
}
if room_ver >= 6:
del content_key_rules["m.room.aliases"]
if room_ver >= 8:
content_key_rules["m.room.join_rules"].append("allow")
if room_ver >= 9:
content_key_rules["m.room.member"].append("join_authorised_via_users_server")
if room_ver >= 11:
content_key_rules["m.room.redaction"] = ["redacts"]
del content_key_rules["m.room.create"] # All keys will be permitted
if event_type in content_key_rules:
allowed_content_keys = content_key_rules[event_type]
if (
room_ver >= 11
and "third_party_invite" in redacted_event
and "signed" in redacted_event["third_party_invite"]
):
third_party_invite_signature = copy.deepcopy(redacted_event["third_party_invite"]["signed"])
else:
third_party_invite_signature = None
redacted_event["content"] = {
k: v
for k, v in redacted_event["content"].items()
if k in allowed_content_keys
}
if third_party_invite_signature:
redacted_event["content"]["third_party_invite"] = {
"signed": third_party_invite_signature
}
else:
redacted_event["content"] = {}
if room_ver >= 11 and event_type == "m.room.create":
pass
else:
redacted_event["content"] = {}
return redacted_event
def hash_and_sign_event(event_object):
def hash_and_sign_event(
event_object: dict,
room_ver: int = 1,
):
content_hash = event_hash(event_object)
event_object["hashes"] = {"sha256": content_hash}
stripped_object = redact_event(event_object)
stripped_object = redact_event(event_object, room_ver)
signed_object = sign_json(stripped_object)
event_object["signatures"] = signed_object["signatures"]
return event_object
@@ -244,7 +284,11 @@ def make_ref_hash(
event: dict,
room_ver: int = 3,
):
stripped = redact_event(event, True)
stripped = redact_event(
event=event,
for_event_id=True,
room_ver=room_ver,
)
evt_bytes = canonical_json(stripped)
evt_hash = base64.b64encode(

View File

@@ -98,7 +98,10 @@ try:
except ValueError:
join_event["origin_server_ts"] = int(f"{time.time() * 1000}".split(".")[0])
signed_join = globals.hash_and_sign_event(join_event)
signed_join = globals.hash_and_sign_event(
join_event,
int(make_join.get("room_version", "1"))
)
try:
send_join_response = http_client.put(