diff --git a/mautrix_telegram/abstract_user.py b/mautrix_telegram/abstract_user.py index 56f47f69..db06ba99 100644 --- a/mautrix_telegram/abstract_user.py +++ b/mautrix_telegram/abstract_user.py @@ -44,7 +44,7 @@ class AbstractUser: self.mxid = None self.is_relaybot = False - async def _init_client(self): + def _init_client(self): self.log.debug(f"Initializing client for {self.name}") device = f"{platform.system()} {platform.release()}" sysversion = MautrixTelegramClient.__version__ @@ -57,7 +57,7 @@ class AbstractUser: system_version=sysversion, device_model=device, report_errors=False) - await self.client.add_event_handler(self._update_catch) + self.client.add_event_handler(self._update_catch) async def update(self, update): return False @@ -83,17 +83,15 @@ class AbstractUser: def name(self): raise NotImplementedError() - @property - def logged_in(self): - return self.client and self.client.is_user_authorized() + async def is_logged_in(self): + return self.client and await self.client.is_user_authorized() - @property - def has_full_access(self): - return self.logged_in and self.whitelisted + async def has_full_access(self): + return await self.is_logged_in() and self.whitelisted async def start(self): if not self.client: - await self._init_client() + self._init_client() self.connected = await self.client.connect() async def ensure_started(self, even_if_no_session=False): diff --git a/mautrix_telegram/bot.py b/mautrix_telegram/bot.py index 878062db..505d7562 100644 --- a/mautrix_telegram/bot.py +++ b/mautrix_telegram/bot.py @@ -60,7 +60,7 @@ class Bot(AbstractUser): async def start(self): await super().start() - if not self.logged_in: + if not await self.is_logged_in(): await self.client.sign_in(bot_token=self.token) await self.post_login() return self @@ -168,7 +168,7 @@ class Bot(AbstractUser): user = await u.User.get_by_mxid(mxid).ensure_started() if not user.relaybot_whitelisted: return await reply("That user is not whitelisted to use the bridge.") - elif user.logged_in: + elif await user.is_logged_in(): displayname = f"@{user.username}" if user.username else user.displayname return await reply("That user seems to be logged in. " f"Just invite [{displayname}](tg://user?id={user.tgid})") diff --git a/mautrix_telegram/commands/auth.py b/mautrix_telegram/commands/auth.py index 1ff1b8d4..d4fad0ee 100644 --- a/mautrix_telegram/commands/auth.py +++ b/mautrix_telegram/commands/auth.py @@ -25,9 +25,7 @@ from ..util import format_duration @command_handler(needs_auth=False) async def ping(evt): - if not evt.sender.logged_in: - return await evt.reply("You're not logged in.") - me = await evt.sender.client.get_me() + me = await evt.sender.client.get_me() if await evt.sender.is_logged_in() else None if me: return await evt.reply(f"You're logged in as @{me.username}") else: @@ -53,7 +51,7 @@ def register(evt): @command_handler(needs_auth=False, management_only=True) async def register(evt): - if evt.sender.logged_in: + if await evt.sender.is_logged_in(): return await evt.reply("You are already logged in.") elif len(evt.args) < 1: return await evt.reply("**Usage:** `$cmdprefix+sp register `") @@ -99,7 +97,7 @@ async def enter_code_register(evt): @command_handler(needs_auth=False, management_only=True) async def login(evt): - if evt.sender.logged_in: + if await evt.sender.is_logged_in(): return await evt.reply("You are already logged in.") allow_matrix_login = evt.config.get("bridge.allow_matrix_login", True) @@ -225,7 +223,7 @@ async def enter_password(evt): @command_handler(needs_auth=False) async def logout(evt): - if not evt.sender.logged_in: + if not await evt.sender.is_logged_in(): return await evt.reply("You're not logged in.") if await evt.sender.log_out(): return await evt.reply("Logged out successfully.") diff --git a/mautrix_telegram/commands/handler.py b/mautrix_telegram/commands/handler.py index 6e8f9335..bca3b55b 100644 --- a/mautrix_telegram/commands/handler.py +++ b/mautrix_telegram/commands/handler.py @@ -26,15 +26,15 @@ command_handlers = {} def command_handler(needs_auth=True, management_only=False, needs_admin=False, name=None): def decorator(func): - def wrapper(evt): + async def wrapper(evt): if management_only and not evt.is_management: - return evt.reply(f"`{evt.command}` is a restricted command:" - "you may only run it in management rooms.") - elif needs_auth and not evt.sender.logged_in: - return evt.reply("This command requires you to be logged in.") + return await evt.reply(f"`{evt.command}` is a restricted command:" + "you may only run it in management rooms.") + elif needs_auth and not await evt.sender.is_logged_in(): + return await evt.reply("This command requires you to be logged in.") elif needs_admin and not evt.sender.is_admin: - return evt.reply("This is command requires administrator privileges.") - return func(evt) + return await evt.reply("This is command requires administrator privileges.") + return await func(evt) command_handlers[name or func.__name__.replace("_", "-")] = wrapper return wrapper diff --git a/mautrix_telegram/commands/portal.py b/mautrix_telegram/commands/portal.py index ce60def9..780c9a29 100644 --- a/mautrix_telegram/commands/portal.py +++ b/mautrix_telegram/commands/portal.py @@ -252,19 +252,20 @@ async def confirm_bridge(evt: CommandEvent): return await evt.reply("Please use `$cmdprefix+sp continue` to confirm the bridging or " "`$cmdprefix+sp cancel` to cancel.") - user = evt.sender if evt.sender.logged_in else evt.tgbot + is_logged_in = await evt.sender.is_logged_in() + user = evt.sender if is_logged_in else evt.tgbot try: entity = await user.client.get_entity(portal.peer) except Exception: evt.log.exception("Failed to get_entity(%s) for manual bridging.", portal.peer) - if evt.sender.logged_in: + if is_logged_in: return await evt.reply("Failed to get info of telegram chat. " "You are logged in, are you in that chat?") else: return await evt.reply("Failed to get info of telegram chat. " "You're not logged in, is the relay bot in the chat?") if isinstance(entity, (ChatForbidden, ChannelForbidden)): - if evt.sender.logged_in: + if is_logged_in: return await evt.reply("You don't seem to be in that chat.") else: return await evt.reply("The bot doesn't seem to be in that chat.") diff --git a/mautrix_telegram/matrix.py b/mautrix_telegram/matrix.py index 1f122f7d..d65dbde2 100644 --- a/mautrix_telegram/matrix.py +++ b/mautrix_telegram/matrix.py @@ -39,7 +39,7 @@ class MatrixHandler: async def handle_puppet_invite(self, room, puppet, inviter): self.log.debug(f"{inviter} invited puppet for {puppet.tgid} to {room}") - if not inviter.logged_in: + if not await inviter.is_logged_in(): await puppet.intent.error_and_leave( room, text="Please log in before inviting Telegram puppets.") return @@ -113,7 +113,7 @@ class MatrixHandler: return await user.ensure_started() portal = Portal.get_by_mxid(room) - if user and user.has_full_access and portal: + if user and await user.has_full_access() and portal: await portal.invite_telegram(inviter, user) return @@ -130,14 +130,14 @@ class MatrixHandler: await portal.main_intent.kick(room, user.mxid, "You are not whitelisted on this Telegram bridge.") return - elif not user.logged_in and not portal.has_bot: + elif not await user.is_logged_in() and not portal.has_bot: await portal.main_intent.kick(room, user.mxid, "This chat does not have a bot relaying " "messages for unauthenticated users.") return self.log.debug(f"{user} joined {room}") - if user.logged_in or portal.has_bot: + if await user.is_logged_in() or portal.has_bot: await portal.join_matrix(user, event_id) async def handle_part(self, room, user, sender, event_id): @@ -160,7 +160,7 @@ class MatrixHandler: if not user: return await user.ensure_started() - if user.logged_in or portal.has_bot: + if await user.is_logged_in() or portal.has_bot: await portal.leave_matrix(user, sender, event_id) def is_command(self, message): @@ -180,7 +180,7 @@ class MatrixHandler: return portal = Portal.get_by_mxid(room) - if not is_command and portal and (sender.logged_in or portal.has_bot): + if not is_command and portal and (await sender.is_logged_in() or portal.has_bot): await portal.handle_matrix_message(sender, message, event_id) return @@ -218,13 +218,13 @@ class MatrixHandler: async def handle_power_levels(self, room, sender, new, old): portal = Portal.get_by_mxid(room) sender = await User.get_by_mxid(sender).ensure_started() - if sender.has_full_access and portal: + if await sender.has_full_access() and portal: await portal.handle_matrix_power_levels(sender, new["users"], old["users"]) async def handle_room_meta(self, type, room, sender, content): portal = Portal.get_by_mxid(room) sender = await User.get_by_mxid(sender).ensure_started() - if sender.has_full_access and portal: + if await sender.has_full_access() and portal: handler, content_key = { "m.room.name": (portal.handle_matrix_title, "name"), "m.room.topic": (portal.handle_matrix_about, "topic"), @@ -237,7 +237,7 @@ class MatrixHandler: async def handle_room_pin(self, room, sender, new_events, old_events): portal = Portal.get_by_mxid(room) sender = await User.get_by_mxid(sender).ensure_started() - if sender.has_full_access and portal: + if await sender.has_full_access() and portal: events = new_events - old_events if len(events) > 0: # New event pinned, set that as pinned in Telegram. diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index f4baa737..cbd124a3 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -560,7 +560,7 @@ class Portal: if p.Puppet.get_id_from_mxid(member) or member == self.main_intent.mxid: continue user = await u.User.get_by_mxid(member).ensure_started() - if (has_bot and user.relaybot_whitelisted) or user.has_full_access: + if (has_bot and user.relaybot_whitelisted) or await user.has_full_access(): authenticated.append(user) return authenticated @@ -607,7 +607,7 @@ class Portal: return "" async def leave_matrix(self, user, source, event_id): - if not user.logged_in: + if not await user.is_logged_in(): async with self.require_send_lock(self.bot.tgid): response = await self.bot.client.send_message( self.peer, f"__{user.displayname} left the room.__", markdown=True) @@ -639,7 +639,7 @@ class Portal: await user.client(LeaveChannelRequest(channel=channel)) async def join_matrix(self, user, event_id): - if not user.logged_in: + if not await user.is_logged_in(): async with self.require_send_lock(self.bot.tgid): response = await self.bot.client.send_message( self.peer, f"__{user.displayname} joined the room.__", markdown=True) @@ -654,7 +654,7 @@ class Portal: pass @staticmethod - def _preprocess_matrix_message(sender, message): + def _preprocess_matrix_message(sender, is_logged_in, message): msgtype = message["msgtype"] if msgtype == "m.emote": if "formatted_body" in message: @@ -666,7 +666,7 @@ class Portal: tpl_args = dict(sender_display_name=sender.displayname, message=message['body']) message["body"] = Template(tpl).safe_substitute(tpl_args) message["msgtype"] = "m.text" - elif not sender.logged_in: + elif not is_logged_in: html = message["formatted_body"] if "formatted_body" in message else None text = message["body"] if msgtype == "m.text": @@ -813,14 +813,15 @@ class Portal: self.db.commit() async def handle_matrix_message(self, sender, message, event_id): - client = sender.client if sender.logged_in else self.bot.client - sender_id = sender.tgid if sender.logged_in else self.bot.tgid + logged_in = await sender.is_logged_in() + client = sender.client if logged_in else self.bot.client + sender_id = sender.tgid if logged_in else self.bot.tgid space = (self.tgid if self.peer_type == "channel" # Channels have their own ID space - else (sender.tgid if sender.logged_in else self.bot.tgid)) + else (sender.tgid if logged_in else self.bot.tgid)) reply_to = formatter.matrix_reply_to_telegram(message, space, room_id=self.mxid) message["mxtg_filename"] = message["body"] - self._preprocess_matrix_message(sender, message) + self._preprocess_matrix_message(sender, logged_in, message) type = message["msgtype"] if type == "m.text" or (self.bridge_notices and type == "m.notice"): @@ -849,7 +850,7 @@ class Portal: pass async def handle_matrix_deletion(self, deleter, event_id): - deleter = deleter if deleter.logged_in else self.bot + deleter = deleter if await deleter.is_logged_in() else self.bot space = self.tgid if self.peer_type == "channel" else deleter.tgid message = DBMessage.query.filter(DBMessage.mxid == event_id, DBMessage.tg_space == space, diff --git a/mautrix_telegram/public/__init__.py b/mautrix_telegram/public/__init__.py index cf72bb8a..e1a4533c 100644 --- a/mautrix_telegram/public/__init__.py +++ b/mautrix_telegram/public/__init__.py @@ -52,7 +52,7 @@ class PublicBridgeWebsite: elif not user.whitelisted: return self.render_login(mxid=user.mxid, error="You are not whitelisted.", status=403) await user.ensure_started() - if not user.logged_in: + if not await user.is_logged_in(): return self.render_login(mxid=user.mxid, state="request") return self.render_login(mxid=user.mxid, username=user.username) @@ -148,7 +148,7 @@ class PublicBridgeWebsite: user = await User.get_by_mxid(data["mxid"]).ensure_started(even_if_no_session=True) if not user.whitelisted: return self.render_login(mxid=user.mxid, error="You are not whitelisted.", status=403) - elif user.logged_in: + elif await user.is_logged_in(): return self.render_login(mxid=user.mxid, username=user.username) if "phone" in data: diff --git a/mautrix_telegram/puppet.py b/mautrix_telegram/puppet.py index e954f1e7..0cd198fd 100644 --- a/mautrix_telegram/puppet.py +++ b/mautrix_telegram/puppet.py @@ -49,7 +49,6 @@ class Puppet: self._db_instance = db_instance self.intent = self.az.intent.user(self.mxid) - self.logged_in = True self.cache[id] = self @@ -57,6 +56,9 @@ class Puppet: def tgid(self): return self.id + async def is_logged_in(self): + return True + @property def db_instance(self): if not self._db_instance: diff --git a/mautrix_telegram/user.py b/mautrix_telegram/user.py index 827609d6..d213f59f 100644 --- a/mautrix_telegram/user.py +++ b/mautrix_telegram/user.py @@ -134,7 +134,7 @@ class User(AbstractUser): async def start(self, delete_unless_authenticated=False): await super().start() - if self.logged_in: + if await self.is_logged_in(): self.log.debug(f"Ensuring post_login() for {self.name}") asyncio.ensure_future(self.post_login(), loop=self.loop) elif delete_unless_authenticated: