2019-09-17 14:55:29 +03:00
|
|
|
# Password auth provider modules
|
|
|
|
|
|
|
|
Password auth providers offer a way for server administrators to
|
|
|
|
integrate their Synapse installation with an existing authentication
|
|
|
|
system.
|
|
|
|
|
|
|
|
A password auth provider is a Python class which is dynamically loaded
|
|
|
|
into Synapse, and provides a number of methods by which it can integrate
|
|
|
|
with the authentication system.
|
|
|
|
|
|
|
|
This document serves as a reference for those looking to implement their
|
2020-04-08 02:46:50 +03:00
|
|
|
own password auth providers. Additionally, here is a list of known
|
|
|
|
password auth provider module implementations:
|
|
|
|
|
|
|
|
* [matrix-synapse-ldap3](https://github.com/matrix-org/matrix-synapse-ldap3/)
|
2020-04-09 14:49:05 +03:00
|
|
|
* [matrix-synapse-shared-secret-auth](https://github.com/devture/matrix-synapse-shared-secret-auth)
|
2020-08-18 16:54:35 +03:00
|
|
|
* [matrix-synapse-rest-password-provider](https://github.com/ma1uta/matrix-synapse-rest-password-provider)
|
2019-09-17 14:55:29 +03:00
|
|
|
|
|
|
|
## Required methods
|
|
|
|
|
|
|
|
Password auth provider classes must provide the following methods:
|
|
|
|
|
2020-07-23 22:45:39 +03:00
|
|
|
* `parse_config(config)`
|
|
|
|
This method is passed the `config` object for this module from the
|
|
|
|
homeserver configuration file.
|
2019-09-17 14:55:29 +03:00
|
|
|
|
2020-07-23 22:45:39 +03:00
|
|
|
It should perform any appropriate sanity checks on the provided
|
|
|
|
configuration, and return an object which is then passed into
|
2020-12-01 13:34:52 +03:00
|
|
|
`__init__`.
|
2019-09-17 14:55:29 +03:00
|
|
|
|
2020-07-23 22:45:39 +03:00
|
|
|
This method should have the `@staticmethod` decoration.
|
2019-09-17 14:55:29 +03:00
|
|
|
|
2020-07-23 22:45:39 +03:00
|
|
|
* `__init__(self, config, account_handler)`
|
|
|
|
|
|
|
|
The constructor is passed the config object returned by
|
|
|
|
`parse_config`, and a `synapse.module_api.ModuleApi` object which
|
|
|
|
allows the password provider to check if accounts exist and/or create
|
|
|
|
new ones.
|
2019-09-17 14:55:29 +03:00
|
|
|
|
|
|
|
## Optional methods
|
|
|
|
|
2020-07-23 22:45:39 +03:00
|
|
|
Password auth provider classes may optionally provide the following methods:
|
|
|
|
|
|
|
|
* `get_db_schema_files(self)`
|
|
|
|
|
|
|
|
This method, if implemented, should return an Iterable of
|
|
|
|
`(name, stream)` pairs of database schema files. Each file is applied
|
|
|
|
in turn at initialisation, and a record is then made in the database
|
|
|
|
so that it is not re-applied on the next start.
|
|
|
|
|
|
|
|
* `get_supported_login_types(self)`
|
|
|
|
|
|
|
|
This method, if implemented, should return a `dict` mapping from a
|
|
|
|
login type identifier (such as `m.login.password`) to an iterable
|
|
|
|
giving the fields which must be provided by the user in the submission
|
|
|
|
to [the `/login` API](https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-login).
|
|
|
|
These fields are passed in the `login_dict` dictionary to `check_auth`.
|
|
|
|
|
|
|
|
For example, if a password auth provider wants to implement a custom
|
|
|
|
login type of `com.example.custom_login`, where the client is expected
|
|
|
|
to pass the fields `secret1` and `secret2`, the provider should
|
|
|
|
implement this method and return the following dict:
|
|
|
|
|
|
|
|
```python
|
|
|
|
{"com.example.custom_login": ("secret1", "secret2")}
|
|
|
|
```
|
|
|
|
|
|
|
|
* `check_auth(self, username, login_type, login_dict)`
|
|
|
|
|
|
|
|
This method does the real work. If implemented, it
|
|
|
|
will be called for each login attempt where the login type matches one
|
|
|
|
of the keys returned by `get_supported_login_types`.
|
|
|
|
|
|
|
|
It is passed the (possibly unqualified) `user` field provided by the client,
|
|
|
|
the login type, and a dictionary of login secrets passed by the
|
|
|
|
client.
|
|
|
|
|
|
|
|
The method should return an `Awaitable` object, which resolves
|
|
|
|
to the canonical `@localpart:domain` user ID if authentication is
|
|
|
|
successful, and `None` if not.
|
|
|
|
|
|
|
|
Alternatively, the `Awaitable` can resolve to a `(str, func)` tuple, in
|
|
|
|
which case the second field is a callback which will be called with
|
|
|
|
the result from the `/login` call (including `access_token`,
|
|
|
|
`device_id`, etc.)
|
|
|
|
|
|
|
|
* `check_3pid_auth(self, medium, address, password)`
|
|
|
|
|
|
|
|
This method, if implemented, is called when a user attempts to
|
|
|
|
register or log in with a third party identifier, such as email. It is
|
|
|
|
passed the medium (ex. "email"), an address (ex.
|
|
|
|
"<jdoe@example.com>") and the user's password.
|
|
|
|
|
|
|
|
The method should return an `Awaitable` object, which resolves
|
|
|
|
to a `str` containing the user's (canonical) User id if
|
|
|
|
authentication was successful, and `None` if not.
|
|
|
|
|
|
|
|
As with `check_auth`, the `Awaitable` may alternatively resolve to a
|
|
|
|
`(user_id, callback)` tuple.
|
|
|
|
|
|
|
|
* `check_password(self, user_id, password)`
|
|
|
|
|
|
|
|
This method provides a simpler interface than
|
|
|
|
`get_supported_login_types` and `check_auth` for password auth
|
|
|
|
providers that just want to provide a mechanism for validating
|
|
|
|
`m.login.password` logins.
|
|
|
|
|
|
|
|
If implemented, it will be called to check logins with an
|
|
|
|
`m.login.password` login type. It is passed a qualified
|
|
|
|
`@localpart:domain` user id, and the password provided by the user.
|
|
|
|
|
|
|
|
The method should return an `Awaitable` object, which resolves
|
|
|
|
to `True` if authentication is successful, and `False` if not.
|
|
|
|
|
|
|
|
* `on_logged_out(self, user_id, device_id, access_token)`
|
|
|
|
|
|
|
|
This method, if implemented, is called when a user logs out. 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.
|
|
|
|
|
|
|
|
It may return an `Awaitable` object; the logout request will
|
|
|
|
wait for the `Awaitable` to complete, but the result is ignored.
|