From 2814accb097e4405926b15eb5dc66167460664f7 Mon Sep 17 00:00:00 2001 From: rht Date: Sun, 1 Oct 2023 01:46:56 -0400 Subject: [PATCH] IRC: Add option for SASL authentication. This additionally reverts to using sync IRC client, because upstream https://github.com/jaraco/irc only supports it for the sync client. --- .../bridge_with_irc/irc-mirror.py | 6 ++++- .../bridge_with_irc/irc_mirror_backend.py | 26 ++++++++----------- .../bridge_with_irc/requirements.txt | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/zulip/integrations/bridge_with_irc/irc-mirror.py b/zulip/integrations/bridge_with_irc/irc-mirror.py index 222ff082..7aaca7b9 100755 --- a/zulip/integrations/bridge_with_irc/irc-mirror.py +++ b/zulip/integrations/bridge_with_irc/irc-mirror.py @@ -18,7 +18,9 @@ Example: --stream is a Zulip stream. --topic is a Zulip topic, is optionally specified, defaults to "IRC". ---nickserv-pw is a password for the nickserv, is optionally specified. +Optional arguments: +--nickserv-pw is a password for the nickserv. +--sasl-password is a password for SASL authentication. Specify your Zulip API credentials and server in a ~/.zuliprc file or using the options. @@ -36,6 +38,7 @@ if __name__ == "__main__": parser.add_argument("--stream", default="general") parser.add_argument("--topic", default="IRC") parser.add_argument("--nickserv-pw", default="") + parser.add_argument("--sasl-password", default=None) options = parser.parse_args() # Setting the client to irc_mirror is critical for this to work @@ -64,5 +67,6 @@ if __name__ == "__main__": options.irc_server, options.nickserv_pw, options.port, + sasl_password=options.sasl_password, ) bot.start() diff --git a/zulip/integrations/bridge_with_irc/irc_mirror_backend.py b/zulip/integrations/bridge_with_irc/irc_mirror_backend.py index c3c534d6..5ee0fd14 100644 --- a/zulip/integrations/bridge_with_irc/irc_mirror_backend.py +++ b/zulip/integrations/bridge_with_irc/irc_mirror_backend.py @@ -1,16 +1,13 @@ import multiprocessing as mp import sys -from typing import Any, Dict +from typing import Any, Dict, Optional import irc.bot import irc.strings from irc.client import Event, ServerConnection, ip_numstr_to_quad -from irc.client_aio import AioReactor class IRCBot(irc.bot.SingleServerIRCBot): - reactor_class = AioReactor - def __init__( self, zulip_client: Any, @@ -21,6 +18,7 @@ class IRCBot(irc.bot.SingleServerIRCBot): server: str, nickserv_password: str = "", port: int = 6667, + sasl_password: Optional[str] = None, ) -> None: self.channel: irc.bot.Channel = channel self.zulip_client = zulip_client @@ -31,19 +29,17 @@ class IRCBot(irc.bot.SingleServerIRCBot): # Make sure the bot is subscribed to the stream self.check_subscription_or_die() # Initialize IRC bot after proper connection to Zulip server has been confirmed. - irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname) + if sasl_password is not None: + irc.bot.SingleServerIRCBot.__init__( + self, [(server, port, sasl_password)], nickname, nickname, sasl_login=nickname + ) + else: + irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname) def zulip_sender(self, sender_string: str) -> str: nick = sender_string.split("!")[0] return nick + "@" + self.IRC_DOMAIN - def connect(self, *args: Any, **kwargs: Any) -> None: - # Taken from - # https://github.com/jaraco/irc/blob/main/irc/client_aio.py, - # in particular the method of AioSimpleIRCClient - self.c = self.reactor.loop.run_until_complete(self.connection.connect(*args, **kwargs)) - print("Listening now. Please send an IRC message to verify operation") - def check_subscription_or_die(self) -> None: resp = self.zulip_client.get_subscriptions() if resp["result"] != "success": @@ -76,7 +72,7 @@ class IRCBot(irc.bot.SingleServerIRCBot): at_the_specified_subject = msg["subject"].casefold() == self.topic.casefold() if in_the_specified_stream and at_the_specified_subject: msg["content"] = "@**{}**: ".format(msg["sender_full_name"]) + msg["content"] - send = lambda x: self.c.privmsg(self.channel, x) + send = lambda x: c.privmsg(self.channel, x) else: return else: @@ -86,9 +82,9 @@ class IRCBot(irc.bot.SingleServerIRCBot): if u["email"] != msg["sender_email"] ] if len(recipients) == 1: - send = lambda x: self.c.privmsg(recipients[0], x) + send = lambda x: c.privmsg(recipients[0], x) else: - send = lambda x: self.c.privmsg_many(recipients, x) + send = lambda x: c.privmsg_many(recipients, x) for line in msg["content"].split("\n"): send(line) diff --git a/zulip/integrations/bridge_with_irc/requirements.txt b/zulip/integrations/bridge_with_irc/requirements.txt index 085dd9a8..130e851d 100644 --- a/zulip/integrations/bridge_with_irc/requirements.txt +++ b/zulip/integrations/bridge_with_irc/requirements.txt @@ -1 +1 @@ -irc==18.0 +irc~=20.3