mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-09-24 18:08:29 -04:00
Port the Password Auth Providers module interface to the new generic interface (#10548)
Co-authored-by: Azrenbeth <7782548+Azrenbeth@users.noreply.github.com> Co-authored-by: Brendan Abolivier <babolivier@matrix.org>
This commit is contained in:
parent
732bbf6737
commit
cdd308845b
13 changed files with 789 additions and 224 deletions
153
docs/modules/password_auth_provider_callbacks.md
Normal file
153
docs/modules/password_auth_provider_callbacks.md
Normal file
|
@ -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. `jdoe@example.com`)
|
||||
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)
|
||||
```
|
|
@ -12,6 +12,9 @@ should register this resource in its `__init__` method using the `register_web_r
|
|||
method from the `ModuleApi` class (see [this section](writing_a_module.html#registering-a-web-resource) for
|
||||
more info).
|
||||
|
||||
There is no longer a `get_db_schema_files` callback provided for password auth provider modules. Any
|
||||
changes to the database should now be made by the module using the module API class.
|
||||
|
||||
The module's author should also update any example in the module's configuration to only
|
||||
use the new `modules` section in Synapse's configuration file (see [this section](index.html#using-modules)
|
||||
for more info).
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue