Ejemplo n.º 1
0
 def testWallopsPrivileges(self):
     """
     https://github.com/ircdocs/modern-irc/pull/118
     """
     self.connectClient("nick1")
     self.sendLine(1, "WALLOPS :hi everyone")
     message = self.getMessage(1)
     if message.command == ERR_UNKNOWNCOMMAND:
         raise runner.NotImplementedByController("WALLOPS")
     self.assertMessageMatch(message,
                             command=ERR_NOPRIVILEGES,
                             params=["nick1", ANYSTR])
Ejemplo n.º 2
0
    def testWallops(self):
        """
        "The WALLOPS command is used to send a message to all currently connected
        users who have set the 'w' user mode for themselves."
        -- https://datatracker.ietf.org/doc/html/rfc2812#section-4.7
        -- https://github.com/ircdocs/modern-irc/pull/118

        "Servers MAY echo WALLOPS messages to their sender even if they don't have
        the 'w' user mode.
        Servers MAY send WALLOPS only to operators."
        -- https://github.com/ircdocs/modern-irc/pull/118

        """
        self.connectClient("nick1")
        self.connectClient("nick2")
        self.connectClient("nick3")

        self.sendLine(2, "MODE nick2 -w")
        self.getMessages(2)
        self.sendLine(3, "MODE nick3 +w")
        self.getMessages(3)

        self.sendLine(1, "OPER operuser operpassword")
        self.assertIn(
            RPL_YOUREOPER,
            [m.command for m in self.getMessages(1)],
            fail_msg="OPER failed",
        )

        self.sendLine(1, "WALLOPS :hi everyone")

        messages = self.getMessages(1)
        if ERR_UNKNOWNCOMMAND in (message.command for message in messages):
            raise runner.NotImplementedByController("WALLOPS")
        for message in messages:
            self.assertMessageMatch(
                message,
                prefix=StrRe("nick1!.*"),
                command="WALLOPS",
                params=[StrRe(".*hi everyone")],
            )

        messages = self.getMessages(3)
        if messages:
            self.assertMessageMatch(
                messages[0],
                prefix=StrRe("nick1!.*"),
                command="WALLOPS",
                params=[StrRe(".*hi everyone")],
            )
        self.assertEqual(self.getMessages(2), [],
                         fail_msg="Server sent WALLOPS to user without +w")
Ejemplo n.º 3
0
 def testChannelsEquivalent(self, casemapping, name1, name2):
     self.connectClient("foo")
     self.connectClient("bar")
     if self.server_support["CASEMAPPING"] != casemapping:
         raise runner.NotImplementedByController(
             "Casemapping {} not implemented".format(casemapping)
         )
     self.joinClient(1, name1)
     self.joinClient(2, name2)
     try:
         m = self.getMessage(1)
         self.assertMessageMatch(m, command="JOIN", nick="bar")
     except client_mock.NoMessageException:
         raise AssertionError(
             "Channel names {} and {} are not equivalent.".format(name1, name2)
         )
Ejemplo n.º 4
0
    def testTargmax(self):
        """
        "Format: TARGMAX=[<command>:[limit]{,<command>:[limit]}]"
        -- https://modern.ircdocs.horse/#targmax-parameter

        "TARGMAX=[cmd:[number][,cmd:[number][,...]]]"
        -- https://defs.ircdocs.horse/defs/isupport.html#targmax
        """
        self.connectClient("foo")

        if "TARGMAX" not in self.server_support:
            raise runner.NotImplementedByController("TARGMAX")

        parts = self.server_support["TARGMAX"].split(",")
        for part in parts:
            self.assertTrue(
                re.match("[A-Z]+:[0-9]*", part), "Invalid TARGMAX key:value: %r", part
            )
Ejemplo n.º 5
0
    def testDoubleKickMessages(self, multiple_targets):
        """“The server MUST NOT send KICK messages with multiple channels or
        users to clients.  This is necessarily to maintain backward
        compatibility with old client software.”
        -- https://tools.ietf.org/html/rfc2812#section-3.2.8

        "The server MUST NOT send KICK messages with multiple channels or
        users to clients.
        This is necessary to maintain backward compatibility with existing
        client software."
        -- https://modern.ircdocs.horse/#kick-message

        "Servers MAY limit the number of target users per `KICK` command
        via the [`TARGMAX` parameter of `RPL_ISUPPORT`](#targmax-parameter),
        and silently drop targets if the number of targets exceeds the limit."
        -- https://modern.ircdocs.horse/#kick-message

        "If the "TARGMAX" parameter is not advertised or a value is not sent
        then a client SHOULD assume that no commands except the "JOIN" and "PART"
        commands accept multiple parameters."
        -- https://defs.ircdocs.horse/defs/isupport.html#targmax

        "If this parameter is not advertised or a value is not sent then a client
        SHOULD assume that no commands except the `JOIN` and `PART` commands
        accept multiple parameters."
        -- https://github.com/ircdocs/modern-irc/pull/113

        "If <limit> is not specified, then there is no maximum number of targets
        for that command."
        -- https://modern.ircdocs.horse/#targmax-parameter
        """
        self.connectClient("foo")
        self.joinChannel(1, "#chan")

        self.connectClient("bar")
        self.joinChannel(2, "#chan")

        self.connectClient("baz")
        self.joinChannel(3, "#chan")

        self.connectClient("qux")
        self.joinChannel(4, "#chan")

        targmax = dict(
            item.split(":", 1)
            for item in self.server_support.get("TARGMAX", "").split(",")
            if item)
        if targmax.get("KICK", "1") == "1":
            raise runner.NotImplementedByController("Multi-target KICK")

        # TODO: check foo is an operator

        # Synchronize
        self.getMessages(1)
        self.getMessages(2)
        self.getMessages(3)
        self.getMessages(4)

        if multiple_targets:
            self.sendLine(1, "KICK #chan,#chan bar,baz :bye")
        else:
            self.sendLine(1, "KICK #chan bar,baz :bye")
        try:
            m = self.getMessage(1)
            if m.command == "482":
                raise runner.OptionalExtensionNotSupported(
                    "Channel creators are not opped by default.")
        except client_mock.NoMessageException:
            # The RFCs do not say KICK must be echoed
            pass

        mgroup = self.getMessages(4)
        self.assertGreaterEqual(len(mgroup), 2, mgroup)
        m1, m2 = mgroup[:2]

        self.assertMessageMatch(m1,
                                command="KICK",
                                params=["#chan", ANYSTR, "bye"])
        self.assertMessageMatch(m2,
                                command="KICK",
                                params=["#chan", ANYSTR, "bye"])

        if (m1.params[1] == "bar"
                and m2.params[1] == "baz") or (m1.params[1] == "baz"
                                               and m2.params[1] == "bar"):
            ...  # success
        else:
            raise AssertionError(
                "Middle params [{}, {}] are not correct.".format(
                    m1.params[1], m2.params[1]))