Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit d8a7a20

Browse files
committed
WIP: Uniformizing with #12918
1 parent 8c40e2a commit d8a7a20

File tree

5 files changed

+168
-91
lines changed

5 files changed

+168
-91
lines changed

changelog.d/12857.feature

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Port spam-checker API callbacks `user_may_join_room`, `user_may_invite`, `user_may_send_3pid_invite`, `user_may_create_room`, `user_may_create_room_alias`, `user_may_publish_room`, `check_media_file_for_spam` to more powerful and less ambiguous `Union[Allow, Codes]`.
1+
Port spam-checker API callbacks `user_may_join_room`, `user_may_invite`, `user_may_send_3pid_invite`, `user_may_create_room`, `user_may_create_room_alias`, `user_may_publish_room`, `check_media_file_for_spam` to more powerful and less ambiguous `Union[Literal["NOT_SPAM"], Codes]`. This is a followup to #12703, #12808, #12846 and builds towards giving the spam-checker API the ability to inform users of *why* their event or operation has been rejected.

docs/modules/spam_checker_callbacks.md

+138-58
Original file line numberDiff line numberDiff line change
@@ -38,62 +38,83 @@ this callback.
3838

3939
_First introduced in Synapse v1.37.0_
4040

41+
_Changed in Synapse v1.60.0: `synapse.module_api.NOT_SPAM` and `synapse.module_api.errors.Codes` can be returned by this callback. Returning a boolean is now deprecated._
42+
4143
```python
42-
async def user_may_join_room(user: str, room: str, is_invited: bool) -> bool
44+
async def user_may_join_room(user: str, room: str, is_invited: bool) -> Union["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes", bool]
4345
```
4446

45-
Called when a user is trying to join a room. The module must return a `bool` to indicate
46-
whether the user can join the room. Return `False` to prevent the user from joining the
47-
room; otherwise return `True` to permit the joining.
48-
49-
The user is represented by their Matrix user ID (e.g.
47+
Called when a user is trying to join a room. The user is represented by their Matrix user ID (e.g.
5048
`@alice:example.com`) and the room is represented by its Matrix ID (e.g.
5149
`!room:example.com`). The module is also given a boolean to indicate whether the user
5250
currently has a pending invite in the room.
5351

54-
This callback isn't called if the join is performed by a server administrator, or in the
55-
context of a room creation.
52+
The callback must return one of:
53+
- `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
54+
decide to reject it.
55+
- `synapse.module_api.errors.Codes` to reject the operation with an error code. In case
56+
of doubt, `synapse.module_api.errors.Codes.FORBIDDEN` is a good error code.
57+
typically will not localize the error message to the user's preferred locale.
58+
- (deprecated) `False`, which is the same as returning `synapse.module_api.NOT_SPAM`.
59+
- (deprecated) `True`, which is the same as returning `synapse.module_api.errors.Codes.FORBIDDEN`.
5660

5761
If multiple modules implement this callback, they will be considered in order. If a
58-
callback returns `True`, Synapse falls through to the next one. The value of the first
59-
callback that does not return `True` will be used. If this happens, Synapse will not call
60-
any of the subsequent implementations of this callback.
62+
callback returns `synapse.module_api.NOT_SPAM`, Synapse falls through to the next one.
63+
The value of the first callback that does not return `synapse.module_api.NOT_SPAM` will
64+
be used. If this happens, Synapse will not call any of the subsequent implementations of
65+
this callback.
66+
67+
68+
This callback isn't called if the join is performed by a server administrator, or in the
69+
context of a room creation.
6170

6271
### `user_may_invite`
6372

6473
_First introduced in Synapse v1.37.0_
6574

75+
_Changed in Synapse v1.60.0: `synapse.module_api.NOT_SPAM` and `synapse.module_api.errors.Codes` can be returned by this callback. Returning a boolean is now deprecated._
76+
6677
```python
67-
async def user_may_invite(inviter: str, invitee: str, room_id: str) -> bool
78+
async def user_may_invite(inviter: str, invitee: str, room_id: str) -> ["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes", bool]
6879
```
6980

70-
Called when processing an invitation. The module must return a `bool` indicating whether
71-
the inviter can invite the invitee to the given room. Both inviter and invitee are
72-
represented by their Matrix user ID (e.g. `@alice:example.com`). Return `False` to prevent
73-
the invitation; otherwise return `True` to permit it.
81+
Called when processing an invitation. Both inviter and invitee are
82+
represented by their Matrix user ID (e.g. `@alice:example.com`).
83+
84+
85+
The callback must return one of:
86+
- `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
87+
decide to reject it.
88+
- `synapse.module_api.errors.Codes` to reject the operation with an error code. In case
89+
of doubt, `synapse.module_api.errors.Codes.FORBIDDEN` is a good error code.
90+
typically will not localize the error message to the user's preferred locale.
91+
- (deprecated) `False`, which is the same as returning `synapse.module_api.NOT_SPAM`.
92+
- (deprecated) `True`, which is the same as returning `synapse.module_api.errors.Codes.FORBIDDEN`.
7493

7594
If multiple modules implement this callback, they will be considered in order. If a
76-
callback returns `True`, Synapse falls through to the next one. The value of the first
77-
callback that does not return `True` will be used. If this happens, Synapse will not call
78-
any of the subsequent implementations of this callback.
95+
callback returns `synapse.module_api.NOT_SPAM`, Synapse falls through to the next one.
96+
The value of the first callback that does not return `synapse.module_api.NOT_SPAM` will
97+
be used. If this happens, Synapse will not call any of the subsequent implementations of
98+
this callback.
99+
79100

80101
### `user_may_send_3pid_invite`
81102

82103
_First introduced in Synapse v1.45.0_
83104

105+
_Changed in Synapse v1.60.0: `synapse.module_api.NOT_SPAM` and `synapse.module_api.errors.Codes` can be returned by this callback. Returning a boolean is now deprecated._
106+
84107
```python
85108
async def user_may_send_3pid_invite(
86109
inviter: str,
87110
medium: str,
88111
address: str,
89112
room_id: str,
90-
) -> bool
113+
) -> ["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes", bool]
91114
```
92115

93116
Called when processing an invitation using a third-party identifier (also called a 3PID,
94-
e.g. an email address or a phone number). The module must return a `bool` indicating
95-
whether the inviter can invite the invitee to the given room. Return `False` to prevent
96-
the invitation; otherwise return `True` to permit it.
117+
e.g. an email address or a phone number).
97118

