-
Notifications
You must be signed in to change notification settings - Fork 344
Add support for MSC4293 - Redact on Kick/Ban #18540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does synapse already pass through the field from /ban requests to the member event?
it does not, I have added support for that as well, missed it the first go around. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a complete review, as I still need to look at tests and the DB updates. But a solid start!
Also be aware that I typically advise people to aim for writing Complement tests when implementing unstable MSCs, such that other homeserver implementations can test against it when it comes time for them to implement the feature.
You don't need to do it here as you've already written a lot of unit tests, but for future reference.
synapse/handlers/federation_event.py
Outdated
@@ -2065,6 +2068,42 @@ async def _check_for_soft_fail( | |||
soft_failed_event_counter.inc() | |||
event.internal_metadata.soft_failed = True | |||
|
|||
if self._config.experimental.msc4293_enabled: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're not actually setting internal_metadata.soft_failed
in the msc4293_enabled
-related code, I'm not sure if it makes sense for the checks to be in this function.
We might even still hit _persist_events_and_state_updates
code later on, event if an event is soft failed(?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My rationale for putting this check here was that this check only applies to events coming in over federation - if a request to send a message into a room the user is banned from comes over the cs api it will just be denied - thus we don't need to worry about redacting it. In this case, however, since the request comes over federation the event is soft-failed but still created, so we need to redact it. I chose this particular location because I was looking for a place where we had already pulled and calculated the state for event, as I was trying to avoid adding database calls if at all possible. If that's not a strong enough rationale for adding it here I can find another place!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, that is very handy. My hangup is that the logic we're doing for redactions here doesn't result in any soft fails occurring.
One way we could refactor this is to take all of the auth DAG calculation out of _check_for_soft_fail
and put that in a _get_current_auth_events
function. Then pass the result of that to _check_for_soft_fail
and, i.e. _check_for_redacted_sender
.
Build errors are odd, I wonder if they are related to #18559 , as the errors mention base64:
Otherwise I am not sure what I did to cause these |
Sorry, I broke develop :( This PR should fix it #18561 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drive-by SCT review to meet implementation requirements on the MSC. Overall, looks great - thank you!
The major detail would be removal of the event type filters, but that looks trivial enough to consider the MSC implemented regardless.
@anoadragon453 just checking that this is still on your radar |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if this is the right architecture for dealing with such redactions. Pulling out all events sent by the user has a few potential issues: a) if there are a lot of events it might take a lot of time, and b) won't redact events that we haven't backfilled over federation yet. The MSC also seems to suggest that events should get unredacted if the ban is replaced with another state event without a redactions?
An alternate method may be to have a separate table that is room_redactions(room_id, sender)
, which we then check (as well as redactions
table) when fetching the event? The new room_redactions
would be updated when we add the ban/kick to the current_state_events
table, and removed if it gets replaced?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The MSC also seems to suggest that events should get unredacted if the ban is replaced with another state event without a redactions?
They shouldn't get unredacted, but the auto-redaction should cease for newly received events. I'll try to clarify this in the MSC itself.
An example series of events:
- Alice sends a message
- Bob bans Alice, with
redact_events: true
- [Servers and clients redact Alice's message in step 1]
- Due to propagation delays, Alice's second message arrives after the ban. The server (and client, if it received it) redacts that message too.
- Later, Bob unbans Alice, setting
redact_events: false
- Again due to propagation delays, or because Alice rejoined, Alice's third message arrives. It is not redacted.
The messages in steps 1 and 4 remain redacted even after step 5.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with Erik's comment above.
Otherwise some minor notes on the current code - which is a lot more readable, thank you!
# self-bans currently are not authorized so we don't check for that | ||
# case |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So self-bans would never appear in auth_events
, is that correct?
# check for msc4293 redact_events flag and apply if found | ||
if ( | ||
not self.hs.config.experimental.msc4293_enabled | ||
or event.type != EventTypes.Member |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sanity check:
or event.type != EventTypes.Member | |
or event.type != EventTypes.Member | |
or event.state_key is None |
if sender_level < room_redaction_level: | ||
continue | ||
|
||
if sender_level > redact_level: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if sender_level > redact_level: | |
if sender_level >= redact_level: |
value_values = [ | ||
(self._clock.time_msec(),) for x in ids_to_redact | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
value_values = [ | |
(self._clock.time_msec(),) for x in ids_to_redact | |
] | |
time_now_ms = self._clock.time_msec() | |
value_values = [ | |
(time_now_ms,) for x in ids_to_redact | |
] |
rather than calling self._clock.time_msec()
repeatedly.
@@ -2768,9 +2850,8 @@ def _store_redaction(self, txn: LoggingTransaction, event: EventBase) -> None: | |||
self.db_pool.simple_upsert_txn( | |||
txn, | |||
table="redactions", | |||
keyvalues={"event_id": event.event_id}, | |||
keyvalues={"event_id": event.event_id, "redacts": event.redacts}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is redacts
unique? I feel you could have multiple redactions redacting a single event.
synapse/handlers/federation_event.py
Outdated
@@ -2065,6 +2068,42 @@ async def _check_for_soft_fail( | |||
soft_failed_event_counter.inc() | |||
event.internal_metadata.soft_failed = True | |||
|
|||
if self._config.experimental.msc4293_enabled: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, that is very handy. My hangup is that the logic we're doing for redactions here doesn't result in any soft fails occurring.
One way we could refactor this is to take all of the auth DAG calculation out of _check_for_soft_fail
and put that in a _get_current_auth_events
function. Then pass the result of that to _check_for_soft_fail
and, i.e. _check_for_redacted_sender
.
Adds support for MSC4293