From 3ab5e4d8ccc40308cd789c4aeb8fd1ad885b16a7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 14 Aug 2021 16:22:31 +0300 Subject: [PATCH] Move remaining manhole stuff to mautrix-python --- mautrix_telegram/__main__.py | 21 +++-- mautrix_telegram/commands/__init__.py | 2 +- mautrix_telegram/commands/manhole.py | 128 -------------------------- mautrix_telegram/config.py | 4 - requirements.txt | 2 +- 5 files changed, 16 insertions(+), 141 deletions(-) delete mode 100644 mautrix_telegram/commands/manhole.py diff --git a/mautrix_telegram/__main__.py b/mautrix_telegram/__main__.py index bd7f7afb..83ee0fb1 100644 --- a/mautrix_telegram/__main__.py +++ b/mautrix_telegram/__main__.py @@ -13,8 +13,9 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from typing import Optional +from typing import Dict, Any +from telethon import __version__ as __telethon_version__ from alchemysession import AlchemySessionContainer from mautrix.types import UserID, RoomID @@ -23,7 +24,6 @@ from mautrix.util.db import Base from .web.provisioning import ProvisioningAPI from .web.public import PublicBridgeWebsite -from .commands.manhole import ManholeState from .abstract_user import init as init_abstract_user from .bot import Bot, init as init_bot from .config import Config @@ -57,7 +57,6 @@ class TelegramBridge(Bridge): config: Config session_container: AlchemySessionContainer bot: Bot - manhole: Optional[ManholeState] def prepare_db(self) -> None: super().prepare_db() @@ -83,7 +82,6 @@ class TelegramBridge(Bridge): context = Context(self.az, self.config, self.loop, self.session_container, self, self.bot) self._prepare_website(context) self.matrix = context.mx = MatrixHandler(context) - self.manhole = None init_abstract_user(context) init_formatter(context) @@ -107,9 +105,6 @@ class TelegramBridge(Bridge): for puppet in Puppet.by_custom_mxid.values(): puppet.stop() self.shutdown_actions = (user.stop() for user in User.by_tgid.values()) - if self.manhole: - self.manhole.close() - self.manhole = None async def get_user(self, user_id: UserID, create: bool = True) -> User: user = User.get_by_mxid(user_id, create=create) @@ -132,5 +127,17 @@ class TelegramBridge(Bridge): async def count_logged_in_users(self) -> int: return len([user for user in User.by_tgid.values() if user.tgid]) + async def manhole_global_namespace(self, user_id: UserID) -> Dict[str, Any]: + return { + **await super().manhole_global_namespace(user_id), + "User": User, + "Portal": Portal, + "Puppet": Puppet, + } + + @property + def manhole_banner_program_version(self) -> str: + return f"{super().manhole_banner_program_version} and Telethon {__telethon_version__}" + TelegramBridge().run() diff --git a/mautrix_telegram/commands/__init__.py b/mautrix_telegram/commands/__init__.py index ebdf60f3..3693689c 100644 --- a/mautrix_telegram/commands/__init__.py +++ b/mautrix_telegram/commands/__init__.py @@ -1,7 +1,7 @@ from .handler import (command_handler, CommandHandler, CommandProcessor, CommandEvent, SECTION_AUTH, SECTION_CREATING_PORTALS, SECTION_PORTAL_MANAGEMENT, SECTION_MISC, SECTION_ADMIN) -from . import portal, telegram, matrix_auth, manhole +from . import portal, telegram, matrix_auth __all__ = ["command_handler", "CommandHandler", "CommandProcessor", "CommandEvent", "SECTION_AUTH", "SECTION_MISC", "SECTION_ADMIN", "SECTION_CREATING_PORTALS", diff --git a/mautrix_telegram/commands/manhole.py b/mautrix_telegram/commands/manhole.py deleted file mode 100644 index ad4cdce8..00000000 --- a/mautrix_telegram/commands/manhole.py +++ /dev/null @@ -1,128 +0,0 @@ -# mautrix-telegram - A Matrix-Telegram puppeting bridge -# Copyright (C) 2019 Tulir Asokan -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -from typing import Set, Callable -import asyncio -import sys -import os - -from attr import dataclass - -from telethon import __version__ as __telethon_version__ - -from mautrix import __version__ as __mautrix_version__ -from mautrix.types import UserID -from mautrix.errors import MatrixConnectionError -from mautrix.util.manhole import start_manhole - -from .. import __version__ -from . import command_handler, CommandEvent, SECTION_ADMIN - - -@dataclass -class ManholeState: - server: asyncio.AbstractServer - opened_by: UserID - close: Callable[[], None] - whitelist: Set[int] - - -@command_handler(needs_auth=False, needs_admin=True, help_section=SECTION_ADMIN, - help_text="Open a manhole into the bridge.", help_args="<_uid..._>") -async def open_manhole(evt: CommandEvent) -> None: - if not evt.config["manhole.enabled"]: - await evt.reply("The manhole has been disabled in the config.") - return - elif len(evt.args) == 0: - await evt.reply("**Usage:** `$cmdprefix+sp open-manhole `") - return - - whitelist = set() - whitelist_whitelist = evt.config["manhole.whitelist"] - for arg in evt.args: - try: - uid = int(arg) - except ValueError: - await evt.reply(f"{arg} is not an integer.") - return - if whitelist_whitelist and uid not in whitelist_whitelist: - await evt.reply(f"{uid} is not in the list of allowed UIDs.") - return - whitelist.add(uid) - - if evt.bridge.manhole: - added = [uid for uid in whitelist - if uid not in evt.bridge.manhole.whitelist] - evt.bridge.manhole.whitelist |= set(added) - if len(added) == 0: - await evt.reply(f"There's an existing manhole opened by {evt.bridge.manhole.opened_by}" - " and all the given UIDs are already whitelisted.") - else: - added_str = (f"{', '.join(str(uid) for uid in added[:-1])} and {added[-1]}" - if len(added) > 1 else added[0]) - await evt.reply(f"There's an existing manhole opened by {evt.bridge.manhole.opened_by}" - f". Added {added_str} to the whitelist.") - evt.log.info(f"{evt.sender.mxid} added {added_str} to the manhole whitelist.") - return - - from ..portal import Portal - from ..puppet import Puppet - from ..user import User - namespace = { - "bridge": evt.bridge, - "User": User, - "Portal": Portal, - "Puppet": Puppet, - } - banner = (f"Python {sys.version} on {sys.platform}\n" - f"mautrix-telegram {__version__} with mautrix-python {__mautrix_version__} " - f"and Telethon {__telethon_version__}\n\nManhole opened by {evt.sender.mxid}\n") - path = evt.config["manhole.path"] - - wl_list = list(whitelist) - whitelist_str = (f"{', '.join(str(uid) for uid in wl_list[:-1])} and {wl_list[-1]}" - if len(wl_list) > 1 else wl_list[0]) - evt.log.info(f"{evt.sender.mxid} opened a manhole with {whitelist_str} whitelisted.") - server, close = await start_manhole(path=path, banner=banner, namespace=namespace, - loop=evt.loop, whitelist=whitelist) - evt.bridge.manhole = ManholeState(server=server, opened_by=evt.sender.mxid, close=close, - whitelist=whitelist) - plrl = "s" if len(whitelist) != 1 else "" - await evt.reply(f"Opened manhole at unix://{path} with UID{plrl} {whitelist_str} whitelisted") - await server.wait_closed() - evt.bridge.manhole = None - try: - os.unlink(path) - except FileNotFoundError: - pass - evt.log.info(f"{evt.sender.mxid}'s manhole was closed.") - try: - await evt.reply("Your manhole was closed.") - except (AttributeError, MatrixConnectionError) as e: - evt.log.warning(f"Failed to send manhole close notification: {e}") - - -@command_handler(needs_auth=False, needs_admin=True, help_section=SECTION_ADMIN, - help_text="Close an open manhole.") -async def close_manhole(evt: CommandEvent) -> None: - if not evt.bridge.manhole: - await evt.reply("There is no open manhole.") - return - - opened_by = evt.bridge.manhole.opened_by - evt.bridge.manhole.close() - evt.bridge.manhole = None - if opened_by != evt.sender.mxid: - await evt.reply(f"Closed manhole opened by {opened_by}") diff --git a/mautrix_telegram/config.py b/mautrix_telegram/config.py index a5d59ed0..30a9d691 100644 --- a/mautrix_telegram/config.py +++ b/mautrix_telegram/config.py @@ -75,10 +75,6 @@ class Config(BaseBridgeConfig): copy("metrics.enabled") copy("metrics.listen_port") - copy("manhole.enabled") - copy("manhole.path") - copy("manhole.whitelist") - copy("bridge.username_template") copy("bridge.alias_template") copy("bridge.displayname_template") diff --git a/requirements.txt b/requirements.txt index 9beef648..688e801d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,6 @@ python-magic>=0.4,<0.5 commonmark>=0.8,<0.10 aiohttp>=3,<4 yarl>=1,<2 -mautrix>=0.10.2,<0.11 +mautrix>=0.10.3,<0.11 telethon>=1.22,<1.23 telethon-session-sqlalchemy>=0.2.14,<0.3