Fixed most tests and made some stricter policy changes, as well handled the case of getUserId returning several hostmasks a little better.

This commit is contained in:
Jeremy Fincher 2004-02-08 09:25:14 +00:00
parent 605129991d
commit 96eecfd477
2 changed files with 56 additions and 28 deletions

View File

@ -31,6 +31,8 @@
__revision__ = "$Id$" __revision__ = "$Id$"
from __future__ import division
import fix import fix
import os import os
@ -96,10 +98,8 @@ def invertCapability(capability):
else: else:
return makeAntiCapability(capability) return makeAntiCapability(capability)
_normal = string.maketrans('\r\n', ' ') def unWildcardHostmask(hostmask):
def _normalize(s): return hostmask.translate(string.ascii, '!@*?')
return s.translate(_normal)
_invert = invertCapability _invert = invertCapability
class CapabilitySet(sets.Set): class CapabilitySet(sets.Set):
@ -258,11 +258,15 @@ class IrcUser(object):
return True return True
for pat in self.hostmasks: for pat in self.hostmasks:
if ircutils.hostmaskPatternEqual(pat, hostmask): if ircutils.hostmaskPatternEqual(pat, hostmask):
return True return pat
return False return False
def addHostmask(self, hostmask): def addHostmask(self, hostmask):
"""Adds a hostmask to the user's hostmasks.""" """Adds a hostmask to the user's hostmasks."""
assert ircutils.isUserHostmask(hostmask)
if len(unWildcardHostmask(hostmask)) < 8:
raise ValueError, \
'Hostmask must contain at least 8 non-wildcard characters.'
self.hostmasks.append(hostmask) self.hostmasks.append(hostmask)
def removeHostmask(self, hostmask): def removeHostmask(self, hostmask):
@ -517,7 +521,7 @@ class UsersDictionary(utils.IterableMap):
def reload(self): def reload(self):
"""Reloads the database from its file.""" """Reloads the database from its file."""
if self.filename is not None: if self.filename is not None:
self.nextId = 1 self.nextId = 0
self.users.clear() self.users.clear()
try: try:
self.open(self.filename) self.open(self.filename)
@ -555,12 +559,13 @@ class UsersDictionary(utils.IterableMap):
try: try:
return self._hostmaskCache[s] return self._hostmaskCache[s]
except KeyError: except KeyError:
ids = [] ids = {}
for (id, user) in self.users.iteritems(): for (id, user) in self.users.iteritems():
if user.checkHostmask(s): x = user.checkHostmask(s)
ids.append(id) if x:
ids[id] = x
if len(ids) == 1: if len(ids) == 1:
id = ids[0] id = ids.keys()[0]
self._hostmaskCache[s] = id self._hostmaskCache[s] = id
try: try:
self._hostmaskCache[id].add(s) self._hostmaskCache[id].add(s)
@ -570,6 +575,11 @@ class UsersDictionary(utils.IterableMap):
elif len(ids) == 0: elif len(ids) == 0:
raise KeyError, s raise KeyError, s
else: else:
log.error('Multiple matches found in user database. '
'Removing the offending hostmasks.')
for (id, hostmask) in ids.iteritems():
log.error('Removing %r from user %s.', hostmask, id)
self.users[id].removeHostmask(hostmask)
raise ValueError, 'Ids %r matched.' % ids raise ValueError, 'Ids %r matched.' % ids
else: # Not a hostmask, must be a name. else: # Not a hostmask, must be a name.
s = s.lower() s = s.lower()
@ -608,17 +618,21 @@ class UsersDictionary(utils.IterableMap):
self.nextId = max(self.nextId, id) self.nextId = max(self.nextId, id)
try: try:
if self.getUserId(user.name) != id: if self.getUserId(user.name) != id:
s = '%s is already registered to someone else.' % user.name s = '%s is someone else\'s hostmask.' % user.name
raise ValueError, s raise ValueError, s
except KeyError: except KeyError:
pass pass
for hostmask in user.hostmasks: for hostmask in user.hostmasks:
try: for (i, u) in self.iteritems():
if self.getUserId(hostmask) != id: if i == id:
s = '%s is already registered to someone else.'% hostmask continue
elif u.checkHostmask(hostmask):
s = '%s is someone else\'s hostmask.' % hostmask
raise ValueError, s raise ValueError, s
except KeyError: for otherHostmask in u.hostmasks:
continue if ircutils.hostmaskPatternEqual(hostmask, otherHostmask):
s = '%s is someone else\'s hostmask.' % hostmask
raise ValueError, s
if id in self._nameCache: if id in self._nameCache:
del self._nameCache[self._nameCache[id]] del self._nameCache[self._nameCache[id]]
del self._nameCache[id] del self._nameCache[id]
@ -732,6 +746,12 @@ class IgnoresDB(object):
else: else:
log.warning('IgnoresDB.flush called without self.filename.') log.warning('IgnoresDB.flush called without self.filename.')
def close(self):
if self.flush in world.flushers:
world.flushers.remove(self.flush)
self.flush()
self.hostmasks.clear()
def reload(self): def reload(self):
if self.filename is not None: if self.filename is not None:
self.hostmasks.clear() self.hostmasks.clear()
@ -749,6 +769,7 @@ class IgnoresDB(object):
return False return False
def addHostmask(self, hostmask): def addHostmask(self, hostmask):
assert ircutils.isUserHostmask(hostmask)
self.hostmasks.add(hostmask) self.hostmasks.add(hostmask)
def removeHostmask(self, hostmask): def removeHostmask(self, hostmask):

