diff --git a/irctest/controllers/charybdis.py b/irctest/controllers/charybdis.py index 9e14a81..db43d08 100644 --- a/irctest/controllers/charybdis.py +++ b/irctest/controllers/charybdis.py @@ -60,7 +60,7 @@ privset "omnioper" {{ privs = oper:general, oper:privs, oper:testline, oper:kill, oper:operwall, oper:message, oper:routing, oper:kline, oper:unkline, oper:xline, oper:resv, oper:cmodes, oper:mass_notice, oper:wallops, - oper:remoteban, + oper:remoteban, oper:local_kill, usermode:servnotice, auspex:oper, auspex:hostname, auspex:umodes, auspex:cmodes, oper:admin, oper:die, oper:rehash, oper:spy, oper:grant; }}; diff --git a/irctest/controllers/inspircd.py b/irctest/controllers/inspircd.py index 6707422..ecd24ea 100644 --- a/irctest/controllers/inspircd.py +++ b/irctest/controllers/inspircd.py @@ -19,7 +19,7 @@ TEMPLATE_CONFIG = """ :::::: -O:*:operpassword:operuser:::: +O:*:operpassword:operuser:::K: """ diff --git a/irctest/server_tests/kill.py b/irctest/server_tests/kill.py new file mode 100644 index 0000000..4b97f61 --- /dev/null +++ b/irctest/server_tests/kill.py @@ -0,0 +1,67 @@ +""" +The KILL command (`Modern `__) +""" + + +from irctest import cases +from irctest.numerics import ERR_NOPRIVILEGES, RPL_YOUREOPER + + +class KillTestCase(cases.BaseServerTestCase): + @cases.mark_specifications("Modern") + @cases.xfailIfSoftware(["Sable"], "https://github.com/Libera-Chat/sable/issues/154") + def testKill(self): + self.connectClient("ircop", name="ircop") + self.connectClient("alice", name="alice") + self.connectClient("bob", name="bob") + + self.sendLine("ircop", "OPER operuser operpassword") + self.assertIn( + RPL_YOUREOPER, + [m.command for m in self.getMessages("ircop")], + fail_msg="OPER failed", + ) + + self.sendLine("alice", "KILL bob :some arbitrary reason") + self.assertIn( + ERR_NOPRIVILEGES, + [m.command for m in self.getMessages("alice")], + fail_msg="unprivileged KILL not rejected", + ) + # bob is not killed + self.getMessages("bob") + + self.sendLine("alice", "KILL alice :some arbitrary reason") + self.assertIn( + ERR_NOPRIVILEGES, + [m.command for m in self.getMessages("alice")], + fail_msg="unprivileged KILL not rejected", + ) + # alice is not killed + self.getMessages("alice") + + # privileged KILL should succeed + self.sendLine("ircop", "KILL alice :some arbitrary reason") + self.getMessages("ircop") + self.assertDisconnected("alice") + + self.sendLine("ircop", "KILL bob :some arbitrary reason") + self.getMessages("ircop") + self.assertDisconnected("bob") + + @cases.mark_specifications("Ergo") + def testKillOneArgument(self): + self.connectClient("ircop", name="ircop") + self.connectClient("alice", name="alice") + + self.sendLine("ircop", "OPER operuser operpassword") + self.assertIn( + RPL_YOUREOPER, + [m.command for m in self.getMessages("ircop")], + fail_msg="OPER failed", + ) + + # 1-argument kill command, accepted by Ergo and some implementations + self.sendLine("ircop", "KILL alice") + self.getMessages("ircop") + self.assertDisconnected("alice")