Skip to content

Commit

Permalink
IRC: Add option for SASL authentication.
Browse files Browse the repository at this point in the history
This additionally reverts to using sync IRC client, because upstream
https://github.com/jaraco/irc only supports it for the sync client.
  • Loading branch information
rht committed Nov 13, 2023
1 parent 6aedfe6 commit b5be49a
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 17 deletions.
6 changes: 5 additions & 1 deletion zulip/integrations/bridge_with_irc/irc-mirror.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
--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.
Expand All @@ -36,6 +38,7 @@
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
Expand Down Expand Up @@ -64,5 +67,6 @@
options.irc_server,
options.nickserv_pw,
options.port,
sasl_password=options.sasl_password,
)
bot.start()
29 changes: 14 additions & 15 deletions zulip/integrations/bridge_with_irc/irc_mirror_backend.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import logging
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

logging.basicConfig(level=logging.DEBUG)

class IRCBot(irc.bot.SingleServerIRCBot):
reactor_class = AioReactor

class IRCBot(irc.bot.SingleServerIRCBot):
def __init__(
self,
zulip_client: Any,
Expand All @@ -21,6 +21,7 @@ def __init__(
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
Expand All @@ -31,19 +32,17 @@ def __init__(
# 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":
Expand Down Expand Up @@ -76,7 +75,7 @@ def forward_to_irc(msg: Dict[str, Any]) -> None:
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:
Expand All @@ -86,9 +85,9 @@ def forward_to_irc(msg: Dict[str, Any]) -> None:
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)

Expand Down
2 changes: 1 addition & 1 deletion zulip/integrations/bridge_with_irc/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
irc==18.0
irc~=20.3

0 comments on commit b5be49a

Please sign in to comment.