예제 #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)")
        self.commands.register(cmd, self.cmd_open)

        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,
            )
            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="STATUS", description="list active users")
            self.commands.register(cmd, self.cmd_status)

            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)

        self.mx_register("m.room.message", self.on_mx_message)
예제 #2
0
    def init(self):
        self.name = None
        self.connected = False
        self.nick = None
        self.username = None
        self.ircname = None
        self.password = None
        self.sasl_username = None
        self.sasl_password = None
        self.autocmd = None

        self.commands = CommandManager()
        self.conn = None
        self.rooms = {}
        self.connlock = asyncio.Lock()
        self.disconnect = True
        self.real_host = "?" * 63  # worst case default
        self.keys = {}  # temp dict of join channel keys

        cmd = CommandParser(
            prog="NICK",
            description="set/change nickname",
            epilog=
            ("You can always see your current nickname on the network without arguments.\n"
             "If connected new nickname will be sent to the server immediately. It may be rejected and an underscore appended"
             " to it automatically.\n"),
        )
        cmd.add_argument("nick", nargs="?", help="new nickname")
        self.commands.register(cmd, self.cmd_nick)

        cmd = CommandParser(
            prog="USERNAME",
            description="set username",
            epilog=
            ("Setting a new username requires reconnecting to the network.\n"
             "\n"
             "Note: If you are a local user it will be replaced by the local part of your Matrix ID.\n"
             "Federated users are generated a shortened digest of their Matrix ID. Bridge admins have an"
             " exception where username will be respected and sent as their ident.\n"
             ),
        )
        cmd.add_argument("username", nargs="?", help="new username")
        cmd.add_argument("--remove",
                         action="store_true",
                         help="remove stored username")
        self.commands.register(cmd, self.cmd_username)

        cmd = CommandParser(
            prog="IRCNAME",
            description="set ircname (realname)",
            epilog=(
                "Setting a new ircname requires reconnecting to the network.\n"
            ),
        )
        cmd.add_argument("ircname", nargs="?", help="new ircname")
        cmd.add_argument("--remove",
                         action="store_true",
                         help="remove stored ircname")
        self.commands.register(cmd, self.cmd_ircname)

        cmd = CommandParser(
            prog="PASSWORD",
            description="set server password",
            epilog=
            ("You can store your network password using this command and it will be automatically offered on connect.\n"
             "Some networks allow using this to identify with NickServ on connect without sending a separate message.\n"
             "\n"
             "Note: Bridge administrators can trivially see the stored password if they want to.\n"
             ),
        )
        cmd.add_argument("password", nargs="?", help="new password")
        cmd.add_argument("--remove",
                         action="store_true",
                         help="remove stored password")
        self.commands.register(cmd, self.cmd_password)

        cmd = CommandParser(
            prog="SASL",
            description="set SASL PLAIN credentials",
            epilog=
            ("If the network supports SASL authentication you can configure them with this command.\n"
             "\n"
             "Note: Bridge administrators can trivially see the stored password if they want to.\n"
             ),
        )
        cmd.add_argument("--username", help="SASL username")
        cmd.add_argument("--password", help="SASL password")
        cmd.add_argument("--remove",
                         action="store_true",
                         help="remove stored credentials")
        self.commands.register(cmd, self.cmd_sasl)

        cmd = CommandParser(
            prog="AUTOCMD",
            description="run commands on connect",
            epilog=
            ("If the network you are connecting to does not support server password to identify you automatically"
             " can set this to send a command before joining channels.\n"
             "\n"
             'Example (QuakeNet): AUTOCMD "UMODE +x; MSG [email protected] auth foo bar"\n'
             "Example (OFTC): AUTOCMD NICKSERV identify foo bar\n"),
        )
        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="CONNECT",
            description="connect to network",
            epilog=
            ("When this command is invoked the connection to this network will be persisted across disconnects and"
             " bridge restart.\n"
             "Only if the server KILLs your connection it will stay disconnected until CONNECT is invoked again.\n"
             "\n"
             "If you want to cancel automatic reconnect you need to issue the DISCONNECT command.\n"
             ),
        )
        self.commands.register(cmd, self.cmd_connect)

        cmd = CommandParser(
            prog="DISCONNECT",
            description="disconnect from network",
            epilog=
            ("In addition to disconnecting from an active network connection this will also cancel any automatic"
             "reconnection attempt.\n"),
        )
        self.commands.register(cmd, self.cmd_disconnect)

        cmd = CommandParser(prog="RECONNECT",
                            description="reconnect to network")
        self.commands.register(cmd, self.cmd_reconnect)

        cmd = CommandParser(
            prog="RAW",
            description="send raw IRC commands",
            epilog=
            ("Arguments (text) are not quoted in any way so it's possible to send ANY command to the server.\n"
             "This is meant as a last resort if the bridge does not have built-in support for some IRC command.\n"
             "\n"
             "Note: You may need to use colon (:) for multi-word arguments, see the IRC RFC for details.\n"
             ),
        )
        cmd.add_argument("text", nargs="+", help="raw text")
        self.commands.register(cmd, self.cmd_raw)

        cmd = CommandParser(
            prog="QUERY",
            description="start a private chat",
            epilog=
            ("Creates a new DM with the target nick. They do not need to be connected for this command to work.\n"
             ),
        )
        cmd.add_argument("nick", help="target nickname")
        cmd.add_argument("message", nargs="*", help="optional message")
        self.commands.register(cmd, self.cmd_query)

        cmd = CommandParser(
            prog="MSG",
            description="send a message without opening a DM",
            epilog=
            ("If the target nick does not exist on the network an error reply may be generated by the server.\n"
             ),
        )
        cmd.add_argument("nick", help="target nickname")
        cmd.add_argument("message", nargs="+", help="message")
        self.commands.register(cmd, self.cmd_msg)

        cmd = CommandParser(
            prog="NICKSERV",
            description="send a message to NickServ (if supported by network)",
            epilog="Alias: NS",
        )
        cmd.add_argument("message", nargs="+", help="message")
        self.commands.register(cmd, self.cmd_nickserv, ["NS"])

        cmd = CommandParser(
            prog="CHANSERV",
            description="send a message to ChanServ (if supported by network)",
            epilog="Alias: CS",
        )
        cmd.add_argument("message", nargs="+", help="message")
        self.commands.register(cmd, self.cmd_chanserv, ["CS"])

        cmd = CommandParser(
            prog="JOIN",
            description="join a channel",
            epilog=
            ("Any channels joined will be persisted between reconnects.\n"
             "\n"
             "Note: Bridge administrators can trivially see the stored channel key if they want to.\n"
             ),
        )
        cmd.add_argument("channel", help="target channel")
        cmd.add_argument("key", nargs="?", help="channel key")
        self.commands.register(cmd, self.cmd_join)

        cmd = CommandParser(
            prog="PLUMB",
            description="plumb a room",
            epilog=
            ("Plumbs a channel in single-puppeted mode. This will make the bridge join the room and then join the"
             " configured IRC channel.\n"),
        )
        cmd.add_argument(
            "room",
            help="target Matrix room ID (eg. !uniqueid:your-homeserver)")
        cmd.add_argument("channel", help="target channel")
        cmd.add_argument("key", nargs="?", help="channel key")
        self.commands.register(cmd, self.cmd_plumb)

        cmd = CommandParser(prog="UMODE", description="set user modes")
        cmd.add_argument("flags", help="user mode flags")
        self.commands.register(cmd, self.cmd_umode)

        cmd = CommandParser(
            prog="WAIT",
            description="wait specified amount of time",
            epilog=("Use with AUTOCMD to add delays between commands."),
        )
        cmd.add_argument("seconds", help="how many seconds to wait")
        self.commands.register(cmd, self.cmd_wait)

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

        self.key = None

        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)

        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)

        self.names_buffer = []
        self.bans_buffer = []
