This repository was archived by the owner on Apr 26, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Port the Password Auth Providers module interface to the new generic interface #10548
Merged
babolivier
merged 27 commits into
matrix-org:develop
from
Azrenbeth:azren/password_auth_providers_to_new_module_system
Oct 13, 2021
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
0841865
Moved to using new callback registering style
58d87e9
Added tests for new and legacy modules
accef11
Removed the old module style from sample_config
d84e47c
Updated docs with information on new callbacks
b198647
Added porting instructions to the docs
d7d89ce
added changelog
1f87fbd
removed now unused ModuleApi object in auth handler
6ad6ccd
Added error handling when calling callbacks
efeb758
auth checkers now MUST return tuple
e6bfd49
Removed duplicated statement in the docs
00c11c5
Merged origin/develop into branch
3083565
Applied suggestions from code review:
4f18f1b
Register login_type, fields, auth_checker all in one chunk
f4a8484
Applied suggestions from code review
e65d49e
Merge remote-tracking branch 'origin/develop' into azren/password_aut…
3c9b6c2
Reformat password_aut_providers docs and fix some small issues
e889594
Run linters
4ad1bd1
Apply suggestion from code review
8e6ebfb
Merge remote-tracking branch 'origin/develop' into azren/password_aut…
55eede5
Run linters
01c65d7
Add link to spec
6fe825f
Tweaks to documentation
86e9607
Add typehints to auth.py
fc72533
Merge branch 'develop' into azren/password_auth_providers_to_new_modu…
babolivier 5e37f11
Apply suggestions from code review
babolivier 1cd658a
Incorporate review comment + cleanup
babolivier 73ff756
Standardise example values
babolivier File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Port the Password Auth Providers module interface to the new generic interface. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
# Password auth provider callbacks | ||
|
||
Password auth providers offer a way for server administrators to integrate | ||
their Synapse installation with an external authentication system. The callbacks can be | ||
registered by using the Module API's `register_password_auth_provider_callbacks` method. | ||
|
||
## Callbacks | ||
|
||
### `auth_checkers` | ||
|
||
``` | ||
auth_checkers: Dict[Tuple[str,Tuple], Callable] | ||
``` | ||
|
||
A dict mapping from tuples of a login type identifier (such as `m.login.password`) and a | ||
tuple of field names (such as `("password", "secret_thing")`) to authentication checking | ||
callbacks, which should be of the following form: | ||
|
||
```python | ||
async def check_auth( | ||
user: str, | ||
login_type: str, | ||
login_dict: "synapse.module_api.JsonDict", | ||
) -> Optional[ | ||
Tuple[ | ||
str, | ||
Optional[Callable[["synapse.module_api.LoginResponse"], Awaitable[None]]] | ||
] | ||
] | ||
``` | ||
|
||
The login type and field names should be provided by the user in the | ||
request to the `/login` API. [The Matrix specification](https://matrix.org/docs/spec/client_server/latest#authentication-types) | ||
defines some types, however user defined ones are also allowed. | ||
|
||
The callback is passed the `user` field provided by the client (which might not be in | ||
`@username:server` form), the login type, and a dictionary of login secrets passed by | ||
the client. | ||
|
||
If the authentication is successful, the module must return the user's Matrix ID (e.g. | ||
`@alice:example.com`) and optionally a callback to be called with the response to the | ||
`/login` request. If the module doesn't wish to return a callback, it must return `None` | ||
instead. | ||
|
||
If the authentication is unsuccessful, the module must return `None`. | ||
|
||
### `check_3pid_auth` | ||
|
||
```python | ||
async def check_3pid_auth( | ||
medium: str, | ||
address: str, | ||
password: str, | ||
) -> Optional[ | ||
Tuple[ | ||
str, | ||
Optional[Callable[["synapse.module_api.LoginResponse"], Awaitable[None]]] | ||
] | ||
] | ||
``` | ||
|
||
Called when a user attempts to register or log in with a third party identifier, | ||
such as email. It is passed the medium (eg. `email`), an address (eg. `[email protected]`) | ||
and the user's password. | ||
|
||
If the authentication is successful, the module must return the user's Matrix ID (e.g. | ||
`@alice:example.com`) and optionally a callback to be called with the response to the `/login` request. | ||
If the module doesn't wish to return a callback, it must return None instead. | ||
|
||
If the authentication is unsuccessful, the module must return None. | ||
|
||
### `on_logged_out` | ||
|
||
```python | ||
async def on_logged_out( | ||
user_id: str, | ||
device_id: Optional[str], | ||
access_token: str | ||
) -> None | ||
``` | ||
Called during a logout request for a user. It is passed the qualified user ID, the ID of the | ||
deactivated device (if any: access tokens are occasionally created without an associated | ||
device ID), and the (now deactivated) access token. | ||
|
||
## Example | ||
|
||
The example module below implements authentication checkers for two different login types: | ||
- `my.login.type` | ||
- Expects a `my_field` field to be sent to `/login` | ||
- Is checked by the method: `self.check_my_login` | ||
- `m.login.password` (defined in [the spec](https://matrix.org/docs/spec/client_server/latest#password-based)) | ||
- Expects a `password` field to be sent to `/login` | ||
- Is checked by the method: `self.check_pass` | ||
|
||
|
||
```python | ||
from typing import Awaitable, Callable, Optional, Tuple | ||
|
||
import synapse | ||
from synapse import module_api | ||
|
||
|
||
class MyAuthProvider: | ||
def __init__(self, config: dict, api: module_api): | ||
|
||
self.api = api | ||
|
||
self.credentials = { | ||
"bob": "building", | ||
"@scoop:matrix.org": "digging", | ||
} | ||
|
||
api.register_password_auth_provider_callbacks( | ||
auth_checkers={ | ||
("my.login_type", ("my_field",)): self.check_my_login, | ||
("m.login.password", ("password",)): self.check_pass, | ||
}, | ||
) | ||
|
||
async def check_my_login( | ||
self, | ||
username: str, | ||
login_type: str, | ||
login_dict: "synapse.module_api.JsonDict", | ||
) -> Optional[ | ||
Tuple[ | ||
str, | ||
Optional[Callable[["synapse.module_api.LoginResponse"], Awaitable[None]]], | ||
] | ||
]: | ||
if login_type != "my.login_type": | ||
return None | ||
|
||
if self.credentials.get(username) == login_dict.get("my_field"): | ||
return self.api.get_qualified_user_id(username) | ||
|
||
async def check_pass( | ||
self, | ||
username: str, | ||
login_type: str, | ||
login_dict: "synapse.module_api.JsonDict", | ||
) -> Optional[ | ||
Tuple[ | ||
str, | ||
Optional[Callable[["synapse.module_api.LoginResponse"], Awaitable[None]]], | ||
] | ||
]: | ||
if login_type != "m.login.password": | ||
return None | ||
|
||
if self.credentials.get(username) == login_dict.get("password"): | ||
return self.api.get_qualified_user_id(username) | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.