diff --git a/mautrix_telegram/__main__.py b/mautrix_telegram/__main__.py index 96baf513..9037736d 100644 --- a/mautrix_telegram/__main__.py +++ b/mautrix_telegram/__main__.py @@ -125,10 +125,10 @@ class TelegramBridge(Bridge): return Portal.get_by_mxid(room_id) async def get_puppet(self, user_id: UserID, create: bool = False) -> Puppet: - return Puppet.get_by_mxid(user_id, create=create) + return await Puppet.get_by_mxid(user_id, create=create) async def get_double_puppet(self, user_id: UserID) -> Puppet: - return Puppet.get_by_custom_mxid(user_id) + return await Puppet.get_by_custom_mxid(user_id) TelegramBridge().run() diff --git a/mautrix_telegram/abstract_user.py b/mautrix_telegram/abstract_user.py index d390c244..c1543a51 100644 --- a/mautrix_telegram/abstract_user.py +++ b/mautrix_telegram/abstract_user.py @@ -182,11 +182,11 @@ class AbstractUser(ABC): raise NotImplementedError() @abstractmethod - def register_portal(self, portal: po.Portal) -> None: + async def register_portal(self, portal: po.Portal) -> None: raise NotImplementedError() @abstractmethod - def unregister_portal(self, tgid: int, tg_receiver: int) -> None: + async def unregister_portal(self, tgid: int, tg_receiver: int) -> None: raise NotImplementedError() async def _update_catch(self, update: TypeUpdate) -> None: @@ -358,10 +358,10 @@ class AbstractUser(ABC): if isinstance(update, UpdateUserName): puppet.username = update.username if await puppet.update_displayname(self, update): - puppet.save() + await puppet.save() elif isinstance(update, UpdateUserPhoto): if await puppet.update_avatar(self, update.photo): - puppet.save() + await puppet.save() else: self.log.warning(f"Unexpected other user info update: {type(update)}") @@ -461,8 +461,8 @@ class AbstractUser(ABC): if isinstance(update.action, MessageActionChannelMigrateFrom): self.log.trace(f"Received %s in %s by %d, unregistering portal...", update.action, portal.tgid_log, sender.id) - self.unregister_portal(update.action.chat_id, update.action.chat_id) - self.register_portal(portal) + await self.unregister_portal(update.action.chat_id, update.action.chat_id) + await self.register_portal(portal) return self.log.trace("Handling action %s to %s by %d", update.action, portal.tgid_log, sender.id) diff --git a/mautrix_telegram/bot.py b/mautrix_telegram/bot.py index 9c4e447e..c618c409 100644 --- a/mautrix_telegram/bot.py +++ b/mautrix_telegram/bot.py @@ -117,10 +117,10 @@ class Bot(AbstractUser): except (ChannelPrivateError, ChannelInvalidError): self.remove_chat(TelegramID(channel_id.channel_id)) - def register_portal(self, portal: po.Portal) -> None: + async def register_portal(self, portal: po.Portal) -> None: self.add_chat(portal.tgid, portal.peer_type) - def unregister_portal(self, tgid: int, tg_receiver: int) -> None: + async def unregister_portal(self, tgid: int, tg_receiver: int) -> None: self.remove_chat(tgid) def add_chat(self, chat_id: TelegramID, chat_type: str) -> None: diff --git a/mautrix_telegram/commands/handler.py b/mautrix_telegram/commands/handler.py index 774bf456..569d2ca2 100644 --- a/mautrix_telegram/commands/handler.py +++ b/mautrix_telegram/commands/handler.py @@ -115,8 +115,7 @@ def command_handler(_func: Optional[CommandHandlerFunc] = None, *, needs_auth: b class CommandProcessor(BaseCommandProcessor): def __init__(self, context: c.Context) -> None: - super().__init__(az=context.az, config=context.config, event_class=CommandEvent, - loop=context.loop, bridge=context.bridge) + super().__init__(event_class=CommandEvent, bridge=context.bridge) self.tgbot = context.bot self.bridge = context.bridge self.az, self.config, self.loop, self.tgbot = context.core diff --git a/mautrix_telegram/commands/portal/admin.py b/mautrix_telegram/commands/portal/admin.py index 1f02abae..820f95b1 100644 --- a/mautrix_telegram/commands/portal/admin.py +++ b/mautrix_telegram/commands/portal/admin.py @@ -86,7 +86,7 @@ async def reload_user(evt: CommandEvent) -> EventID: user = u.User.get_by_mxid(mxid, create=False) if not user: return await evt.reply("User not found") - puppet = pu.Puppet.get_by_custom_mxid(mxid) + puppet = await pu.Puppet.get_by_custom_mxid(mxid) if puppet: puppet.sync_task.cancel() await user.stop() diff --git a/mautrix_telegram/commands/portal/bridge.py b/mautrix_telegram/commands/portal/bridge.py index 206f33b9..84cba621 100644 --- a/mautrix_telegram/commands/portal/bridge.py +++ b/mautrix_telegram/commands/portal/bridge.py @@ -177,7 +177,7 @@ async def confirm_bridge(evt: CommandEvent) -> Optional[EventID]: portal.mxid = bridge_to_mxid portal.title, portal.about, levels = await get_initial_state(evt.az.intent, evt.room_id) portal.photo_id = "" - portal.save() + await portal.save() asyncio.ensure_future(portal.update_matrix_room(user, entity, direct, levels=levels), loop=evt.loop) diff --git a/mautrix_telegram/commands/portal/config.py b/mautrix_telegram/commands/portal/config.py index dcda35ca..1e8e649e 100644 --- a/mautrix_telegram/commands/portal/config.py +++ b/mautrix_telegram/commands/portal/config.py @@ -63,7 +63,7 @@ async def config(evt: CommandEvent) -> None: await config_add_del(evt, portal, key, value, cmd) else: return - portal.save() + await portal.save() def config_help(evt: CommandEvent) -> Awaitable[EventID]: diff --git a/mautrix_telegram/config.py b/mautrix_telegram/config.py index ae88f04b..108dceb2 100644 --- a/mautrix_telegram/config.py +++ b/mautrix_telegram/config.py @@ -114,6 +114,9 @@ class Config(BaseBridgeConfig): copy("bridge.encryption.allow") copy("bridge.encryption.default") copy("bridge.encryption.database") + copy("bridge.encryption.key_sharing.allow") + copy("bridge.encryption.key_sharing.require_cross_signing") + copy("bridge.encryption.key_sharing.require_verification") copy("bridge.private_chat_portal_meta") copy("bridge.delivery_receipts") copy("bridge.delivery_error_reports") diff --git a/mautrix_telegram/example-config.yaml b/mautrix_telegram/example-config.yaml index 62e15718..578b853b 100644 --- a/mautrix_telegram/example-config.yaml +++ b/mautrix_telegram/example-config.yaml @@ -223,6 +223,18 @@ bridge: # Pickle: pickle:///filename.pickle # Postgres: postgres://username:password@hostname/dbname database: default + # Options for automatic key sharing. + key_sharing: + # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. + # You must use a client that supports requesting keys from other users to use this feature. + allow: false + # Require the requesting device to have a valid cross-signing signature? + # This doesn't require that the bridge has verified the device, only that the user has verified it. + # Not yet implemented. + require_cross_signing: false + # Require devices to be verified by the bridge? + # Verification by the bridge is not yet implemented. + require_verification: true # Whether or not to explicitly set the avatar and room name for private # chat portal rooms. This will be implicitly enabled if encryption.default is true. private_chat_portal_meta: false diff --git a/mautrix_telegram/formatter/from_matrix/parser.py b/mautrix_telegram/formatter/from_matrix/parser.py index fdcf5aac..cf672210 100644 --- a/mautrix_telegram/formatter/from_matrix/parser.py +++ b/mautrix_telegram/formatter/from_matrix/parser.py @@ -48,7 +48,7 @@ class MatrixParser(BaseMatrixParser[TelegramMessage]): @classmethod def user_pill_to_fstring(cls, msg: TelegramMessage, user_id: UserID) -> TelegramMessage: - user = (pu.Puppet.get_by_mxid(user_id) + user = (pu.Puppet.deprecated_sync_get_by_mxid(user_id) or u.User.get_by_mxid(user_id, create=False)) if not user: return msg diff --git a/mautrix_telegram/formatter/from_telegram.py b/mautrix_telegram/formatter/from_telegram.py index bd6bea0f..bae332e7 100644 --- a/mautrix_telegram/formatter/from_telegram.py +++ b/mautrix_telegram/formatter/from_telegram.py @@ -130,7 +130,7 @@ async def _add_reply_header(source: 'AbstractUser', content: TextMessageEventCon event: MessageEvent = await main_intent.get_event(msg.mx_room, msg.mxid) if isinstance(event.content, TextMessageEventContent): event.content.trim_reply_fallback() - puppet = pu.Puppet.get_by_mxid(event.sender, create=False) + puppet = await pu.Puppet.get_by_mxid(event.sender, create=False) content.set_reply(event, displayname=puppet.displayname if puppet else event.sender) except MatrixRequestError: log.exception("Failed to get event to add reply fallback") diff --git a/mautrix_telegram/matrix.py b/mautrix_telegram/matrix.py index db96dedb..f9558006 100644 --- a/mautrix_telegram/matrix.py +++ b/mautrix_telegram/matrix.py @@ -53,9 +53,7 @@ class MatrixHandler(BaseMatrixHandler): self.user_id_prefix = f"@{prefix}" self.user_id_suffix = f"{suffix}:{homeserver}" - super(MatrixHandler, self).__init__(context.az, context.config, loop=context.loop, - command_processor=com.CommandProcessor(context), - bridge=context.bridge) + super().__init__(command_processor=com.CommandProcessor(context), bridge=context.bridge) self.bot = context.bot self.previously_typing = {} @@ -107,8 +105,8 @@ class MatrixHandler(BaseMatrixHandler): e2be_ok = None if self.config["bridge.encryption.default"] and self.e2ee: e2be_ok = await portal.enable_dm_encryption() - portal.save() - inviter.register_portal(portal) + await portal.save() + await inviter.register_portal(portal) if e2be_ok is True: evt_type, content = await self.e2ee.encrypt( room_id, EventType.ROOM_MESSAGE, @@ -208,7 +206,7 @@ class MatrixHandler(BaseMatrixHandler): return await sender.ensure_started() - puppet = pu.Puppet.get_by_mxid(user_id) + puppet = await pu.Puppet.get_by_mxid(user_id) if puppet: if ban: await portal.ban_matrix(puppet, sender) @@ -375,7 +373,7 @@ class MatrixHandler(BaseMatrixHandler): if not isinstance(evt, (RedactionEvent, MessageEvent, StateEvent, EncryptedEvent)): return True if evt.content.get(self.az.real_user_content_key, False): - puppet = pu.Puppet.get_by_custom_mxid(evt.sender) + puppet = pu.Puppet.deprecated_sync_get_by_custom_mxid(evt.sender) if puppet: self.log.debug("Ignoring puppet-sent event %s", evt.event_id) return True @@ -412,11 +410,6 @@ class MatrixHandler(BaseMatrixHandler): elif evt.type == EventType.ROOM_TOMBSTONE: await self.handle_room_upgrade(evt.room_id, evt.sender, evt.content.replacement_room, evt.event_id) - elif evt.type == EventType.ROOM_ENCRYPTION: - portal = po.Portal.get_by_mxid(evt.room_id) - if portal: - portal.encrypted = True - portal.save() async def log_event_handle_duration(self, evt: Event, duration: float) -> None: if EVENT_TIME: diff --git a/mautrix_telegram/portal/base.py b/mautrix_telegram/portal/base.py index e94946a5..35421a8e 100644 --- a/mautrix_telegram/portal/base.py +++ b/mautrix_telegram/portal/base.py @@ -35,6 +35,7 @@ from mautrix.types import (RoomID, RoomAlias, UserID, EventID, EventType, Messag from mautrix.util.simple_template import SimpleTemplate from mautrix.util.simple_lock import SimpleLock from mautrix.util.logging import TraceLogger +from mautrix.bridge import BasePortal as MautrixBasePortal from ..types import TelegramID from ..context import Context @@ -57,7 +58,7 @@ InviteList = Union[UserID, List[UserID]] config: Optional['Config'] = None -class BasePortal(ABC): +class BasePortal(MautrixBasePortal, ABC): base_log: TraceLogger = logging.getLogger("mau.portal") az: AppService = None bot: 'Bot' = None @@ -129,7 +130,7 @@ class BasePortal(ABC): self.deleted = False self.log = self.base_log.getChild(self.tgid_log if self.tgid else self.mxid) self.backfill_lock = SimpleLock("Waiting for backfilling to finish before handling %s", - log=self.log, loop=self.loop) + log=self.log) self.backfill_leave = None self.dedup = PortalDedup(self) @@ -289,12 +290,13 @@ class BasePortal(ABC): @classmethod async def cleanup_room(cls, intent: IntentAPI, room_id: RoomID, message: str, puppets_only: bool = False) -> None: + # TODO use the cleanup_room from BasePortal instead of this try: members = await intent.get_room_members(room_id) except MatrixRequestError: members = [] for user in members: - puppet = p.Puppet.get_by_mxid(UserID(user), create=False) + puppet = await p.Puppet.get_by_mxid(UserID(user), create=False) if user != intent.mxid and (not puppets_only or puppet): try: if puppet: @@ -340,7 +342,7 @@ class BasePortal(ABC): config=json.dumps(self.local_config), avatar_url=self.avatar_url, encrypted=self.encrypted) - def save(self) -> None: + async def save(self) -> None: self.db_instance.edit(mxid=self.mxid, username=self.username, title=self.title, about=self.about, photo_id=self.photo_id, megagroup=self.megagroup, config=json.dumps(self.local_config), avatar_url=self.avatar_url, @@ -474,15 +476,6 @@ class BasePortal(ABC): type_name if create else None) # endregion - - async def _send_message(self, intent: IntentAPI, content: MessageEventContent, - event_type: EventType = EventType.ROOM_MESSAGE, **kwargs) -> EventID: - if self.encrypted and self.matrix.e2ee: - if intent.api.is_real_user: - content[intent.api.real_user_content_key] = True - event_type, content = await self.matrix.e2ee.encrypt(self.mxid, event_type, content) - return await intent.send_message_event(self.mxid, event_type, content, **kwargs) - # region Abstract methods (cross-called in matrix/metadata/telegram classes) @abstractmethod diff --git a/mautrix_telegram/portal/matrix.py b/mautrix_telegram/portal/matrix.py index bbc14d59..7cbea649 100644 --- a/mautrix_telegram/portal/matrix.py +++ b/mautrix_telegram/portal/matrix.py @@ -37,7 +37,6 @@ from telethon.tl.types import ( from mautrix.types import (EventID, RoomID, UserID, ContentURI, MessageType, MessageEventContent, TextMessageEventContent, MediaMessageEventContent, Format, LocationMessageEventContent) -from mautrix.bridge import BasePortal as MautrixBasePortal from ..types import TelegramID from ..db import Message as DBMessage @@ -61,7 +60,7 @@ TypeMessage = Union[Message, MessageService] config: Optional['Config'] = None -class PortalMatrix(BasePortal, MautrixBasePortal, ABC): +class PortalMatrix(BasePortal, ABC): async def _get_state_change_message(self, event: str, user: 'u.User', **kwargs: Any ) -> Optional[str]: tpl = self.get_config(f"state_event_formats.{event}") @@ -484,7 +483,7 @@ class PortalMatrix(BasePortal, MautrixBasePortal, ABC): peer = await self.get_input_entity(sender) await sender.client(EditChatAboutRequest(peer=peer, about=about)) self.about = about - self.save() + await self.save() await self._send_delivery_receipt(event_id) async def handle_matrix_title(self, sender: 'u.User', title: str, event_id: EventID) -> None: @@ -498,7 +497,7 @@ class PortalMatrix(BasePortal, MautrixBasePortal, ABC): response = await sender.client(EditTitleRequest(channel=channel, title=title)) self.dedup.register_outgoing_actions(response) self.title = title - self.save() + await self.save() await self._send_delivery_receipt(event_id) await self.update_bridge_info() @@ -530,7 +529,7 @@ class PortalMatrix(BasePortal, MautrixBasePortal, ABC): if is_photo_update: loc, size = self._get_largest_photo_size(update.message.action.photo) self.photo_id = f"{size.location.volume_id}-{size.location.local_id}" - self.save() + await self.save() break await self._send_delivery_receipt(event_id) await self.update_bridge_info() diff --git a/mautrix_telegram/portal/metadata.py b/mautrix_telegram/portal/metadata.py index 4a5ed114..fefceb33 100644 --- a/mautrix_telegram/portal/metadata.py +++ b/mautrix_telegram/portal/metadata.py @@ -114,7 +114,7 @@ class PortalMetadata(BasePortal, ABC): await source.client( UpdateUsernameRequest(await self.get_input_entity(source), username)) if await self._update_username(username): - self.save() + await self.save() async def create_telegram_chat(self, source: 'u.User', supergroup: bool = False) -> None: if not self.mxid: @@ -217,10 +217,10 @@ class PortalMetadata(BasePortal, ABC): changed = await self._update_title(puppet.displayname) changed = await self._update_avatar(user, entity.photo) or changed if changed: - self.save() + await self.save() await self.update_bridge_info() - puppet = p.Puppet.get_by_custom_mxid(user.mxid) + puppet = await p.Puppet.get_by_custom_mxid(user.mxid) if puppet: try: await puppet.intent.ensure_joined(self.mxid) @@ -352,7 +352,7 @@ class PortalMetadata(BasePortal, ABC): invites += extra_invites for invite in extra_invites: power_levels.users.setdefault(invite, 100) - self._participants_to_power_levels(participants, power_levels) + await self._participants_to_power_levels(participants, power_levels) elif self.bot and self.tg_receiver == self.bot.tgid: invites = config["bridge.relaybot.private_chat.invite"] for invite in invites: @@ -408,9 +408,9 @@ class PortalMetadata(BasePortal, ABC): self.mxid = room_id self.by_mxid[self.mxid] = self - self.save() + await self.save() await self.az.state_store.set_power_levels(self.mxid, power_levels) - user.register_portal(self) + await user.register_portal(self) update_room = self.loop.create_task(self.update_matrix_room( user, entity, direct, puppet, @@ -497,8 +497,8 @@ class PortalMetadata(BasePortal, ABC): return True return False - def _participants_to_power_levels(self, participants: List[TypeParticipant], - levels: PowerLevelStateEventContent) -> bool: + async def _participants_to_power_levels(self, participants: List[TypeParticipant], + levels: PowerLevelStateEventContent) -> bool: bot_level = levels.get_user_level(self.main_intent.mxid) if bot_level < levels.get_event_level(EventType.ROOM_POWER_LEVELS): return False @@ -514,7 +514,7 @@ class PortalMetadata(BasePortal, ABC): new_level = self._get_level_from_participant(participant) if user: - user.register_portal(self) + await user.register_portal(self) changed = self._participant_to_power_levels(levels, user, new_level, bot_level) or changed @@ -527,17 +527,17 @@ class PortalMetadata(BasePortal, ABC): levels: PowerLevelStateEventContent = None) -> None: if not levels: levels = await self.main_intent.get_power_levels(self.mxid) - if self._participants_to_power_levels(participants, levels): + if await self._participants_to_power_levels(participants, levels): await self.main_intent.set_power_levels(self.mxid, levels) - def _add_bot_chat(self, bot: User) -> None: + async def _add_bot_chat(self, bot: User) -> None: if self.bot and bot.id == self.bot.tgid: self.bot.add_chat(self.tgid, self.peer_type) return user = u.User.get_by_tgid(TelegramID(bot.id)) if user and user.is_bot: - user.register_portal(self) + await user.register_portal(self) async def _sync_telegram_users(self, source: 'AbstractUser', users: List[User]) -> None: allowed_tgids = set() @@ -547,7 +547,7 @@ class PortalMetadata(BasePortal, ABC): continue puppet = p.Puppet.get(TelegramID(entity.id)) if entity.bot: - self._add_bot_chat(entity) + await self._add_bot_chat(entity) allowed_tgids.add(entity.id) await puppet.intent_for(self).ensure_joined(self.mxid) await puppet.update_info(source, entity) @@ -556,7 +556,7 @@ class PortalMetadata(BasePortal, ABC): if user: await self.invite_to_matrix(user.mxid) - puppet = p.Puppet.get_by_custom_mxid(user.mxid) + puppet = await p.Puppet.get_by_custom_mxid(user.mxid) if puppet: try: await puppet.intent.ensure_joined(self.mxid) @@ -587,7 +587,7 @@ class PortalMetadata(BasePortal, ABC): continue mx_user = u.User.get_by_mxid(user_mxid, create=False) if mx_user and mx_user.is_bot and mx_user.tgid not in allowed_tgids: - mx_user.unregister_portal(*self.tgid_full) + await mx_user.unregister_portal(*self.tgid_full) if mx_user and not self.has_bot and mx_user.tgid not in allowed_tgids: try: @@ -607,7 +607,7 @@ class PortalMetadata(BasePortal, ABC): user = u.User.get_by_tgid(user_id) if user: - user.register_portal(self) + await user.register_portal(self) await self.invite_to_matrix(user.mxid) async def _delete_telegram_user(self, user_id: TelegramID, sender: p.Puppet) -> None: @@ -624,7 +624,7 @@ class PortalMetadata(BasePortal, ABC): else: await puppet.intent_for(self).leave_room(self.mxid) if user: - user.unregister_portal(*self.tgid_full) + await user.unregister_portal(*self.tgid_full) if sender.tgid != puppet.tgid: try: await sender.intent_for(self).kick_user(self.mxid, puppet.mxid) @@ -664,7 +664,7 @@ class PortalMetadata(BasePortal, ABC): self.log.exception(f"Failed to update info from source {user.tgid}") if changed: - self.save() + await self.save() await self.update_bridge_info() async def _update_username(self, username: str, save: bool = False) -> bool: @@ -682,7 +682,7 @@ class PortalMetadata(BasePortal, ABC): await self.main_intent.set_join_rule(self.mxid, "invite") if save: - self.save() + await self.save() return True async def _try_set_state(self, sender: Optional['p.Puppet'], evt_type: EventType, @@ -707,7 +707,7 @@ class PortalMetadata(BasePortal, ABC): await self._try_set_state(sender, EventType.ROOM_TOPIC, RoomTopicStateEventContent(topic=self.about)) if save: - self.save() + await self.save() return True async def _update_title(self, title: str, sender: Optional['p.Puppet'] = None, @@ -719,7 +719,7 @@ class PortalMetadata(BasePortal, ABC): await self._try_set_state(sender, EventType.ROOM_NAME, RoomNameStateEventContent(name=self.title)) if save: - self.save() + await self.save() return True async def _update_avatar(self, user: 'AbstractUser', photo: TypeChatPhoto, @@ -750,7 +750,7 @@ class PortalMetadata(BasePortal, ABC): self.photo_id = "" self.avatar_url = None if save: - self.save() + await self.save() return True file = await util.transfer_file_to_matrix(user.client, self.main_intent, loc) if file: @@ -759,7 +759,7 @@ class PortalMetadata(BasePortal, ABC): self.photo_id = photo_id self.avatar_url = file.mxc if save: - self.save() + await self.save() return True return False diff --git a/mautrix_telegram/puppet.py b/mautrix_telegram/puppet.py index 7aa8cdf6..e7c38789 100644 --- a/mautrix_telegram/puppet.py +++ b/mautrix_telegram/puppet.py @@ -24,7 +24,7 @@ from telethon.tl.types import (UserProfilePhoto, User, UpdateUserName, PeerUser, from mautrix.appservice import AppService, IntentAPI from mautrix.errors import MatrixRequestError -from mautrix.bridge import CustomPuppetMixin +from mautrix.bridge import BasePuppet from mautrix.types import UserID, SyncToken, RoomID from mautrix.util.simple_template import SimpleTemplate @@ -41,7 +41,7 @@ if TYPE_CHECKING: config: Optional['Config'] = None -class Puppet(CustomPuppetMixin): +class Puppet(BasePuppet): log: logging.Logger = logging.getLogger("mau.puppet") az: AppService mx: 'MatrixHandler' @@ -166,7 +166,7 @@ class Puppet(CustomPuppetMixin): def new_db_instance(self) -> DBPuppet: return DBPuppet(id=self.id, **self._fields) - def save(self) -> None: + async def save(self) -> None: self.db_instance.edit(**self._fields) @classmethod @@ -249,7 +249,7 @@ class Puppet(CustomPuppetMixin): self.is_bot = info.bot if changed: - self.save() + await self.save() async def update_displayname(self, source: 'AbstractUser', info: Union[User, UpdateUserName] ) -> bool: @@ -355,7 +355,7 @@ class Puppet(CustomPuppetMixin): return None @classmethod - def get_by_mxid(cls, mxid: UserID, create: bool = True) -> Optional['Puppet']: + def deprecated_sync_get_by_mxid(cls, mxid: UserID, create: bool = True) -> Optional['Puppet']: tgid = cls.get_id_from_mxid(mxid) if tgid: return cls.get(tgid, create) @@ -363,7 +363,11 @@ class Puppet(CustomPuppetMixin): return None @classmethod - def get_by_custom_mxid(cls, mxid: UserID) -> Optional['Puppet']: + async def get_by_mxid(cls, mxid: UserID, create: bool = True) -> Optional['Puppet']: + return cls.deprecated_sync_get_by_mxid(mxid, create) + + @classmethod + def deprecated_sync_get_by_custom_mxid(cls, mxid: UserID) -> Optional['Puppet']: if not mxid: raise ValueError("Matrix ID can't be empty") @@ -379,6 +383,10 @@ class Puppet(CustomPuppetMixin): return None + @classmethod + async def get_by_custom_mxid(cls, mxid: UserID) -> Optional['Puppet']: + return cls.deprecated_sync_get_by_custom_mxid(mxid) + @classmethod def all_with_custom_mxid(cls) -> Iterable['Puppet']: return (cls.by_custom_mxid[puppet.custom_mxid] diff --git a/mautrix_telegram/user.py b/mautrix_telegram/user.py index 81458355..00579ccf 100644 --- a/mautrix_telegram/user.py +++ b/mautrix_telegram/user.py @@ -152,7 +152,7 @@ class User(AbstractUser, BaseUser): return DBUser(mxid=self.mxid, tgid=self.tgid, tg_username=self.username, saved_contacts=self.saved_contacts, portals=self.db_portals) - def save(self, contacts: bool = False, portals: bool = False) -> None: + async def save(self, contacts: bool = False, portals: bool = False) -> None: self.db_instance.edit(tgid=self.tgid, tg_username=self.username, tg_phone=self.phone, saved_contacts=self.saved_contacts) if contacts: @@ -242,7 +242,7 @@ class User(AbstractUser, BaseUser): return False if portal: - self.register_portal(portal) + await self.register_portal(portal) return False # Don't bother handling the update @@ -271,7 +271,7 @@ class User(AbstractUser, BaseUser): self.tgid = TelegramID(info.id) self.by_tgid[self.tgid] = self if changed: - self.save() + await self.save() async def log_out(self) -> bool: puppet = pu.Puppet.get(self.tgid) @@ -287,14 +287,14 @@ class User(AbstractUser, BaseUser): pass self.portals = {} self.contacts = [] - self.save(portals=True, contacts=True) + await self.save(portals=True, contacts=True) if self.tgid: try: del self.by_tgid[self.tgid] except KeyError: pass self.tgid = None - self.save() + await self.save() ok = await self.client.log_out() if not ok: return False @@ -367,11 +367,11 @@ class User(AbstractUser, BaseUser): create_task = portal.create_matrix_room(self, entity, invites=[self.mxid]) creators.append(self.loop.create_task(create_task)) index += 1 - self.save(portals=True) + await self.save(portals=True) await asyncio.gather(*creators) self.log.debug("Dialog syncing complete") - def register_portal(self, portal: po.Portal) -> None: + async def register_portal(self, portal: po.Portal) -> None: self.log.trace(f"Registering portal {portal.tgid_full}") try: if self.portals[portal.tgid_full] == portal: @@ -379,13 +379,13 @@ class User(AbstractUser, BaseUser): except KeyError: pass self.portals[portal.tgid_full] = portal - self.save(portals=True) + await self.save(portals=True) - def unregister_portal(self, tgid: int, tg_receiver: int) -> None: + async def unregister_portal(self, tgid: int, tg_receiver: int) -> None: self.log.trace(f"Unregistering portal {(tgid, tg_receiver)}") try: del self.portals[(tgid, tg_receiver)] - self.save(portals=True) + await self.save(portals=True) except KeyError: pass @@ -410,7 +410,7 @@ class User(AbstractUser, BaseUser): puppet = pu.Puppet.get(user.id) await puppet.update_info(self, user) self.contacts.append(puppet) - self.save(contacts=True) + await self.save(contacts=True) # endregion # region Class instance lookup diff --git a/mautrix_telegram/util/file_transfer.py b/mautrix_telegram/util/file_transfer.py index 3383c68f..441f3063 100644 --- a/mautrix_telegram/util/file_transfer.py +++ b/mautrix_telegram/util/file_transfer.py @@ -136,8 +136,7 @@ async def transfer_thumbnail_to_matrix(client: MautrixTelegramClient, intent: In decryption_info = None upload_mime_type = mime_type if encrypt: - file, decryption_info_dict = encrypt_attachment(file) - decryption_info = EncryptedFile.deserialize(decryption_info_dict) + file, decryption_info = encrypt_attachment(file) upload_mime_type = "application/octet-stream" content_uri = await intent.upload_media(file, upload_mime_type) if decryption_info: @@ -232,8 +231,7 @@ async def _unlocked_transfer_file_to_matrix(client: MautrixTelegramClient, inten decryption_info = None upload_mime_type = mime_type if encrypt and encrypt_attachment: - file, decryption_info_dict = encrypt_attachment(file) - decryption_info = EncryptedFile.deserialize(decryption_info_dict) + file, decryption_info = encrypt_attachment(file) upload_mime_type = "application/octet-stream" content_uri = await intent.upload_media(file, upload_mime_type) if decryption_info: diff --git a/mautrix_telegram/web/provisioning/__init__.py b/mautrix_telegram/web/provisioning/__init__.py index cc186f85..82a56755 100644 --- a/mautrix_telegram/web/provisioning/__init__.py +++ b/mautrix_telegram/web/provisioning/__init__.py @@ -183,7 +183,7 @@ class ProvisioningAPI(AuthAPI): portal.mxid = room_id portal.title, portal.about, levels = await get_initial_state(self.az.intent, room_id) portal.photo_id = "" - portal.save() + await portal.save() asyncio.ensure_future(portal.update_matrix_room(user, entity, direct, levels=levels), loop=self.loop) diff --git a/requirements.txt b/requirements.txt index f2ff6bbd..b1bbd1f3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,6 @@ ruamel.yaml>=0.15.35,<0.17 python-magic>=0.4,<0.5 commonmark>=0.8,<0.10 aiohttp>=3,<4 -mautrix>=0.6,<0.7 +mautrix==0.7.0rc1 telethon>=1.16,<1.17 telethon-session-sqlalchemy>=0.2.14,<0.3