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.
This commit is contained in:
rht 2023-10-01 01:46:56 -04:00 committed by Anders Kaseorg
parent f11e960537
commit 2814accb09
3 changed files with 17 additions and 17 deletions

View file

@ -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()

View file

@ -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.
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)

View file

@ -1 +1 @@
irc==18.0
irc~=20.3