mirror of
https://github.com/jlu5/PyLink.git
synced 2024-12-25 20:22:45 +01:00
parent
99790bfae2
commit
d12f12ae22
26
classes.py
26
classes.py
@ -18,6 +18,7 @@ import ipaddress
|
|||||||
import queue
|
import queue
|
||||||
import functools
|
import functools
|
||||||
import collections
|
import collections
|
||||||
|
import string
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import ircmatch
|
import ircmatch
|
||||||
@ -1074,6 +1075,31 @@ class PyLinkNetworkCoreWithUtils(PyLinkNetworkCore):
|
|||||||
if self.match_host(banmask, uid) and uid in self.users:
|
if self.match_host(banmask, uid) and uid in self.users:
|
||||||
yield uid
|
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):
|
def updateTS(self, sender, channel, their_ts, modes=None):
|
||||||
"""
|
"""
|
||||||
Merges modes of a channel given the remote TS and a list of modes.
|
Merges modes of a channel given the remote TS and a list of modes.
|
||||||
|
@ -67,6 +67,62 @@ def checkban(irc, source, args):
|
|||||||
else:
|
else:
|
||||||
irc.reply('No, \x02%s\x02 does not match \x02%s\x02.' % (args.target, args.banmask))
|
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
|
@utils.add_cmd
|
||||||
def jupe(irc, source, args):
|
def jupe(irc, source, args):
|
||||||
"""<server> [<reason>]
|
"""<server> [<reason>]
|
||||||
|
Loading…
Reference in New Issue
Block a user