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:
parent
83797573be
commit
660f7839f5
|
@ -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 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
|
// 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())
|
||||||
|
|
|
@ -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
|
Loading…
Reference in a new issue