diff --git a/docs/modules/media_repository_callbacks.md b/docs/modules/media_repository_callbacks.md
new file mode 100644
index 0000000000..fc37130439
--- /dev/null
+++ b/docs/modules/media_repository_callbacks.md
@@ -0,0 +1,66 @@
+# Media repository callbacks
+
+Media repository callbacks allow module developers to customise the behaviour of the
+media repository on a per user basis. Media repository callbacks can be registered
+using the module API's `register_media_repository_callbacks` method.
+
+The available media repository callbacks are:
+
+### `get_media_config_for_user`
+
+_First introduced in Synapse v1.132.0_
+
+```python
+async def get_media_config_for_user(user_id: str) -> Optional[JsonDict]
+```
+
+**<span style="color:red">
+Caution: This callback is currently experimental . The method signature or behaviour
+may change without notice.
+</span>**
+
+Called when processing a request from a client for the
+[media config endpoint](https://spec.matrix.org/latest/client-server-api/#get_matrixclientv1mediaconfig).
+
+The arguments passed to this callback are:
+
+* `user_id`: The Matrix user ID of the user (e.g. `@alice:example.com`) making the request.
+
+If the callback returns a dictionary then it will be used as the body of the response to the
+client.
+
+If multiple modules implement this callback, they will be considered in order. If a
+callback returns `None`, Synapse falls through to the next one. The value of the first
+callback that does not return `None` will be used. If this happens, Synapse will not call
+any of the subsequent implementations of this callback.
+
+If no module returns a non-`None` value then the default media config will be returned.
+
+### `is_user_allowed_to_upload_media_of_size`
+
+_First introduced in Synapse v1.132.0_
+
+```python
+async def is_user_allowed_to_upload_media_of_size(user_id: str, size: int) -> bool
+```
+
+**<span style="color:red">
+Caution: This callback is currently experimental . The method signature or behaviour
+may change without notice.
+</span>**
+
+Called before media is accepted for upload from a user, in case the module needs to
+enforce a different limit for the particular user.
+
+The arguments passed to this callback are:
+
+* `user_id`: The Matrix user ID of the user (e.g. `@alice:example.com`) making the request.
+* `size`: The size in bytes of media that is being requested to upload.
+
+If the module returns `False`, the current request will be denied with the error code
+`M_TOO_LARGE` and the HTTP status code 413.
+
+If multiple modules implement this callback, they will be considered in order. If a callback
+returns `True`, Synapse falls through to the next one. The value of the first callback that
+returns `False` will be used. If this happens, Synapse will not call any of the subsequent
+implementations of this callback.
diff --git a/docs/modules/password_auth_provider_callbacks.md b/docs/modules/password_auth_provider_callbacks.md
index d66ac7df31..6b3105de34 100644
--- a/docs/modules/password_auth_provider_callbacks.md
+++ b/docs/modules/password_auth_provider_callbacks.md
@@ -144,16 +144,6 @@ Here's an example featuring all currently supported keys:
"m.login.dummy": True, # Dummy authentication
"m.login.terms": True, # User has accepted the terms of service for the homeserver
"m.login.recaptcha": True, # User has completed the recaptcha challenge
- "m.login.email.identity": { # User has provided and verified an email address
- "medium": "email",
- "address": "alice@example.com",
- "validated_at": 1642701357084,
- },
- "m.login.msisdn": { # User has provided and verified a phone number
- "medium": "msisdn",
- "address": "33123456789",
- "validated_at": 1642701357084,
- },
"m.login.registration_token": "sometoken", # User has registered through a registration token
}
```
@@ -200,26 +190,6 @@ callback that does not return `None` will be used. If this happens, Synapse will
any of the subsequent implementations of this callback. If every callback returns `None`,
the username will be used (e.g. `alice` if the user being registered is `@alice:example.com`).
-## `is_3pid_allowed`
-
-_First introduced in Synapse v1.53.0_
-
-```python
-async def is_3pid_allowed(self, medium: str, address: str, registration: bool) -> bool
-```
-
-Called when attempting to bind a third-party identifier (i.e. an email address or a phone
-number). The module is given the medium of the third-party identifier (which is `email` if
-the identifier is an email address, or `msisdn` if the identifier is a phone number) and
-its address, as well as a boolean indicating whether the attempt to bind is happening as
-part of registering a new user. The module must return a boolean indicating whether the
-identifier can be allowed to be bound to an account on the local homeserver.
-
-If multiple modules implement this callback, they will be considered in order. If a
-callback returns `True`, Synapse falls through to the next one. The value of the first
-callback that does not return `True` will be used. If this happens, Synapse will not call
-any of the subsequent implementations of this callback.
-
## Example
The example module below implements authentication checkers for two different login types:
diff --git a/docs/modules/ratelimit_callbacks.md b/docs/modules/ratelimit_callbacks.md
new file mode 100644
index 0000000000..30d94024fa
--- /dev/null
+++ b/docs/modules/ratelimit_callbacks.md
@@ -0,0 +1,43 @@
+# Ratelimit callbacks
+
+Ratelimit callbacks allow module developers to override ratelimit settings dynamically whilst
+Synapse is running. Ratelimit callbacks can be registered using the module API's
+`register_ratelimit_callbacks` method.
+
+The available ratelimit callbacks are:
+
+### `get_ratelimit_override_for_user`
+
+_First introduced in Synapse v1.132.0_
+
+```python
+async def get_ratelimit_override_for_user(user: str, limiter_name: str) -> Optional[synapse.module_api.RatelimitOverride]
+```
+
+**<span style="color:red">
+Caution: This callback is currently experimental . The method signature or behaviour
+may change without notice.
+</span>**
+
+Called when constructing a ratelimiter of a particular type for a user. The module can
+return a `messages_per_second` and `burst_count` to be used, or `None` if
+the default settings are adequate. The user is represented by their Matrix user ID
+(e.g. `@alice:example.com`). The limiter name is usually taken from the `RatelimitSettings` key
+value.
+
+The limiters that are currently supported are:
+
+- `rc_invites.per_room`
+- `rc_invites.per_user`
+- `rc_invites.per_issuer`
+
+The `RatelimitOverride` return type has the following fields:
+
+- `per_second: float`. The number of actions that can be performed in a second. `0.0` means that ratelimiting is disabled.
+- `burst_count: int`. The number of actions that can be performed before being limited.
+
+If multiple modules implement this callback, they will be considered in order. If a
+callback returns `None`, Synapse falls through to the next one. The value of the first
+callback that does not return `None` will be used. If this happens, Synapse will not call
+any of the subsequent implementations of this callback. If no module returns a non-`None` value
+then the default settings will be used.
diff --git a/docs/modules/spam_checker_callbacks.md b/docs/modules/spam_checker_callbacks.md
index ffdfe6082e..39d7cbc000 100644
--- a/docs/modules/spam_checker_callbacks.md
+++ b/docs/modules/spam_checker_callbacks.md
@@ -76,8 +76,9 @@ _Changed in Synapse v1.62.0: `synapse.module_api.NOT_SPAM` and `synapse.module_a
async def user_may_invite(inviter: str, invitee: str, room_id: str) -> Union["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes", bool]
```
-Called when processing an invitation. Both inviter and invitee are
-represented by their Matrix user ID (e.g. `@alice:example.com`).
+Called when processing an invitation, both when one is created locally or when
+receiving an invite over federation. Both inviter and invitee are represented by
+their Matrix user ID (e.g. `@alice:example.com`).
The callback must return one of:
@@ -112,7 +113,9 @@ async def user_may_send_3pid_invite(
```
Called when processing an invitation using a third-party identifier (also called a 3PID,
-e.g. an email address or a phone number).
+e.g. an email address or a phone number). It is only called when a 3PID invite is created
+locally - not when one is received in a room over federation. If the 3PID is already associated
+with a Matrix ID, the spam check will go through the `user_may_invite` callback instead.
The inviter is represented by their Matrix user ID (e.g. `@alice:example.com`), and the
invitee is represented by its medium (e.g. "email") and its address
@@ -156,12 +159,19 @@ _First introduced in Synapse v1.37.0_
_Changed in Synapse v1.62.0: `synapse.module_api.NOT_SPAM` and `synapse.module_api.errors.Codes` can be returned by this callback. Returning a boolean is now deprecated._
+_Changed in Synapse v1.132.0: Added the `room_config` argument. Callbacks that only expect a single `user_id` argument are still supported._
+
```python
-async def user_may_create_room(user_id: str) -> Union["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes", bool]
+async def user_may_create_room(user_id: str, room_config: synapse.module_api.JsonDict) -> Union["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes", bool]
```
Called when processing a room creation request.
+The arguments passed to this callback are:
+
+* `user_id`: The Matrix user ID of the user (e.g. `@alice:example.com`).
+* `room_config`: The contents of the body of a [/createRoom request](https://spec.matrix.org/latest/client-server-api/#post_matrixclientv3createroom) as a dictionary.
+
The callback must return one of:
- `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
decide to reject it.
@@ -236,13 +246,48 @@ be used. If this happens, Synapse will not call any of the subsequent implementa
this callback.
+### `user_may_send_state_event`
+
+_First introduced in Synapse v1.132.0_
+
+```python
+async def user_may_send_state_event(user_id: str, room_id: str, event_type: str, state_key: str, content: JsonDict) -> Union["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes"]
+```
+
+**<span style="color:red">
+Caution: This callback is currently experimental . The method signature or behaviour
+may change without notice.
+</span>**
+
+Called when processing a request to [send state events](https://spec.matrix.org/latest/client-server-api/#put_matrixclientv3roomsroomidstateeventtypestatekey) to a room.
+
+The arguments passed to this callback are:
+
+* `user_id`: The Matrix user ID of the user (e.g. `@alice:example.com`) sending the state event.
+* `room_id`: The ID of the room that the requested state event is being sent to.
+* `event_type`: The requested type of event.
+* `state_key`: The requested state key.
+* `content`: The requested event contents.
+
+The callback must return one of:
+ - `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
+ decide to reject it.
+ - `synapse.module_api.errors.Codes` to reject the operation with an error code. In case
+ of doubt, `synapse.module_api.errors.Codes.FORBIDDEN` is a good error code.
+
+If multiple modules implement this callback, they will be considered in order. If a
+callback returns `synapse.module_api.NOT_SPAM`, Synapse falls through to the next one.
+The value of the first callback that does not return `synapse.module_api.NOT_SPAM` will
+be used. If this happens, Synapse will not call any of the subsequent implementations of
+this callback.
+
### `check_username_for_spam`
_First introduced in Synapse v1.37.0_
```python
-async def check_username_for_spam(user_profile: synapse.module_api.UserProfile) -> bool
+async def check_username_for_spam(user_profile: synapse.module_api.UserProfile, requester_id: str) -> bool
```
Called when computing search results in the user directory. The module must return a
@@ -261,6 +306,8 @@ The profile is represented as a dictionary with the following keys:
The module is given a copy of the original dictionary, so modifying it from within the
module cannot modify a user's profile when included in user directory search results.
+The requester_id parameter is the ID of the user that called the user directory API.
+
If multiple modules implement this callback, they will be considered in order. If a
callback returns `False`, Synapse falls through to the next one. The value of the first
callback that does not return `False` will be used. If this happens, Synapse will not call
@@ -348,6 +395,8 @@ callback returns `False`, Synapse falls through to the next one. The value of th
callback that does not return `False` will be used. If this happens, Synapse will not call
any of the subsequent implementations of this callback.
+Note that this check is applied to federation invites as of Synapse v1.130.0.
+
### `check_login_for_spam`
diff --git a/docs/modules/third_party_rules_callbacks.md b/docs/modules/third_party_rules_callbacks.md
index b97e28db11..b4162a317d 100644
--- a/docs/modules/third_party_rules_callbacks.md
+++ b/docs/modules/third_party_rules_callbacks.md
@@ -86,26 +86,6 @@ room creation will be forbidden as soon as one of the callbacks raises an except
this happens, Synapse will not call any of the subsequent implementations of this
callback.
-### `check_threepid_can_be_invited`
-
-_First introduced in Synapse v1.39.0_
-
-```python
-async def check_threepid_can_be_invited(
- medium: str,
- address: str,
- state_events: "synapse.types.StateMap",
-) -> bool:
-```
-
-Called when processing an invite via a third-party identifier (i.e. email or phone number).
-The module must return a boolean indicating whether the invite can go through.
-
-If multiple modules implement this callback, they will be considered in order. If a
-callback returns `True`, Synapse falls through to the next one. The value of the first
-callback that does not return `True` will be used. If this happens, Synapse will not call
-any of the subsequent implementations of this callback.
-
### `check_visibility_can_be_modified`
_First introduced in Synapse v1.39.0_
@@ -254,67 +234,6 @@ admin API.
If multiple modules implement this callback, Synapse runs them all in order.
-### `on_threepid_bind`
-
-_First introduced in Synapse v1.56.0_
-
-**<span style="color:red">
-This callback is deprecated in favour of the `on_add_user_third_party_identifier` callback, which
-features the same functionality. The only difference is in name.
-</span>**
-
-```python
-async def on_threepid_bind(user_id: str, medium: str, address: str) -> None:
-```
-
-Called after creating an association between a local user and a third-party identifier
-(email address, phone number). The module is given the Matrix ID of the user the
-association is for, as well as the medium (`email` or `msisdn`) and address of the
-third-party identifier.
-
-Note that this callback is _not_ called after a successful association on an _identity
-server_.
-
-If multiple modules implement this callback, Synapse runs them all in order.
-
-### `on_add_user_third_party_identifier`
-
-_First introduced in Synapse v1.79.0_
-
-```python
-async def on_add_user_third_party_identifier(user_id: str, medium: str, address: str) -> None:
-```
-
-Called after successfully creating an association between a user and a third-party identifier
-(email address, phone number). The module is given the Matrix ID of the user the
-association is for, as well as the medium (`email` or `msisdn`) and address of the
-third-party identifier (i.e. an email address).
-
-Note that this callback is _not_ called if a user attempts to bind their third-party identifier
-to an identity server (via a call to [`POST
-/_matrix/client/v3/account/3pid/bind`](https://spec.matrix.org/v1.5/client-server-api/#post_matrixclientv3account3pidbind)).
-
-If multiple modules implement this callback, Synapse runs them all in order.
-
-### `on_remove_user_third_party_identifier`
-
-_First introduced in Synapse v1.79.0_
-
-```python
-async def on_remove_user_third_party_identifier(user_id: str, medium: str, address: str) -> None:
-```
-
-Called after successfully removing an association between a user and a third-party identifier
-(email address, phone number). The module is given the Matrix ID of the user the
-association is for, as well as the medium (`email` or `msisdn`) and address of the
-third-party identifier (i.e. an email address).
-
-Note that this callback is _not_ called if a user attempts to unbind their third-party
-identifier from an identity server (via a call to [`POST
-/_matrix/client/v3/account/3pid/unbind`](https://spec.matrix.org/v1.5/client-server-api/#post_matrixclientv3account3pidunbind)).
-
-If multiple modules implement this callback, Synapse runs them all in order.
-
## Example
The example below is a module that implements the third-party rules callback
|