Move Spam Checker callbacks to a dedicated file (#15453)
parent
929797d939
commit
aec639e3e3
|
@ -0,0 +1 @@
|
||||||
|
Move various module API callback registration methods to a dedicated class.
|
|
@ -64,7 +64,6 @@ from synapse.config.homeserver import HomeServerConfig
|
||||||
from synapse.config.server import ListenerConfig, ManholeConfig, TCPListenerConfig
|
from synapse.config.server import ListenerConfig, ManholeConfig, TCPListenerConfig
|
||||||
from synapse.crypto import context_factory
|
from synapse.crypto import context_factory
|
||||||
from synapse.events.presence_router import load_legacy_presence_router
|
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.events.third_party_rules import load_legacy_third_party_event_rules
|
||||||
from synapse.handlers.auth import load_legacy_password_auth_providers
|
from synapse.handlers.auth import load_legacy_password_auth_providers
|
||||||
from synapse.http.site import SynapseSite
|
from synapse.http.site import SynapseSite
|
||||||
|
@ -73,6 +72,7 @@ from synapse.logging.opentracing import init_tracer
|
||||||
from synapse.metrics import install_gc_manager, register_threadpool
|
from synapse.metrics import install_gc_manager, register_threadpool
|
||||||
from synapse.metrics.background_process_metrics import wrap_as_background_process
|
from synapse.metrics.background_process_metrics import wrap_as_background_process
|
||||||
from synapse.metrics.jemalloc import setup_jemalloc_stats
|
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.types import ISynapseReactor
|
||||||
from synapse.util import SYNAPSE_VERSION
|
from synapse.util import SYNAPSE_VERSION
|
||||||
from synapse.util.caches.lrucache import setup_expire_lru_cache_entries
|
from synapse.util.caches.lrucache import setup_expire_lru_cache_entries
|
||||||
|
|
|
@ -51,7 +51,7 @@ class FederationBase:
|
||||||
|
|
||||||
self.server_name = hs.hostname
|
self.server_name = hs.hostname
|
||||||
self.keyring = hs.get_keyring()
|
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.store = hs.get_datastores().main
|
||||||
self._clock = hs.get_clock()
|
self._clock = hs.get_clock()
|
||||||
self._storage_controllers = hs.get_storage_controllers()
|
self._storage_controllers = hs.get_storage_controllers()
|
||||||
|
@ -137,9 +137,9 @@ class FederationBase:
|
||||||
)
|
)
|
||||||
return redacted_event
|
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)
|
logger.warning("Event contains spam, soft-failing %s", pdu.event_id)
|
||||||
log_kv(
|
log_kv(
|
||||||
{
|
{
|
||||||
|
|
|
@ -130,7 +130,7 @@ class FederationServer(FederationBase):
|
||||||
super().__init__(hs)
|
super().__init__(hs)
|
||||||
|
|
||||||
self.handler = hs.get_federation_handler()
|
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._federation_event_handler = hs.get_federation_event_handler()
|
||||||
self.state = hs.get_state_handler()
|
self.state = hs.get_state_handler()
|
||||||
self._event_auth_handler = hs.get_event_auth_handler()
|
self._event_auth_handler = hs.get_event_auth_handler()
|
||||||
|
@ -1129,7 +1129,7 @@ class FederationServer(FederationBase):
|
||||||
logger.warning("event id %s: %s", pdu.event_id, e)
|
logger.warning("event id %s: %s", pdu.event_id, e)
|
||||||
raise FederationError("ERROR", 403, str(e), affected=pdu.event_id)
|
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(
|
logger.warning(
|
||||||
"Unstaged federated event contains spam, dropping %s", pdu.event_id
|
"Unstaged federated event contains spam, dropping %s", pdu.event_id
|
||||||
)
|
)
|
||||||
|
@ -1174,7 +1174,9 @@ class FederationServer(FederationBase):
|
||||||
|
|
||||||
origin, event = next
|
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(
|
logger.warning(
|
||||||
"Staged federated event contains spam, dropping %s",
|
"Staged federated event contains spam, dropping %s",
|
||||||
event.event_id,
|
event.event_id,
|
||||||
|
|
|
@ -60,7 +60,7 @@ class DirectoryHandler:
|
||||||
"directory", self.on_directory_query
|
"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(
|
async def _create_association(
|
||||||
self,
|
self,
|
||||||
|
@ -145,10 +145,12 @@ class DirectoryHandler:
|
||||||
403, "You must be in the room to create an alias for it"
|
403, "You must be in the room to create an alias for it"
|
||||||
)
|
)
|
||||||
|
|
||||||
spam_check = await self.spam_checker.user_may_create_room_alias(
|
spam_check = (
|
||||||
user_id, room_alias
|
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(
|
raise AuthError(
|
||||||
403,
|
403,
|
||||||
"This user is not permitted to create this alias",
|
"This user is not permitted to create this alias",
|
||||||
|
@ -444,7 +446,9 @@ class DirectoryHandler:
|
||||||
"""
|
"""
|
||||||
user_id = requester.user.to_string()
|
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:
|
if spam_check != NOT_SPAM:
|
||||||
raise AuthError(
|
raise AuthError(
|
||||||
403,
|
403,
|
||||||
|
|
|
@ -141,7 +141,7 @@ class FederationHandler:
|
||||||
self.server_name = hs.hostname
|
self.server_name = hs.hostname
|
||||||
self.keyring = hs.get_keyring()
|
self.keyring = hs.get_keyring()
|
||||||
self.is_mine_id = hs.is_mine_id
|
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_creation_handler = hs.get_event_creation_handler()
|
||||||
self.event_builder_factory = hs.get_event_builder_factory()
|
self.event_builder_factory = hs.get_event_builder_factory()
|
||||||
self._event_auth_handler = hs.get_event_auth_handler()
|
self._event_auth_handler = hs.get_event_auth_handler()
|
||||||
|
@ -1042,7 +1042,7 @@ class FederationHandler:
|
||||||
if self.hs.config.server.block_non_admin_invites:
|
if self.hs.config.server.block_non_admin_invites:
|
||||||
raise SynapseError(403, "This server does not accept room 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
|
event.sender, event.state_key, event.room_id
|
||||||
)
|
)
|
||||||
if spam_check != NOT_SPAM:
|
if spam_check != NOT_SPAM:
|
||||||
|
|
|
@ -508,7 +508,7 @@ class EventCreationHandler:
|
||||||
|
|
||||||
self._bulk_push_rule_evaluator = hs.get_bulk_push_rule_evaluator()
|
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.third_party_event_rules: "ThirdPartyEventRules" = (
|
||||||
self.hs.get_third_party_event_rules()
|
self.hs.get_third_party_event_rules()
|
||||||
)
|
)
|
||||||
|
@ -1035,8 +1035,12 @@ class EventCreationHandler:
|
||||||
event.sender,
|
event.sender,
|
||||||
)
|
)
|
||||||
|
|
||||||
spam_check_result = await self.spam_checker.check_event_for_spam(event)
|
spam_check_result = (
|
||||||
if spam_check_result != self.spam_checker.NOT_SPAM:
|
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):
|
if isinstance(spam_check_result, tuple):
|
||||||
try:
|
try:
|
||||||
[code, dict] = spam_check_result
|
[code, dict] = spam_check_result
|
||||||
|
|
|
@ -110,7 +110,7 @@ class RegistrationHandler:
|
||||||
self._server_notices_mxid = hs.config.servernotices.server_notices_mxid
|
self._server_notices_mxid = hs.config.servernotices.server_notices_mxid
|
||||||
self._server_name = hs.hostname
|
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:
|
if hs.config.worker.worker_app:
|
||||||
self._register_client = ReplicationRegisterServlet.make_client(hs)
|
self._register_client = ReplicationRegisterServlet.make_client(hs)
|
||||||
|
@ -259,7 +259,7 @@ class RegistrationHandler:
|
||||||
|
|
||||||
await self.check_registration_ratelimit(address)
|
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,
|
threepid,
|
||||||
localpart,
|
localpart,
|
||||||
user_agent_ips or [],
|
user_agent_ips or [],
|
||||||
|
|
|
@ -106,7 +106,7 @@ class RoomCreationHandler:
|
||||||
self.auth_blocking = hs.get_auth_blocking()
|
self.auth_blocking = hs.get_auth_blocking()
|
||||||
self.clock = hs.get_clock()
|
self.clock = hs.get_clock()
|
||||||
self.hs = hs
|
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.event_creation_handler = hs.get_event_creation_handler()
|
||||||
self.room_member_handler = hs.get_room_member_handler()
|
self.room_member_handler = hs.get_room_member_handler()
|
||||||
self._event_auth_handler = hs.get_event_auth_handler()
|
self._event_auth_handler = hs.get_event_auth_handler()
|
||||||
|
@ -449,7 +449,9 @@ class RoomCreationHandler:
|
||||||
"""
|
"""
|
||||||
user_id = requester.user.to_string()
|
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:
|
if spam_check != NOT_SPAM:
|
||||||
raise SynapseError(
|
raise SynapseError(
|
||||||
403,
|
403,
|
||||||
|
@ -761,7 +763,9 @@ class RoomCreationHandler:
|
||||||
)
|
)
|
||||||
|
|
||||||
if not is_requester_admin:
|
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:
|
if spam_check != NOT_SPAM:
|
||||||
raise SynapseError(
|
raise SynapseError(
|
||||||
403,
|
403,
|
||||||
|
|
|
@ -96,7 +96,7 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
||||||
self.member_as_limiter = Linearizer(max_count=10, name="member_as_limiter")
|
self.member_as_limiter = Linearizer(max_count=10, name="member_as_limiter")
|
||||||
|
|
||||||
self.clock = hs.get_clock()
|
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.third_party_event_rules = hs.get_third_party_event_rules()
|
||||||
self._server_notices_mxid = self.config.servernotices.server_notices_mxid
|
self._server_notices_mxid = self.config.servernotices.server_notices_mxid
|
||||||
self._enable_lookup = hs.config.registration.enable_3pid_lookup
|
self._enable_lookup = hs.config.registration.enable_3pid_lookup
|
||||||
|
@ -806,7 +806,7 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
||||||
)
|
)
|
||||||
block_invite_result = (Codes.FORBIDDEN, {})
|
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
|
requester.user.to_string(), target_id, room_id
|
||||||
)
|
)
|
||||||
if spam_check != NOT_SPAM:
|
if spam_check != NOT_SPAM:
|
||||||
|
@ -940,8 +940,10 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
||||||
# a room then they're allowed to join it.
|
# a room then they're allowed to join it.
|
||||||
and not new_room
|
and not new_room
|
||||||
):
|
):
|
||||||
spam_check = await self.spam_checker.user_may_join_room(
|
spam_check = (
|
||||||
target.to_string(), room_id, is_invited=inviter is not None
|
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:
|
if spam_check != NOT_SPAM:
|
||||||
raise SynapseError(
|
raise SynapseError(
|
||||||
|
@ -1550,11 +1552,13 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Check if the spamchecker(s) allow this invite to go through.
|
# Check if the spamchecker(s) allow this invite to go through.
|
||||||
spam_check = await self.spam_checker.user_may_send_3pid_invite(
|
spam_check = (
|
||||||
inviter_userid=requester.user.to_string(),
|
await self._spam_checker_module_callbacks.user_may_send_3pid_invite(
|
||||||
medium=medium,
|
inviter_userid=requester.user.to_string(),
|
||||||
address=address,
|
medium=medium,
|
||||||
room_id=room_id,
|
address=address,
|
||||||
|
room_id=room_id,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if spam_check != NOT_SPAM:
|
if spam_check != NOT_SPAM:
|
||||||
raise SynapseError(
|
raise SynapseError(
|
||||||
|
|
|
@ -94,7 +94,7 @@ class UserDirectoryHandler(StateDeltasHandler):
|
||||||
self.is_mine_id = hs.is_mine_id
|
self.is_mine_id = hs.is_mine_id
|
||||||
self.update_user_directory = hs.config.worker.should_update_user_directory
|
self.update_user_directory = hs.config.worker.should_update_user_directory
|
||||||
self.search_all_users = hs.config.userdirectory.user_directory_search_all_users
|
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
|
self._hs = hs
|
||||||
|
|
||||||
# The current position in the current_state_delta stream
|
# The current position in the current_state_delta stream
|
||||||
|
@ -149,7 +149,9 @@ class UserDirectoryHandler(StateDeltasHandler):
|
||||||
# Remove any spammy users from the results.
|
# Remove any spammy users from the results.
|
||||||
non_spammy_users = []
|
non_spammy_users = []
|
||||||
for user in results["results"]:
|
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)
|
non_spammy_users.append(user)
|
||||||
results["results"] = non_spammy_users
|
results["results"] = non_spammy_users
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ from twisted.internet.defer import Deferred
|
||||||
from twisted.internet.interfaces import IConsumer
|
from twisted.internet.interfaces import IConsumer
|
||||||
from twisted.protocols.basic import FileSender
|
from twisted.protocols.basic import FileSender
|
||||||
|
|
||||||
import synapse
|
|
||||||
from synapse.api.errors import NotFoundError
|
from synapse.api.errors import NotFoundError
|
||||||
from synapse.logging.context import defer_to_thread, make_deferred_yieldable
|
from synapse.logging.context import defer_to_thread, make_deferred_yieldable
|
||||||
from synapse.util import Clock
|
from synapse.util import Clock
|
||||||
|
@ -74,7 +73,7 @@ class MediaStorage:
|
||||||
self.local_media_directory = local_media_directory
|
self.local_media_directory = local_media_directory
|
||||||
self.filepaths = filepaths
|
self.filepaths = filepaths
|
||||||
self.storage_providers = storage_providers
|
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()
|
self.clock = hs.get_clock()
|
||||||
|
|
||||||
async def store_file(self, source: IO, file_info: FileInfo) -> str:
|
async def store_file(self, source: IO, file_info: FileInfo) -> str:
|
||||||
|
@ -145,10 +144,10 @@ class MediaStorage:
|
||||||
f.flush()
|
f.flush()
|
||||||
f.close()
|
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
|
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")
|
logger.info("Blocking media due to spam checker")
|
||||||
# Note that we'll delete the stored media, due to the
|
# Note that we'll delete the stored media, due to the
|
||||||
# try/except below. The media also won't be stored in
|
# try/except below. The media also won't be stored in
|
||||||
|
|
|
@ -44,20 +44,6 @@ from synapse.events.presence_router import (
|
||||||
GET_USERS_FOR_STATES_CALLBACK,
|
GET_USERS_FOR_STATES_CALLBACK,
|
||||||
PresenceRouter,
|
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 (
|
from synapse.events.third_party_rules import (
|
||||||
CHECK_CAN_DEACTIVATE_USER_CALLBACK,
|
CHECK_CAN_DEACTIVATE_USER_CALLBACK,
|
||||||
CHECK_CAN_SHUTDOWN_ROOM_CALLBACK,
|
CHECK_CAN_SHUTDOWN_ROOM_CALLBACK,
|
||||||
|
@ -105,6 +91,20 @@ from synapse.module_api.callbacks.account_validity_callbacks import (
|
||||||
ON_LEGACY_SEND_MAIL_CALLBACK,
|
ON_LEGACY_SEND_MAIL_CALLBACK,
|
||||||
ON_USER_REGISTRATION_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.rest.client.login import LoginResponse
|
||||||
from synapse.storage import DataStore
|
from synapse.storage import DataStore
|
||||||
from synapse.storage.background_updates import (
|
from synapse.storage.background_updates import (
|
||||||
|
@ -147,7 +147,7 @@ are loaded into Synapse.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
PRESENCE_ALL_USERS = PresenceRouter.ALL_USERS
|
PRESENCE_ALL_USERS = PresenceRouter.ALL_USERS
|
||||||
NOT_SPAM = SpamChecker.NOT_SPAM
|
NOT_SPAM = SpamCheckerModuleApiCallbacks.NOT_SPAM
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"errors",
|
"errors",
|
||||||
|
@ -271,7 +271,6 @@ class ModuleApi:
|
||||||
self._public_room_list_manager = PublicRoomListManager(hs)
|
self._public_room_list_manager = PublicRoomListManager(hs)
|
||||||
self._account_data_manager = AccountDataManager(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._third_party_event_rules = hs.get_third_party_event_rules()
|
||||||
self._password_auth_provider = hs.get_password_auth_provider()
|
self._password_auth_provider = hs.get_password_auth_provider()
|
||||||
self._presence_router = hs.get_presence_router()
|
self._presence_router = hs.get_presence_router()
|
||||||
|
@ -305,7 +304,7 @@ class ModuleApi:
|
||||||
|
|
||||||
Added in Synapse v1.37.0.
|
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,
|
check_event_for_spam=check_event_for_spam,
|
||||||
should_drop_federated_event=should_drop_federated_event,
|
should_drop_federated_event=should_drop_federated_event,
|
||||||
user_may_join_room=user_may_join_room,
|
user_may_join_room=user_may_join_room,
|
||||||
|
|
|
@ -12,11 +12,20 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from synapse.server import HomeServer
|
||||||
|
|
||||||
from synapse.module_api.callbacks.account_validity_callbacks import (
|
from synapse.module_api.callbacks.account_validity_callbacks import (
|
||||||
AccountValidityModuleApiCallbacks,
|
AccountValidityModuleApiCallbacks,
|
||||||
)
|
)
|
||||||
|
from synapse.module_api.callbacks.spamchecker_callbacks import (
|
||||||
|
SpamCheckerModuleApiCallbacks,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ModuleApiCallbacks:
|
class ModuleApiCallbacks:
|
||||||
def __init__(self) -> None:
|
def __init__(self, hs: "HomeServer") -> None:
|
||||||
self.account_validity = AccountValidityModuleApiCallbacks()
|
self.account_validity = AccountValidityModuleApiCallbacks()
|
||||||
|
self.spam_checker = SpamCheckerModuleApiCallbacks(hs)
|
||||||
|
|
|
@ -286,11 +286,10 @@ def load_legacy_spam_checkers(hs: "synapse.server.HomeServer") -> None:
|
||||||
api.register_spam_checker_callbacks(**hooks)
|
api.register_spam_checker_callbacks(**hooks)
|
||||||
|
|
||||||
|
|
||||||
class SpamChecker:
|
class SpamCheckerModuleApiCallbacks:
|
||||||
NOT_SPAM: Literal["NOT_SPAM"] = "NOT_SPAM"
|
NOT_SPAM: Literal["NOT_SPAM"] = "NOT_SPAM"
|
||||||
|
|
||||||
def __init__(self, hs: "synapse.server.HomeServer") -> None:
|
def __init__(self, hs: "synapse.server.HomeServer") -> None:
|
||||||
self.hs = hs
|
|
||||||
self.clock = hs.get_clock()
|
self.clock = hs.get_clock()
|
||||||
|
|
||||||
self._check_event_for_spam_callbacks: List[CHECK_EVENT_FOR_SPAM_CALLBACK] = []
|
self._check_event_for_spam_callbacks: List[CHECK_EVENT_FOR_SPAM_CALLBACK] = []
|
|
@ -42,7 +42,6 @@ from synapse.crypto.context_factory import RegularPolicyForHTTPS
|
||||||
from synapse.crypto.keyring import Keyring
|
from synapse.crypto.keyring import Keyring
|
||||||
from synapse.events.builder import EventBuilderFactory
|
from synapse.events.builder import EventBuilderFactory
|
||||||
from synapse.events.presence_router import PresenceRouter
|
from synapse.events.presence_router import PresenceRouter
|
||||||
from synapse.events.spamcheck import SpamChecker
|
|
||||||
from synapse.events.third_party_rules import ThirdPartyEventRules
|
from synapse.events.third_party_rules import ThirdPartyEventRules
|
||||||
from synapse.events.utils import EventClientSerializer
|
from synapse.events.utils import EventClientSerializer
|
||||||
from synapse.federation.federation_client import FederationClient
|
from synapse.federation.federation_client import FederationClient
|
||||||
|
@ -687,10 +686,6 @@ class HomeServer(metaclass=abc.ABCMeta):
|
||||||
def get_stats_handler(self) -> StatsHandler:
|
def get_stats_handler(self) -> StatsHandler:
|
||||||
return StatsHandler(self)
|
return StatsHandler(self)
|
||||||
|
|
||||||
@cache_in_self
|
|
||||||
def get_spam_checker(self) -> SpamChecker:
|
|
||||||
return SpamChecker(self)
|
|
||||||
|
|
||||||
@cache_in_self
|
@cache_in_self
|
||||||
def get_third_party_event_rules(self) -> ThirdPartyEventRules:
|
def get_third_party_event_rules(self) -> ThirdPartyEventRules:
|
||||||
return ThirdPartyEventRules(self)
|
return ThirdPartyEventRules(self)
|
||||||
|
@ -803,7 +798,7 @@ class HomeServer(metaclass=abc.ABCMeta):
|
||||||
|
|
||||||
@cache_in_self
|
@cache_in_self
|
||||||
def get_module_api_callbacks(self) -> ModuleApiCallbacks:
|
def get_module_api_callbacks(self) -> ModuleApiCallbacks:
|
||||||
return ModuleApiCallbacks()
|
return ModuleApiCallbacks(self)
|
||||||
|
|
||||||
@cache_in_self
|
@cache_in_self
|
||||||
def get_account_data_handler(self) -> AccountDataHandler:
|
def get_account_data_handler(self) -> AccountDataHandler:
|
||||||
|
|
|
@ -792,7 +792,7 @@ class UserDirectoryTestCase(unittest.HomeserverTestCase):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Configure a spam checker that does not filter any users.
|
# 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]
|
spam_checker._check_username_for_spam_callbacks = [allow_all]
|
||||||
|
|
||||||
# The results do not change:
|
# The results do not change:
|
||||||
|
|
|
@ -31,7 +31,6 @@ from twisted.test.proto_helpers import MemoryReactor
|
||||||
|
|
||||||
from synapse.api.errors import Codes
|
from synapse.api.errors import Codes
|
||||||
from synapse.events import EventBase
|
from synapse.events import EventBase
|
||||||
from synapse.events.spamcheck import load_legacy_spam_checkers
|
|
||||||
from synapse.http.types import QueryParams
|
from synapse.http.types import QueryParams
|
||||||
from synapse.logging.context import make_deferred_yieldable
|
from synapse.logging.context import make_deferred_yieldable
|
||||||
from synapse.media._base import FileInfo
|
from synapse.media._base import FileInfo
|
||||||
|
@ -39,6 +38,7 @@ from synapse.media.filepath import MediaFilePaths
|
||||||
from synapse.media.media_storage import MediaStorage, ReadableFileWrapper
|
from synapse.media.media_storage import MediaStorage, ReadableFileWrapper
|
||||||
from synapse.media.storage_provider import FileStorageProviderBackend
|
from synapse.media.storage_provider import FileStorageProviderBackend
|
||||||
from synapse.module_api import ModuleApi
|
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 import admin
|
||||||
from synapse.rest.client import login
|
from synapse.rest.client import login
|
||||||
from synapse.server import HomeServer
|
from synapse.server import HomeServer
|
||||||
|
|
|
@ -814,7 +814,9 @@ class RoomsCreateTestCase(RoomBase):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
join_mock = Mock(side_effect=user_may_join_room)
|
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(
|
channel = self.make_request(
|
||||||
"POST",
|
"POST",
|
||||||
|
@ -840,7 +842,9 @@ class RoomsCreateTestCase(RoomBase):
|
||||||
return Codes.CONSENT_NOT_GIVEN
|
return Codes.CONSENT_NOT_GIVEN
|
||||||
|
|
||||||
join_mock = Mock(side_effect=user_may_join_room_codes)
|
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(
|
channel = self.make_request(
|
||||||
"POST",
|
"POST",
|
||||||
|
@ -1162,7 +1166,9 @@ class RoomJoinTestCase(RoomBase):
|
||||||
# `spec` argument is needed for this function mock to have `__qualname__`, which
|
# `spec` argument is needed for this function mock to have `__qualname__`, which
|
||||||
# is needed for `Measure` metrics buried in SpamChecker.
|
# is needed for `Measure` metrics buried in SpamChecker.
|
||||||
callback_mock = Mock(side_effect=user_may_join_room, spec=lambda *x: None)
|
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.
|
# Join a first room, without being invited to it.
|
||||||
self.helper.join(self.room1, self.user2, tok=self.tok2)
|
self.helper.join(self.room1, self.user2, tok=self.tok2)
|
||||||
|
@ -1227,7 +1233,9 @@ class RoomJoinTestCase(RoomBase):
|
||||||
# `spec` argument is needed for this function mock to have `__qualname__`, which
|
# `spec` argument is needed for this function mock to have `__qualname__`, which
|
||||||
# is needed for `Measure` metrics buried in SpamChecker.
|
# is needed for `Measure` metrics buried in SpamChecker.
|
||||||
callback_mock = Mock(side_effect=user_may_join_room, spec=lambda *x: None)
|
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.
|
# Join a first room, without being invited to it.
|
||||||
self.helper.join(self.room1, self.user2, tok=self.tok2)
|
self.helper.join(self.room1, self.user2, tok=self.tok2)
|
||||||
|
@ -1643,7 +1651,7 @@ class RoomMessagesTestCase(RoomBase):
|
||||||
|
|
||||||
spam_checker = SpamCheck()
|
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
|
spam_checker.check_event_for_spam
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3381,7 +3389,9 @@ class ThreepidInviteTestCase(unittest.HomeserverTestCase):
|
||||||
# `spec` argument is needed for this function mock to have `__qualname__`, which
|
# `spec` argument is needed for this function mock to have `__qualname__`, which
|
||||||
# is needed for `Measure` metrics buried in SpamChecker.
|
# is needed for `Measure` metrics buried in SpamChecker.
|
||||||
mock = Mock(return_value=make_awaitable(True), spec=lambda *x: None)
|
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.
|
# Send a 3PID invite into the room and check that it succeeded.
|
||||||
email_to_invite = "teresa@example.com"
|
email_to_invite = "teresa@example.com"
|
||||||
|
@ -3446,7 +3456,9 @@ class ThreepidInviteTestCase(unittest.HomeserverTestCase):
|
||||||
return_value=make_awaitable(synapse.module_api.NOT_SPAM),
|
return_value=make_awaitable(synapse.module_api.NOT_SPAM),
|
||||||
spec=lambda *x: None,
|
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.
|
# Send a 3PID invite into the room and check that it succeeded.
|
||||||
email_to_invite = "teresa@example.com"
|
email_to_invite = "teresa@example.com"
|
||||||
|
|
|
@ -73,11 +73,11 @@ from twisted.web.server import Request, Site
|
||||||
from synapse.config.database import DatabaseConnectionConfig
|
from synapse.config.database import DatabaseConnectionConfig
|
||||||
from synapse.config.homeserver import HomeServerConfig
|
from synapse.config.homeserver import HomeServerConfig
|
||||||
from synapse.events.presence_router import load_legacy_presence_router
|
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.events.third_party_rules import load_legacy_third_party_event_rules
|
||||||
from synapse.handlers.auth import load_legacy_password_auth_providers
|
from synapse.handlers.auth import load_legacy_password_auth_providers
|
||||||
from synapse.http.site import SynapseRequest
|
from synapse.http.site import SynapseRequest
|
||||||
from synapse.logging.context import ContextResourceUsage
|
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.server import HomeServer
|
||||||
from synapse.storage import DataStore
|
from synapse.storage import DataStore
|
||||||
from synapse.storage.database import LoggingDatabaseConnection
|
from synapse.storage.database import LoggingDatabaseConnection
|
||||||
|
|
Loading…
Reference in New Issue