From bb9b35cec0605e4bd7922058d77ba5812b4a0197 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 8 Mar 2023 16:22:10 +0000 Subject: [PATCH 1/4] Move Spam Checker callbacks to a dedicated file The next commit updates all the uses of the spam checker (of which there are quite a few...), hence breaking up the commits. --- synapse/module_api/__init__.py | 33 +++++++++---------- synapse/module_api/callbacks/__init__.py | 13 +++++--- .../callbacks/spamchecker_callbacks.py} | 3 +- synapse/server.py | 7 +--- 4 files changed, 27 insertions(+), 29 deletions(-) rename synapse/{events/spamcheck.py => module_api/callbacks/spamchecker_callbacks.py} (99%) diff --git a/synapse/module_api/__init__.py b/synapse/module_api/__init__.py index 595c23e78d7e..eeafea74d15c 100644 --- a/synapse/module_api/__init__.py +++ b/synapse/module_api/__init__.py @@ -44,20 +44,6 @@ GET_USERS_FOR_STATES_CALLBACK, PresenceRouter, ) -from synapse.events.spamcheck import ( - CHECK_EVENT_FOR_SPAM_CALLBACK, - CHECK_MEDIA_FILE_FOR_SPAM_CALLBACK, - CHECK_REGISTRATION_FOR_SPAM_CALLBACK, - CHECK_USERNAME_FOR_SPAM_CALLBACK, - SHOULD_DROP_FEDERATED_EVENT_CALLBACK, - USER_MAY_CREATE_ROOM_ALIAS_CALLBACK, - USER_MAY_CREATE_ROOM_CALLBACK, - USER_MAY_INVITE_CALLBACK, - USER_MAY_JOIN_ROOM_CALLBACK, - USER_MAY_PUBLISH_ROOM_CALLBACK, - USER_MAY_SEND_3PID_INVITE_CALLBACK, - SpamChecker, -) from synapse.events.third_party_rules import ( CHECK_CAN_DEACTIVATE_USER_CALLBACK, CHECK_CAN_SHUTDOWN_ROOM_CALLBACK, @@ -105,6 +91,20 @@ ON_LEGACY_SEND_MAIL_CALLBACK, ON_USER_REGISTRATION_CALLBACK, ) +from synapse.module_api.callbacks.spamchecker_callbacks import ( + CHECK_EVENT_FOR_SPAM_CALLBACK, + CHECK_MEDIA_FILE_FOR_SPAM_CALLBACK, + CHECK_REGISTRATION_FOR_SPAM_CALLBACK, + CHECK_USERNAME_FOR_SPAM_CALLBACK, + SHOULD_DROP_FEDERATED_EVENT_CALLBACK, + USER_MAY_CREATE_ROOM_ALIAS_CALLBACK, + USER_MAY_CREATE_ROOM_CALLBACK, + USER_MAY_INVITE_CALLBACK, + USER_MAY_JOIN_ROOM_CALLBACK, + USER_MAY_PUBLISH_ROOM_CALLBACK, + USER_MAY_SEND_3PID_INVITE_CALLBACK, + SpamCheckerModuleApiCallbacks, +) from synapse.rest.client.login import LoginResponse from synapse.storage import DataStore from synapse.storage.background_updates import ( @@ -147,7 +147,7 @@ """ PRESENCE_ALL_USERS = PresenceRouter.ALL_USERS -NOT_SPAM = SpamChecker.NOT_SPAM +NOT_SPAM = SpamCheckerModuleApiCallbacks.NOT_SPAM __all__ = [ "errors", @@ -271,7 +271,6 @@ def __init__(self, hs: "HomeServer", auth_handler: AuthHandler) -> None: self._public_room_list_manager = PublicRoomListManager(hs) self._account_data_manager = AccountDataManager(hs) - self._spam_checker = hs.get_spam_checker() self._third_party_event_rules = hs.get_third_party_event_rules() self._password_auth_provider = hs.get_password_auth_provider() self._presence_router = hs.get_presence_router() @@ -305,7 +304,7 @@ def register_spam_checker_callbacks( Added in Synapse v1.37.0. """ - return self._spam_checker.register_callbacks( + return self._callbacks.spam_checker.register_callbacks( check_event_for_spam=check_event_for_spam, should_drop_federated_event=should_drop_federated_event, user_may_join_room=user_may_join_room, diff --git a/synapse/module_api/callbacks/__init__.py b/synapse/module_api/callbacks/__init__.py index 3d977bf6558a..89b5c8d55286 100644 --- a/synapse/module_api/callbacks/__init__.py +++ b/synapse/module_api/callbacks/__init__.py @@ -12,11 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -from synapse.module_api.callbacks.account_validity_callbacks import ( - AccountValidityModuleApiCallbacks, -) +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from synapse.server import HomeServer + +from .account_validity_callbacks import AccountValidityModuleApiCallbacks +from .spamchecker_callbacks import SpamCheckerModuleApiCallbacks class ModuleApiCallbacks: - def __init__(self) -> None: + def __init__(self, hs: "HomeServer") -> None: self.account_validity = AccountValidityModuleApiCallbacks() + self.spam_checker = SpamCheckerModuleApiCallbacks(hs) diff --git a/synapse/events/spamcheck.py b/synapse/module_api/callbacks/spamchecker_callbacks.py similarity index 99% rename from synapse/events/spamcheck.py rename to synapse/module_api/callbacks/spamchecker_callbacks.py index 765c15bb5135..4456d1b81eb2 100644 --- a/synapse/events/spamcheck.py +++ b/synapse/module_api/callbacks/spamchecker_callbacks.py @@ -286,11 +286,10 @@ def run(*args: Any, **kwargs: Any) -> Awaitable: api.register_spam_checker_callbacks(**hooks) -class SpamChecker: +class SpamCheckerModuleApiCallbacks: NOT_SPAM: Literal["NOT_SPAM"] = "NOT_SPAM" def __init__(self, hs: "synapse.server.HomeServer") -> None: - self.hs = hs self.clock = hs.get_clock() self._check_event_for_spam_callbacks: List[CHECK_EVENT_FOR_SPAM_CALLBACK] = [] diff --git a/synapse/server.py b/synapse/server.py index a191c1999347..559724594b89 100644 --- a/synapse/server.py +++ b/synapse/server.py @@ -42,7 +42,6 @@ from synapse.crypto.keyring import Keyring from synapse.events.builder import EventBuilderFactory from synapse.events.presence_router import PresenceRouter -from synapse.events.spamcheck import SpamChecker from synapse.events.third_party_rules import ThirdPartyEventRules from synapse.events.utils import EventClientSerializer from synapse.federation.federation_client import FederationClient @@ -687,10 +686,6 @@ def get_user_directory_handler(self) -> UserDirectoryHandler: def get_stats_handler(self) -> StatsHandler: return StatsHandler(self) - @cache_in_self - def get_spam_checker(self) -> SpamChecker: - return SpamChecker(self) - @cache_in_self def get_third_party_event_rules(self) -> ThirdPartyEventRules: return ThirdPartyEventRules(self) @@ -803,7 +798,7 @@ def get_module_api(self) -> ModuleApi: @cache_in_self def get_module_api_callbacks(self) -> ModuleApiCallbacks: - return ModuleApiCallbacks() + return ModuleApiCallbacks(self) @cache_in_self def get_account_data_handler(self) -> AccountDataHandler: From 2525210daee5f961de7f3c844451564f5020216d Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 8 Mar 2023 16:22:49 +0000 Subject: [PATCH 2/4] Update calling code for the Spam Checker It's questionable whether `NOT_SPAM` should be defined in "SpamCheckerModuleApiCallbacks", but putting just that in a separate class feels a bit silly. It is still re-exported by ModuleApi, which is where modules should be pulling it from. --- synapse/app/_base.py | 2 +- synapse/federation/federation_base.py | 6 +++--- synapse/federation/federation_server.py | 8 +++++--- synapse/handlers/directory.py | 14 ++++++++----- synapse/handlers/federation.py | 4 ++-- synapse/handlers/message.py | 10 +++++++--- synapse/handlers/register.py | 4 ++-- synapse/handlers/room.py | 10 +++++++--- synapse/handlers/room_member.py | 22 ++++++++++++--------- synapse/handlers/user_directory.py | 6 ++++-- synapse/media/media_storage.py | 7 +++---- tests/handlers/test_user_directory.py | 2 +- tests/media/test_media_storage.py | 2 +- tests/rest/client/test_rooms.py | 26 ++++++++++++++++++------- tests/server.py | 2 +- 15 files changed, 78 insertions(+), 47 deletions(-) diff --git a/synapse/app/_base.py b/synapse/app/_base.py index f7b866978cca..954402e4d2cc 100644 --- a/synapse/app/_base.py +++ b/synapse/app/_base.py @@ -64,7 +64,6 @@ from synapse.config.server import ListenerConfig, ManholeConfig, TCPListenerConfig from synapse.crypto import context_factory from synapse.events.presence_router import load_legacy_presence_router -from synapse.events.spamcheck import load_legacy_spam_checkers from synapse.events.third_party_rules import load_legacy_third_party_event_rules from synapse.handlers.auth import load_legacy_password_auth_providers from synapse.http.site import SynapseSite @@ -73,6 +72,7 @@ from synapse.metrics import install_gc_manager, register_threadpool from synapse.metrics.background_process_metrics import wrap_as_background_process from synapse.metrics.jemalloc import setup_jemalloc_stats +from synapse.module_api.callbacks.spamchecker_callbacks import load_legacy_spam_checkers from synapse.types import ISynapseReactor from synapse.util import SYNAPSE_VERSION from synapse.util.caches.lrucache import setup_expire_lru_cache_entries diff --git a/synapse/federation/federation_base.py b/synapse/federation/federation_base.py index 29fae716f589..3df975958da2 100644 --- a/synapse/federation/federation_base.py +++ b/synapse/federation/federation_base.py @@ -51,7 +51,7 @@ def __init__(self, hs: "HomeServer"): self.server_name = hs.hostname self.keyring = hs.get_keyring() - self.spam_checker = hs.get_spam_checker() + self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker self.store = hs.get_datastores().main self._clock = hs.get_clock() self._storage_controllers = hs.get_storage_controllers() @@ -137,9 +137,9 @@ async def _check_sigs_and_hash( ) return redacted_event - spam_check = await self.spam_checker.check_event_for_spam(pdu) + spam_check = await self._spam_checker_module_callbacks.check_event_for_spam(pdu) - if spam_check != self.spam_checker.NOT_SPAM: + if spam_check != self._spam_checker_module_callbacks.NOT_SPAM: logger.warning("Event contains spam, soft-failing %s", pdu.event_id) log_kv( { diff --git a/synapse/federation/federation_server.py b/synapse/federation/federation_server.py index 64e99292ec04..d7740eb3b448 100644 --- a/synapse/federation/federation_server.py +++ b/synapse/federation/federation_server.py @@ -130,7 +130,7 @@ def __init__(self, hs: "HomeServer"): super().__init__(hs) self.handler = hs.get_federation_handler() - self._spam_checker = hs.get_spam_checker() + self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker self._federation_event_handler = hs.get_federation_event_handler() self.state = hs.get_state_handler() self._event_auth_handler = hs.get_event_auth_handler() @@ -1129,7 +1129,7 @@ async def _handle_received_pdu(self, origin: str, pdu: EventBase) -> None: logger.warning("event id %s: %s", pdu.event_id, e) raise FederationError("ERROR", 403, str(e), affected=pdu.event_id) - if await self._spam_checker.should_drop_federated_event(pdu): + if await self._spam_checker_module_callbacks.should_drop_federated_event(pdu): logger.warning( "Unstaged federated event contains spam, dropping %s", pdu.event_id ) @@ -1174,7 +1174,9 @@ async def _get_next_nonspam_staged_event_for_room( origin, event = next - if await self._spam_checker.should_drop_federated_event(event): + if await self._spam_checker_module_callbacks.should_drop_federated_event( + event + ): logger.warning( "Staged federated event contains spam, dropping %s", event.event_id, diff --git a/synapse/handlers/directory.py b/synapse/handlers/directory.py index 1fb23cc9bf51..5e8316e2e511 100644 --- a/synapse/handlers/directory.py +++ b/synapse/handlers/directory.py @@ -60,7 +60,7 @@ def __init__(self, hs: "HomeServer"): "directory", self.on_directory_query ) - self.spam_checker = hs.get_spam_checker() + self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker async def _create_association( self, @@ -145,10 +145,12 @@ async def create_association( 403, "You must be in the room to create an alias for it" ) - spam_check = await self.spam_checker.user_may_create_room_alias( - user_id, room_alias + spam_check = ( + await self._spam_checker_module_callbacks.user_may_create_room_alias( + user_id, room_alias + ) ) - if spam_check != self.spam_checker.NOT_SPAM: + if spam_check != self._spam_checker_module_callbacks.NOT_SPAM: raise AuthError( 403, "This user is not permitted to create this alias", @@ -444,7 +446,9 @@ async def edit_published_room_list( """ user_id = requester.user.to_string() - spam_check = await self.spam_checker.user_may_publish_room(user_id, room_id) + spam_check = await self._spam_checker_module_callbacks.user_may_publish_room( + user_id, room_id + ) if spam_check != NOT_SPAM: raise AuthError( 403, diff --git a/synapse/handlers/federation.py b/synapse/handlers/federation.py index 65461a078723..d1a88cc60460 100644 --- a/synapse/handlers/federation.py +++ b/synapse/handlers/federation.py @@ -141,7 +141,7 @@ def __init__(self, hs: "HomeServer"): self.server_name = hs.hostname self.keyring = hs.get_keyring() self.is_mine_id = hs.is_mine_id - self.spam_checker = hs.get_spam_checker() + self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker self.event_creation_handler = hs.get_event_creation_handler() self.event_builder_factory = hs.get_event_builder_factory() self._event_auth_handler = hs.get_event_auth_handler() @@ -1042,7 +1042,7 @@ async def on_invite_request( if self.hs.config.server.block_non_admin_invites: raise SynapseError(403, "This server does not accept room invites") - spam_check = await self.spam_checker.user_may_invite( + spam_check = await self._spam_checker_module_callbacks.user_may_invite( event.sender, event.state_key, event.room_id ) if spam_check != NOT_SPAM: diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py index a17fe3bf530b..2e964ed37e9a 100644 --- a/synapse/handlers/message.py +++ b/synapse/handlers/message.py @@ -508,7 +508,7 @@ def __init__(self, hs: "HomeServer"): self._bulk_push_rule_evaluator = hs.get_bulk_push_rule_evaluator() - self.spam_checker = hs.get_spam_checker() + self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker self.third_party_event_rules: "ThirdPartyEventRules" = ( self.hs.get_third_party_event_rules() ) @@ -1035,8 +1035,12 @@ async def create_and_send_nonmember_event( event.sender, ) - spam_check_result = await self.spam_checker.check_event_for_spam(event) - if spam_check_result != self.spam_checker.NOT_SPAM: + spam_check_result = ( + await self._spam_checker_module_callbacks.check_event_for_spam( + event + ) + ) + if spam_check_result != self._spam_checker_module_callbacks.NOT_SPAM: if isinstance(spam_check_result, tuple): try: [code, dict] = spam_check_result diff --git a/synapse/handlers/register.py b/synapse/handlers/register.py index c8bf2439afb5..61c4b833bd30 100644 --- a/synapse/handlers/register.py +++ b/synapse/handlers/register.py @@ -110,7 +110,7 @@ def __init__(self, hs: "HomeServer"): self._server_notices_mxid = hs.config.servernotices.server_notices_mxid self._server_name = hs.hostname - self.spam_checker = hs.get_spam_checker() + self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker if hs.config.worker.worker_app: self._register_client = ReplicationRegisterServlet.make_client(hs) @@ -259,7 +259,7 @@ async def register_user( await self.check_registration_ratelimit(address) - result = await self.spam_checker.check_registration_for_spam( + result = await self._spam_checker_module_callbacks.check_registration_for_spam( threepid, localpart, user_agent_ips or [], diff --git a/synapse/handlers/room.py b/synapse/handlers/room.py index 2d69cabf43d0..efd9612d90ca 100644 --- a/synapse/handlers/room.py +++ b/synapse/handlers/room.py @@ -106,7 +106,7 @@ def __init__(self, hs: "HomeServer"): self.auth_blocking = hs.get_auth_blocking() self.clock = hs.get_clock() self.hs = hs - self.spam_checker = hs.get_spam_checker() + self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker self.event_creation_handler = hs.get_event_creation_handler() self.room_member_handler = hs.get_room_member_handler() self._event_auth_handler = hs.get_event_auth_handler() @@ -449,7 +449,9 @@ async def clone_existing_room( """ user_id = requester.user.to_string() - spam_check = await self.spam_checker.user_may_create_room(user_id) + spam_check = await self._spam_checker_module_callbacks.user_may_create_room( + user_id + ) if spam_check != NOT_SPAM: raise SynapseError( 403, @@ -761,7 +763,9 @@ async def create_room( ) if not is_requester_admin: - spam_check = await self.spam_checker.user_may_create_room(user_id) + spam_check = await self._spam_checker_module_callbacks.user_may_create_room( + user_id + ) if spam_check != NOT_SPAM: raise SynapseError( 403, diff --git a/synapse/handlers/room_member.py b/synapse/handlers/room_member.py index 1d8b0aee6ff7..ec317e60239a 100644 --- a/synapse/handlers/room_member.py +++ b/synapse/handlers/room_member.py @@ -96,7 +96,7 @@ def __init__(self, hs: "HomeServer"): self.member_as_limiter = Linearizer(max_count=10, name="member_as_limiter") self.clock = hs.get_clock() - self.spam_checker = hs.get_spam_checker() + self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker self.third_party_event_rules = hs.get_third_party_event_rules() self._server_notices_mxid = self.config.servernotices.server_notices_mxid self._enable_lookup = hs.config.registration.enable_3pid_lookup @@ -806,7 +806,7 @@ async def update_membership_locked( ) block_invite_result = (Codes.FORBIDDEN, {}) - spam_check = await self.spam_checker.user_may_invite( + spam_check = await self._spam_checker_module_callbacks.user_may_invite( requester.user.to_string(), target_id, room_id ) if spam_check != NOT_SPAM: @@ -940,8 +940,10 @@ async def update_membership_locked( # a room then they're allowed to join it. and not new_room ): - spam_check = await self.spam_checker.user_may_join_room( - target.to_string(), room_id, is_invited=inviter is not None + spam_check = ( + await self._spam_checker_module_callbacks.user_may_join_room( + target.to_string(), room_id, is_invited=inviter is not None + ) ) if spam_check != NOT_SPAM: raise SynapseError( @@ -1550,11 +1552,13 @@ async def do_3pid_invite( ) else: # Check if the spamchecker(s) allow this invite to go through. - spam_check = await self.spam_checker.user_may_send_3pid_invite( - inviter_userid=requester.user.to_string(), - medium=medium, - address=address, - room_id=room_id, + spam_check = ( + await self._spam_checker_module_callbacks.user_may_send_3pid_invite( + inviter_userid=requester.user.to_string(), + medium=medium, + address=address, + room_id=room_id, + ) ) if spam_check != NOT_SPAM: raise SynapseError( diff --git a/synapse/handlers/user_directory.py b/synapse/handlers/user_directory.py index 28a92d41d6fc..05197edc9546 100644 --- a/synapse/handlers/user_directory.py +++ b/synapse/handlers/user_directory.py @@ -94,7 +94,7 @@ def __init__(self, hs: "HomeServer"): self.is_mine_id = hs.is_mine_id self.update_user_directory = hs.config.worker.should_update_user_directory self.search_all_users = hs.config.userdirectory.user_directory_search_all_users - self.spam_checker = hs.get_spam_checker() + self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker self._hs = hs # The current position in the current_state_delta stream @@ -149,7 +149,9 @@ async def search_users( # Remove any spammy users from the results. non_spammy_users = [] for user in results["results"]: - if not await self.spam_checker.check_username_for_spam(user): + if not await self._spam_checker_module_callbacks.check_username_for_spam( + user + ): non_spammy_users.append(user) results["results"] = non_spammy_users diff --git a/synapse/media/media_storage.py b/synapse/media/media_storage.py index a7e22a91e115..a819d954070a 100644 --- a/synapse/media/media_storage.py +++ b/synapse/media/media_storage.py @@ -36,7 +36,6 @@ from twisted.internet.interfaces import IConsumer from twisted.protocols.basic import FileSender -import synapse from synapse.api.errors import NotFoundError from synapse.logging.context import defer_to_thread, make_deferred_yieldable from synapse.util import Clock @@ -74,7 +73,7 @@ def __init__( self.local_media_directory = local_media_directory self.filepaths = filepaths self.storage_providers = storage_providers - self.spam_checker = hs.get_spam_checker() + self._spam_checker_module_callbacks = hs.get_module_api_callbacks().spam_checker self.clock = hs.get_clock() async def store_file(self, source: IO, file_info: FileInfo) -> str: @@ -145,10 +144,10 @@ async def finish() -> None: f.flush() f.close() - spam_check = await self.spam_checker.check_media_file_for_spam( + spam_check = await self._spam_checker_module_callbacks.check_media_file_for_spam( ReadableFileWrapper(self.clock, fname), file_info ) - if spam_check != synapse.module_api.NOT_SPAM: + if spam_check != self._spam_checker_module_callbacks.NOT_SPAM: logger.info("Blocking media due to spam checker") # Note that we'll delete the stored media, due to the # try/except below. The media also won't be stored in diff --git a/tests/handlers/test_user_directory.py b/tests/handlers/test_user_directory.py index da4d24082648..15a7dc681854 100644 --- a/tests/handlers/test_user_directory.py +++ b/tests/handlers/test_user_directory.py @@ -792,7 +792,7 @@ async def allow_all(user_profile: UserProfile) -> bool: return False # Configure a spam checker that does not filter any users. - spam_checker = self.hs.get_spam_checker() + spam_checker = self.hs.get_module_api_callbacks().spam_checker spam_checker._check_username_for_spam_callbacks = [allow_all] # The results do not change: diff --git a/tests/media/test_media_storage.py b/tests/media/test_media_storage.py index 870047d0f250..f0f2da65db0b 100644 --- a/tests/media/test_media_storage.py +++ b/tests/media/test_media_storage.py @@ -31,7 +31,6 @@ from synapse.api.errors import Codes from synapse.events import EventBase -from synapse.events.spamcheck import load_legacy_spam_checkers from synapse.http.types import QueryParams from synapse.logging.context import make_deferred_yieldable from synapse.media._base import FileInfo @@ -39,6 +38,7 @@ from synapse.media.media_storage import MediaStorage, ReadableFileWrapper from synapse.media.storage_provider import FileStorageProviderBackend from synapse.module_api import ModuleApi +from synapse.module_api.callbacks.spamchecker_callbacks import load_legacy_spam_checkers from synapse.rest import admin from synapse.rest.client import login from synapse.server import HomeServer diff --git a/tests/rest/client/test_rooms.py b/tests/rest/client/test_rooms.py index a4900703c415..4d39c89f6f19 100644 --- a/tests/rest/client/test_rooms.py +++ b/tests/rest/client/test_rooms.py @@ -814,7 +814,9 @@ async def user_may_join_room( return False join_mock = Mock(side_effect=user_may_join_room) - self.hs.get_spam_checker()._user_may_join_room_callbacks.append(join_mock) + self.hs.get_module_api_callbacks().spam_checker._user_may_join_room_callbacks.append( + join_mock + ) channel = self.make_request( "POST", @@ -840,7 +842,9 @@ async def user_may_join_room_codes( return Codes.CONSENT_NOT_GIVEN join_mock = Mock(side_effect=user_may_join_room_codes) - self.hs.get_spam_checker()._user_may_join_room_callbacks.append(join_mock) + self.hs.get_module_api_callbacks().spam_checker._user_may_join_room_callbacks.append( + join_mock + ) channel = self.make_request( "POST", @@ -1162,7 +1166,9 @@ async def user_may_join_room( # `spec` argument is needed for this function mock to have `__qualname__`, which # is needed for `Measure` metrics buried in SpamChecker. callback_mock = Mock(side_effect=user_may_join_room, spec=lambda *x: None) - self.hs.get_spam_checker()._user_may_join_room_callbacks.append(callback_mock) + self.hs.get_module_api_callbacks().spam_checker._user_may_join_room_callbacks.append( + callback_mock + ) # Join a first room, without being invited to it. self.helper.join(self.room1, self.user2, tok=self.tok2) @@ -1227,7 +1233,9 @@ async def user_may_join_room( # `spec` argument is needed for this function mock to have `__qualname__`, which # is needed for `Measure` metrics buried in SpamChecker. callback_mock = Mock(side_effect=user_may_join_room, spec=lambda *x: None) - self.hs.get_spam_checker()._user_may_join_room_callbacks.append(callback_mock) + self.hs.get_module_api_callbacks().spam_checker._user_may_join_room_callbacks.append( + callback_mock + ) # Join a first room, without being invited to it. self.helper.join(self.room1, self.user2, tok=self.tok2) @@ -1643,7 +1651,7 @@ async def check_event_for_spam( spam_checker = SpamCheck() - self.hs.get_spam_checker()._check_event_for_spam_callbacks.append( + self.hs.get_module_api_callbacks().spam_checker._check_event_for_spam_callbacks.append( spam_checker.check_event_for_spam ) @@ -3381,7 +3389,9 @@ def test_threepid_invite_spamcheck_deprecated(self) -> None: # `spec` argument is needed for this function mock to have `__qualname__`, which # is needed for `Measure` metrics buried in SpamChecker. mock = Mock(return_value=make_awaitable(True), spec=lambda *x: None) - self.hs.get_spam_checker()._user_may_send_3pid_invite_callbacks.append(mock) + self.hs.get_module_api_callbacks().spam_checker._user_may_send_3pid_invite_callbacks.append( + mock + ) # Send a 3PID invite into the room and check that it succeeded. email_to_invite = "teresa@example.com" @@ -3446,7 +3456,9 @@ def test_threepid_invite_spamcheck(self) -> None: return_value=make_awaitable(synapse.module_api.NOT_SPAM), spec=lambda *x: None, ) - self.hs.get_spam_checker()._user_may_send_3pid_invite_callbacks.append(mock) + self.hs.get_module_api_callbacks().spam_checker._user_may_send_3pid_invite_callbacks.append( + mock + ) # Send a 3PID invite into the room and check that it succeeded. email_to_invite = "teresa@example.com" diff --git a/tests/server.py b/tests/server.py index b52ff1c4632c..a49dc90e3272 100644 --- a/tests/server.py +++ b/tests/server.py @@ -73,11 +73,11 @@ from synapse.config.database import DatabaseConnectionConfig from synapse.config.homeserver import HomeServerConfig from synapse.events.presence_router import load_legacy_presence_router -from synapse.events.spamcheck import load_legacy_spam_checkers from synapse.events.third_party_rules import load_legacy_third_party_event_rules from synapse.handlers.auth import load_legacy_password_auth_providers from synapse.http.site import SynapseRequest from synapse.logging.context import ContextResourceUsage +from synapse.module_api.callbacks.spamchecker_callbacks import load_legacy_spam_checkers from synapse.server import HomeServer from synapse.storage import DataStore from synapse.storage.database import LoggingDatabaseConnection From ad7e74d3a3ddfad75c77ba6dbc16c9185ed9a664 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 17 Apr 2023 11:25:48 -0600 Subject: [PATCH 3/4] changelog --- changelog.d/15453.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/15453.misc diff --git a/changelog.d/15453.misc b/changelog.d/15453.misc new file mode 100644 index 000000000000..9981606c3226 --- /dev/null +++ b/changelog.d/15453.misc @@ -0,0 +1 @@ +Move various module API callback registration methods to a dedicated class. \ No newline at end of file From 75d3024ef0e503a0921d4bf7a651abafc45dce96 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 17 Apr 2023 18:21:14 -0600 Subject: [PATCH 4/4] make relative imports absolute --- synapse/module_api/callbacks/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/synapse/module_api/callbacks/__init__.py b/synapse/module_api/callbacks/__init__.py index 89b5c8d55286..5cdb2c003a7c 100644 --- a/synapse/module_api/callbacks/__init__.py +++ b/synapse/module_api/callbacks/__init__.py @@ -17,8 +17,12 @@ if TYPE_CHECKING: from synapse.server import HomeServer -from .account_validity_callbacks import AccountValidityModuleApiCallbacks -from .spamchecker_callbacks import SpamCheckerModuleApiCallbacks +from synapse.module_api.callbacks.account_validity_callbacks import ( + AccountValidityModuleApiCallbacks, +) +from synapse.module_api.callbacks.spamchecker_callbacks import ( + SpamCheckerModuleApiCallbacks, +) class ModuleApiCallbacks: