Skip to content

Commit

Permalink
Add configuration variable conf.supybot.capabilities.private.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
progval committed Oct 29, 2012
1 parent 88b2b23 commit fba70d1
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 5 deletions.
9 changes: 9 additions & 0 deletions plugins/User/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ def list(self, irc, msg, args, optlist, glob):
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)
Expand Down
10 changes: 9 additions & 1 deletion plugins/User/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import supybot.ircdb as ircdb

class UserTestCase(PluginTestCase):
plugins = ('User', 'Admin')
plugins = ('User', 'Admin', 'Config')
prefix1 = '[email protected]'
prefix2 = '[email protected]'
def testHostmaskList(self):
Expand Down Expand Up @@ -95,6 +95,14 @@ def testList(self):
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')

Expand Down
8 changes: 6 additions & 2 deletions src/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,8 +484,12 @@ def errorNoCapability(self, capability, s='', **kwargs):
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, '
Expand Down
3 changes: 3 additions & 0 deletions src/ircdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,9 @@ def setValue(self, v, allowDefaultOwner=conf.allowDefaultOwner):
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:
7 changes: 5 additions & 2 deletions test/test_callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,13 +531,16 @@ def testNoEscapingArgumentError(self):
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):
Expand Down

0 comments on commit fba70d1

Please sign in to comment.