Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

coretasks: add userhost-in-names CAP and UHNAMES ISUPPORT token #2102

Merged
merged 2 commits into from
Jul 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions sopel/coretasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ def handle_isupport(bot, trigger):
"""Handle ``RPL_ISUPPORT`` events."""
# remember if NAMESX is known to be supported, before parsing RPL_ISUPPORT
namesx_support = 'NAMESX' in bot.isupport
uhnames_support = 'UHNAMES' in bot.isupport

# parse ISUPPORT message from server
parameters = {}
Expand All @@ -333,6 +334,13 @@ def handle_isupport(bot, trigger):
# and the server doesn't have the multi-prefix capability
# so we can ask the server to use the NAMESX feature
bot.write(('PROTOCTL', 'NAMESX'))
# was UHNAMES support status updated?
if not uhnames_support and 'UHNAMES' in bot.isupport:
# yes it was!
if 'userhost-in-names' not in bot.server_capabilities:
# and the server doesn't have the userhost-in-names capability
# so we should ask for UHNAMES instead
bot.write(('PROTOCTL', 'UHNAMES'))


@module.event(events.RPL_MYINFO)
Expand Down Expand Up @@ -424,8 +432,6 @@ def handle_names(bot, trigger):

This function keeps track of users' privileges when Sopel joins channels.
"""
names = trigger.split()

# TODO specific to one channel type. See issue 281.
channels = re.search(r'(#\S*)', trigger.raw)
if not channels:
Expand All @@ -449,20 +455,31 @@ def handle_names(bot, trigger):
"!": module.OPER,
}

uhnames = 'UHNAMES' in bot.isupport
userhost_in_names = 'userhost-in-names' in bot.enabled_capabilities

names = trigger.split()
for name in names:
if uhnames or userhost_in_names:
name, mask = name.rsplit('!', 1)
username, hostname = mask.split('@', 1)
else:
username = hostname = None

priv = 0
for prefix, value in iteritems(mapping):
if prefix in name:
priv = priv | value

nick = Identifier(name.lstrip(''.join(mapping.keys())))
bot.privileges[channel][nick] = priv
user = bot.users.get(nick)
if user is None:
# It's not possible to set the username/hostname from info received
# in a NAMES reply, unfortunately.
# The username/hostname will be included in a NAMES reply only if
# userhost-in-names is available. We can use them if present.
# Fortunately, the user should already exist in bot.users by the
# time this code runs, so this is 99.9% ass-covering.
user = target.User(nick, None, None)
user = target.User(nick, username, hostname)
bot.users[nick] = user
bot.channels[channel].add_user(user, privs=priv)

Expand Down Expand Up @@ -900,6 +917,7 @@ def receive_cap_ls_reply(bot, trigger):
'away-notify',
'cap-notify',
'server-time',
'userhost-in-names',
]
for cap in core_caps:
if cap not in bot._cap_reqs:
Expand Down
26 changes: 26 additions & 0 deletions test/test_coretasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,32 @@ def test_handle_isupport_namesx(mockbot):
assert len(mockbot.backend.message_sent) == 1, 'No need to resend!'


def test_handle_isupport_uhnames(mockbot):
mockbot.on_message(
':irc.example.com 005 Sopel '
'SAFELIST ELIST=CTU CPRIVMSG CNOTICE '
':are supported by this server')

assert 'UHNAMES' not in mockbot.isupport
assert mockbot.backend.message_sent == []
assert 'userhost-in-names' not in mockbot.server_capabilities

mockbot.on_message(
':irc.example.com 005 Sopel '
'UHNAMES '
':are supported by this server')

assert 'UHNAMES' in mockbot.isupport
assert mockbot.backend.message_sent == rawlist('PROTOCTL UHNAMES')

mockbot.on_message(
':irc.example.com 005 Sopel '
'UHNAMES '
':are supported by this server')

assert len(mockbot.backend.message_sent) == 1, 'No need to resend!'


def test_handle_isupport_namesx_with_multi_prefix(mockbot):
# set multi-prefix
mockbot.server_capabilities['multi-prefix'] = None
Expand Down