Added RFE #801859: no-hostmask (secure) option for users.

This commit is contained in:
Jeremy Fincher 2003-10-03 09:57:52 +00:00
parent 9cbc766b7c
commit 36984d3fa5
3 changed files with 70 additions and 5 deletions

View File

@ -315,6 +315,39 @@ class UserCommands(callbacks.Privmsg):
except KeyError:
irc.error(msg, conf.replyNotRegistered)
def setsecure(self, irc, msg, args):
"""<password> [<True|False>]
Sets the secure flag on the user of the person sending the message.
Requires that the person's hostmask be in the list of hostmasks for
that user in addition to the password being correct. When the secure
flag is set, the user *must* identify before he can be recognized.
If a specific True/False value is not given, it inverts the current
value.
"""
if not self._checkNotChannel(irc, msg, password):
return
try:
id = ircdb.users.getUserId(msg.prefix)
user = ircdb.users.getUser(id)
except KeyError:
irc.error(msg, conf.replyNotRegistered)
(password, value) = privmsgs.getArgs(args, optional=1)
if value == '':
value = not user.secure
elif value.lower() in ('true', 'false'):
value = eval(value.capitalize())
else:
irc.error(msg, '%s is not a valid boolean value.' % value)
return
if user.checkPassword(password) and \
user.checkHostmask(msg.prefix, useAuth=False):
user.secure = value
ircdb.users.setUser(id, user)
irc.reply(msg, 'Secure flag set to %s' % value)
else:
irc.error(msg, conf.replyIncorrectAuth)
Class = UserCommands

View File

@ -171,10 +171,11 @@ class IrcUser(object):
"""This class holds the capabilities and authentications for a user.
"""
def __init__(self, ignore=False, password='', name='',
capabilities=(), hostmasks=None):
capabilities=(), hostmasks=None, secure=False):
self.auth = None # The (time, hostmask) a user authenticated under
self.name = name # The name of the user.
self.ignore = ignore # A boolean deciding if the person is ignored.
self.secure = secure # A boolean describing if hostmasks *must* match.
self.password = password # password (plaintext? hashed?)
self.capabilities = UserCapabilitySet()
for capability in capabilities:
@ -186,9 +187,9 @@ class IrcUser(object):
def __repr__(self):
return '%s(ignore=%s, password=%r, name=%r, '\
'capabilities=%r, hostmasks=%r)\n' %\
'capabilities=%r, hostmasks=%r, secure=%r)\n' %\
(self.__class__.__name__, self.ignore, self.password,
self.name, self.capabilities, self.hostmasks)
self.name, self.capabilities, self.hostmasks, self.secure)
def addCapability(self, capability):
self.capabilities.add(capability)
@ -211,8 +212,8 @@ class IrcUser(object):
def checkPassword(self, password):
return (self.password == password)
def checkHostmask(self, hostmask):
if self.auth and (hostmask == self.auth[1]):
def checkHostmask(self, hostmask, useAuth=True):
if useAuth and self.auth and (hostmask == self.auth[1]):
return True
for pat in self.hostmasks:
if ircutils.hostmaskPatternEqual(pat, hostmask):
@ -558,6 +559,9 @@ def checkCapability(hostmask, capability, users=users, channels=channels):
return _x(capability, True)
try:
u = users.getUser(hostmask)
if u.secure and not u.checkHostmask(hostmask, useAuth=False):
debug.printf('Secure user with non-matching hostmask.')
raise KeyError
except KeyError:
#debug.printf('user could not be found.')
if isChannelCapability(capability):

View File

@ -307,6 +307,7 @@ class CheckCapabilityTestCase(unittest.TestCase):
antifoo = 'antifoo!antifoo@antifoo'
justchanfoo = 'justchanfoo!justchanfoo@justchanfoo'
antichanfoo = 'antichanfoo!antichanfoo@antichanfoo'
securefoo = 'securefoo!securefoo@securefoo'
channel = '#channel'
cap = 'foo'
anticap = ircdb.makeAntiCapability(cap)
@ -325,35 +326,49 @@ class CheckCapabilityTestCase(unittest.TestCase):
pass
self.users = ircdb.UsersDB(self.filename)
self.channels = ircdb.ChannelsDictionary(self.filename)
(id, owner) = self.users.newUser()
owner.name = 'owner'
owner.addCapability('owner')
owner.addHostmask(self.owner)
self.users.setUser(id, owner)
(id, nothing) = self.users.newUser()
nothing.name = 'nothing'
nothing.addHostmask(self.nothing)
self.users.setUser(id, nothing)
(id, justfoo) = self.users.newUser()
justfoo.name = 'justfoo'
justfoo.addCapability(self.cap)
justfoo.addHostmask(self.justfoo)
self.users.setUser(id, justfoo)
(id, antifoo) = self.users.newUser()
antifoo.name = 'antifoo'
antifoo.addCapability(self.anticap)
antifoo.addHostmask(self.antifoo)
self.users.setUser(id, antifoo)
(id, justchanfoo) = self.users.newUser()
justchanfoo.name = 'justchanfoo'
justchanfoo.addCapability(self.chancap)
justchanfoo.addHostmask(self.justchanfoo)
self.users.setUser(id, justchanfoo)
(id, antichanfoo) = self.users.newUser()
antichanfoo.name = 'antichanfoo'
antichanfoo.addCapability(self.antichancap)
antichanfoo.addHostmask(self.antichanfoo)
self.users.setUser(id, antichanfoo)
(id, securefoo) = self.users.newUser()
securefoo.name = 'securefoo'
securefoo.addCapability(self.cap)
securefoo.secure = True
securefoo.addHostmask(self.securefoo)
self.users.setUser(id, securefoo)
channel = ircdb.IrcChannel()
self.channels.setChannel(self.channel, channel)
@ -428,6 +443,19 @@ class CheckCapabilityTestCase(unittest.TestCase):
self.failUnless(self.checkCapability(self.antichanfoo,
self.antichancap))
def testSecurefoo(self):
self.failUnless(self.checkCapability(self.securefoo, self.cap))
id = self.users.getUserId(self.securefoo)
u = self.users.getUser(id)
u.setAuth(self.securefoo)
self.users.setUser(id, u)
try:
originalConfDefaultAllow = conf.defaultAllow
conf.defaultAllow = False
self.failIf(self.checkCapability('a' + self.securefoo, self.cap))
finally:
conf.defaultAllow = originalConfDefaultAllow
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: