Fixed that one bug submitted by jamessan about plugin.command capabilities being unhandled.

This commit is contained in:
Jeremy Fincher 2004-01-30 22:14:39 +00:00
parent 3f4a4297fe
commit 5b2d89b086
2 changed files with 67 additions and 23 deletions

View File

@ -271,19 +271,42 @@ def formatArgumentError(method, name=None):
return 'Invalid arguments for %s.' % method.__name__ return 'Invalid arguments for %s.' % method.__name__
def checkCommandCapability(msg, cb, command): def checkCommandCapability(msg, cb, command):
anticap = ircdb.makeAntiCapability(command) plugin = cb.name().lower()
if ircdb.checkCapability(msg.prefix, anticap): pluginCommand = '%s.%s' % (plugin, command)
log.info('Preventing because of anticap: %s', msg.prefix) def checkCapability(capability):
return False assert ircdb.isAntiCapability(capability)
if ircdb.checkCapability(msg.prefix, capability):
log.info('Preventing %s from calling %s because of %s.',
msg.prefix, pluginCommand, capability)
raise RuntimeError, capability
try:
antiPlugin = ircdb.makeAntiCapability(plugin)
antiCommand = ircdb.makeAntiCapability(command)
antiPluginCommand = ircdb.makeAntiCapability(pluginCommand)
checkCapability(antiPlugin)
checkCapability(antiCommand)
checkCapability(antiPluginCommand)
checkAtEnd = [command, pluginCommand]
default = conf.supybot.defaultAllow()
if ircutils.isChannel(msg.args[0]): if ircutils.isChannel(msg.args[0]):
channel = msg.args[0] channel = msg.args[0]
antichancap = ircdb.makeChannelCapability(channel, anticap) checkCapability(ircdb.makeChannelCapability(channel, antiCommand))
if ircdb.checkCapability(msg.prefix, antichancap): checkCapability(ircdb.makeChannelCapability(channel, antiPlugin))
log.info('Preventing because of antichancap: %s', msg.prefix) checkCapability(ircdb.makeChannelCapability(channel,
return False antiPluginCommand))
return conf.supybot.defaultAllow() or \ chanPlugin = ircdb.makeChannelCapability(channel, plugin)
ircdb.checkCapability(msg.prefix, command) or \ chanCommand = ircdb.makeChannelCapability(channel, command)
ircdb.checkCapability(msg.prefix, chancap) chanPluginCommand = ircdb.makeChannelCapability(channel,
pluginCommand)
checkAtEnd += [chanCommand, chanPluginCommand]
default &= ircdb.channels.getChannel(channel).defaultAllow
return not (default or \
any(lambda x: ircdb.checkCapability(msg.prefix, x),
checkAtEnd))
except RuntimeError, e:
s = ircdb.unAntiCapability(str(e))
return s
class RichReplyMethods(object): class RichReplyMethods(object):
@ -330,12 +353,18 @@ class RichReplyMethods(object):
self.reply(prefixer(s)) self.reply(prefixer(s))
def errorNoCapability(self, capability, s='', **kwargs): def errorNoCapability(self, capability, s='', **kwargs):
if isinstance(capability, basestring): # checkCommandCapability!
log.warning('Denying %s for lacking %r capability', log.warning('Denying %s for lacking %r capability',
self.msg.prefix, capability) self.msg.prefix, capability)
if not conf.supybot.reply.noCapabilityError(): if not conf.supybot.reply.noCapabilityError():
v = conf.supybot.replies.noCapability.get(self.msg.args[0])() v = conf.supybot.replies.noCapability.get(self.msg.args[0])()
s = self.__makeReply(v % capability, s) s = self.__makeReply(v % capability, s)
self.error(s, **kwargs) self.error(s, **kwargs)
else:
log.warning('Denying %s for some unspecified capability '
'(or a default)', self.msg.prefix)
v = conf.supybot.replies.genericNoCapability.get(msg.args[0])()
self.error(self.__makeReply(v, s), **kwargs)
def errorPossibleBug(self, s='', **kwargs): def errorPossibleBug(self, s='', **kwargs):
v = conf.supybot.replies.possibleBug.get(self.msg.args[0])() v = conf.supybot.replies.possibleBug.get(self.msg.args[0])()
@ -470,8 +499,9 @@ class IrcObjectProxy(RichReplyMethods):
else: else:
del self.args[0] del self.args[0]
cb = cbs[0] cb = cbs[0]
if not checkCommandCapability(self.msg, cb, name): cap = checkCommandCapability(self.msg, cb, name)
self.errorNoCapability(name) if cap:
self.errorNoCapability(cap)
return return
command = getattr(cb, name) command = getattr(cb, name)
Privmsg.handled = True Privmsg.handled = True
@ -673,8 +703,9 @@ class Privmsg(irclib.IrcCallback):
if name == canonicalName(self.name()): if name == canonicalName(self.name()):
handleBadArgs() handleBadArgs()
elif self.isCommand(name): elif self.isCommand(name):
if not checkCommandCapability(msg, self, name): cap = checkCommandCapability(msg, self, name)
irc.errorNoCapability(name) if cap:
irc.errorNoCapability(cap)
return return
del args[0] del args[0]
method = getattr(self, name) method = getattr(self, name)

View File

@ -278,6 +278,19 @@ registerChannelValue(supybot.replies, 'noCapability',
telling someone they aren't cool enough to use the command they tried to telling someone they aren't cool enough to use the command they tried to
use.""")) use."""))
registerChannelValue(supybot.replies, 'genericNoCapability',
registry.NormalizedString("""You're missing some capability you need.
This could be because you actually possess the anti-capability for the
capability that's required of you, or because the channel provides that
anti-capability by default, or because the global capabilities include
that anti-capability. Or, it could be because the channel or the global
defaultAllow is set to False, meaning that no commands are allowed unless
explicitly in your capabilities. Either way, you can't do what you want
to do.""", """Dertermines what generic error message is given when the bot
is telling someone that they aren't cool enough to use the command they
tried to use, and the author of the code calling errorNoCapability didn't
provide an explicit capability for whatever reason."""))
registerChannelValue(supybot.replies, 'success', registerChannelValue(supybot.replies, 'success',
registry.NormalizedString("""The operation succeeded.""", """Determines registry.NormalizedString("""The operation succeeded.""", """Determines
what message the bot replies with when a command succeeded.""")) what message the bot replies with when a command succeeded."""))