Support CAP 3.2

This commit is contained in:
jesopo 2018-09-07 15:51:41 +01:00
parent ac76b81421
commit 7e3d7542b9
3 changed files with 42 additions and 18 deletions

View file

@ -287,27 +287,43 @@ class LineHandler(object):
# the server is telling us about its capabilities! # the server is telling us about its capabilities!
def cap(self, event): def cap(self, event):
capabilities = (event["arbitrary"] or "").split(" ") capabilities_list = (event["arbitrary"] or "").split(" ")
capabilities = {}
for capability in capabilities_list:
argument = None
if "=" in capability:
capability, argument = capability.split("=", 1)
capabilities[capability] = argument
subcommand = event["args"][1].lower() subcommand = event["args"][1].lower()
is_multiline = len(event["args"]) > 2 and event["args"][2] == "*"
if subcommand == "ls": if subcommand == "ls":
matched_capabilities = set(capabilities) & CAPABILITIES event["server"].server_capabilities.update(capabilities)
if matched_capabilities: if not is_multiline:
event["server"].queue_capabilities(matched_capabilities) matched_capabilities = set(event["server"
].server_capabilities.keys()) & CAPABILITIES
if matched_capabilities:
event["server"].queue_capabilities(matched_capabilities)
self.events.on("received.cap").on(subcommand).call( self.events.on("received.cap.ls").call(
capabilities=capabilities, server=event["server"]) capabilities=event["server"].server_capabilities,
server=event["server"])
if subcommand == "ls": if event["server"].has_capability_queue():
if event["server"].has_capability_queue(): event["server"].send_capability_queue()
event["server"].send_capability_queue() else:
else: event["server"].send_capability_end()
event["server"].send_capability_end()
elif subcommand == "ack": elif subcommand == "ack":
if not event["server"].waiting_for_capabilities(): event["server"].capabilities.update(capabilities)
event["server"].send_capability_end() if not is_multiline:
event["server"].capabilities = set(capabilities) self.events.on("received.cap.ack").call(
elif subcommand == "ack" or subcommand == "nack": capabilities=event["server"].capabilities,
server=event["server"])
if not event["server"].waiting_for_capabilities():
event["server"].send_capability_end()
elif subcommand == "nack":
event["server"].send_capability_end() event["server"].send_capability_end()
# the server is asking for authentication # the server is asking for authentication

View file

@ -30,6 +30,7 @@ class Server(object):
self._capability_queue = set([]) self._capability_queue = set([])
self._capabilities_waiting = set([]) self._capabilities_waiting = set([])
self.capabilities = set([]) self.capabilities = set([])
self.server_capabilities = {}
self.write_buffer = b"" self.write_buffer = b""
self.buffered_lines = [] self.buffered_lines = []
@ -278,7 +279,7 @@ class Server(object):
self.send("NICK %s" % nickname) self.send("NICK %s" % nickname)
def send_capibility_ls(self): def send_capibility_ls(self):
self.send("CAP LS") self.send("CAP LS 302")
def queue_capability(self, capability): def queue_capability(self, capability):
self._capability_queue.add(capability) self._capability_queue.add(capability)
def queue_capabilities(self, capabilities): def queue_capabilities(self, capabilities):

View file

@ -14,9 +14,16 @@ class Module(object):
event["server"].send_capability_request("sasl") event["server"].send_capability_request("sasl")
def on_cap(self, event): def on_cap(self, event):
if "sasl" in event["capabilities"] and event["server"].get_setting( has_sasl = "sasl" in event["capabilities"]
"sasl", None): has_mechanisms = has_sasl and not event["capabilities"]["sasl"
] == None
has_plaintext = has_mechanisms and "PLAIN" in event["capabilities"
]["sasl"].split(",")
if has_sasl and (has_plaintext or not has_mechanisms) and event[
"server"].get_setting("sasl", None):
event["server"].queue_capability("sasl") event["server"].queue_capability("sasl")
def on_cap_ack(self, event): def on_cap_ack(self, event):
if "sasl" in event["capabilities"]: if "sasl" in event["capabilities"]:
event["server"].send_authenticate("PLAIN") event["server"].send_authenticate("PLAIN")