3
0
mirror of https://github.com/jlu5/PyLink.git synced 2025-02-17 14:01:03 +01:00

relay: fix relaying between channels not matching their lowercase (DB) name

This rewrites get_relay() to be case insensitive by taking the IRC object instead of a string name.
This fixes a regression introduced by 32249ac (case-insensitive channel state)
This commit is contained in:
James Lu 2017-08-18 12:39:47 -07:00
parent 70fbbb206e
commit 8563556850
2 changed files with 21 additions and 18 deletions

View File

@ -428,9 +428,12 @@ def get_orig_user(irc, user, targetirc=None):
else: else:
return remoteuser return remoteuser
def get_relay(chanpair): def get_relay(irc, channel):
"""Finds the matching relay entry name for the given (network name, channel) """Finds the matching relay entry name for the given network, channel
pair, if one exists.""" pair, if one exists."""
chanpair = (irc.name, irc.to_lower(channel))
if chanpair in db: # This chanpair is a shared channel; others link to it if chanpair in db: # This chanpair is a shared channel; others link to it
return chanpair return chanpair
# This chanpair is linked *to* a remote channel # This chanpair is linked *to* a remote channel
@ -441,11 +444,11 @@ def get_relay(chanpair):
def get_remote_channel(irc, remoteirc, channel): def get_remote_channel(irc, remoteirc, channel):
"""Returns the linked channel name for the given channel on remoteirc, """Returns the linked channel name for the given channel on remoteirc,
if one exists.""" if one exists."""
query = (irc.name, channel)
remotenetname = remoteirc.name remotenetname = remoteirc.name
chanpair = get_relay(query) chanpair = get_relay(irc, channel)
if chanpair is None: if chanpair is None:
return return
if chanpair[0] == remotenetname: if chanpair[0] == remotenetname:
return chanpair[1] return chanpair[1]
else: else:
@ -457,7 +460,7 @@ def initialize_channel(irc, channel):
"""Initializes a relay channel (merge local/remote users, set modes, etc.).""" """Initializes a relay channel (merge local/remote users, set modes, etc.)."""
# We're initializing a relay that already exists. This can be done at # We're initializing a relay that already exists. This can be done at
# ENDBURST, or on the LINK command. # ENDBURST, or on the LINK command.
relay = get_relay((irc.name, channel)) relay = get_relay(irc, channel)
log.debug('(%s) relay.initialize_channel being called on %s', irc.name, channel) log.debug('(%s) relay.initialize_channel being called on %s', irc.name, channel)
log.debug('(%s) relay.initialize_channel: relay pair found to be %s', irc.name, relay) log.debug('(%s) relay.initialize_channel: relay pair found to be %s', irc.name, relay)
queued_users = [] queued_users = []
@ -507,7 +510,7 @@ def remove_channel(irc, channel):
if irc.pseudoclient: if irc.pseudoclient:
irc.part(irc.pseudoclient.uid, channel, 'Channel delinked.') irc.part(irc.pseudoclient.uid, channel, 'Channel delinked.')
relay = get_relay((irc.name, channel)) relay = get_relay(irc, channel)
if relay: if relay:
for user in irc.channels[channel].users.copy(): for user in irc.channels[channel].users.copy():
if not is_relay_client(irc, user): if not is_relay_client(irc, user):
@ -537,7 +540,7 @@ def check_claim(irc, channel, sender, chanobj=None):
(this is because we allow u-lines to override with ops to prevent mode floods). (this is because we allow u-lines to override with ops to prevent mode floods).
6) The sender is a PyLink client/server (checks are suppressed in this case). 6) The sender is a PyLink client/server (checks are suppressed in this case).
""" """
relay = get_relay((irc.name, channel)) relay = get_relay(irc, channel)
try: try:
mlist = chanobj.prefixmodes mlist = chanobj.prefixmodes
except AttributeError: except AttributeError:
@ -999,7 +1002,7 @@ utils.add_hook(handle_operup, 'CLIENT_OPERED')
def handle_join(irc, numeric, command, args): def handle_join(irc, numeric, command, args):
channel = args['channel'] channel = args['channel']
if not get_relay((irc.name, channel)): if not get_relay(irc, channel):
# No relay here, return. # No relay here, return.
return return
ts = args['ts'] ts = args['ts']
@ -1122,7 +1125,7 @@ def handle_part(irc, numeric, command, args):
# For clientbot: treat forced parts to the bot as clearchan, and attempt to rejoin only # For clientbot: treat forced parts to the bot as clearchan, and attempt to rejoin only
# if it affected a relay. # if it affected a relay.
if not irc.has_cap('can-spawn-clients'): if not irc.has_cap('can-spawn-clients'):
for channel in [c for c in channels if get_relay((irc.name, c))]: for channel in [c for c in channels if get_relay(irc, c)]:
for user in irc.channels[channel].users: for user in irc.channels[channel].users:
if (not irc.is_internal_client(user)) and (not is_relay_client(irc, user)): if (not irc.is_internal_client(user)) and (not is_relay_client(irc, user)):
irc.call_hooks([irc.sid, 'CLIENTBOT_SERVICE_KICKED', {'channel': channel, 'target': user, irc.call_hooks([irc.sid, 'CLIENTBOT_SERVICE_KICKED', {'channel': channel, 'target': user,
@ -1158,7 +1161,7 @@ def handle_messages(irc, numeric, command, args):
irc.name, numeric, target) irc.name, numeric, target)
return return
relay = get_relay((irc.name, target)) relay = get_relay(irc, target)
remoteusers = relayusers[(irc.name, numeric)] remoteusers = relayusers[(irc.name, numeric)]
# HACK: Don't break on sending to @#channel or similar. TODO: This should really # HACK: Don't break on sending to @#channel or similar. TODO: This should really
@ -1281,7 +1284,7 @@ def handle_kick(irc, source, command, args):
target = args['target'] target = args['target']
text = args['text'] text = args['text']
kicker = source kicker = source
relay = get_relay((irc.name, channel)) relay = get_relay(irc, channel)
# Special case for clientbot: treat kicks to the PyLink service bot as channel clear. # Special case for clientbot: treat kicks to the PyLink service bot as channel clear.
if (not irc.has_cap('can-spawn-clients')) and irc.pseudoclient and target == irc.pseudoclient.uid: if (not irc.has_cap('can-spawn-clients')) and irc.pseudoclient and target == irc.pseudoclient.uid:
@ -1753,7 +1756,7 @@ def create(irc, source, args):
# Check to see whether the channel requested is already part of a different # Check to see whether the channel requested is already part of a different
# relay. # relay.
localentry = get_relay((irc.name, channel)) localentry = get_relay(irc, channel)
if localentry: if localentry:
irc.error('Channel %r is already part of a relay.' % channel) irc.error('Channel %r is already part of a relay.' % channel)
return return
@ -1899,7 +1902,7 @@ def link(irc, source, args):
if remotenet not in world.networkobjects: if remotenet not in world.networkobjects:
irc.error('No network named %r exists.' % remotenet) irc.error('No network named %r exists.' % remotenet)
return return
localentry = get_relay((irc.name, localchan)) localentry = get_relay(irc, localchan)
if localentry: if localentry:
irc.error('Channel %r is already part of a relay.' % localchan) irc.error('Channel %r is already part of a relay.' % localchan)
@ -1970,7 +1973,7 @@ def delink(irc, source, args):
if not utils.isChannel(channel): if not utils.isChannel(channel):
irc.error('Invalid channel %r.' % channel) irc.error('Invalid channel %r.' % channel)
return return
entry = get_relay((irc.name, channel)) entry = get_relay(irc, channel)
if entry: if entry:
if entry[0] == irc.name: # We own this channel. if entry[0] == irc.name: # We own this channel.
if not remotenet: if not remotenet:
@ -2094,7 +2097,7 @@ def linkacl(irc, source, args):
if not utils.isChannel(channel): if not utils.isChannel(channel):
irc.error('Invalid channel %r.' % channel) irc.error('Invalid channel %r.' % channel)
return return
relay = get_relay((irc.name, channel)) relay = get_relay(irc, channel)
if not relay: if not relay:
irc.error('No such relay %r exists.' % channel) irc.error('No such relay %r exists.' % channel)
return return
@ -2154,7 +2157,7 @@ def showuser(irc, source, args):
irc.reply("\x02Relay nicks\x02: %s" % ', '.join(nicks), private=True) irc.reply("\x02Relay nicks\x02: %s" % ', '.join(nicks), private=True)
relaychannels = [] relaychannels = []
for ch in irc.users[u].channels: for ch in irc.users[u].channels:
relay = get_relay((irc.name, ch)) relay = get_relay(irc, ch)
if relay: if relay:
relaychannels.append(''.join(relay)) relaychannels.append(''.join(relay))
if relaychannels and (irc.is_oper(source) or u == source): if relaychannels and (irc.is_oper(source) or u == source):
@ -2184,7 +2187,7 @@ def showchan(irc, source, args):
return return
else: else:
relayentry = get_relay((irc.name, channel)) relayentry = get_relay(irc, channel)
if relayentry: if relayentry:
relays = ['\x02%s\x02' % ''.join(relayentry)] relays = ['\x02%s\x02' % ''.join(relayentry)]
relays += [''.join(link) for link in db[relayentry]['links']] relays += [''.join(link) for link in db[relayentry]['links']]

View File

@ -121,7 +121,7 @@ def cb_relay_core(irc, source, command, args):
# No user data given. This was probably some other global event such as SQUIT. # No user data given. This was probably some other global event such as SQUIT.
userdata = irc.pseudoclient userdata = irc.pseudoclient
targets = [channel for channel in userdata.channels if relay.get_relay((irc.name, channel))] targets = [channel for channel in userdata.channels if relay.get_relay(irc, channel)]
else: else:
# Pluralize the channel so that we can iterate over it. # Pluralize the channel so that we can iterate over it.
targets = [target] targets = [target]