예제 #4
0
    def init(self):
        self.name = None
        self.connected = False
        self.nick = None
        self.username = None
        self.ircname = None
        self.password = None
        self.autocmd = None

        self.commands = CommandManager()
        self.conn = None
        self.rooms = {}
        self.connlock = asyncio.Lock()
        self.disconnect = True
        self.real_host = "?" * 63  # worst case default

        cmd = CommandParser(prog="NICK", description="Change nickname")
        cmd.add_argument("nick", nargs="?", help="new nickname")
        self.commands.register(cmd, self.cmd_nick)

        cmd = CommandParser(prog="USERNAME", description="Change username")
        cmd.add_argument("username", nargs="?", help="new username")
        cmd.add_argument("--remove",
                         action="store_true",
                         help="remove stored username")
        self.commands.register(cmd, self.cmd_username)

        cmd = CommandParser(prog="IRCNAME", description="Change ircname")
        cmd.add_argument("ircname", nargs="?", help="new ircname")
        cmd.add_argument("--remove",
                         action="store_true",
                         help="remove stored ircname")
        self.commands.register(cmd, self.cmd_ircname)

        cmd = CommandParser(prog="PASSWORD", description="Set server password")
        cmd.add_argument("password", nargs="?", help="new password")
        cmd.add_argument("--remove",
                         action="store_true",
                         help="remove stored password")
        self.commands.register(cmd, self.cmd_password)

        cmd = CommandParser(
            prog="AUTOCMD",
            description="Run a RAW IRC command on connect (to identify)")
        cmd.add_argument("command", nargs="*", help="raw IRC command")
        cmd.add_argument("--remove",
                         action="store_true",
                         help="remove stored command")
        self.commands.register(cmd, self.cmd_autocmd)

        cmd = CommandParser(prog="CONNECT", description="Connect to network")
        self.commands.register(cmd, self.cmd_connect)

        cmd = CommandParser(prog="DISCONNECT",
                            description="Disconnect from network")
        self.commands.register(cmd, self.cmd_disconnect)

        cmd = CommandParser(prog="RECONNECT",
                            description="Reconnect to network")
        self.commands.register(cmd, self.cmd_reconnect)

        cmd = CommandParser(prog="RAW", description="Send raw IRC commands")
        cmd.add_argument("text", nargs="+", help="raw text")
        self.commands.register(cmd, self.cmd_raw)

        cmd = CommandParser(prog="QUERY", description="Start a private chat")
        cmd.add_argument("nick", help="target nickname")
        cmd.add_argument("message", nargs="*", help="optional message")
        self.commands.register(cmd, self.cmd_query)

        cmd = CommandParser(prog="MSG",
                            description="Send a message without opening a DM")
        cmd.add_argument("nick", help="target nickname")
        cmd.add_argument("message", nargs="+", help="message")
        self.commands.register(cmd, self.cmd_msg)

        cmd = CommandParser(prog="JOIN", description="Join a channel")
        cmd.add_argument("channel", help="target channel")
        cmd.add_argument("key", nargs="?", help="channel key")
        self.commands.register(cmd, self.cmd_join)

        self.mx_register("m.room.message", self.on_mx_message)
