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

Commit aec639e

Browse files
Move Spam Checker callbacks to a dedicated file (#15453)
1 parent 929797d commit aec639e

20 files changed

+107
-73
lines changed

changelog.d/15453.misc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Move various module API callback registration methods to a dedicated class.

synapse/app/_base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
from synapse.config.server import ListenerConfig, ManholeConfig, TCPListenerConfig
6565
from synapse.crypto import context_factory
6666
from synapse.events.presence_router import load_legacy_presence_router
67-
from synapse.events.spamcheck import load_legacy_spam_checkers
6867
from synapse.events.third_party_rules import load_legacy_third_party_event_rules
6968
from synapse.handlers.auth import load_legacy_password_auth_providers
7069
from synapse.http.site import SynapseSite
@@ -73,6 +72,7 @@
7372
from synapse.metrics import install_gc_manager, register_threadpool
7473
from synapse.metrics.background_process_metrics import wrap_as_background_process
7574
from synapse.metrics.jemalloc import setup_jemalloc_stats
75+
from synapse.module_api.callbacks.spamchecker_callbacks import load_legacy_spam_checkers
7676
from synapse.types import ISynapseReactor
7777
from synapse.util import SYNAPSE_VERSION
7878
from synapse.util.caches.lrucache import setup_expire_lru_cache_entries

synapse/federation/federation_base.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def __init__(self, hs: "HomeServer"):
5151

5252
self.server_name = hs.hostname
5353
self.keyring = hs.get_keyring()
54-
self.spam_checker = hs.get_spam_checker()
54+
self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker
5555
self.store = hs.get_datastores().main
5656
self._clock = hs.get_clock()
5757
self._storage_controllers = hs.get_storage_controllers()
@@ -137,9 +137,9 @@ async def _check_sigs_and_hash(
137137
)
138138
return redacted_event
139139

140-
spam_check = await self.spam_checker.check_event_for_spam(pdu)
140+
spam_check = await self._spam_checker_module_callbacks.check_event_for_spam(pdu)
141141

142-
if spam_check != self.spam_checker.NOT_SPAM:
142+
if spam_check != self._spam_checker_module_callbacks.NOT_SPAM:
143143
logger.warning("Event contains spam, soft-failing %s", pdu.event_id)
144144
log_kv(
145145
{

synapse/federation/federation_server.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def __init__(self, hs: "HomeServer"):
130130
super().__init__(hs)
131131

132132
self.handler = hs.get_federation_handler()
133-
self._spam_checker = hs.get_spam_checker()
133+
self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker
134134
self._federation_event_handler = hs.get_federation_event_handler()
135135
self.state = hs.get_state_handler()
136136
self._event_auth_handler = hs.get_event_auth_handler()
@@ -1129,7 +1129,7 @@ async def _handle_received_pdu(self, origin: str, pdu: EventBase) -> None:
11291129
logger.warning("event id %s: %s", pdu.event_id, e)
11301130
raise FederationError("ERROR", 403, str(e), affected=pdu.event_id)
11311131

1132-
if await self._spam_checker.should_drop_federated_event(pdu):
1132+
if await self._spam_checker_module_callbacks.should_drop_federated_event(pdu):
11331133
logger.warning(
11341134
"Unstaged federated event contains spam, dropping %s", pdu.event_id
11351135
)
@@ -1174,7 +1174,9 @@ async def _get_next_nonspam_staged_event_for_room(
11741174

11751175
origin, event = next
11761176

1177-
if await self._spam_checker.should_drop_federated_event(event):
1177+
if await self._spam_checker_module_callbacks.should_drop_federated_event(
1178+
event
1179+
):
11781180
logger.warning(
11791181
"Staged federated event contains spam, dropping %s",
11801182
event.event_id,

synapse/handlers/directory.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def __init__(self, hs: "HomeServer"):
6060
"directory", self.on_directory_query
6161
)
6262

63-
self.spam_checker = hs.get_spam_checker()
63+
self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker
6464

6565
async def _create_association(
6666
self,
@@ -145,10 +145,12 @@ async def create_association(
145145
403, "You must be in the room to create an alias for it"
146146
)
147147

148-
spam_check = await self.spam_checker.user_may_create_room_alias(
149-
user_id, room_alias
148+
spam_check = (
149+
await self._spam_checker_module_callbacks.user_may_create_room_alias(
150+
user_id, room_alias
151+
)
150152
)
151-
if spam_check != self.spam_checker.NOT_SPAM:
153+
if spam_check != self._spam_checker_module_callbacks.NOT_SPAM:
152154
raise AuthError(
153155
403,
154156
"This user is not permitted to create this alias",
@@ -444,7 +446,9 @@ async def edit_published_room_list(
444446
"""
445447
user_id = requester.user.to_string()
446448

447-
spam_check = await self.spam_checker.user_may_publish_room(user_id, room_id)
449+
spam_check = await self._spam_checker_module_callbacks.user_may_publish_room(
450+
user_id, room_id
451+
)
448452
if spam_check != NOT_SPAM:
449453
raise AuthError(
450454
403,

synapse/handlers/federation.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def __init__(self, hs: "HomeServer"):
141141
self.server_name = hs.hostname
142142
self.keyring = hs.get_keyring()
143143
self.is_mine_id = hs.is_mine_id
144-
self.spam_checker = hs.get_spam_checker()
144+
self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker
145145
self.event_creation_handler = hs.get_event_creation_handler()
146146
self.event_builder_factory = hs.get_event_builder_factory()
147147
self._event_auth_handler = hs.get_event_auth_handler()
@@ -1042,7 +1042,7 @@ async def on_invite_request(
10421042
if self.hs.config.server.block_non_admin_invites:
10431043
raise SynapseError(403, "This server does not accept room invites")
10441044

1045-
spam_check = await self.spam_checker.user_may_invite(
1045+
spam_check = await self._spam_checker_module_callbacks.user_may_invite(
10461046
event.sender, event.state_key, event.room_id
10471047
)
10481048
if spam_check != NOT_SPAM:

synapse/handlers/message.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ def __init__(self, hs: "HomeServer"):
508508

509509
self._bulk_push_rule_evaluator = hs.get_bulk_push_rule_evaluator()
510510

511-
self.spam_checker = hs.get_spam_checker()
511+
self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker
512512
self.third_party_event_rules: "ThirdPartyEventRules" = (
513513
self.hs.get_third_party_event_rules()
514514
)
@@ -1035,8 +1035,12 @@ async def create_and_send_nonmember_event(
10351035
event.sender,
10361036
)
10371037

1038-
spam_check_result = await self.spam_checker.check_event_for_spam(event)
1039-
if spam_check_result != self.spam_checker.NOT_SPAM:
1038+
spam_check_result = (
1039+
await self._spam_checker_module_callbacks.check_event_for_spam(
1040+
event
1041+
)
1042+
)
1043+
if spam_check_result != self._spam_checker_module_callbacks.NOT_SPAM:
10401044
if isinstance(spam_check_result, tuple):
10411045
try:
10421046
[code, dict] = spam_check_result

synapse/handlers/register.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def __init__(self, hs: "HomeServer"):
110110
self._server_notices_mxid = hs.config.servernotices.server_notices_mxid
111111
self._server_name = hs.hostname
112112

113-
self.spam_checker = hs.get_spam_checker()
113+
self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker
114114

115115
if hs.config.worker.worker_app:
116116
self._register_client = ReplicationRegisterServlet.make_client(hs)
@@ -259,7 +259,7 @@ async def register_user(
259259

260260
await self.check_registration_ratelimit(address)
261261

262-
result = await self.spam_checker.check_registration_for_spam(
262+
result = await self._spam_checker_module_callbacks.check_registration_for_spam(
263263
threepid,
264264
localpart,
265265
user_agent_ips or [],

synapse/handlers/room.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def __init__(self, hs: "HomeServer"):
106106
self.auth_blocking = hs.get_auth_blocking()
107107
self.clock = hs.get_clock()
108108
self.hs = hs
109-
self.spam_checker = hs.get_spam_checker()
109+
self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker
110110
self.event_creation_handler = hs.get_event_creation_handler()
111111
self.room_member_handler = hs.get_room_member_handler()
112112
self._event_auth_handler = hs.get_event_auth_handler()
@@ -449,7 +449,9 @@ async def clone_existing_room(
449449
"""
450450
user_id = requester.user.to_string()
451451

452-
spam_check = await self.spam_checker.user_may_create_room(user_id)
452+
spam_check = await self._spam_checker_module_callbacks.user_may_create_room(
453+
user_id
454+
)
453455
if spam_check != NOT_SPAM:
454456
raise SynapseError(
455457
403,
@@ -761,7 +763,9 @@ async def create_room(
761763
)
762764

763765
if not is_requester_admin:
764-
spam_check = await self.spam_checker.user_may_create_room(user_id)
766+
spam_check = await self._spam_checker_module_callbacks.user_may_create_room(
767+
user_id
768+
)
765769
if spam_check != NOT_SPAM:
766770
raise SynapseError(
767771
403,

synapse/handlers/room_member.py

+13-9
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def __init__(self, hs: "HomeServer"):
9696
self.member_as_limiter = Linearizer(max_count=10, name="member_as_limiter")
9797

9898
self.clock = hs.get_clock()
99-
self.spam_checker = hs.get_spam_checker()
99+
self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker
100100
self.third_party_event_rules = hs.get_third_party_event_rules()
101101
self._server_notices_mxid = self.config.servernotices.server_notices_mxid
102102
self._enable_lookup = hs.config.registration.enable_3pid_lookup
@@ -806,7 +806,7 @@ async def update_membership_locked(
806806
)
807807
block_invite_result = (Codes.FORBIDDEN, {})
808808

809-
spam_check = await self.spam_checker.user_may_invite(
809+
spam_check = await self._spam_checker_module_callbacks.user_may_invite(
810810
requester.user.to_string(), target_id, room_id
811811
)
812812
if spam_check != NOT_SPAM:
@@ -940,8 +940,10 @@ async def update_membership_locked(
940940
# a room then they're allowed to join it.
941941
and not new_room
942942
):
943-
spam_check = await self.spam_checker.user_may_join_room(
944-
target.to_string(), room_id, is_invited=inviter is not None
943+
spam_check = (
944+
await self._spam_checker_module_callbacks.user_may_join_room(
945+
target.to_string(), room_id, is_invited=inviter is not None
946+
)
945947
)
946948
if spam_check != NOT_SPAM:
947949
raise SynapseError(
@@ -1550,11 +1552,13 @@ async def do_3pid_invite(
15501552
)
15511553
else:
15521554
# Check if the spamchecker(s) allow this invite to go through.
1553-
spam_check = await self.spam_checker.user_may_send_3pid_invite(
1554-
inviter_userid=requester.user.to_string(),
1555-
medium=medium,
1556-
address=address,
1557-
room_id=room_id,
1555+
spam_check = (
1556+
await self._spam_checker_module_callbacks.user_may_send_3pid_invite(
1557+
inviter_userid=requester.user.to_string(),
1558+
medium=medium,
1559+
address=address,
1560+
room_id=room_id,
1561+
)
15581562
)
15591563
if spam_check != NOT_SPAM:
15601564
raise SynapseError(

synapse/handlers/user_directory.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def __init__(self, hs: "HomeServer"):
9494
self.is_mine_id = hs.is_mine_id
9595
self.update_user_directory = hs.config.worker.should_update_user_directory
9696
self.search_all_users = hs.config.userdirectory.user_directory_search_all_users
97-
self.spam_checker = hs.get_spam_checker()
97+
self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker
9898
self._hs = hs
9999

100100
# The current position in the current_state_delta stream
@@ -149,7 +149,9 @@ async def search_users(
149149
# Remove any spammy users from the results.
150150
non_spammy_users = []
151151
for user in results["results"]:
152-
if not await self.spam_checker.check_username_for_spam(user):
152+
if not await self._spam_checker_module_callbacks.check_username_for_spam(
153+
user
154+
):
153155
non_spammy_users.append(user)
154156
results["results"] = non_spammy_users
155157

synapse/media/media_storage.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
from twisted.internet.interfaces import IConsumer
3737
from twisted.protocols.basic import FileSender
3838

39-
import synapse
4039
from synapse.api.errors import NotFoundError
4140
from synapse.logging.context import defer_to_thread, make_deferred_yieldable
4241
from synapse.util import Clock
@@ -74,7 +73,7 @@ def __init__(
7473
self.local_media_directory = local_media_directory
7574
self.filepaths = filepaths
7675
self.storage_providers = storage_providers
77-
self.spam_checker = hs.get_spam_checker()
76+
self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker
7877
self.clock = hs.get_clock()
7978

8079
async def store_file(self, source: IO, file_info: FileInfo) -> str:
@@ -145,10 +144,10 @@ async def finish() -> None:
145144
f.flush()
146145
f.close()
147146

148-
spam_check = await self.spam_checker.check_media_file_for_spam(
147+
spam_check = await self._spam_checker_module_callbacks.check_media_file_for_spam(
149148
ReadableFileWrapper(self.clock, fname), file_info
150149
)
151-
if spam_check != synapse.module_api.NOT_SPAM:
150+
if spam_check != self._spam_checker_module_callbacks.NOT_SPAM:
152151
logger.info("Blocking media due to spam checker")
153152
# Note that we'll delete the stored media, due to the
154153
# try/except below. The media also won't be stored in

synapse/module_api/__init__.py

+16-17
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,6 @@
4444
GET_USERS_FOR_STATES_CALLBACK,
4545
PresenceRouter,
4646
)
47-
from synapse.events.spamcheck import (
48-
CHECK_EVENT_FOR_SPAM_CALLBACK,
49-
CHECK_MEDIA_FILE_FOR_SPAM_CALLBACK,
50-
CHECK_REGISTRATION_FOR_SPAM_CALLBACK,
51-
CHECK_USERNAME_FOR_SPAM_CALLBACK,
52-
SHOULD_DROP_FEDERATED_EVENT_CALLBACK,
53-
USER_MAY_CREATE_ROOM_ALIAS_CALLBACK,
54-
USER_MAY_CREATE_ROOM_CALLBACK,
55-
USER_MAY_INVITE_CALLBACK,
56-
USER_MAY_JOIN_ROOM_CALLBACK,
57-
USER_MAY_PUBLISH_ROOM_CALLBACK,
58-
USER_MAY_SEND_3PID_INVITE_CALLBACK,
59-
SpamChecker,
60-
)
6147
from synapse.events.third_party_rules import (
6248
CHECK_CAN_DEACTIVATE_USER_CALLBACK,
6349
CHECK_CAN_SHUTDOWN_ROOM_CALLBACK,
@@ -105,6 +91,20 @@
10591
ON_LEGACY_SEND_MAIL_CALLBACK,
10692
ON_USER_REGISTRATION_CALLBACK,
10793
)
94+
from synapse.module_api.callbacks.spamchecker_callbacks import (
95+
CHECK_EVENT_FOR_SPAM_CALLBACK,
96+
CHECK_MEDIA_FILE_FOR_SPAM_CALLBACK,
97+
CHECK_REGISTRATION_FOR_SPAM_CALLBACK,
98+
CHECK_USERNAME_FOR_SPAM_CALLBACK,
99+
SHOULD_DROP_FEDERATED_EVENT_CALLBACK,
100+
USER_MAY_CREATE_ROOM_ALIAS_CALLBACK,
101+
USER_MAY_CREATE_ROOM_CALLBACK,
102+
USER_MAY_INVITE_CALLBACK,
103+
USER_MAY_JOIN_ROOM_CALLBACK,
104+
USER_MAY_PUBLISH_ROOM_CALLBACK,
105+
USER_MAY_SEND_3PID_INVITE_CALLBACK,
106+
SpamCheckerModuleApiCallbacks,
107+
)
108108
from synapse.rest.client.login import LoginResponse
109109
from synapse.storage import DataStore
110110
from synapse.storage.background_updates import (
@@ -147,7 +147,7 @@
147147
"""
148148

149149
PRESENCE_ALL_USERS = PresenceRouter.ALL_USERS
150-
NOT_SPAM = SpamChecker.NOT_SPAM
150+
NOT_SPAM = SpamCheckerModuleApiCallbacks.NOT_SPAM
151151

152152
__all__ = [
153153
"errors",
@@ -271,7 +271,6 @@ def __init__(self, hs: "HomeServer", auth_handler: AuthHandler) -> None:
271271
self._public_room_list_manager = PublicRoomListManager(hs)
272272
self._account_data_manager = AccountDataManager(hs)
273273

274-
self._spam_checker = hs.get_spam_checker()
275274
self._third_party_event_rules = hs.get_third_party_event_rules()
276275
self._password_auth_provider = hs.get_password_auth_provider()
277276
self._presence_router = hs.get_presence_router()
@@ -305,7 +304,7 @@ def register_spam_checker_callbacks(
305304
306305
Added in Synapse v1.37.0.
307306
"""
308-
return self._spam_checker.register_callbacks(
307+
return self._callbacks.spam_checker.register_callbacks(
309308
check_event_for_spam=check_event_for_spam,
310309
should_drop_federated_event=should_drop_federated_event,
311310
user_may_join_room=user_may_join_room,

synapse/module_api/callbacks/__init__.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,20 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from typing import TYPE_CHECKING
16+
17+
if TYPE_CHECKING:
18+
from synapse.server import HomeServer
19+
1520
from synapse.module_api.callbacks.account_validity_callbacks import (
1621
AccountValidityModuleApiCallbacks,
1722
)
23+
from synapse.module_api.callbacks.spamchecker_callbacks import (
24+
SpamCheckerModuleApiCallbacks,
25+
)
1826

1927

2028
class ModuleApiCallbacks:
21-
def __init__(self) -> None:
29+
def __init__(self, hs: "HomeServer") -> None:
2230
self.account_validity = AccountValidityModuleApiCallbacks()
31+
self.spam_checker = SpamCheckerModuleApiCallbacks(hs)

synapse/events/spamcheck.py synapse/module_api/callbacks/spamchecker_callbacks.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -286,11 +286,10 @@ def run(*args: Any, **kwargs: Any) -> Awaitable:
286286
api.register_spam_checker_callbacks(**hooks)
287287

288288

289-
class SpamChecker:
289+
class SpamCheckerModuleApiCallbacks:
290290
NOT_SPAM: Literal["NOT_SPAM"] = "NOT_SPAM"
291291

292292
def __init__(self, hs: "synapse.server.HomeServer") -> None:
293-
self.hs = hs
294293
self.clock = hs.get_clock()
295294

296295
self._check_event_for_spam_callbacks: List[CHECK_EVENT_FOR_SPAM_CALLBACK] = []

0 commit comments

Comments
 (0)