def migrate_state_store(): conn = op.get_bind() session: orm.Session = orm.sessionmaker(bind=conn)() try: with open("mx-state.json") as file: data = json.load(file) except FileNotFoundError: return if not data: return registrations = data.get("registrations", []) mxtg_config_path = context.get_x_argument(as_dictionary=True).get( "config", "config.yaml") mxtg_config = Config(mxtg_config_path, None, None) mxtg_config.load() username_template = mxtg_config.get("bridge.username_template", "telegram_{userid}") hs_domain = mxtg_config["homeserver.domain"] localpart = username_template.format(userid="(.+)") mxid_regex = re.compile("@{}:{}".format(localpart, hs_domain)) for user in registrations: match = mxid_regex.match(user) if not match: continue puppet = session.query(Puppet).get(match.group(1)) if not puppet: continue puppet.matrix_registered = True session.merge(puppet) session.commit() user_profiles = [ UserProfile(room_id=room, user_id=user, membership=member.get("membership", "leave"), displayname=member.get("displayname", None), avatar_url=member.get("avatar_url", None)) for room, members in data.get("members", {}).items() for user, member in members.items() ] session.add_all(user_profiles) session.commit() room_state = [ RoomState(room_id=room, power_levels=json.dumps(levels)) for room, levels in data.get("power_levels", {}).items() ] session.add_all(room_state) session.commit()
def context(request: FixtureRequest) -> Context: """Returns a Context with mocked Attributes. Uses the attribute cls.config as Config. """ # Config(path, registration_path, base_path) config = getattr(request.cls, 'config', Config("", "", "")) return Context(az=Mock(), config=config, loop=Mock(), session_container=Mock(), bot=Mock())
class TestCommandEvent: config = Config("", "", "") config["bridge.command_prefix"] = "tg" config["bridge.permissions"] = {"*": "noperm"} def test_reply(self, command_processor: CommandProcessor, mocker: MockFixture) -> None: mocker.patch("mautrix_telegram.user.config", self.config) evt = CommandEvent( processor=command_processor, room_id=RoomID("#mock_room:example.org"), event_id=EventID("$H45H:example.org"), sender=u.User(UserID("@sender:example.org")), command="help", args=[], is_management=True, is_portal=False, ) mock_az = command_processor.az message = "**This** <i>was</i><br/><strong>all</strong>fun*!" # html, no markdown evt.reply(message, allow_html=True, render_markdown=False) mock_az.intent.send_notice.assert_called_with( RoomID("#mock_room:example.org"), "**This** <i>was</i><br/><strong>all</strong>fun*!", html="**This** <i>was</i><br/><strong>all</strong>fun*!\n", ) # html, markdown (default) evt.reply(message, allow_html=True, render_markdown=True) mock_az.intent.send_notice.assert_called_with( RoomID("#mock_room:example.org"), "**This** <i>was</i><br/><strong>all</strong>fun*!", html=("<p><strong>This</strong> <i>was</i><br/>" "<strong>all</strong>fun*!</p>\n"), ) # no html, no markdown evt.reply(message, allow_html=False, render_markdown=False) mock_az.intent.send_notice.assert_called_with( RoomID("#mock_room:example.org"), "**This** <i>was</i><br/><strong>all</strong>fun*!", html=None, ) # no html, markdown evt.reply(message, allow_html=False, render_markdown=True) mock_az.intent.send_notice.assert_called_with( RoomID("#mock_room:example.org"), "**This** <i>was</i><br/><strong>all</strong>fun*!", html="<p><strong>This</strong> <i>was</i><br/>" "<strong>all</strong>fun*!</p>\n") def test_reply_with_cmdprefix(self, command_processor: CommandProcessor, mocker: MockFixture) -> None: mocker.patch("mautrix_telegram.user.config", self.config) evt = CommandEvent( processor=command_processor, room_id=RoomID("#mock_room:example.org"), event_id=EventID("$H45H:example.org"), sender=u.User(UserID("@sender:example.org")), command="help", args=[], is_management=False, is_portal=False, ) mock_az = command_processor.az evt.reply("$cmdprefix+sp ....$cmdprefix+sp...$cmdprefix $cmdprefix", allow_html=False, render_markdown=False) mock_az.intent.send_notice.assert_called_with( RoomID("#mock_room:example.org"), "tg ....tg+sp...tg tg", html=None, ) def test_reply_with_cmdprefix_in_management_room( self, command_processor: CommandProcessor, mocker: MockFixture) -> None: mocker.patch("mautrix_telegram.user.config", self.config) evt = CommandEvent( processor=command_processor, room_id=RoomID("#mock_room:example.org"), event_id=EventID("$H45H:example.org"), sender=u.User(UserID("@sender:example.org")), command="help", args=[], is_management=True, is_portal=False, ) mock_az = command_processor.az evt.reply( "$cmdprefix+sp ....$cmdprefix+sp...$cmdprefix $cmdprefix", allow_html=True, render_markdown=True, ) mock_az.intent.send_notice.assert_called_with( RoomID("#mock_room:example.org"), "....tg+sp...tg tg", html="<p>....tg+sp...tg tg</p>\n", )
class TestCommandProcessor: config = Config("", "", "") config["bridge.command_prefix"] = "tg" config["bridge.permissions"] = {"*": "relaybot"} @pytest.mark.asyncio async def test_handle(self, command_processor: CommandProcessor, boolean2: Tuple[bool, bool], mocker: MockFixture) -> None: mocker.patch('mautrix_telegram.user.config', self.config) mocker.patch('mautrix.bridge.commands.handler.command_handlers', { "help": AsyncMock(), "unknown-command": AsyncMock() }) sender = u.User(UserID("@sender:example.org")) result = await command_processor.handle( room_id=RoomID("#mock_room:example.org"), event_id=EventID("$H45H:example.org"), sender=sender, command="hElp", args=[], is_management=boolean2[0], is_portal=boolean2[1]) assert result is None command_handlers = mautrix.bridge.commands.handler.command_handlers command_handlers["help"].mock.assert_called_once() # type: ignore @pytest.mark.asyncio async def test_handle_unknown_command(self, command_processor: CommandProcessor, boolean2: Tuple[bool, bool], mocker: MockFixture) -> None: mocker.patch('mautrix_telegram.user.config', self.config) mocker.patch('mautrix.bridge.commands.handler.command_handlers', { "help": AsyncMock(), "unknown-command": AsyncMock() }) sender = u.User(UserID("@sender:example.org")) sender.command_status = {} result = await command_processor.handle( room_id=RoomID("#mock_room:example.org"), event_id=EventID("$H45H:example.org"), sender=sender, command="foo", args=[], is_management=boolean2[0], is_portal=boolean2[1], ) assert result is None command_handlers = mautrix.bridge.commands.handler.command_handlers command_handlers["help"].mock.assert_not_called() # type: ignore command_handlers["unknown-command"].mock.assert_called_once( ) # type: ignore @pytest.mark.asyncio async def test_handle_delegated_handler( self, command_processor: CommandProcessor, boolean2: Tuple[bool, bool], mocker: MockFixture) -> None: mocker.patch('mautrix_telegram.user.config', self.config) mocker.patch('mautrix.bridge.commands.handler.command_handlers', { "help": AsyncMock(), "unknown-command": AsyncMock() }) sender = u.User(UserID("@sender:example.org")) sender.command_status = {"foo": AsyncMock(), "next": AsyncMock()} result = await command_processor.handle( room_id=RoomID("#mock_room:example.org"), event_id=EventID("$H45H:example.org"), sender=sender, # u.User command="foo", args=[], is_management=boolean2[0], is_portal=boolean2[1]) assert result is None command_handlers = mautrix.bridge.commands.handler.command_handlers command_handlers["help"].mock.assert_not_called() # type: ignore command_handlers["unknown-command"].mock.assert_not_called( ) # type: ignore sender.command_status["foo"].mock.assert_not_called() # type: ignore sender.command_status["next"].mock.assert_called_once() # type: ignore
class TestCommandHandler: config = Config("", "", "") config["bridge.permissions"] = {"*": "noperm"} @pytest.mark.parametrize(("needs_auth," "needs_puppeting," "needs_matrix_puppeting," "needs_admin," "management_only,"), [l for l in list_true_once_each(length=5)]) @pytest.mark.asyncio async def test_permissions_denied( self, needs_auth: bool, needs_puppeting: bool, needs_matrix_puppeting: bool, needs_admin: bool, management_only: bool, command_processor: CommandProcessor, boolean: bool, mocker: MockFixture, ) -> None: mocker.patch("mautrix_telegram.user.config", self.config) command = "testcmd" mock_handler = Mock() command_handler = CommandHandler( handler=mock_handler, needs_auth=needs_auth, needs_puppeting=needs_puppeting, needs_matrix_puppeting=needs_matrix_puppeting, needs_admin=needs_admin, management_only=management_only, name=command, help_text="No real command", help_args="mock mockmock", help_section=HelpSection("Mock Section", 42, ""), ) sender = u.User(UserID("@sender:example.org")) sender.puppet_whitelisted = False sender.matrix_puppet_whitelisted = False sender.is_admin = False event = CommandEvent( processor=command_processor, room_id=RoomID("#mock_room:example.org"), event_id=EventID("$H45H:example.org"), sender=sender, command=command, args=[], is_management=False, is_portal=boolean, ) assert await command_handler.get_permission_error(event) assert not command_handler.has_permission( HelpCacheKey(False, False, False, False, False, False)) @pytest.mark.parametrize(("is_management," "puppet_whitelisted," "matrix_puppet_whitelisted," "is_admin," "is_logged_in,"), [l for l in list_true_once_each(length=5)]) @pytest.mark.asyncio async def test_permission_granted( self, is_management: bool, puppet_whitelisted: bool, matrix_puppet_whitelisted: bool, is_admin: bool, is_logged_in: bool, command_processor: CommandProcessor, boolean: bool, mocker: MockFixture, ) -> None: mocker.patch("mautrix_telegram.user.config", self.config) command = "testcmd" mock_handler = Mock() command_handler = CommandHandler( handler=mock_handler, needs_auth=False, needs_puppeting=False, needs_matrix_puppeting=False, needs_admin=False, management_only=False, name=command, help_text="No real command", help_args="mock mockmock", help_section=HelpSection("Mock Section", 42, ""), ) sender = u.User(UserID("@sender:example.org")) sender.puppet_whitelisted = puppet_whitelisted sender.matrix_puppet_whitelisted = matrix_puppet_whitelisted sender.is_admin = is_admin mocker.patch.object(u.User, 'is_logged_in', return_value=is_logged_in) event = CommandEvent( processor=command_processor, room_id=RoomID("#mock_room:example.org"), event_id=EventID("$H45H:example.org"), sender=sender, command=command, args=[], is_management=is_management, is_portal=boolean, ) assert not await command_handler.get_permission_error(event) assert command_handler.has_permission( HelpCacheKey(is_management=is_management, puppet_whitelisted=puppet_whitelisted, matrix_puppet_whitelisted=matrix_puppet_whitelisted, is_admin=is_admin, is_logged_in=is_logged_in, is_portal=boolean))
from os.path import abspath, dirname sys.path.insert(0, dirname(dirname(abspath(__file__)))) from mautrix.util.db import Base import mautrix_telegram.db from mautrix_telegram.config import Config from alchemysession import AlchemySessionContainer # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config mxtg_config_path = context.get_x_argument(as_dictionary=True).get( "config", "config.yaml") mxtg_config = Config(mxtg_config_path, None, None) mxtg_config.load() config.set_main_option("sqlalchemy.url", mxtg_config["appservice.database"].replace("%", "%%")) AlchemySessionContainer.create_table_classes(None, "telethon_", Base) # Interpret the config file for Python logging. # This line sets up loggers basically. fileConfig(config.config_file_name) # add your model's MetaData object here # for 'autogenerate' support # from myapp import mymodel # target_metadata = mymodel.Base.metadata target_metadata = Base.metadata
import sys from os.path import abspath, dirname sys.path.insert(0, dirname(dirname(abspath(__file__)))) from mautrix_telegram.base import Base from mautrix_telegram.config import Config from alchemysession import AlchemySessionContainer import mautrix_telegram.db # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config mxtg_config_path = context.get_x_argument(as_dictionary=True).get("config", "config.yaml") mxtg_config = Config(mxtg_config_path, None, None) mxtg_config.load() config.set_main_option("sqlalchemy.url", mxtg_config.get("appservice.database", "sqlite:///mautrix-telegram.db")) class FakeDB: @staticmethod def query_property(): return None AlchemySessionContainer.create_table_classes(FakeDB(), "telethon_", Base) # Interpret the config file for Python logging. # This line sets up loggers basically.
from mautrix_telegram.config import Config from mautrix_telegram.db import Portal, Message, Puppet, BotChat from .models import ChatLink, TgUser, MatrixUser, Message as TMMessage, Base as TelematrixBase parser = argparse.ArgumentParser( description="mautrix-telegram telematrix import script", prog="python -m mautrix_telegram.scripts.telematrix_import") parser.add_argument("-c", "--config", type=str, default="config.yaml", metavar="<path>", help="the path to your mautrix-telegram config file") parser.add_argument("-b", "--bot-id", type=int, required=True, metavar="<id>", help="the telegram user ID of your relay bot") parser.add_argument("-t", "--telematrix-database", type=str, default="sqlite:///database.db", metavar="<url>", help="your telematrix database URL") args = parser.parse_args() config = Config(args.config, None, None) config.load() mxtg_db_engine = sql.create_engine(config.get("appservice.database", "sqlite:///mautrix-telegram.db")) mxtg = orm.sessionmaker(bind=mxtg_db_engine)() Base.metadata.bind = mxtg_db_engine telematrix_db_engine = sql.create_engine(args.telematrix_database) telematrix = orm.sessionmaker(bind=telematrix_db_engine)() TelematrixBase.metadata.bind = telematrix_db_engine chat_links = telematrix.query(ChatLink).all() tg_users = telematrix.query(TgUser).all() mx_users = telematrix.query(MatrixUser).all() messages = telematrix.query(TMMessage).all()
from mautrix_telegram.config import Config from .models import ChatLink, TgUser, MatrixUser, Message as TMMessage, Base as TelematrixBase parser = argparse.ArgumentParser( description="mautrix-telegram telematrix import script", prog="python -m mautrix_telegram.scripts.telematrix_import") parser.add_argument("-c", "--config", type=str, default="config.yaml", metavar="<path>", help="the path to your mautrix-telegram config file") parser.add_argument("-b", "--bot-id", type=int, required=True, metavar="<id>", help="the telegram user ID of your relay bot") parser.add_argument("-t", "--telematrix-database", type=str, default="sqlite:///database.db", metavar="<url>", help="your telematrix database URL") args = parser.parse_args() config = Config(args.config, None, None) config.load() mxtg_db_engine = sql.create_engine( config.get("appservice.database", "sqlite:///mautrix-telegram.db")) mxtg = orm.sessionmaker(bind=mxtg_db_engine)() Base.metadata.bind = mxtg_db_engine telematrix_db_engine = sql.create_engine(args.telematrix_database) telematrix = orm.sessionmaker(bind=telematrix_db_engine)() TelematrixBase.metadata.bind = telematrix_db_engine chat_links = telematrix.query(ChatLink).all() tg_users = telematrix.query(TgUser).all() mx_users = telematrix.query(MatrixUser).all() tm_messages = telematrix.query(TMMessage).all()
help="the path to your mautrix-telegram config file") parser.add_argument("-b", "--bot-id", type=int, required=True, metavar="<id>", help="the telegram user ID of your relay bot") parser.add_argument("-t", "--telematrix-database", type=str, default="sqlite:///database.db", metavar="<url>", help="your telematrix database URL") args = parser.parse_args() config = Config(args.config, None, None) config.load() mxtg_db_engine = sql.create_engine(config["appservice.database"]) mxtg = orm.sessionmaker(bind=mxtg_db_engine)() Base.metadata.bind = mxtg_db_engine telematrix_db_engine = sql.create_engine(args.telematrix_database) telematrix = orm.sessionmaker(bind=telematrix_db_engine)() TelematrixBase.metadata.bind = telematrix_db_engine chat_links = telematrix.query(ChatLink).all() tg_users = telematrix.query(TgUser).all() mx_users = telematrix.query(MatrixUser).all() tm_messages = telematrix.query(TMMessage).all()