aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTill <2353100+S7evinK@users.noreply.github.com>2022-06-09 18:38:07 +0200
committerGitHub <noreply@github.com>2022-06-09 18:38:07 +0200
commit660f7839f52f319a205dc61b96e43c730e5cb91a (patch)
tree9d29e228927d5d730c7ab2f4bb7ac653c57d1f25
parent83797573be87616bea0644918b82e2b20e8b78ca (diff)
Correctly redact events over federation (#2526)
* Ensure we check powerlevel/origin before redacting an event * Add passing test * Use pl.UserLevel * Make check more readable, also check for the sender
-rw-r--r--roomserver/storage/shared/storage.go30
-rw-r--r--sytest-whitelist1
2 files changed, 29 insertions, 2 deletions
diff --git a/roomserver/storage/shared/storage.go b/roomserver/storage/shared/storage.go
index cc4a9fff..67dcfdf3 100644
--- a/roomserver/storage/shared/storage.go
+++ b/roomserver/storage/shared/storage.go
@@ -823,13 +823,39 @@ func (d *Database) handleRedactions(
return nil, "", nil
}
+ // Get the power level from the database, so we can verify the user is allowed to redact the event
+ powerLevels, err := d.GetStateEvent(ctx, event.RoomID(), gomatrixserverlib.MRoomPowerLevels, "")
+ if err != nil {
+ return nil, "", fmt.Errorf("d.GetStateEvent: %w", err)
+ }
+ pl, err := powerLevels.PowerLevels()
+ if err != nil {
+ return nil, "", fmt.Errorf("unable to get powerlevels for room: %w", err)
+ }
+
+ redactUser := pl.UserLevel(redactionEvent.Sender())
+ switch {
+ case redactUser >= pl.Redact:
+ // The power level of the redaction event’s sender is greater than or equal to the redact level.
+ case redactedEvent.Origin() == redactionEvent.Origin() && redactedEvent.Sender() == redactionEvent.Sender():
+ // The domain of the redaction event’s sender matches that of the original event’s sender.
+ default:
+ return nil, "", nil
+ }
+
// mark the event as redacted
+ if redactionsArePermanent {
+ redactedEvent.Event = redactedEvent.Redact()
+ }
+
err = redactedEvent.SetUnsignedField("redacted_because", redactionEvent)
if err != nil {
return nil, "", fmt.Errorf("redactedEvent.SetUnsignedField: %w", err)
}
- if redactionsArePermanent {
- redactedEvent.Event = redactedEvent.Redact()
+ // NOTSPEC: sytest relies on this unspecced field existing :(
+ err = redactedEvent.SetUnsignedField("redacted_by", redactionEvent.EventID())
+ if err != nil {
+ return nil, "", fmt.Errorf("redactedEvent.SetUnsignedField: %w", err)
}
// overwrite the eventJSON table
err = d.EventJSONTable.InsertEventJSON(ctx, txn, redactedEvent.EventNID, redactedEvent.JSON())
diff --git a/sytest-whitelist b/sytest-whitelist
index 21bbc396..60a3b73f 100644
--- a/sytest-whitelist
+++ b/sytest-whitelist
@@ -720,3 +720,4 @@ registration is idempotent, with username specified
Setting state twice is idempotent
Joining room twice is idempotent
Inbound federation can return missing events for shared visibility
+Inbound federation ignores redactions from invalid servers room > v3 \ No newline at end of file