View File

@ -215,6 +215,10 @@ class IrcUserTestCase(IrcdbTestCase):
self.assertRaises(KeyError, u.checkCapability, 'foo') self.assertRaises(KeyError, u.checkCapability, 'foo')
self.assertRaises(KeyError, u.checkCapability, '-bar') self.assertRaises(KeyError, u.checkCapability, '-bar')
def testAddhostmask(self):
u = ircdb.IrcUser()
self.assertRaises(ValueError, u.addHostmask, '*!*@*')
def testRemoveHostmask(self): def testRemoveHostmask(self):
u = ircdb.IrcUser() u = ircdb.IrcUser()
u.addHostmask('foo!bar@baz') u.addHostmask('foo!bar@baz')
@ -247,8 +251,8 @@ class IrcUserTestCase(IrcdbTestCase):
self.assertNotEqual(u.password, 'foobar') self.assertNotEqual(u.password, 'foobar')
def testHostmasks(self): def testHostmasks(self):
prefix = 'foo!bar@baz' prefix = 'foo12341234!bar@baz.domain.tld'
hostmasks = ['*!bar@baz', 'foo!*@*'] hostmasks = ['*!bar@baz.domain.tld', 'foo12341234!*@*']
u = ircdb.IrcUser() u = ircdb.IrcUser()
self.failIf(u.checkHostmask(prefix)) self.failIf(u.checkHostmask(prefix))
for hostmask in hostmasks: for hostmask in hostmasks:
@ -315,21 +319,21 @@ class IrcChannelTestCase(IrcdbTestCase):
c.removeBan(banmask) c.removeBan(banmask)
self.failIf(c.checkIgnored(prefix)) self.failIf(c.checkIgnored(prefix))
class UsersDBTestCase(IrcdbTestCase): class UsersDictionaryTestCase(IrcdbTestCase):
filename = os.path.join(conf.supybot.directories.conf(), filename = os.path.join(conf.supybot.directories.conf(),
'UsersDBTestCase.conf') 'UsersDictionaryTestCase.conf')
def setUp(self): def setUp(self):
try: try:
os.remove(self.filename) os.remove(self.filename)
except: except:
pass pass
self.users = ircdb.UsersDB(self.filename) self.users = ircdb.UsersDictionary()
IrcdbTestCase.setUp(self) IrcdbTestCase.setUp(self)
def testIterAndNumUsers(self): def testIterAndNumUsers(self):
self.assertEqual(self.users.numUsers(), 0) self.assertEqual(self.users.numUsers(), 0)
(id, u) = self.users.newUser() (id, u) = self.users.newUser()
hostmask = 'foo!bar@baz' hostmask = 'foo!xyzzy@baz.domain.com'
banmask = ircutils.banmask(hostmask) banmask = ircutils.banmask(hostmask)
u.addHostmask(banmask) u.addHostmask(banmask)
u.name = 'foo' u.name = 'foo'
@ -349,9 +353,10 @@ class UsersDBTestCase(IrcdbTestCase):
def testGetSetDelUser(self): def testGetSetDelUser(self):
self.assertRaises(KeyError, self.users.getUser, 'foo') self.assertRaises(KeyError, self.users.getUser, 'foo')
self.assertRaises(KeyError, self.users.getUser, 'foo!bar@baz') self.assertRaises(KeyError,
self.users.getUser, 'foo!xyzzy@baz.domain.com')
(id, u) = self.users.newUser() (id, u) = self.users.newUser()
hostmask = 'foo!bar@baz' hostmask = 'foo!xyzzy@baz.domain.com'
banmask = ircutils.banmask(hostmask) banmask = ircutils.banmask(hostmask)
u.addHostmask(banmask) u.addHostmask(banmask)
u.name = 'foo' u.name = 'foo'
@ -360,10 +365,10 @@ class UsersDBTestCase(IrcdbTestCase):
self.assertEqual(self.users.getUser('FOO'), u) self.assertEqual(self.users.getUser('FOO'), u)
self.assertEqual(self.users.getUser(hostmask), u) self.assertEqual(self.users.getUser(hostmask), u)
self.assertEqual(self.users.getUser(banmask), u) self.assertEqual(self.users.getUser(banmask), u)
# The UsersDB shouldn't allow users to be added whose hostmasks # The UsersDictionary shouldn't allow users to be added whose hostmasks
# match another user's already in the database. # match another user's already in the database.
(id, u2) = self.users.newUser() (id, u2) = self.users.newUser()
u2.addHostmask('*!*@*') u2.addHostmask('*!xyzzy@baz.domain.c?m')
self.assertRaises(ValueError, self.users.setUser, id, u2) self.assertRaises(ValueError, self.users.setUser, id, u2)
@ -394,8 +399,10 @@ class CheckCapabilityTestCase(IrcdbTestCase):
os.remove(self.filename) os.remove(self.filename)
except: except:
pass pass
self.users = ircdb.UsersDB(self.filename) self.users = ircdb.UsersDictionary()
self.channels = ircdb.ChannelsDictionary(self.filename) #self.users.open(self.filename)
self.channels = ircdb.ChannelsDictionary()
#self.channels.open(self.filename)
(id, owner) = self.users.newUser() (id, owner) = self.users.newUser()
owner.name = 'owner' owner.name = 'owner'