-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Add 3pid unbind callback to module API #13227
Conversation
6e8db1e
to
6cd2726
Compare
381e73e
to
89ef487
Compare
This is now tested alongside matrix-org/synapse-bind-sydent#2, and tests seems to pass outside of an unrelated (flaky ?) one I think. |
89ef487
to
0951ff7
Compare
Co-authored-by: Brendan Abolivier <[email protected]>
9ad1153
to
9b4c0e7
Compare
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.
Sorry about the delay on this one!
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.
Mostly changes for documentation (but also a bit about the logic around the return value). I haven't looked at the test yet, since I assume it might change as a result of discussions around some of the comments I've made.
A module can hence do its own custom unbinding, if for example it did also registered a custom | ||
binding logic with `on_threepid_bind`. | ||
|
||
It should return a tuple of 2 booleans: |
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.
It should return a tuple of 2 booleans: | |
The module must return a tuple of 2 booleans, which indicate respectively: |
The main thing here is replacing "should" by "must": "should" implies the module is strongly encouraged to do something but there isn't a strict obligation. "must" implies there's a strict obligation, rather than a strong encouragement (which is the case here - Synapse won't be able to process any other type of return value).
) -> Tuple[bool, bool]: | ||
``` | ||
|
||
Called before a threepid association is removed. |
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.
Called before a threepid association is removed. | |
Called before the association between a local user and a third-party identifier | |
(email address, phone number) is removed. |
I wouldn't expect users who aren't deeply familiar with Matrix's concepts to know what a "threepid" is.
as well as the medium (`email` or `msisdn`), address of the third-party identifier and | ||
the identity server where the threepid was successfully registered. | ||
|
||
A module can hence do its own custom unbinding, if for example it did also registered a custom |
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.
A module can hence do its own custom unbinding, if for example it did also registered a custom | |
A module can hence implement its own custom unbinding, if for example it also implemented a custom |
(changed, stop) = await callback( | ||
user_id, medium, address, identity_server | ||
) | ||
global_changed |= changed |
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.
Shouldn't we rather indicate whether all callbacks succeeded, rather than just one of them?
- first one should be `True` on a success calling the identity server, otherwise `False` if | ||
the identity server doesn't support unbinding (or no identity server found to contact). | ||
- second one should be `True` if unbind needs to stop there. In this case no other module | ||
unbind will be called, and the default unbind made to the IS that was used on bind will also be | ||
skipped. In any case the mapping will be removed from the Synapse 3pid remote table, | ||
except if an Exception was raised at some point. |
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.
- first one should be `True` on a success calling the identity server, otherwise `False` if | |
the identity server doesn't support unbinding (or no identity server found to contact). | |
- second one should be `True` if unbind needs to stop there. In this case no other module | |
unbind will be called, and the default unbind made to the IS that was used on bind will also be | |
skipped. In any case the mapping will be removed from the Synapse 3pid remote table, | |
except if an Exception was raised at some point. | |
- whether the unbind was successful (`True` in this case, `False` otherwise). | |
- whether Synapse should stop the unbinding process there (`True` in this case, `False` otherwise). In | |
this case, Synapse will also remove any local record of an association between the local user and the | |
third-party identifier on a remote identity server. | |
If multiple modules implement this callback, they will be considered in order. Unless the return value of | |
a callback indicates to stop the unbinding process, Synapse falls through to the next one. Otherwise, | |
Synapse will not call any subsequent implementation of this callback. |
We should also add to the last paragraph a mention of how the first boolean is processed once we have resolved this question in a previous thread.
A few things this suggestion changes:
- I don't believe it is safe to assume all modules will do their binding/unbinding against an identity server, so it might not make sense to tie the definition of return values to the existence of an identity server.
- The bit about exceptions don't feel right to me: first, looking at the code it doesn't look correct; second the way it's phrased makes it sound like modules should use exceptions to define whether Synapse should delete the remote record, and using exceptions as a control method is something we actively try to discourage.
- Also some clarity and consistency on how Synapse handles multiple modules implementing this callback.
url_bytes=url_bytes, | ||
content=content, | ||
destination_is=id_server.encode("ascii"), | ||
(changed, stop,) = await self.hs.get_third_party_event_rules().unbind_threepid( |
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.
(changed, stop,) = await self.hs.get_third_party_event_rules().unbind_threepid( | |
changed, stop = await self.hs.get_third_party_event_rules().unbind_threepid( |
await self.blacklisting_http_client.post_json_get_json( | ||
url, content, headers | ||
# If a module wants to take over unbind it will return stop = True, | ||
# in this case we should just purge the table from the 3pid record |
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.
# in this case we should just purge the table from the 3pid record | |
# in this case we should just remove the entry from the 3pid remote records table |
Note that this callback is called before an association is deleted on the | ||
local homeserver. |
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.
This feels a bit superfluous with the line above?
A tuple of 2 booleans reporting if a changed happened for the first, and if unbind | ||
needs to stop there for the second (True value). In this case no other module unbind will be | ||
called, and the default unbind made to the IS that was used on bind will also be skipped. | ||
In any case the mapping will be removed from the Synapse 3pid remote table, except if an Exception | ||
was raised at some point. |
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.
A tuple of 2 booleans reporting if a changed happened for the first, and if unbind | |
needs to stop there for the second (True value). In this case no other module unbind will be | |
called, and the default unbind made to the IS that was used on bind will also be skipped. | |
In any case the mapping will be removed from the Synapse 3pid remote table, except if an Exception | |
was raised at some point. | |
A tuple of 2 booleans reporting, respectively, if the unbind was successful, and if the unbind process | |
should stop there. |
The bit about what happens if the second bool is True
is only relevant to module callbacks, not to the interface.
Not quite I'm afraid. Currently we have a Additionally in the same issue, I've tweaked the design of the module callback method proposed by this PR: #14955 (comment). The tweaked design only returns a single boolean while still fitting the use case of synapse-bind-sydent. |
This PR has been superseded by #15044. |
Currently we have a module interface that can react on a 3pid bind action, but it doesn't exist for unbind.
We rely on the fact that the identity server where we want to unbind should be stored in
user_threepid_id_server
table.Unfortunately the info there doesn't include the scheme, hence a bind to
http://localhost:7777
will fail on unbind becausehttps://localhost:7777
is called instead.To overcome that this PR introduces a similar callback for 3pid unbind, so we can also override the identity server URL there for example.