Allow multiple authentication.

This commit is contained in:
Jeremy Fincher 2004-09-13 02:01:00 +00:00
parent 75b33b8b44
commit 4fec6def71
2 changed files with 52 additions and 21 deletions

View File

@ -196,7 +196,7 @@ 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, secure=False, hashed=False): capabilities=(), hostmasks=None, secure=False, hashed=False):
self.auth = None # The (time, hostmask) a user authenticated under self.auth = [] # The (time, hostmask) list of auth crap.
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.secure = secure # A boolean describing if hostmasks *must* match.
@ -211,11 +211,10 @@ class IrcUser(object):
self.hostmasks = hostmasks self.hostmasks = hostmasks
def __repr__(self): def __repr__(self):
return '%s(ignore=%s, password=%r, name=%r, hashed=%r, ' \ return '%s(ignore=%s, password="", name=%r, hashed=%r, ' \
'capabilities=%r, hostmasks=%r, secure=%r)\n' % \ 'capabilities=%r, hostmasks=[], secure=%r)\n' % \
(self.__class__.__name__, (self.__class__.__name__, self.ignore, self.name, self.hashed,
self.ignore, self.password, self.name, self.hashed, self.capabilities, self.secure)
self.capabilities, self.hostmasks, self.secure)
def addCapability(self, capability): def addCapability(self, capability):
"""Gives the user the given capability.""" """Gives the user the given capability."""
@ -257,12 +256,17 @@ class IrcUser(object):
hostmasks. hostmasks.
""" """
if useAuth: if useAuth:
if self.auth: timeout = conf.supybot.databases.users.timeoutIdentification()
i = conf.supybot.databases.users.timeoutIdentification() removals = []
if i > 0 and self.auth[0] < time.time() - i: try:
self.unsetAuth() for (when, authmask) in self.auth:
elif hostmask == self.auth[1]: if timeout and when+timeout < time.time():
return True removals.append((when, authmask))
elif hostmask == authmask:
return True
finally:
while removals:
self.auth.remove(removals.pop())
for pat in self.hostmasks: for pat in self.hostmasks:
if ircutils.hostmaskPatternEqual(pat, hostmask): if ircutils.hostmaskPatternEqual(pat, hostmask):
return pat return pat
@ -280,18 +284,18 @@ class IrcUser(object):
"""Removes a hostmask from the user's hostmasks.""" """Removes a hostmask from the user's hostmasks."""
self.hostmasks = [s for s in self.hostmasks if s != hostmask] self.hostmasks = [s for s in self.hostmasks if s != hostmask]
def setAuth(self, hostmask): def addAuth(self, hostmask):
"""Sets a user's authenticated hostmask. This times out in 1 hour.""" """Sets a user's authenticated hostmask. This times out in 1 hour."""
if self.checkHostmask(hostmask, useAuth=False) or not self.secure: if self.checkHostmask(hostmask, useAuth=False) or not self.secure:
self.auth = (time.time(), hostmask) self.auth.append((time.time(), hostmask))
else: else:
raise ValueError, 'secure flag set, unmatched hostmask' raise ValueError, 'secure flag set, unmatched hostmask'
def unsetAuth(self): def clearAuth(self):
"""Unsets a user's authenticated hostmask.""" """Unsets a user's authenticated hostmask."""
if self.auth is not None: for (when, hostmask) in self.auth:
users.invalidateCache(hostmask=self.auth[1]) users.invalidateCache(hostmask=hostmask)
self.auth = None self.auth = []
def preserve(self, fd, indent=''): def preserve(self, fd, indent=''):
def write(s): def write(s):

View File

@ -243,6 +243,33 @@ class IrcUserTestCase(IrcdbTestCase):
self.failUnless(u.checkPassword('foobar')) self.failUnless(u.checkPassword('foobar'))
self.failIf(u.checkPassword('somethingelse')) self.failIf(u.checkPassword('somethingelse'))
def testTimeoutAuth(self):
orig = conf.supybot.databases.users.timeoutIdentification()
try:
conf.supybot.databases.users.timeoutIdentification.setValue(2)
u = ircdb.IrcUser()
u.addAuth('foo!bar@baz')
self.failUnless(u.checkHostmask('foo!bar@baz'))
time.sleep(2.1)
self.failIf(u.checkHostmask('foo!bar@baz'))
finally:
conf.supybot.databases.users.timeoutIdentification.setValue(orig)
def testMultipleAuth(self):
orig = conf.supybot.databases.users.timeoutIdentification()
try:
conf.supybot.databases.users.timeoutIdentification.setValue(2)
u = ircdb.IrcUser()
u.addAuth('foo!bar@baz')
self.failUnless(u.checkHostmask('foo!bar@baz'))
u.addAuth('boo!far@fizz')
self.failUnless(u.checkHostmask('boo!far@fizz'))
time.sleep(2.1)
self.failIf(u.checkHostmask('foo!bar@baz'))
self.failIf(u.checkHostmask('boo!far@fizz'))
finally:
conf.supybot.databases.users.timeoutIdentification.setValue(orig)
def testHashedPassword(self): def testHashedPassword(self):
u = ircdb.IrcUser() u = ircdb.IrcUser()
u.setPassword('foobar', hashed=True) u.setPassword('foobar', hashed=True)
@ -262,9 +289,9 @@ class IrcUserTestCase(IrcdbTestCase):
def testAuth(self): def testAuth(self):
prefix = 'foo!bar@baz' prefix = 'foo!bar@baz'
u = ircdb.IrcUser() u = ircdb.IrcUser()
u.setAuth(prefix) u.addAuth(prefix)
self.failUnless(u.auth) self.failUnless(u.auth)
u.unsetAuth() u.clearAuth()
self.failIf(u.auth) self.failIf(u.auth)
def testIgnore(self): def testIgnore(self):
@ -525,7 +552,7 @@ class CheckCapabilityTestCase(IrcdbTestCase):
self.failUnless(self.checkCapability(self.securefoo, self.cap)) self.failUnless(self.checkCapability(self.securefoo, self.cap))
id = self.users.getUserId(self.securefoo) id = self.users.getUserId(self.securefoo)
u = self.users.getUser(id) u = self.users.getUser(id)
u.setAuth(self.securefoo) u.addAuth(self.securefoo)
self.users.setUser(id, u) self.users.setUser(id, u)
try: try:
originalConfDefaultAllow = conf.supybot.capabilities.default() originalConfDefaultAllow = conf.supybot.capabilities.default()