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