예제 #1
0
    def init(self):
        self.commands = CommandManager()

        cmd = CommandParser(prog="NETWORKS",
                            description="list available networks")
        self.commands.register(cmd, self.cmd_networks)

        cmd = CommandParser(prog="SERVERS",
                            description="list servers for a network")
        cmd.add_argument("network", help="network name (see NETWORKS)")
        self.commands.register(cmd, self.cmd_servers)

        cmd = CommandParser(prog="OPEN",
                            description="open network for connecting")
        cmd.add_argument("name", help="network name (see NETWORKS)")
        cmd.add_argument("--new",
                         action="store_true",
                         help="force open a new network connection")
        self.commands.register(cmd, self.cmd_open)

        cmd = CommandParser(
            prog="STATUS",
            description="show bridge status",
            epilog="Note: admins see all users but only their own rooms",
        )
        self.commands.register(cmd, self.cmd_status)

        cmd = CommandParser(
            prog="QUIT",
            description="disconnect from all networks",
            epilog=
            ("For quickly leaving all networks and removing configurations in a single command.\n"
             "\n"
             "Additionally this will close current DM session with the bridge.\n"
             ),
        )
        self.commands.register(cmd, self.cmd_quit)

        if self.serv.is_admin(self.user_id):
            cmd = CommandParser(prog="MASKS", description="list allow masks")
            self.commands.register(cmd, self.cmd_masks)

            cmd = CommandParser(
                prog="ADDMASK",
                description="add new allow mask",
                epilog=
                ("For anyone else than the owner to use this bridge they need to be allowed to talk with the bridge bot.\n"
                 "This is accomplished by adding an allow mask that determines their permission level when using the bridge.\n"
                 "\n"
                 "Only admins can manage networks, normal users can just connect.\n"
                 ),
            )
            cmd.add_argument(
                "mask",
                help="Matrix ID mask (eg: @friend:contoso.com or *:contoso.com)"
            )
            cmd.add_argument("--admin",
                             help="Admin level access",
                             action="store_true")
            self.commands.register(cmd, self.cmd_addmask)

            cmd = CommandParser(
                prog="DELMASK",
                description="delete allow mask",
                epilog=
                ("Note: Removing a mask only prevents starting a new DM with the bridge bot. Use FORGET for ending existing"
                 " sessions."),
            )
            cmd.add_argument(
                "mask",
                help="Matrix ID mask (eg: @friend:contoso.com or *:contoso.com)"
            )
            self.commands.register(cmd, self.cmd_delmask)

            cmd = CommandParser(prog="ADDNETWORK",
                                description="add new network")
            cmd.add_argument("name", help="network name")
            self.commands.register(cmd, self.cmd_addnetwork)

            cmd = CommandParser(prog="DELNETWORK",
                                description="delete network")
            cmd.add_argument("name", help="network name")
            self.commands.register(cmd, self.cmd_delnetwork)

            cmd = CommandParser(prog="ADDSERVER",
                                description="add server to a network")
            cmd.add_argument("network", help="network name")
            cmd.add_argument("address", help="server address")
            cmd.add_argument("port",
                             nargs="?",
                             type=int,
                             help="server port",
                             default=6667)
            cmd.add_argument("--tls",
                             action="store_true",
                             help="use TLS encryption",
                             default=False)
            cmd.add_argument(
                "--tls-insecure",
                action="store_true",
                help=
                "ignore TLS verification errors (hostname, self-signed, expired)",
                default=False,
            )
            cmd.add_argument("--proxy",
                             help="use a SOCKS proxy (socks5://...)",
                             default=None)
            self.commands.register(cmd, self.cmd_addserver)

            cmd = CommandParser(prog="DELSERVER",
                                description="delete server from a network")
            cmd.add_argument("network", help="network name")
            cmd.add_argument("address", help="server address")
            cmd.add_argument("port",
                             nargs="?",
                             type=int,
                             help="server port",
                             default=6667)
            self.commands.register(cmd, self.cmd_delserver)

            cmd = CommandParser(
                prog="FORGET",
                description=
                "remove all connections and configuration of a user",
                epilog=
                ("Kills all connections of this user, removes all user set configuration and makes the bridge leave all rooms"
                 " where this user is in.\n"
                 "If the user still has an allow mask they can DM the bridge again to reconfigure and reconnect.\n"
                 "\n"
                 "This is meant as a way to kick users after removing an allow mask or resetting a user after losing access to"
                 " existing account/rooms for any reason.\n"),
            )
            cmd.add_argument("user",
                             help="Matrix ID (eg: @ex-friend:contoso.com)")
            self.commands.register(cmd, self.cmd_forget)

            cmd = CommandParser(prog="DISPLAYNAME",
                                description="change bridge displayname")
            cmd.add_argument("displayname", help="new bridge displayname")
            self.commands.register(cmd, self.cmd_displayname)

            cmd = CommandParser(prog="AVATAR",
                                description="change bridge avatar")
            cmd.add_argument("url", help="new avatar URL (mxc:// format)")
            self.commands.register(cmd, self.cmd_avatar)

            cmd = CommandParser(
                prog="IDENT",
                description="configure ident replies",
                epilog=
                "Note: MXID here is case sensitive, see subcommand help with IDENTCFG SET -h",
            )
            subcmd = cmd.add_subparsers(help="commands", dest="cmd")
            subcmd.add_parser("list", help="list custom idents (default)")
            cmd_set = subcmd.add_parser("set", help="set custom ident")
            cmd_set.add_argument("mxid", help="mxid of the user")
            cmd_set.add_argument("ident", help="custom ident for the user")
            cmd_remove = subcmd.add_parser("remove",
                                           help="remove custom ident")
            cmd_remove.add_argument("mxid", help="mxid of the user")
            self.commands.register(cmd, self.cmd_ident)

            cmd = CommandParser(
                prog="SYNC",
                description="set default IRC member sync mode",
                epilog="Note: Users can override this per room.",
            )
            group = cmd.add_mutually_exclusive_group()
            group.add_argument(
                "--lazy",
                help="set lazy sync, members are added when they talk",
                action="store_true")
            group.add_argument(
                "--half",
                help=
                "set half sync, members are added when they join or talk (default)",
                action="store_true")
            group.add_argument(
                "--full",
                help="set full sync, members are fully synchronized",
                action="store_true")
            self.commands.register(cmd, self.cmd_sync)

            cmd = CommandParser(
                prog="MAXLINES",
                description=
                "set default maximum number of lines per message until truncation or pastebin",
                epilog="Note: Users can override this per room.",
            )
            cmd.add_argument("lines",
                             type=int,
                             nargs="?",
                             help="Number of lines")
            self.commands.register(cmd, self.cmd_maxlines)

            cmd = CommandParser(
                prog="PASTEBIN",
                description=
                "enable or disable automatic pastebin of long messages by default",
                epilog="Note: Users can override this per room.",
            )
            cmd.add_argument("--enable",
                             dest="enabled",
                             action="store_true",
                             help="Enable pastebin")
            cmd.add_argument(
                "--disable",
                dest="enabled",
                action="store_false",
                help="Disable pastebin (messages will be truncated)")
            cmd.set_defaults(enabled=None)
            self.commands.register(cmd, self.cmd_pastebin)

            cmd = CommandParser(prog="MEDIAURL",
                                description="configure media URL for links")
            cmd.add_argument("url", nargs="?", help="new URL override")
            cmd.add_argument(
                "--remove",
                help="remove URL override (will retry auto-detection)",
                action="store_true")
            self.commands.register(cmd, self.cmd_media_url)

            cmd = CommandParser(prog="VERSION",
                                description="show bridge version")
            self.commands.register(cmd, self.cmd_version)

        self.mx_register("m.room.message", self.on_mx_message)
