[WIP] Add test for CHGHOST using services

Only Insp + Anope for now

TODO: cleanup code
This commit is contained in:
Valentin Lorentz 2022-04-03 20:42:13 +02:00
parent 9a19416731
commit 77c3c10847
4 changed files with 121 additions and 6 deletions

View File

@ -210,9 +210,10 @@ class BaseServerController(_BaseController):
case: irctest.cases.BaseServerTestCase, # type: ignore
username: str,
password: Optional[str] = None,
**kwargs: Any,
) -> None:
if self.services_controller is not None:
self.services_controller.registerUser(case, username, password)
self.services_controller.registerUser(case, username, password, **kwargs)
else:
raise NotImplementedByController("account registration")
@ -293,7 +294,7 @@ class BaseServicesController(_BaseController):
timeout = time.time() + 5
while True:
c.sendLine(f"PRIVMSG {self.server_controller.nickserv} :HELP")
msgs = self.getNickServResponse(c)
msgs = self.getServiceResponse(c)
for msg in msgs:
if msg.command == "401":
# NickServ not available yet
@ -319,7 +320,7 @@ class BaseServicesController(_BaseController):
c.disconnect()
self.services_up = True
def getNickServResponse(self, client: Any) -> List[Message]:
def getServiceResponse(self, client: Any) -> List[Message]:
"""Wrapper aroung getMessages() that waits longer, because NickServ
is queried asynchronously."""
msgs: List[Message] = []
@ -333,11 +334,14 @@ class BaseServicesController(_BaseController):
case: irctest.cases.BaseServerTestCase, # type: ignore
username: str,
password: Optional[str] = None,
**kwargs: Any,
) -> None:
if not case.run_services:
raise ValueError(
"Attempted to register a nick, but `run_services` it not True."
)
if kwargs:
raise NotImplementedByController(", ".join(kwargs))
assert password
client = case.addClient(show_io=True)
case.sendLine(client, "NICK " + username)
@ -350,7 +354,7 @@ class BaseServicesController(_BaseController):
f"PRIVMSG {self.server_controller.nickserv} "
f":REGISTER {password} foo@example.org",
)
msgs = self.getNickServResponse(case.clients[client])
msgs = self.getServiceResponse(case.clients[client])
if self.server_controller.software_name == "inspircd":
assert "900" in {msg.command for msg in msgs}, msgs
assert "NOTICE" in {msg.command for msg in msgs}, msgs

View File

@ -1,9 +1,12 @@
import os
import shutil
import subprocess
from typing import Type
from typing import Any, Optional, Type
from irctest import cases, runner
from irctest.basecontrollers import BaseServicesController, DirectoryBasedController
from irctest.client_mock import ClientMock
from irctest.irc_utils.sasl import sasl_plain_blob
TEMPLATE_CONFIG = """
serverinfo {{
@ -30,12 +33,17 @@ networkinfo {{
userlen = 10
hostlen = 64
chanlen = 32
vhost_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-"
}}
mail {{
usemail = no
}}
/************************
* NickServ:
*/
service {{
nick = "NickServ"
user = "services"
@ -57,6 +65,29 @@ module {{
}}
command {{ service = "NickServ"; name = "REGISTER"; command = "nickserv/register"; }}
/************************
* HostServ:
*/
service {{
nick = "HostServ"
user = "services"
host = "services.host"
gecos = "vHost Service"
}}
module {{
name = "hostserv"
client = "HostServ"
}}
module {{ name = "hs_set" }}
command {{ service = "HostServ"; name = "SET"; command = "hostserv/set"; }}
/************************
* Misc:
*/
options {{
casemap = "ascii"
readtimeout = 5s
@ -66,7 +97,6 @@ options {{
module {{ name = "m_sasl" }}
module {{ name = "enc_sha256" }}
module {{ name = "ns_cert" }}
"""
@ -121,6 +151,39 @@ class AnopeController(BaseServicesController, DirectoryBasedController):
# stderr=subprocess.DEVNULL,
)
def registerUser(
self,
case: cases.BaseServerTestCase, # type: ignore
username: str,
password: Optional[str] = None,
vhost: Optional[str] = None,
**kwargs: Any,
) -> None:
super().registerUser(case, username, password)
if vhost:
if not password:
raise runner.NotImplementedByController(
"vHost for users with no password"
)
c = ClientMock(name="setVhost", show_io=True)
c.connect(self.server_controller.hostname, self.server_controller.port)
c.sendLine("CAP REQ :sasl")
c.sendLine("NICK " + username)
c.sendLine("USER r e g :user")
while c.getMessage(synchronize=False).command != "CAP":
pass
c.sendLine("AUTHENTICATE PLAIN")
while c.getMessage(synchronize=False).command != "AUTHENTICATE":
pass
c.sendLine(sasl_plain_blob(username, password))
c.sendLine("CAP END")
while c.getMessage(synchronize=False).command != "001":
pass
c.getMessages()
c.sendLine(f"PRIVMSG HostServ :SET {username} {vhost}")
self.getServiceResponse(c)
def get_irctest_controller_class() -> Type[AnopeController]:
return AnopeController

View File

@ -61,10 +61,12 @@ TEMPLATE_CONFIG = """
# Protocol:
<module name="botmode">
<module name="cap">
<module name="chghost">
<module name="ircv3">
<module name="ircv3_accounttag">
<module name="ircv3_batch">
<module name="ircv3_capnotify">
<module name="ircv3_chghost">
<module name="ircv3_ctctags">
<module name="ircv3_echomessage">
<module name="ircv3_invitenotify">

View File

@ -0,0 +1,46 @@
"""
<http://ircv3.net/specs/extensions/chghost.html>
"""
from irctest import cases
from irctest.irc_utils.sasl import sasl_plain_blob
from irctest.patma import ANYSTR, StrRe
@cases.mark_services
class ChghostServicesTestCase(cases.BaseServerTestCase, cases.OptionalityHelper):
def testChghostFromServices(self):
self.connectClient("observer", capabilities=["chghost"], skip_if_cap_nak=True)
self.connectClient("oldclient")
self.controller.registerUser(
self, "vhostuser", "sesame", vhost="vhost.example.com"
)
self.connectClient("vhost-user", capabilities=["sasl"], skip_if_cap_nak=True)
for i in (1, 2, 3):
self.sendLine(i, "JOIN #chan")
self.getMessages(i)
for i in (1, 2, 3):
self.getMessages(i)
self.sendLine(3, "AUTHENTICATE PLAIN")
self.assertMessageMatch(
self.getRegistrationMessage(3),
command="AUTHENTICATE",
params=["+"],
)
self.sendLine(3, sasl_plain_blob("vhostuser", "sesame"))
self.assertMessageMatch(
self.getRegistrationMessage(3),
command="900",
)
self.assertMessageMatch(
self.getMessage(1),
prefix=StrRe("vhost-user!.*@(?!vhost-user.example)"),
command="CHGHOST",
params=[ANYSTR, "vhost.example.com"],
)
self.assertEqual(self.getMessages(2), []) # cycle?