예제 #5
0
    def init(self) -> None:
        self.name = None
        self.network = None
        self.network_id = None
        self.network_name = None  # deprecated
        self.media = []
        self.lazy_members = {}  # allow lazy joining your own ghost for echo

        self.commands = CommandManager()

        if type(self) == PrivateRoom:
            cmd = CommandParser(prog="WHOIS",
                                description="WHOIS the other user")
            self.commands.register(cmd, self.cmd_whois)

        cmd = CommandParser(
            prog="MAXLINES",
            description=
            "set maximum number of lines per message until truncation or pastebin"
        )
        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"
        )
        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)

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

        self.key = None

        cmd = CommandParser(prog="MODE", description="send MODE command")
        cmd.add_argument("args", nargs="*", help="MODE command arguments")
        self.commands.register(cmd, self.cmd_mode)

        cmd = CommandParser(prog="NAMES",
                            description="resynchronize channel members")
        self.commands.register(cmd, self.cmd_names)

        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)

        self.names_buffer = []
        self.bans_buffer = []
예제 #7
0
    def init(self) -> None:
        super().init()

        cmd = CommandParser(
            prog="DISPLAYNAMES",
            description=
            "enable or disable use of displaynames in relayed messages")
        cmd.add_argument("--enable",
                         dest="enabled",
                         action="store_true",
                         help="Enable displaynames")
        cmd.add_argument("--disable",
                         dest="enabled",
                         action="store_false",
                         help="Disable displaynames (fallback to MXID)")
        cmd.set_defaults(enabled=None)
        self.commands.register(cmd, self.cmd_displaynames)

        cmd = CommandParser(
            prog="DISAMBIGUATION",
            description=
            "enable or disable disambiguation of conflicting displaynames")
        cmd.add_argument("--enable",
                         dest="enabled",
                         action="store_true",
                         help="Enable disambiguation (postfix with MXID)")
        cmd.add_argument("--disable",
                         dest="enabled",
                         action="store_false",
                         help="Disable disambiguation")
        cmd.set_defaults(enabled=None)
        self.commands.register(cmd, self.cmd_disambiguation)

        cmd = CommandParser(
            prog="ZWSP",
            description="enable or disable Zero-Width-Space anti-ping")
        cmd.add_argument("--enable",
                         dest="enabled",
                         action="store_true",
                         help="Enable ZWSP anti-ping")
        cmd.add_argument("--disable",
                         dest="enabled",
                         action="store_false",
                         help="Disable ZWSP anti-ping")
        cmd.set_defaults(enabled=None)
        self.commands.register(cmd, self.cmd_zwsp)

        cmd = CommandParser(
            prog="NOTICERELAY",
            description="enable or disable relaying of Matrix notices to IRC")
        cmd.add_argument("--enable",
                         dest="enabled",
                         action="store_true",
                         help="Enable notice relay")
        cmd.add_argument("--disable",
                         dest="enabled",
                         action="store_false",
                         help="Disable notice relay")
        cmd.set_defaults(enabled=None)
        self.commands.register(cmd, self.cmd_noticerelay)

        cmd = CommandParser(
            prog="TOPIC",
            description="show or set channel topic and configure sync mode")
        cmd.add_argument("--sync",
                         choices=["off", "irc", "matrix", "any"],
                         help="Topic sync targets, defaults to off")
        cmd.add_argument("text", nargs="*", help="topic text if setting")
        self.commands.register(cmd, self.cmd_topic)

        cmd = CommandParser(
            prog="RELAYTAG",
            description="set RELAYMSG tag if supported by server")
        cmd.add_argument("tag", nargs="?", help="new tag")
        self.commands.register(cmd, self.cmd_relaytag)

        self.mx_register("m.room.topic", self._on_mx_room_topic)
예제 #8
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)
예제 #9
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 = []
예제 #10
0
    def init(self):
        self.commands = CommandManager()

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

        cmd = CommandParser(prog="SERVERS", description="List servers")
        cmd.add_argument("network", help="network name")
        self.commands.register(cmd, self.cmd_servers)

        cmd = CommandParser(prog="OPEN",
                            description="Open network room to connect")
        cmd.add_argument("name", help="network name")
        self.commands.register(cmd, self.cmd_open)

        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 allow mask")
            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="Remove allow mask")
            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 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 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)
            self.commands.register(cmd, self.cmd_addserver)

            cmd = CommandParser(prog="DELSERVER",
                                description="Delete server from 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)

        self.mx_register("m.room.message", self.on_mx_message)