3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-27 21:19:31 +01:00

relay: move claim enforcement routines outside the mode/kick loops

This prevents claim responses from being sent multiple times.
This commit is contained in:
James Lu 2017-12-14 12:15:19 -08:00
parent 59c12ff354
commit b2270ca3eb

View File

@ -1483,30 +1483,6 @@ def handle_kick(irc, source, command, args):
log.debug('(%s) relay.handle_kick: target %s is an internal client, going to look up the real user', irc.name, target)
real_target = get_orig_user(irc, target, targetirc=remoteirc)
if not check_claim(irc, channel, kicker):
log.debug('(%s) relay.handle_kick: kicker %s is not opped... We should rejoin the target user %s', irc.name, kicker, real_target)
# Home network is not in the channel's claim AND the kicker is not
# opped. We won't propograte the kick then.
# TODO: make the check slightly more advanced: i.e. halfops can't
# kick ops, admins can't kick owners, etc.
modes = get_prefix_modes(remoteirc, irc, remotechan, real_target)
# Join the kicked client back with its respective modes.
irc.sjoin(irc.sid, channel, [(modes, target)])
if kicker in irc.users:
log.info('(%s) relay: Blocked KICK (reason %r) from %s/%s to relay client %s on %s.',
irc.name, args['text'], irc.users[source].nick, irc.name,
remoteirc.users[real_target].nick, channel)
irc.msg(kicker, "This channel is claimed; your kick to "
"%s has been blocked because you are not "
"(half)opped." % channel, notice=True)
else:
log.info('(%s) relay: Blocked KICK (reason %r) from server %s to relay client %s/%s on %s.',
irc.name, args['text'], irc.servers[source].name,
remoteirc.users[real_target].nick, remoteirc.name, channel)
return
if not real_target:
return
@ -1541,6 +1517,35 @@ def handle_kick(irc, source, command, args):
del relayusers[(irc.name, target)][remoteirc.name]
remoteirc.quit(real_target, 'Left all shared channels.')
if not check_claim(irc, channel, kicker):
homenet, real_target = get_orig_user(irc, target)
homeirc = world.networkobjects.get(homenet)
homenick = homeirc.users[real_target].nick if homeirc else '<ghost user>'
homechan = get_remote_channel(irc, homeirc, channel)
log.debug('(%s) relay.handle_kick: kicker %s is not opped... We should rejoin the target user %s', irc.name, kicker, real_target)
# Home network is not in the channel's claim AND the kicker is not
# opped. We won't propograte the kick then.
# TODO: make the check slightly more advanced: i.e. halfops can't
# kick ops, admins can't kick owners, etc.
modes = get_prefix_modes(homeirc, irc, homechan, real_target)
# Join the kicked client back with its respective modes.
irc.sjoin(irc.sid, channel, [(modes, target)])
if kicker in irc.users:
log.info('(%s) relay: Blocked KICK (reason %r) from %s/%s to %s/%s on %s.',
irc.name, args['text'], irc.users[source].nick, irc.name,
homenick, homenet, channel)
irc.msg(kicker, "This channel is claimed; your kick to "
"%s has been blocked because you are not "
"(half)opped." % channel, notice=True)
else:
log.info('(%s) relay: Blocked KICK (reason %r) from server %s to %s/%s on %s.',
irc.name, args['text'], irc.servers[source].name ,
homenick, homenet, channel)
return
iterate_all(irc, _handle_kick_loop, extra_args=(source, command, args))
if origuser and not irc.users[target].channels:
@ -1582,15 +1587,11 @@ def _is_uline(irc, client):
return irc.get_friendly_name(irc.get_server(client)) in irc.serverdata.get('ulines', [])
def handle_mode(irc, numeric, command, args):
def _handle_mode_loop(irc, remoteirc, numeric, command, args):
target = args['target']
modes = args['modes']
def _handle_mode_loop(irc, remoteirc, numeric, command, args):
if irc.is_channel(target):
# Use the old state of the channel to check for CLAIM access.
oldchan = args.get('channeldata')
if check_claim(irc, target, numeric, chanobj=oldchan):
remotechan = get_remote_channel(irc, remoteirc, target)
if not remotechan:
return
@ -1603,8 +1604,10 @@ def handle_mode(irc, numeric, command, args):
if not remoteirc.has_cap('can-spawn-clients'):
friendly_modes = []
for modepair in modes:
if modepair[0][-1] in irc.prefixmodes:
modechar = modepair[0][-1]
if modechar in irc.prefixmodes:
orig_user = get_orig_user(irc, modepair[1])
if orig_user and orig_user[0] == remoteirc.name:
# Don't display prefix mode changes for someone on the target clientbot
@ -1613,7 +1616,7 @@ def handle_mode(irc, numeric, command, args):
# Convert UIDs to nicks when relaying this to clientbot.
modepair = (modepair[0], irc.get_friendly_name(modepair[1]))
elif modepair[0][-1] in irc.cmodes['*A'] and irc.is_hostmask(modepair[1]) and \
elif modechar in irc.cmodes['*A'] and irc.is_hostmask(modepair[1]) and \
conf.conf.get('relay', {}).get('clientbot_modesync', 'none').lower() != 'none':
# Don't show bans if the ban is a simple n!u@h and modesync is enabled
continue
@ -1626,7 +1629,29 @@ def handle_mode(irc, numeric, command, args):
if supported_modes:
remoteirc.mode(remotesender, remotechan, supported_modes)
else: # Mode change blocked by CLAIM.
else:
# Set hideoper on remote opers, to prevent inflating
# /lusers and various /stats
hideoper_mode = remoteirc.umodes.get('hideoper')
modes = get_supported_umodes(irc, remoteirc, modes)
if hideoper_mode:
if ('+o', None) in modes:
modes.append(('+%s' % hideoper_mode, None))
elif ('-o', None) in modes:
modes.append(('-%s' % hideoper_mode, None))
remoteuser = get_remote_user(irc, remoteirc, target, spawn_if_missing=False)
if remoteuser and modes:
remoteirc.mode(remoteuser, remoteuser, modes)
if irc.is_channel(target):
# Use the old state of the channel to check for CLAIM access.
oldchan = args.get('channeldata')
if not check_claim(irc, target, numeric, chanobj=oldchan):
# Mode change blocked by CLAIM.
reversed_modes = irc.reverse_modes(target, modes, oldobj=oldchan)
if _is_uline(irc, numeric):
@ -1649,22 +1674,6 @@ def handle_mode(irc, numeric, command, args):
irc.mode(irc.sid, target, reversed_modes)
return
else:
# Set hideoper on remote opers, to prevent inflating
# /lusers and various /stats
hideoper_mode = remoteirc.umodes.get('hideoper')
modes = get_supported_umodes(irc, remoteirc, modes)
if hideoper_mode:
if ('+o', None) in modes:
modes.append(('+%s' % hideoper_mode, None))
elif ('-o', None) in modes:
modes.append(('-%s' % hideoper_mode, None))
remoteuser = get_remote_user(irc, remoteirc, target, spawn_if_missing=False)
if remoteuser and modes:
remoteirc.mode(remoteuser, remoteuser, modes)
iterate_all(irc, _handle_mode_loop, extra_args=(numeric, command, args))
utils.add_hook(handle_mode, 'MODE')