Add configuration variable conf.supybot.capabilities.private.

This variable is a list of capabilities that are considered as 'private',
ie. the bot won't tell anyone but admins that a user has it, nor will the
bot give a list of users with this capability.
This commit is contained in:
Valentin Lorentz 2012-10-29 20:15:14 +01:00
parent 88b2b235ff
commit fba70d15bc
5 changed files with 32 additions and 5 deletions

View File

@ -54,6 +54,15 @@ class User(callbacks.Plugin):
predicates = []
for (option, arg) in optlist:
if option == 'capability':
try:
u = ircdb.users.getUser(msg.prefix)
if arg in conf.supybot.capabilities.private() and \
not u._checkCapability('admin'):
raise KeyError
except KeyError:
# Note that it may be raised by checkCapability too.
irc.error(_('This is a private capability. Only admins '
'can see who has it.'), Raise=True)
def p(u, cap=arg):
try:
return u._checkCapability(cap)

View File

@ -33,7 +33,7 @@ import supybot.world as world
import supybot.ircdb as ircdb
class UserTestCase(PluginTestCase):
plugins = ('User', 'Admin')
plugins = ('User', 'Admin', 'Config')
prefix1 = 'somethingElse!user@host.tld'
prefix2 = 'EvensomethingElse!user@host.tld'
def testHostmaskList(self):
@ -95,6 +95,14 @@ class UserTestCase(PluginTestCase):
self.assertRegexp('user list --capability testcap', 'no matching')
self.assertNotError('admin capability add biff testcap')
self.assertResponse('user list --capability testcap', 'biff')
self.assertNotError('config capabilities.private testcap')
self.assertRegexp('user list --capability testcap', 'Error:.*private')
self.assertNotError('admin capability add biff admin')
self.assertResponse('user list --capability testcap', 'biff')
self.assertNotError('admin capability remove biff admin')
self.assertRegexp('user list --capability testcap', 'Error:.*private')
self.assertNotError('config capabilities.private ""')
self.assertResponse('user list --capability testcap', 'biff')
self.assertNotError('admin capability remove biff testcap')
self.assertRegexp('user list --capability testcap', 'no matching')

View File

@ -484,8 +484,12 @@ class RichReplyMethods(object):
log.warning('Denying %s for lacking %q capability.',
self.msg.prefix, capability)
if not self._getConfig(conf.supybot.reply.error.noCapability):
v = self._getConfig(conf.supybot.replies.noCapability)
s = self.__makeReply(v % capability, s)
if capability in conf.supybot.capabilities.private():
v = self._getConfig(conf.supybot.replies.genericNoCapability)
else:
v = self._getConfig(conf.supybot.replies.noCapability)
v %= capability
s = self.__makeReply(v, s)
return self._error(s, **kwargs)
else:
log.debug('Not sending capability error, '

View File

@ -1082,6 +1082,9 @@ conf.registerGlobalValue(conf.supybot.capabilities, 'default',
registry.Boolean(True, """Determines whether the bot by default will allow
users to have a capability. If this is disabled, a user must explicitly
have the capability for whatever command he wishes to run."""))
conf.registerGlobalValue(conf.supybot.capabilities, 'private',
registry.SpaceSeparatedListOfStrings([], """Determines what capabilities
the bot will never tell to a non-admin whether or not a user has them."""))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

@ -531,13 +531,16 @@ class PluginRegexpTestCase(PluginTestCase):
self.assertResponse('test', 'test <foo>')
class RichReplyMethodsTestCase(PluginTestCase):
plugins = ()
plugins = ('Config',)
class NoCapability(callbacks.Plugin):
def error(self, irc, msg, args):
irc.errorNoCapability('admin')
def testErrorNoCapability(self):
self.irc.addCallback(self.NoCapability(self.irc))
self.assertRegexp('error', 'admin')
self.assertRegexp('error', 'You don\'t have the admin capability')
self.assertNotError('config capabilities.private admin')
self.assertRegexp('error', 'Error: You\'re missing some capability')
self.assertNotError('config capabilities.private ""')
class SourceNestedPluginTestCase(PluginTestCase):