From 4214ab4f69c319c7106ab5fe6105565651587008 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Sun, 7 Oct 2012 17:20:48 +0200 Subject: [PATCH] AttackProtector: Add the 'kicked' trigger to kban people kicked too much. --- AttackProtector/config.py | 28 +++++++++++++++------------- AttackProtector/plugin.py | 12 +++++++++++- AttackProtector/test.py | 17 +++++++++++++++++ 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/AttackProtector/config.py b/AttackProtector/config.py index f61f278..dd20177 100644 --- a/AttackProtector/config.py +++ b/AttackProtector/config.py @@ -88,22 +88,24 @@ conf.registerGlobalValue(AttackProtector, 'delay', wait before being enabled. A too low value makes the bot believe that its incoming messages 'flood' on connection is an attack."""))) -kinds = {'join': ['5p10', 'ban'], - 'part': ['4p5', 'ban'], - 'nick': ['7p300', 'ban'], - 'message': ['10p20', 'kick'], - 'groupjoin': ['20p10', 'mode+i'], - 'grouppart': ['20p10', 'mode+i'], - 'groupnick': ['20p10', 'mode+N'], - 'groupmessage': ['100p10', 'mode+m']} -for kind in kinds: - data = kinds[kind] +kinds = {'join': ['5p10', 'ban', ''], + 'part': ['4p5', 'ban', ''], + 'nick': ['7p300', 'ban', ''], + 'message': ['10p20', 'kick', ''], + 'kicked': ['5p60', 'kban', _('user has been kicked multiple times')], + 'groupjoin': ['20p10', 'mode+i', ''], + 'grouppart': ['20p10', 'mode+i', ''], + 'groupnick': ['20p10', 'mode+N', ''], + 'groupmessage': ['100p10', 'mode+m', '']} +for kind, data in kinds.items(): + detection, punishment, help_ = data + help_ = help_ or (_('a %s flood is detected') % kind) conf.registerGroup(AttackProtector, kind) conf.registerChannelValue(getattr(AttackProtector, kind), 'detection', - XpY(data[0], _("""In the format XpY, where X is the number of %s per + XpY(detection, _("""In the format XpY, where X is the number of %s per Y seconds that triggers the punishment.""") % kind)) conf.registerChannelValue(getattr(AttackProtector, kind), 'punishment', - Punishment(data[1], _("""Determines the punishment applied when a - %s flood is detected.""") % kind)) + Punishment(punishment, _("""Determines the punishment applied when + %s.""") % help_)) # vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: diff --git a/AttackProtector/plugin.py b/AttackProtector/plugin.py index a85f391..5828200 100644 --- a/AttackProtector/plugin.py +++ b/AttackProtector/plugin.py @@ -115,7 +115,7 @@ class AttackProtector(callbacks.Plugin): self._enableOn = time.time() + self.registryValue('delay') self._database = AttackProtectorDatabase() - def _eventCatcher(self, irc, msg, kind): + def _eventCatcher(self, irc, msg, kind, **kwargs): if kind in ['part', 'join', 'message']: channels = [msg.args[0]] prefix = msg.prefix @@ -126,6 +126,11 @@ class AttackProtector(callbacks.Plugin): if newNick in c.users: channels.append(channel) prefix = '*!' + msg.prefix.split('!')[1] + elif kind in ['kicked']: + assert 'kicked_prefix' in kwargs + channel = msg.args[0] + channels = [channel] + prefix = kwargs['kicked_prefix'] try: for channel in channels: item = None @@ -183,6 +188,11 @@ class AttackProtector(callbacks.Plugin): punishment = self.registryValue('%s.punishment' % kind, channel) reason = _('%s flood detected') % kind + if punishment == 'kick': + self._eventCatcher(irc, msg, 'kicked', kicked_prefix=prefix) + if kind == 'kicked': + reason = _('You exceeded your kick quota.') + banmaskstyle = conf.supybot.protocols.irc.banmask banmask = banmaskstyle.makeBanmask(prefix) if punishment == 'kick': diff --git a/AttackProtector/test.py b/AttackProtector/test.py index 32bb9d7..0f35b5c 100644 --- a/AttackProtector/test.py +++ b/AttackProtector/test.py @@ -206,6 +206,23 @@ class AttackProtectorTestCase(ChannelPluginTestCase): return self._getIfAnswerIsEqual(ircmsgs.IrcMsg(prefix="", command="MODE", args=(self.channel, mode, self.nick))) + ################################# + # 'Kicked' tests + def testKbanAfterKicks(self): + prefix = 'testing!Attack@Protector' + for i in range(1, 5): + for i in range(1, 11): + msg = ircmsgs.privmsg(self.channel, 'Hi, this is a flood', + prefix=prefix) + self.irc.feedMsg(msg) + m = self.irc.takeMsg() + self.assertEqual(m.command, 'KICK') + for i in range(1, 11): + msg = ircmsgs.privmsg(self.channel, 'Hi, this is a flood', + prefix=prefix) + self.irc.feedMsg(msg) + self.assertEqual(self.irc.takeMsg().command, 'MODE') + ################################# # Global tests def testCleanCollection(self):