mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-30 06:49:24 +01:00
Allow multiple authentication.
This commit is contained in:
parent
75b33b8b44
commit
4fec6def71
40
src/ircdb.py
40
src/ircdb.py
@ -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):
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user