예제 #2
0
    def init(self) -> None:
        super().init()

        self.key = None
        self.autocmd = None

        # for migration the class default is full
        self.member_sync = "full"

        cmd = CommandParser(
            prog="AUTOCMD",
            description="run commands on join",
            epilog=
            ("Works _exactly_ like network AUTOCMD and runs in the network context."
             " You can use this to login to bots or other services after joining a channel."
             ),
        )
        cmd.add_argument("command",
                         nargs="*",
                         help="commands separated with ';'")
        cmd.add_argument("--remove",
                         action="store_true",
                         help="remove stored command")
        self.commands.register(cmd, self.cmd_autocmd)

        cmd = CommandParser(
            prog="SYNC",
            description="override IRC member sync type for this room",
            epilog=
            "Note: To force full sync after setting to full, use the NAMES command",
        )
        group = cmd.add_mutually_exclusive_group()
        group.add_argument(
            "--lazy",
            help="set lazy sync, members are added when they talk",
            action="store_true")
        group.add_argument(
            "--half",
            help="set half sync, members are added when they join or talk",
            action="store_true")
        group.add_argument(
            "--full",
            help="set full sync, members are fully synchronized",
            action="store_true")
        group.add_argument(
            "--off",
            help=
            "disable member sync completely, the bridge will relay all messages, may be useful during spam attacks",
            action="store_true",
        )
        self.commands.register(cmd, self.cmd_sync)

        cmd = CommandParser(
            prog="MODE",
            description="send MODE command",
            epilog=
            ("Can be used to change channel modes, ban lists or invoke/manage custom lists.\n"
             "It is very network specific what modes or lists are supported, please see their documentation"
             " for comprehensive help.\n"
             "\n"
             "Note: Some common modes and lists may have a command, see HELP.\n"
             ),
        )
        cmd.add_argument("args", nargs="*", help="MODE command arguments")
        self.commands.register(cmd, self.cmd_mode)

        cmd = CommandParser(
            prog="NAMES",
            description="list channel members",
            epilog=
            ("Sends a NAMES command to server.\n"
             "\n"
             "This can be used to see what IRC permissions users currently have on this channel.\n"
             "\n"
             "Note: In addition this will resynchronize the Matrix room members list and may cause joins/leaves"
             " if it has fallen out of sync.\n"),
        )
        self.commands.register(cmd, self.cmd_names)

        # plumbs have a slightly adjusted version
        if type(self) == ChannelRoom:
            cmd = CommandParser(prog="TOPIC",
                                description="show or set channel topic")
            cmd.add_argument("text", nargs="*", help="topic text if setting")
            self.commands.register(cmd, self.cmd_topic)

        cmd = CommandParser(prog="BANS", description="show channel ban list")
        self.commands.register(cmd, self.cmd_bans)

        cmd = CommandParser(prog="OP", description="op someone")
        cmd.add_argument("nick", help="nick to target")
        self.commands.register(cmd, self.cmd_op)

        cmd = CommandParser(prog="DEOP", description="deop someone")
        cmd.add_argument("nick", help="nick to target")
        self.commands.register(cmd, self.cmd_deop)

        cmd = CommandParser(prog="VOICE", description="voice someone")
        cmd.add_argument("nick", help="nick to target")
        self.commands.register(cmd, self.cmd_voice)

        cmd = CommandParser(prog="DEVOICE", description="devoice someone")
        cmd.add_argument("nick", help="nick to target")
        self.commands.register(cmd, self.cmd_devoice)

        cmd = CommandParser(prog="KICK", description="kick someone")
        cmd.add_argument("nick", help="nick to target")
        cmd.add_argument("reason", nargs="*", help="reason")
        self.commands.register(cmd, self.cmd_kick)

        cmd = CommandParser(prog="KB", description="kick and ban someone")
        cmd.add_argument("nick", help="nick to target")
        cmd.add_argument("reason", nargs="*", help="reason")
        self.commands.register(cmd, self.cmd_kb)

        cmd = CommandParser(prog="JOIN",
                            description="join this channel if not on it")
        self.commands.register(cmd, self.cmd_join)

        cmd = CommandParser(prog="PART",
                            description="leave this channel temporarily")
        self.commands.register(cmd, self.cmd_part)

        cmd = CommandParser(
            prog="STOP",
            description=
            "immediately clear all queued IRC events like long messages",
            epilog=
            "Use this to stop accidental long pastes, also known as STAHP!",
        )
        self.commands.register(cmd, self.cmd_stop,
                               ["STOP!", "STAHP", "STAHP!"])

        self.names_buffer = []
        self.bans_buffer = []
        self.on_channel = []