TotallyNotRobots / CloudBot

CloudBot - The simple, fast, expandable, open-source Python IRC Bot!
GNU General Public License v3.0
72 stars 39 forks source link

Multiple changes: hastebin_server, cap end after sasl, error core.chan_track:on_mode #641

Open d3xt3r01 opened 1 year ago

d3xt3r01 commented 1 year ago

It all started with seeing that the bot authorizes after connecting... even when using SASL.

1) So, digging I saw it does "CAP REQ" for each capability, one by one... why not all at once? More digging made me see that CAP END is sent immediately instead of doing it after sasl. If no sasl, I don't want it to connect anyway... this can and should be improved.

2) [ERROR] Error in hook core.chan_track:on_mode AttributeError: 'NoneType' object has no attribute 'type' for https://github.com/TotallyNotRobots/CloudBot/blob/main/cloudbot/util/irc.py#L49

3) Also the HASTEBIN_SERVER is a redirect and all sorts of errors show up for /documents...

I'm not a coder, I'm sure I did something wrong but oh well..

Here are my changes:

diff --git a/cloudbot/util/irc.py b/cloudbot/util/irc.py
index 0de64a71..c5dadd9d 100644
--- a/cloudbot/util/irc.py
+++ b/cloudbot/util/irc.py
@@ -83,8 +83,9 @@ def parse_mode_string(
             else:
                 param = None

-            new_modes.append(
-                ModeChange(char=c, adding=adding, param=param, info=mode_info)
-            )
+            if mode_info:
+                new_modes.append(
+                    ModeChange(char=c, adding=adding, param=param, info=mode_info)
+                )

     return new_modes
diff --git a/cloudbot/util/web.py b/cloudbot/util/web.py
index 80a3484c..a27614d5 100644
--- a/cloudbot/util/web.py
+++ b/cloudbot/util/web.py
@@ -26,7 +26,7 @@ from requests import HTTPError, PreparedRequest, RequestException, Response
 DEFAULT_SHORTENER = "is.gd"
 DEFAULT_PASTEBIN = ""

-HASTEBIN_SERVER = "https://hastebin.com"
+HASTEBIN_SERVER = "https://www.toptal.com/developers/hastebin"

 logger = logging.getLogger("cloudbot")

@@ -340,7 +340,7 @@ class Hastebin(Pastebin):

         try:
             r = requests.post(self.url + "/documents", data=encoded)
-            r.raise_for_status()
+            # r.raise_for_status()
         except HTTPError as e:
             r = e.response
             raise ServiceHTTPError(r.reason, r) from e
diff --git a/plugins/core/cap.py b/plugins/core/cap.py
index 77ceec53..14d4d61e 100644
--- a/plugins/core/cap.py
+++ b/plugins/core/cap.py
@@ -20,9 +20,11 @@ def send_cap_ls(conn):

 async def handle_available_caps(conn, caplist, event, irc_paramlist, bot):
+    sasl_auth = conn.config.get("sasl")
     available_caps = conn.memory["available_caps"]  # type: CapList
     available_caps.extend(caplist)
     cap_queue = conn.memory["cap_queue"]
+    tosend = ""
     for cap in caplist:
         name = cap.name
         name_cf = name.casefold()
@@ -36,12 +38,14 @@ async def handle_available_caps(conn, caplist, event, irc_paramlist, bot):
         results = await asyncio.gather(*tasks)
         if any(ok and (res or res is None) for ok, res in results):
             cap_queue[name_cf] = async_util.create_future(conn.loop)
-            conn.cmd("CAP", "REQ", name)
-
-    if irc_paramlist[2] != "*":
-        await asyncio.gather(*cap_queue.values())
-        cap_queue.clear()
-        conn.send("CAP END")
+            tosend = " "+tosend+" "+name
+    conn.cmd("CAP", "REQ", tosend)
+
+    if not sasl_auth or not sasl_auth.get("enabled", False):
+        if irc_paramlist[2] != "*":
+            await asyncio.gather(*cap_queue.values())
+            cap_queue.clear()
+            conn.send("CAP END")

diff --git a/plugins/core/sasl.py b/plugins/core/sasl.py
index 12c9dc83..c6dd498b 100644
--- a/plugins/core/sasl.py
+++ b/plugins/core/sasl.py
@@ -39,6 +39,8 @@ async def sasl_ack(conn):
                 logger.warning("[%s|sasl] SASL nick locked", conn.name)
             elif numeric == "903":
                 logger.info("[%s|sasl] SASL auth successful", conn.name)
+                conn.send("CAP END")
+
             elif numeric == "904":
                 logger.warning("[%s|sasl] SASL auth failed", conn.name)
             elif numeric == "905":
linuxdaemon commented 6 months ago

Hey, the sasl plugin (core/sasl.py) handles the authentication flow by sending AUTHENTICATE once it receives the CAP ACK. Can you provide logs showing the behavior you experienced with it not sending sasl properly?

All of the other issues appear to be symptoms rather than the cause. I'm submitting some changes to fix the mode issues