From fd8f72c3cc488b701cc41a59aafa3176d5c01a48 Mon Sep 17 00:00:00 2001 From: user Date: Sun, 15 Feb 2026 12:53:12 +0100 Subject: [PATCH] fix: detect oper status when users join channels Previously the bot only sent WHO on connect (001), so users joining after the initial scan were never checked for oper status. Now sends WHO on every JOIN event to detect opers mid-session. Co-Authored-By: Claude Opus 4.6 --- src/derp/bot.py | 6 ++++++ tests/test_integration.py | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/derp/bot.py b/src/derp/bot.py index 40ad43a..6483819 100644 --- a/src/derp/bot.py +++ b/src/derp/bot.py @@ -265,6 +265,12 @@ class Bot: if "*" in flags: self._opers.add(f"{nick}!{user}@{host}") + # JOIN — WHO the joining user to detect oper status + if msg.command == "JOIN" and msg.nick and msg.nick != self.nick: + channel = msg.params[0] if msg.params else "" + if channel: + await self.conn.send(format_msg("WHO", msg.nick)) + # QUIT — remove departed nicks from oper set if msg.command == "QUIT" and msg.prefix: self._opers.discard(msg.prefix) diff --git a/tests/test_integration.py b/tests/test_integration.py index 2bd3897..940e464 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -292,6 +292,27 @@ class TestAdmin: assert not any("Permission denied" in r for r in replies) assert any("Opers:" in r for r in replies) + def test_oper_detection_on_join(self): + """User joining a channel triggers WHO; oper detected mid-session.""" + h = _Harness(channels=["#test"]) + h.inject_registration() + # User joins the channel after the bot is already connected + h.conn.inject(":oper!oper@operhost JOIN #test") + # Server responds to the WHO triggered by the JOIN + h.conn.inject( + ":server 352 test #test oper operhost irc.server oper H* " + ":0 Oper Name" + ) + h.privmsg("oper", "#test", "!admins", user="oper", host="operhost") + asyncio.run(h.run()) + + # Verify WHO was sent for the joining nick + who_sent = [s for s in h.conn.sent if "WHO" in s and "oper" in s] + assert len(who_sent) >= 1 + replies = h.sent_privmsgs("#test") + assert not any("Permission denied" in r for r in replies) + assert any("oper!oper@operhost" in r for r in replies) + # -- Channel filter ---------------------------------------------------------