import hmac from mautrix.bridge.commands import HelpSection, command_handler from mauigpapi.state import AndroidState from mauigpapi.http import AndroidAPI from mauigpapi.errors import (IGLoginTwoFactorRequiredError, IGLoginBadPasswordError, IGLoginInvalidUserError, IGBad2FACodeError, IGCheckpointError, IGChallengeWrongCodeError) from mauigpapi.types import BaseResponseUser from .typehint import CommandEvent if TYPE_CHECKING: from ..user import User SECTION_AUTH = HelpSection("Authentication", 10, "") async def get_login_state(user: '******', username: str, seed: str ) -> Tuple[AndroidAPI, AndroidState]: if user.command_status and user.command_status["action"] == "Login": api: AndroidAPI = user.command_status["api"] state: AndroidState = user.command_status["state"] else: state = AndroidState() seed = hmac.new(seed.encode("utf-8"), username.encode("utf-8"), hashlib.sha256).digest() state.device.generate(seed) api = AndroidAPI(state, log=user.api_log) await api.qe_sync_login_experiments() user.command_status = { "action": "Login",
BaseCommandEvent, CommandHandler as BaseCommandHandler, CommandProcessor as BaseCommandProcessor, CommandHandlerFunc, command_handler as base_command_handler) from .. import user as u if TYPE_CHECKING: from ..__main__ import SignalBridge HelpCacheKey = NamedTuple('HelpCacheKey', is_management=bool, is_portal=bool, is_admin=bool, is_logged_in=bool) SECTION_AUTH = HelpSection("Authentication", 10, "") SECTION_CONNECTION = HelpSection("Connection management", 15, "") class CommandEvent(BaseCommandEvent): sender: u.User bridge: 'SignalBridge' def __init__(self, processor: 'CommandProcessor', room_id: RoomID, event_id: EventID, sender: u.User, command: str, args: List[str], content: MessageEventContent, is_management: bool, is_portal: bool) -> None: super().__init__(processor, room_id, event_id, sender, command, args, content, is_management, is_portal) self.bridge = processor.bridge self.config = processor.config
from mautrix.bridge.commands import HelpSection, command_handler, SECTION_ADMIN from mautrix.types import EventID from mausignald.types import Address from mausignald.errors import UnknownIdentityKey from .. import puppet as pu, portal as po from .auth import make_qr, remove_extra_chars from .typehint import CommandEvent try: import qrcode import PIL as _ except ImportError: qrcode = None SECTION_SIGNAL = HelpSection("Signal actions", 20, "") async def _get_puppet_from_cmd(evt: CommandEvent) -> Optional['pu.Puppet']: if len(evt.args) == 0 or not evt.args[0].startswith("+"): await evt.reply(f"**Usage:** `$cmdprefix+sp {evt.command} <phone>` " "(enter phone number in international format)") return None phone = "".join(evt.args).translate(remove_extra_chars) if not phone[1:].isdecimal(): await evt.reply(f"**Usage:** `$cmdprefix+sp {evt.command} <phone>` " "(enter phone number in international format)") return None return await pu.Puppet.get_by_address(Address(number=phone))
# 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 <https://www.gnu.org/licenses/>. from mauigpapi.errors import IGNotLoggedInError from mautrix.bridge.commands import HelpSection, command_handler from .typehint import CommandEvent SECTION_CONNECTION = HelpSection("Connection management", 15, "") @command_handler(needs_auth=False, management_only=True, help_section=SECTION_CONNECTION, help_text="Mark this room as your bridge notice room") async def set_notice_room(evt: CommandEvent) -> None: evt.sender.notice_room = evt.room_id await evt.sender.update() await evt.reply("This room has been marked as your bridge notice room") @command_handler(needs_auth=False, management_only=True, help_section=SECTION_CONNECTION,
# 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 <https://www.gnu.org/licenses/>. from typing import Awaitable, Callable, Dict, Optional, NamedTuple from mautrix.bridge.commands import (HelpSection, CommandEvent as BaseCommandEvent, command_handler as base_command_handler, CommandHandler as BaseCommandHandler, CommandProcessor as BaseCommandProcessor) from .. import user as u, context as c, web as w HelpCacheKey = NamedTuple('HelpCacheKey', is_management=bool, is_admin=bool) SECTION_AUTH = HelpSection("Authentication", 10, "") SECTION_CREATING_PORTALS = HelpSection("Creating portals", 20, "") SECTION_PORTAL_MANAGEMENT = HelpSection("Portal management", 30, "") SECTION_MISC = HelpSection("Miscellaneous", 40, "") SECTION_ADMIN = HelpSection("Administration", 50, "") class CommandEvent(BaseCommandEvent): sender: 'u.User' processor: 'CommandProcessor' @property def print_error_traceback(self) -> bool: return self.sender.is_admin async def help_key(self) -> HelpCacheKey:
# 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 <https://www.gnu.org/licenses/>. from typing import Iterable, List import asyncio import fbchat from mautrix.bridge.commands import HelpSection, command_handler from .. import puppet as pu, portal as po, user as u from ..db import UserPortal as DBUserPortal from .typehint import CommandEvent SECTION_MISC = HelpSection("Miscellaneous", 40, "") @command_handler(needs_auth=True, management_only=False, help_section=SECTION_MISC, help_text="Search for a Facebook user", help_args="<_search query_>") async def search(evt: CommandEvent) -> None: res = await evt.sender.client.search_for_users(" ".join(evt.args), limit=10) await evt.reply(await _handle_search_result(evt.sender, res)) @command_handler(needs_auth=True, management_only=False) async def search_by_id(evt: CommandEvent) -> None: res = [item async for item in evt.sender.client.fetch_thread_info(evt.args)] await evt.reply(await _handle_search_result(evt.sender, res))
# mautrix-facebook - A Matrix-Facebook Messenger puppeting bridge. # Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. from typing import NamedTuple from mautrix.bridge.commands import HelpSection HelpCacheKey = NamedTuple('FBHelpCacheKey', is_management=bool, is_admin=bool, is_logged_in=bool) SECTION_AUTH = HelpSection("Authentication", 10, "") SECTION_CONNECTION = HelpSection("Connection management", 15, "") SECTION_CREATING_PORTALS = HelpSection("Creating portals", 20, "") SECTION_PORTAL_MANAGEMENT = HelpSection("Portal management", 30, "") SECTION_ADMIN = HelpSection("Administration", 50, "")