98119
The inviter is represented by their Matrix user ID (e.g. `@alice:example.com`), and the
99120
invitee is represented by its medium (e.g. "email") and its address
@@ -115,63 +136,108 @@ await user_may_send_3pid_invite(
115136
**Note**: If the third-party identifier is already associated with a matrix user ID,
116137
[`user_may_invite`](#user_may_invite) will be used instead.
117138

139+
The callback must return one of:
140+
- `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
141+
decide to reject it.
142+
- `synapse.module_api.errors.Codes` to reject the operation with an error code. In case
143+
of doubt, `synapse.module_api.errors.Codes.FORBIDDEN` is a good error code.
144+
typically will not localize the error message to the user's preferred locale.
145+
- (deprecated) `False`, which is the same as returning `synapse.module_api.NOT_SPAM`.
146+
- (deprecated) `True`, which is the same as returning `synapse.module_api.errors.Codes.FORBIDDEN`.
147+
118148
If multiple modules implement this callback, they will be considered in order. If a
119-
callback returns `True`, Synapse falls through to the next one. The value of the first
120-
callback that does not return `True` will be used. If this happens, Synapse will not call
121-
any of the subsequent implementations of this callback.
149+
callback returns `synapse.module_api.NOT_SPAM`, Synapse falls through to the next one.
150+
The value of the first callback that does not return `synapse.module_api.NOT_SPAM` will
151+
be used. If this happens, Synapse will not call any of the subsequent implementations of
152+
this callback.
153+
122154

123155
### `user_may_create_room`
124156

125157
_First introduced in Synapse v1.37.0_
126158

159+
_Changed in Synapse v1.60.0: `synapse.module_api.NOT_SPAM` and `synapse.module_api.errors.Codes` can be returned by this callback. Returning a boolean is now deprecated._
160+
127161
```python
128-
async def user_may_create_room(user: str) -> bool
162+
async def user_may_create_room(user_id: str) -> ["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes", bool]
129163
```
130164

131-
Called when processing a room creation request. The module must return a `bool` indicating
132-
whether the given user (represented by their Matrix user ID) is allowed to create a room.
133-
Return `False` to prevent room creation; otherwise return `True` to permit it.
165+
Called when processing a room creation request.
166+
167+
The callback must return one of:
168+
- `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
169+
decide to reject it.
170+
- `synapse.module_api.errors.Codes` to reject the operation with an error code. In case
171+
of doubt, `synapse.module_api.errors.Codes.FORBIDDEN` is a good error code.
172+
typically will not localize the error message to the user's preferred locale.
173+
- (deprecated) `False`, which is the same as returning `synapse.module_api.NOT_SPAM`.
174+
- (deprecated) `True`, which is the same as returning `synapse.module_api.errors.Codes.FORBIDDEN`.
134175

135176
If multiple modules implement this callback, they will be considered in order. If a
136-
callback returns `True`, Synapse falls through to the next one. The value of the first
137-
callback that does not return `True` will be used. If this happens, Synapse will not call
138-
any of the subsequent implementations of this callback.
177+
callback returns `synapse.module_api.NOT_SPAM`, Synapse falls through to the next one.
178+
The value of the first callback that does not return `synapse.module_api.NOT_SPAM` will
179+
be used. If this happens, Synapse will not call any of the subsequent implementations of
180+
this callback.
181+
182+
139183

140184
### `user_may_create_room_alias`
141185

142186
_First introduced in Synapse v1.37.0_
143187

188+
_Changed in Synapse v1.60.0: `synapse.module_api.NOT_SPAM` and `synapse.module_api.errors.Codes` can be returned by this callback. Returning a boolean is now deprecated._
189+
144190
```python
145-
async def user_may_create_room_alias(user: str, room_alias: "synapse.types.RoomAlias") -> bool
191+
async def user_may_create_room_alias(user_id: str, room_alias: "synapse.types.RoomAlias") -> ["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes", bool]
146192
```
147193

148-
Called when trying to associate an alias with an existing room. The module must return a
149-
`bool` indicating whether the given user (represented by their Matrix user ID) is allowed
150-
to set the given alias. Return `False` to prevent the alias creation; otherwise return
151-
`True` to permit it.
194+
Called when trying to associate an alias with an existing room.
195+
196+
The callback must return one of:
197+
- `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
198+
decide to reject it.
199+
- `synapse.module_api.errors.Codes` to reject the operation with an error code. In case
200+
of doubt, `synapse.module_api.errors.Codes.FORBIDDEN` is a good error code.
201+
typically will not localize the error message to the user's preferred locale.
202+
- (deprecated) `False`, which is the same as returning `synapse.module_api.NOT_SPAM`.
203+
- (deprecated) `True`, which is the same as returning `synapse.module_api.errors.Codes.FORBIDDEN`.
152204

153205
If multiple modules implement this callback, they will be considered in order. If a
154-
callback returns `True`, Synapse falls through to the next one. The value of the first
155-
callback that does not return `True` will be used. If this happens, Synapse will not call
156-
any of the subsequent implementations of this callback.
206+
callback returns `synapse.module_api.NOT_SPAM`, Synapse falls through to the next one.
207+
The value of the first callback that does not return `synapse.module_api.NOT_SPAM` will
208+
be used. If this happens, Synapse will not call any of the subsequent implementations of
209+
this callback.
210+
211+
157212

158213
### `user_may_publish_room`
159214

160215
_First introduced in Synapse v1.37.0_
161216

217+
_Changed in Synapse v1.60.0: `synapse.module_api.NOT_SPAM` and `synapse.module_api.errors.Codes` can be returned by this callback. Returning a boolean is now deprecated._
218+
162219
```python
163-
async def user_may_publish_room(user: str, room_id: str) -> bool
220+
async def user_may_publish_room(user_id: str, room_id: str) -> ["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes", bool]
164221
```
165222

166-
Called when trying to publish a room to the homeserver's public rooms directory. The
167-
module must return a `bool` indicating whether the given user (represented by their
168-
Matrix user ID) is allowed to publish the given room. Return `False` to prevent the
169-
room from being published; otherwise return `True` to permit its publication.
223+
Called when trying to publish a room to the homeserver's public rooms directory.
224+
225+
The callback must return one of:
226+
- `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
227+
decide to reject it.
228+
- `synapse.module_api.errors.Codes` to reject the operation with an error code. In case
229+
of doubt, `synapse.module_api.errors.Codes.FORBIDDEN` is a good error code.
230+
typically will not localize the error message to the user's preferred locale.
231+
- (deprecated) `False`, which is the same as returning `synapse.module_api.NOT_SPAM`.
232+
- (deprecated) `True`, which is the same as returning `synapse.module_api.errors.Codes.FORBIDDEN`.
170233

171234
If multiple modules implement this callback, they will be considered in order. If a
172-
callback returns `True`, Synapse falls through to the next one. The value of the first
173-
callback that does not return `True` will be used. If this happens, Synapse will not call
174-
any of the subsequent implementations of this callback.
235+
callback returns `synapse.module_api.NOT_SPAM`, Synapse falls through to the next one.
236+
The value of the first callback that does not return `synapse.module_api.NOT_SPAM` will
237+
be used. If this happens, Synapse will not call any of the subsequent implementations of
238+
this callback.
239+
240+
175241

176242
### `check_username_for_spam`
177243

@@ -239,21 +305,32 @@ this callback.
239305

240306
_First introduced in Synapse v1.37.0_
241307

308+
_Changed in Synapse v1.60.0: `synapse.module_api.NOT_SPAM` and `synapse.module_api.errors.Codes` can be returned by this callback. Returning a boolean is now deprecated._
309+
242310
```python
243311
async def check_media_file_for_spam(
244312
file_wrapper: "synapse.rest.media.v1.media_storage.ReadableFileWrapper",
245313
file_info: "synapse.rest.media.v1._base.FileInfo",
246-
) -> bool
314+
) -> ["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes", bool]
247315
```
248316

249-
Called when storing a local or remote file. The module must return a `bool` indicating
250-
whether the given file should be excluded from the homeserver's media store. Return
251-
`True` to prevent this file from being stored; otherwise return `False`.
317+
Called when storing a local or remote file.
318+
319+
The callback must return one of:
320+
- `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
321+
decide to reject it.
322+
- `synapse.module_api.errors.Codes` to reject the operation with an error code. In case
323+
of doubt, `synapse.module_api.errors.Codes.FORBIDDEN` is a good error code.
324+
typically will not localize the error message to the user's preferred locale.
325+
- (deprecated) `False`, which is the same as returning `synapse.module_api.NOT_SPAM`.
326+
- (deprecated) `True`, which is the same as returning `synapse.module_api.errors.Codes.FORBIDDEN`.
252327

253328
If multiple modules implement this callback, they will be considered in order. If a
254-
callback returns `False`, Synapse falls through to the next one. The value of the first
255-
callback that does not return `False` will be used. If this happens, Synapse will not call
256-
any of the subsequent implementations of this callback.
329+
callback returns `synapse.module_api.NOT_SPAM`, Synapse falls through to the next one.
330+
The value of the first callback that does not return `synapse.module_api.NOT_SPAM` will
331+
be used. If this happens, Synapse will not call any of the subsequent implementations of
332+
this callback.
333+
257334

258335
### `should_drop_federated_event`
259336

@@ -316,6 +393,9 @@ class ListSpamChecker:
316393
resource=IsUserEvilResource(config),
317394
)
318395

319-
async def check_event_for_spam(self, event: "synapse.events.EventBase") -> Union[bool, str]:
320-
return event.sender not in self.evil_users
396+
async def check_event_for_spam(self, event: "synapse.events.EventBase") -> Union[Literal["NOT_SPAM"], Codes]:
397+
if event.sender in self.evil_users:
398+
return Codes.FORBIDDEN
399+
else:
400+
return "NOT_SPAM"
321401
```

0 commit comments

Comments
 (0)