diff --git a/plugins/Channel/config.py b/plugins/Channel/config.py index 5d47a1525..355582cc2 100644 --- a/plugins/Channel/config.py +++ b/plugins/Channel/config.py @@ -1,7 +1,7 @@ ### # Copyright (c) 2004-2005, Jeremiah Fincher # Copyright (c) 2009, James McCoy -# Copyright (c) 2010-2021, Valentin Lorentz +# Copyright (c) 2010-2025, Valentin Lorentz # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -63,4 +63,10 @@ conf.registerChannelValue(Channel, 'partMsg', be used (they are optional in the IRC protocol). The standard substitutions ($version, $nick, etc.) are all handled appropriately."""))) +conf.registerGroup(Channel, 'invite') +conf.registerChannelValue(Channel.invite, 'requireCapability', + registry.String('op', _("""Determines what capability (if any) the bot should + require people trying to use the 'invite' command to have. + Leave empty to allow anyone to use it."""))) + # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/plugins/Channel/plugin.py b/plugins/Channel/plugin.py index 3589e8bd5..00e8e7248 100644 --- a/plugins/Channel/plugin.py +++ b/plugins/Channel/plugin.py @@ -1,7 +1,7 @@ ### # Copyright (c) 2002-2005, Jeremiah Fincher # Copyright (c) 2009-2012, James McCoy -# Copyright (c) 2010-2021, Valentin Lorentz +# Copyright (c) 2010-2025, Valentin Lorentz # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -508,10 +508,17 @@ class Channel(callbacks.Plugin): to join . is only necessary if the message isn't sent in the channel itself. """ + capability = self.registryValue('invite.requireCapability', + channel, irc.network) + if capability: + capability = ircdb.makeChannelCapability(channel, capability) + if not ircdb.checkCapability(msg.prefix, capability): + irc.errorNoCapability(capability, Raise=True) + nick = nick or msg.nick self._sendMsg(irc, ircmsgs.invite(nick, channel)) self.invites[(irc.getRealIrc(), ircutils.toLower(nick))] = irc - invite = wrap(invite, ['op', ('haveHalfop+', _('invite someone')), + invite = wrap(invite, [('haveHalfop+', _('invite someone')), additional('nick')]) def do341(self, irc, msg): diff --git a/plugins/Channel/test.py b/plugins/Channel/test.py index bcfc52786..c2ed15ae2 100644 --- a/plugins/Channel/test.py +++ b/plugins/Channel/test.py @@ -1,7 +1,7 @@ ### # Copyright (c) 2002-2005, Jeremiah Fincher # Copyright (c) 2009, James McCoy -# Copyright (c) 2010-2021, Valentin Lorentz +# Copyright (c) 2010-2025, Valentin Lorentz # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -414,5 +414,36 @@ class ChannelTestCase(ChannelPluginTestCase): self.assertEqual(m.args[0], '#foo') self.assertEqual(m.args[1], 'reason') + def testInvite(self): + self.irc.feedMsg(ircmsgs.op(self.channel, self.nick)) + m = self.getMsg('invite foo') + self.assertEqual(m.command, 'INVITE') + self.assertEqual(m.args, ('foo', self.channel)) + + def testInviteNoCapability(self): + self.irc.feedMsg(ircmsgs.op(self.channel, self.nick)) + m = self.assertError('invite foo', + frm='test!user@with__no_testcap__') + + def testInviteCustomCapability(self): + self.irc.feedMsg(ircmsgs.op(self.channel, self.nick)) + + with conf.supybot.plugins.Channel.invite.requireCapability.context('freeinvite'): + m = self.getMsg('invite foo', + frm='test!user@with__no_testcap__') + self.assertEqual(m.command, 'INVITE') + self.assertEqual(m.args, ('foo', self.channel)) + + self.assertNotError('channel capability set -freeinvite') + + self.assertError('invite foo', + frm='test!user@with__no_testcap__') + + with conf.supybot.plugins.Channel.invite.requireCapability.context(''): + m = self.getMsg('invite foo', + frm='test!user@with__no_testcap__') + self.assertEqual(m.command, 'INVITE') + self.assertEqual(m.args, ('foo', self.channel)) + # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: