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
This commit is contained in:
Till 2022-06-09 18:38:07 +02:00 committed by GitHub
parent 83797573be
commit 660f7839f5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 2 deletions

View file

@ -823,13 +823,39 @@ func (d *Database) handleRedactions(
return nil, "", nil 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 events sender is greater than or equal to the redact level.
case redactedEvent.Origin() == redactionEvent.Origin() && redactedEvent.Sender() == redactionEvent.Sender():
// The domain of the redaction events sender matches that of the original events sender.
default:
return nil, "", nil
}
// mark the event as redacted // mark the event as redacted
if redactionsArePermanent {
redactedEvent.Event = redactedEvent.Redact()
}
err = redactedEvent.SetUnsignedField("redacted_because", redactionEvent) err = redactedEvent.SetUnsignedField("redacted_because", redactionEvent)
if err != nil { if err != nil {
return nil, "", fmt.Errorf("redactedEvent.SetUnsignedField: %w", err) return nil, "", fmt.Errorf("redactedEvent.SetUnsignedField: %w", err)
} }
if redactionsArePermanent { // NOTSPEC: sytest relies on this unspecced field existing :(
redactedEvent.Event = redactedEvent.Redact() err = redactedEvent.SetUnsignedField("redacted_by", redactionEvent.EventID())
if err != nil {
return nil, "", fmt.Errorf("redactedEvent.SetUnsignedField: %w", err)
} }
// overwrite the eventJSON table // overwrite the eventJSON table
err = d.EventJSONTable.InsertEventJSON(ctx, txn, redactedEvent.EventNID, redactedEvent.JSON()) err = d.EventJSONTable.InsertEventJSON(ctx, txn, redactedEvent.EventNID, redactedEvent.JSON())

View file

@ -720,3 +720,4 @@ registration is idempotent, with username specified
Setting state twice is idempotent Setting state twice is idempotent
Joining room twice is idempotent Joining room twice is idempotent
Inbound federation can return missing events for shared visibility Inbound federation can return missing events for shared visibility
Inbound federation ignores redactions from invalid servers room > v3