diff --git a/synapse/module_api/__init__.py b/synapse/module_api/__init__.py
index f6bfd93d3c..e22d6f3ab7 100644
--- a/synapse/module_api/__init__.py
+++ b/synapse/module_api/__init__.py
@@ -18,7 +18,6 @@
# [This file includes modifications made by New Vector Limited]
#
#
-import email.utils
import logging
from typing import (
TYPE_CHECKING,
@@ -45,6 +44,7 @@ from twisted.internet.interfaces import IDelayedCall
from twisted.web.resource import Resource
from synapse.api import errors
+from synapse.api.constants import ProfileFields
from synapse.api.errors import SynapseError
from synapse.api.presence import UserPresenceState
from synapse.config import ConfigError
@@ -89,6 +89,14 @@ from synapse.module_api.callbacks.account_validity_callbacks import (
ON_USER_LOGIN_CALLBACK,
ON_USER_REGISTRATION_CALLBACK,
)
+from synapse.module_api.callbacks.media_repository_callbacks import (
+ GET_MEDIA_CONFIG_FOR_USER_CALLBACK,
+ IS_USER_ALLOWED_TO_UPLOAD_MEDIA_OF_SIZE_CALLBACK,
+)
+from synapse.module_api.callbacks.ratelimit_callbacks import (
+ GET_RATELIMIT_OVERRIDE_FOR_USER_CALLBACK,
+ RatelimitOverride,
+)
from synapse.module_api.callbacks.spamchecker_callbacks import (
CHECK_EVENT_FOR_SPAM_CALLBACK,
CHECK_LOGIN_FOR_SPAM_CALLBACK,
@@ -101,21 +109,17 @@ from synapse.module_api.callbacks.spamchecker_callbacks import (
USER_MAY_INVITE_CALLBACK,
USER_MAY_JOIN_ROOM_CALLBACK,
USER_MAY_PUBLISH_ROOM_CALLBACK,
- USER_MAY_SEND_3PID_INVITE_CALLBACK,
+ USER_MAY_SEND_STATE_EVENT_CALLBACK,
SpamCheckerModuleApiCallbacks,
)
from synapse.module_api.callbacks.third_party_event_rules_callbacks import (
CHECK_CAN_DEACTIVATE_USER_CALLBACK,
CHECK_CAN_SHUTDOWN_ROOM_CALLBACK,
CHECK_EVENT_ALLOWED_CALLBACK,
- CHECK_THREEPID_CAN_BE_INVITED_CALLBACK,
CHECK_VISIBILITY_CAN_BE_MODIFIED_CALLBACK,
- ON_ADD_USER_THIRD_PARTY_IDENTIFIER_CALLBACK,
ON_CREATE_ROOM_CALLBACK,
ON_NEW_EVENT_CALLBACK,
ON_PROFILE_UPDATE_CALLBACK,
- ON_REMOVE_USER_THIRD_PARTY_IDENTIFIER_CALLBACK,
- ON_THREEPID_BIND_CALLBACK,
ON_USER_DEACTIVATION_STATUS_CHANGED_CALLBACK,
)
from synapse.push.httppusher import HttpPusher
@@ -188,6 +192,7 @@ __all__ = [
"ProfileInfo",
"RoomAlias",
"UserProfile",
+ "RatelimitOverride",
]
logger = logging.getLogger(__name__)
@@ -260,7 +265,6 @@ class ModuleApi:
self._state = hs.get_state_handler()
self._clock: Clock = hs.get_clock()
self._registration_handler = hs.get_registration_handler()
- self._send_email_handler = hs.get_send_email_handler()
self._push_rules_handler = hs.get_push_rules_handler()
self._pusherpool = hs.get_pusherpool()
self._device_handler = hs.get_device_handler()
@@ -269,20 +273,6 @@ class ModuleApi:
self.msc3861_oauth_delegation_enabled = hs.config.experimental.msc3861.enabled
self._event_serializer = hs.get_event_client_serializer()
- try:
- app_name = self._hs.config.email.email_app_name
-
- self._from_string = self._hs.config.email.email_notif_from % {
- "app": app_name
- }
- except (KeyError, TypeError):
- # If substitution failed (which can happen if the string contains
- # placeholders other than just "app", or if the type of the placeholder is
- # not a string), fall back to the bare strings.
- self._from_string = self._hs.config.email.email_notif_from
-
- self._raw_from = email.utils.parseaddr(self._from_string)[1]
-
# We expose these as properties below in order to attach a helpful docstring.
self._http_client: SimpleHttpClient = hs.get_simple_http_client()
self._public_room_list_manager = PublicRoomListManager(hs)
@@ -304,12 +294,12 @@ class ModuleApi:
] = None,
user_may_join_room: Optional[USER_MAY_JOIN_ROOM_CALLBACK] = None,
user_may_invite: Optional[USER_MAY_INVITE_CALLBACK] = None,
- user_may_send_3pid_invite: Optional[USER_MAY_SEND_3PID_INVITE_CALLBACK] = None,
user_may_create_room: Optional[USER_MAY_CREATE_ROOM_CALLBACK] = None,
user_may_create_room_alias: Optional[
USER_MAY_CREATE_ROOM_ALIAS_CALLBACK
] = None,
user_may_publish_room: Optional[USER_MAY_PUBLISH_ROOM_CALLBACK] = None,
+ user_may_send_state_event: Optional[USER_MAY_SEND_STATE_EVENT_CALLBACK] = None,
check_username_for_spam: Optional[CHECK_USERNAME_FOR_SPAM_CALLBACK] = None,
check_registration_for_spam: Optional[
CHECK_REGISTRATION_FOR_SPAM_CALLBACK
@@ -326,7 +316,6 @@ class ModuleApi:
should_drop_federated_event=should_drop_federated_event,
user_may_join_room=user_may_join_room,
user_may_invite=user_may_invite,
- user_may_send_3pid_invite=user_may_send_3pid_invite,
user_may_create_room=user_may_create_room,
user_may_create_room_alias=user_may_create_room_alias,
user_may_publish_room=user_may_publish_room,
@@ -334,6 +323,7 @@ class ModuleApi:
check_registration_for_spam=check_registration_for_spam,
check_media_file_for_spam=check_media_file_for_spam,
check_login_for_spam=check_login_for_spam,
+ user_may_send_state_event=user_may_send_state_event,
)
def register_account_validity_callbacks(
@@ -359,14 +349,41 @@ class ModuleApi:
on_legacy_admin_request=on_legacy_admin_request,
)
+ def register_ratelimit_callbacks(
+ self,
+ *,
+ get_ratelimit_override_for_user: Optional[
+ GET_RATELIMIT_OVERRIDE_FOR_USER_CALLBACK
+ ] = None,
+ ) -> None:
+ """Registers callbacks for ratelimit capabilities.
+ Added in Synapse v1.132.0.
+ """
+ return self._callbacks.ratelimit.register_callbacks(
+ get_ratelimit_override_for_user=get_ratelimit_override_for_user,
+ )
+
+ def register_media_repository_callbacks(
+ self,
+ *,
+ get_media_config_for_user: Optional[GET_MEDIA_CONFIG_FOR_USER_CALLBACK] = None,
+ is_user_allowed_to_upload_media_of_size: Optional[
+ IS_USER_ALLOWED_TO_UPLOAD_MEDIA_OF_SIZE_CALLBACK
+ ] = None,
+ ) -> None:
+ """Registers callbacks for media repository capabilities.
+ Added in Synapse v1.132.0.
+ """
+ return self._callbacks.media_repository.register_callbacks(
+ get_media_config_for_user=get_media_config_for_user,
+ is_user_allowed_to_upload_media_of_size=is_user_allowed_to_upload_media_of_size,
+ )
+
def register_third_party_rules_callbacks(
self,
*,
check_event_allowed: Optional[CHECK_EVENT_ALLOWED_CALLBACK] = None,
on_create_room: Optional[ON_CREATE_ROOM_CALLBACK] = None,
- check_threepid_can_be_invited: Optional[
- CHECK_THREEPID_CAN_BE_INVITED_CALLBACK
- ] = None,
check_visibility_can_be_modified: Optional[
CHECK_VISIBILITY_CAN_BE_MODIFIED_CALLBACK
] = None,
@@ -377,13 +394,6 @@ class ModuleApi:
on_user_deactivation_status_changed: Optional[
ON_USER_DEACTIVATION_STATUS_CHANGED_CALLBACK
] = None,
- on_threepid_bind: Optional[ON_THREEPID_BIND_CALLBACK] = None,
- on_add_user_third_party_identifier: Optional[
- ON_ADD_USER_THIRD_PARTY_IDENTIFIER_CALLBACK
- ] = None,
- on_remove_user_third_party_identifier: Optional[
- ON_REMOVE_USER_THIRD_PARTY_IDENTIFIER_CALLBACK
- ] = None,
) -> None:
"""Registers callbacks for third party event rules capabilities.
@@ -392,16 +402,12 @@ class ModuleApi:
return self._callbacks.third_party_event_rules.register_third_party_rules_callbacks(
check_event_allowed=check_event_allowed,
on_create_room=on_create_room,
- check_threepid_can_be_invited=check_threepid_can_be_invited,
check_visibility_can_be_modified=check_visibility_can_be_modified,
on_new_event=on_new_event,
check_can_shutdown_room=check_can_shutdown_room,
check_can_deactivate_user=check_can_deactivate_user,
on_profile_update=on_profile_update,
on_user_deactivation_status_changed=on_user_deactivation_status_changed,
- on_threepid_bind=on_threepid_bind,
- on_add_user_third_party_identifier=on_add_user_third_party_identifier,
- on_remove_user_third_party_identifier=on_remove_user_third_party_identifier,
)
def register_presence_router_callbacks(
@@ -561,14 +567,6 @@ class ModuleApi:
return self._hs.config.server.public_baseurl
@property
- def email_app_name(self) -> str:
- """The application name configured in the homeserver's configuration.
-
- Added in Synapse v1.39.0.
- """
- return self._hs.config.email.email_app_name
-
- @property
def server_name(self) -> str:
"""The server name for the local homeserver.
@@ -695,23 +693,6 @@ class ModuleApi:
user_id = UserID.from_string(f"@{localpart}:{server_name}")
return await self._store.get_profileinfo(user_id)
- async def get_threepids_for_user(self, user_id: str) -> List[Dict[str, str]]:
- """Look up the threepids (email addresses and phone numbers) associated with the
- given Matrix user ID.
-
- Added in Synapse v1.39.0.
-
- Args:
- user_id: The Matrix user ID to look up threepids for.
-
- Returns:
- A list of threepids, each threepid being represented by a dictionary
- containing a "medium" key which value is "email" for email addresses and
- "msisdn" for phone numbers, and an "address" key which value is the
- threepid's address.
- """
- return [attr.asdict(t) for t in await self._store.user_get_threepids(user_id)]
-
def check_user_exists(self, user_id: str) -> "defer.Deferred[Optional[str]]":
"""Check if user exists.
@@ -893,9 +874,9 @@ class ModuleApi:
Raises:
synapse.api.errors.AuthError: the access token is invalid
"""
- assert isinstance(
- self._device_handler, DeviceHandler
- ), "invalidate_access_token can only be called on the main process"
+ assert isinstance(self._device_handler, DeviceHandler), (
+ "invalidate_access_token can only be called on the main process"
+ )
# see if the access token corresponds to a device
user_info = yield defer.ensureDeferred(
@@ -1086,7 +1067,10 @@ class ModuleApi:
content = {}
# Set the profile if not already done by the module.
- if "avatar_url" not in content or "displayname" not in content:
+ if (
+ ProfileFields.AVATAR_URL not in content
+ or ProfileFields.DISPLAYNAME not in content
+ ):
try:
# Try to fetch the user's profile.
profile = await self._hs.get_profile_handler().get_profile(
@@ -1095,8 +1079,8 @@ class ModuleApi:
except SynapseError as e:
# If the profile couldn't be found, use default values.
profile = {
- "displayname": target_user_id.localpart,
- "avatar_url": None,
+ ProfileFields.DISPLAYNAME: target_user_id.localpart,
+ ProfileFields.AVATAR_URL: None,
}
if e.code != 404:
@@ -1109,11 +1093,9 @@ class ModuleApi:
)
# Set the profile where it needs to be set.
- if "avatar_url" not in content:
- content["avatar_url"] = profile["avatar_url"]
-
- if "displayname" not in content:
- content["displayname"] = profile["displayname"]
+ for field_name in [ProfileFields.AVATAR_URL, ProfileFields.DISPLAYNAME]:
+ if field_name not in content and field_name in profile:
+ content[field_name] = profile[field_name]
event_id, _ = await self._hs.get_room_member_handler().update_membership(
requester=requester,
@@ -1398,31 +1380,6 @@ class ModuleApi:
status[p.device_id] = sent
return status
- async def send_mail(
- self,
- recipient: str,
- subject: str,
- html: str,
- text: str,
- ) -> None:
- """Send an email on behalf of the homeserver.
-
- Added in Synapse v1.39.0.
-
- Args:
- recipient: The email address for the recipient.
- subject: The email's subject.
- html: The email's HTML content.
- text: The email's text content.
- """
- await self._send_email_handler.send_email(
- email_address=recipient,
- subject=subject,
- app_name=self.email_app_name,
- html=html,
- text=text,
- )
-
def read_templates(
self,
filenames: List[str],
@@ -1584,30 +1541,6 @@ class ModuleApi:
"""
await self._registration_handler.check_username(username)
- async def store_remote_3pid_association(
- self, user_id: str, medium: str, address: str, id_server: str
- ) -> None:
- """Stores an existing association between a user ID and a third-party identifier.
-
- The association must already exist on the remote identity server.
-
- Added in Synapse v1.56.0.
-
- Args:
- user_id: The user ID that's been associated with the 3PID.
- medium: The medium of the 3PID (current supported values are "msisdn" and
- "email").
- address: The address of the 3PID.
- id_server: The identity server the 3PID association has been registered on.
- This should only be the domain (or IP address, optionally with the port
- number) for the identity server. This will be used to reach out to the
- identity server using HTTPS (unless specified otherwise by Synapse's
- configuration) when attempting to unbind the third-party identifier.
-
-
- """
- await self._store.add_user_bound_threepid(user_id, medium, address, id_server)
-
def check_push_rule_actions(
self, actions: List[Union[str, Dict[str, str]]]
) -> None:
@@ -1844,6 +1777,10 @@ class ModuleApi:
deactivation=deactivation,
)
+ def get_current_time_msec(self) -> int:
+ """Returns the current server time in milliseconds."""
+ return self._clock.time_msec()
+
class PublicRoomListManager:
"""Contains methods for adding to, removing from and querying whether a room
|