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: except KeyError:
irc.error(msg, conf.replyNotRegistered) 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 Class = UserCommands

View File

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

View File

@ -307,6 +307,7 @@ class CheckCapabilityTestCase(unittest.TestCase):
antifoo = 'antifoo!antifoo@antifoo' antifoo = 'antifoo!antifoo@antifoo'
justchanfoo = 'justchanfoo!justchanfoo@justchanfoo' justchanfoo = 'justchanfoo!justchanfoo@justchanfoo'
antichanfoo = 'antichanfoo!antichanfoo@antichanfoo' antichanfoo = 'antichanfoo!antichanfoo@antichanfoo'
securefoo = 'securefoo!securefoo@securefoo'
channel = '#channel' channel = '#channel'
cap = 'foo' cap = 'foo'
anticap = ircdb.makeAntiCapability(cap) anticap = ircdb.makeAntiCapability(cap)
@ -325,35 +326,49 @@ class CheckCapabilityTestCase(unittest.TestCase):
pass pass
self.users = ircdb.UsersDB(self.filename) self.users = ircdb.UsersDB(self.filename)
self.channels = ircdb.ChannelsDictionary(self.filename) self.channels = ircdb.ChannelsDictionary(self.filename)
(id, owner) = self.users.newUser() (id, owner) = self.users.newUser()
owner.name = 'owner' owner.name = 'owner'
owner.addCapability('owner') owner.addCapability('owner')
owner.addHostmask(self.owner) owner.addHostmask(self.owner)
self.users.setUser(id, owner) self.users.setUser(id, owner)
(id, nothing) = self.users.newUser() (id, nothing) = self.users.newUser()
nothing.name = 'nothing' nothing.name = 'nothing'
nothing.addHostmask(self.nothing) nothing.addHostmask(self.nothing)
self.users.setUser(id, nothing) self.users.setUser(id, nothing)
(id, justfoo) = self.users.newUser() (id, justfoo) = self.users.newUser()
justfoo.name = 'justfoo' justfoo.name = 'justfoo'
justfoo.addCapability(self.cap) justfoo.addCapability(self.cap)
justfoo.addHostmask(self.justfoo) justfoo.addHostmask(self.justfoo)
self.users.setUser(id, justfoo) self.users.setUser(id, justfoo)
(id, antifoo) = self.users.newUser() (id, antifoo) = self.users.newUser()
antifoo.name = 'antifoo' antifoo.name = 'antifoo'
antifoo.addCapability(self.anticap) antifoo.addCapability(self.anticap)
antifoo.addHostmask(self.antifoo) antifoo.addHostmask(self.antifoo)
self.users.setUser(id, antifoo) self.users.setUser(id, antifoo)
(id, justchanfoo) = self.users.newUser() (id, justchanfoo) = self.users.newUser()
justchanfoo.name = 'justchanfoo' justchanfoo.name = 'justchanfoo'
justchanfoo.addCapability(self.chancap) justchanfoo.addCapability(self.chancap)
justchanfoo.addHostmask(self.justchanfoo) justchanfoo.addHostmask(self.justchanfoo)
self.users.setUser(id, justchanfoo) self.users.setUser(id, justchanfoo)
(id, antichanfoo) = self.users.newUser() (id, antichanfoo) = self.users.newUser()
antichanfoo.name = 'antichanfoo' antichanfoo.name = 'antichanfoo'
antichanfoo.addCapability(self.antichancap) antichanfoo.addCapability(self.antichancap)
antichanfoo.addHostmask(self.antichanfoo) antichanfoo.addHostmask(self.antichanfoo)
self.users.setUser(id, 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() channel = ircdb.IrcChannel()
self.channels.setChannel(self.channel, channel) self.channels.setChannel(self.channel, channel)
@ -428,6 +443,19 @@ class CheckCapabilityTestCase(unittest.TestCase):
self.failUnless(self.checkCapability(self.antichanfoo, self.failUnless(self.checkCapability(self.antichanfoo,
self.antichancap)) 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: # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: