mirror of
https://github.com/jlu5/PyLink.git
synced 2024-12-24 03:33:10 +01:00
parent
99790bfae2
commit
d12f12ae22
26
classes.py
26
classes.py
@ -18,6 +18,7 @@ import ipaddress
|
||||
import queue
|
||||
import functools
|
||||
import collections
|
||||
import string
|
||||
|
||||
try:
|
||||
import ircmatch
|
||||
@ -1074,6 +1075,31 @@ class PyLinkNetworkCoreWithUtils(PyLinkNetworkCore):
|
||||
if self.match_host(banmask, uid) and uid in self.users:
|
||||
yield uid
|
||||
|
||||
def make_channel_ban(self, uid, ban_type='ban'):
|
||||
"""Creates a hostmask-based ban for the given user.
|
||||
|
||||
Ban exceptions, invite exceptions quiets, and extbans are also supported by setting ban_type
|
||||
to the appropriate PyLink named mode (e.g. "ban", "banexception", "invex", "quiet", "ban_nonick")."""
|
||||
assert uid in self.users, "Unknown user %s" % uid
|
||||
|
||||
# FIXME: verify that this is a valid mask.
|
||||
# XXX: support slicing hosts so things like *!ident@*.isp.net are possible. This is actually
|
||||
# more annoying to do than it appears because of vHosts using /, IPv6 addresses
|
||||
# (cloaked and uncloaked), etc.
|
||||
ban_style = self.serverdata.get('ban_style') or conf.conf['pylink'].get('ban_style') or \
|
||||
'*!*@$host'
|
||||
|
||||
template = string.Template(ban_style)
|
||||
banhost = template.safe_substitute(ban_style, **self.users[uid].__dict__)
|
||||
assert utils.isHostmask(banhost), "Ban mask %r is not a valid hostmask!" % banhost
|
||||
|
||||
if ban_type in self.cmodes:
|
||||
return ('+%s' % self.cmodes[ban_type], banhost)
|
||||
elif ban_type in self.extbans_acting: # Handle extbans, which are generally "+b prefix:banmask"
|
||||
return ('+%s' % self.cmodes['ban'], self.extbans_acting[ban_type]+banhost)
|
||||
else:
|
||||
raise ValueError("ban_type %r is not available on IRCd %r" % (ban_type, self.protoname))
|
||||
|
||||
def updateTS(self, sender, channel, their_ts, modes=None):
|
||||
"""
|
||||
Merges modes of a channel given the remote TS and a list of modes.
|
||||
|
@ -67,6 +67,62 @@ def checkban(irc, source, args):
|
||||
else:
|
||||
irc.reply('No, \x02%s\x02 does not match \x02%s\x02.' % (args.target, args.banmask))
|
||||
|
||||
massban_parser = utils.IRCParser()
|
||||
massban_parser.add_argument('channel')
|
||||
massban_parser.add_argument('banmask')
|
||||
# Regarding default ban reason: it's a good idea not to leave in the caller to prevent retaliation...
|
||||
massban_parser.add_argument('reason', nargs='*', default="Banned")
|
||||
massban_parser.add_argument('--quiet', '-q', action='store_true')
|
||||
|
||||
def massban(irc, source, args):
|
||||
"""<channel> <banmask / exttarget> [<kick reason>] [--quiet/-q]
|
||||
|
||||
Applies (i.e. kicks affected users) the given PyLink banmask on the specified channel.
|
||||
|
||||
The --quiet option can also be given to mass-mute the given user on networks where this is supported
|
||||
(currently ts6, unreal, and inspircd). No kicks will be sent in this case."""
|
||||
permissions.check_permissions(irc, source, ['opercmds.massban'])
|
||||
|
||||
args = massban_parser.parse_args(args)
|
||||
|
||||
if args.channel not in irc.channels:
|
||||
irc.error("Unknown channel %r" % args.channel)
|
||||
return
|
||||
|
||||
results = 0
|
||||
|
||||
for uid in irc.match_all(args.banmask, channel=args.channel):
|
||||
# Remove the target's access before banning them.
|
||||
bans = [('-%s' % irc.cmodes[prefix], uid) for prefix in irc.channels[args.channel].get_prefix_modes(uid) if prefix in irc.cmodes]
|
||||
|
||||
# Then, add the actual ban.
|
||||
bans += [irc.make_channel_ban(uid, ban_type='quiet' if args.quiet else 'ban')]
|
||||
irc.mode(irc.pseudoclient.uid, args.channel, bans)
|
||||
|
||||
try:
|
||||
irc.call_hooks([irc.pseudoclient.uid, 'OPERCMDS_MASSBAN',
|
||||
{'target': args.channel, 'modes': bans, 'parse_as': 'MODE'}])
|
||||
except:
|
||||
log.exception('(%s) Failed to send process massban hook; some bans may have not '
|
||||
'been sent to plugins / relay networks!', irc.name)
|
||||
|
||||
if not args.quiet:
|
||||
irc.kick(irc.pseudoclient.uid, args.channel, uid, args.reason)
|
||||
|
||||
# XXX: this better not be blocking...
|
||||
try:
|
||||
irc.call_hooks([irc.pseudoclient.uid, 'OPERCMDS_MASSKICK',
|
||||
{'channel': args.channel, 'target': uid, 'text': args.reason, 'parse_as': 'KICK'}])
|
||||
|
||||
except:
|
||||
log.exception('(%s) Failed to send process massban hook; some kicks may have not '
|
||||
'been sent to plugins / relay networks!', irc.name)
|
||||
|
||||
results += 1
|
||||
else:
|
||||
irc.reply('Banned %s users on %r.' % (results, args.channel))
|
||||
utils.add_cmd(massban, aliases=('mban',))
|
||||
|
||||
@utils.add_cmd
|
||||
def jupe(irc, source, args):
|
||||
"""<server> [<reason>]
|
||||
|
Loading…
Reference in New Issue
Block a user