Updated ircdb to have persistent user ids.

This commit is contained in:
Jeremy Fincher 2003-09-12 20:06:58 +00:00
parent a0e0ca2c5f
commit 41d266f207
13 changed files with 261 additions and 237 deletions

View File

@ -148,7 +148,7 @@ class ChannelDB(callbacks.PrivmsgCommandAndRegexp, ChannelDBHandler):
actions=actions+%s""",
smileys, frowns, chars, words, int(isAction))
try:
name = ircdb.users.getUserName(msg.prefix)
name = ircdb.users.getUser(msg.prefix).name
except KeyError:
return
cursor.execute("""SELECT COUNT(*)
@ -181,7 +181,7 @@ class ChannelDB(callbacks.PrivmsgCommandAndRegexp, ChannelDBHandler):
cursor.execute("""UPDATE channel_stats SET joins=joins+1""")
try:
if ircutils.isUserHostmask(msg.prefix):
name = ircdb.users.getUserName(msg.prefix)
name = ircdb.users.getUser(msg.prefix).name
else:
name = msg.prefix
cursor.execute("""UPDATE user_stats
@ -198,7 +198,7 @@ class ChannelDB(callbacks.PrivmsgCommandAndRegexp, ChannelDBHandler):
cursor.execute("""UPDATE channel_stats SET parts=parts+1""")
try:
if ircutils.isUserHostmask(msg.prefix):
name = ircdb.users.getUserName(msg.prefix)
name = ircdb.users.getUser(msg.prefix).name
else:
name = msg.prefix
cursor.execute("UPDATE user_stats SET parts=parts+1 WHERE name=%s",
@ -214,7 +214,7 @@ class ChannelDB(callbacks.PrivmsgCommandAndRegexp, ChannelDBHandler):
cursor.execute("""UPDATE channel_stats SET topics=topics+1""")
try:
if ircutils.isUserHostmask(msg.prefix):
name = ircdb.users.getUserName(msg.prefix)
name = ircdb.users.getUser(msg.prefix).name
else:
name = msg.prefix
cursor.execute("""UPDATE user_stats
@ -231,7 +231,7 @@ class ChannelDB(callbacks.PrivmsgCommandAndRegexp, ChannelDBHandler):
cursor.execute("""UPDATE channel_stats SET modes=modes+1""")
try:
if ircutils.isUserHostmask(msg.prefix):
name = ircdb.users.getUserName(msg.prefix)
name = ircdb.users.getUser(msg.prefix).name
else:
name = msg.prefix
cursor.execute("""UPDATE user_stats
@ -248,7 +248,7 @@ class ChannelDB(callbacks.PrivmsgCommandAndRegexp, ChannelDBHandler):
cursor.execute("""UPDATE channel_stats SET kicks=kicks+1""")
try:
if ircutils.isUserHostmask(msg.prefix):
name = ircdb.users.getUserName(msg.prefix)
name = ircdb.users.getUser(msg.prefix).name
else:
name = msg.prefix
cursor.execute("""UPDATE user_stats
@ -258,7 +258,7 @@ class ChannelDB(callbacks.PrivmsgCommandAndRegexp, ChannelDBHandler):
pass
try:
kicked = msg.args[1]
name = ircdb.users.getUserName(irc.state.nickToHostmask(kicked))
name = ircdb.users.getUser(irc.state.nickToHostmask(kicked)).name
cursor.execute("""UPDATE user_stats
SET kicked=kicked+1
WHERE name=%s""", name)
@ -278,7 +278,7 @@ class ChannelDB(callbacks.PrivmsgCommandAndRegexp, ChannelDBHandler):
if not ircdb.users.hasUser(name):
try:
hostmask = irc.state.nickToHostmask(name)
name = ircdb.users.getUserName(hostmask)
name = ircdb.users.getUser(hostmask).name
except KeyError:
irc.error(msg, conf.replyNoUser)
return
@ -369,7 +369,7 @@ class ChannelDB(callbacks.PrivmsgCommandAndRegexp, ChannelDBHandler):
if not ircdb.users.hasUser(name):
hostmask = irc.state.nickToHostmask(name)
try:
name = ircdb.users.getUserName(hostmask)
name = ircdb.users.getUser(hostmask).name
except KeyError:
irc.error(msg, conf.replyNoUser)
return

View File

@ -144,7 +144,7 @@ class Factoids(ChannelDBHandler, callbacks.Privmsg):
irc.error(msg, conf.replyNoCapability % capability)
return
if ircdb.users.hasUser(msg.prefix):
name = ircdb.users.getUserName(msg.prefix)
name = ircdb.users.getUser(msg.prefix).name
else:
name = msg.nick
cursor.execute("""INSERT INTO factoids VALUES
@ -364,6 +364,7 @@ class Factoids(ChannelDBHandler, callbacks.Privmsg):
utils.nItems(cursor.rowcount, 'key'))
else:
irc.reply(msg, s)
Class = Factoids
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:

View File

@ -262,7 +262,7 @@ class FunDB(callbacks.Privmsg):
(table, s) = privmsgs.getArgs(args, needed=2)
table = table.lower()
try:
name = ircdb.users.getUserName(msg.prefix)
name = ircdb.users.getUser(msg.prefix).name
except KeyError:
irc.error(msg, conf.replyNotRegistered)
return
@ -295,7 +295,7 @@ class FunDB(callbacks.Privmsg):
(table, id) = privmsgs.getArgs(args, needed=2)
table = table.lower()
try:
ircdb.users.getUserName(msg.prefix)
ircdb.users.getUser(msg.prefix).name
except KeyError:
irc.error(msg, conf.replyNotRegistered)
return
@ -464,7 +464,7 @@ class FunDB(callbacks.Privmsg):
irc.queueMsg(ircmsgs.action(channel, '%s for %s (#%s)' %\
(praise, reason, id)))
else:
irc.queueMsg(ircmsgs.action(channel, '%s (#%s)' % (praise, id)))
irc.queueMsg(ircmsgs.action(channel, '%s (#%s)' %(praise, id)))
raise callbacks.CannotNest
def addword(self, irc, msg, args):

View File

@ -84,7 +84,7 @@ class Topic(callbacks.Privmsg):
return
currentTopic = irc.state.getTopic(channel)
try:
name = ircdb.users.getUserName(msg.prefix)
name = ircdb.users.getUser(msg.prefix).name
except KeyError:
name = msg.nick
formattedTopic = self.topicFormatter % (topic, name)
@ -166,7 +166,7 @@ class Topic(callbacks.Privmsg):
else:
(topic, name) = match.groups()
try:
senderName = ircdb.users.getUserName(msg.prefix)
senderName = ircdb.users.getUser(msg.prefix).name
except KeyError:
irc.error(msg, conf.replyNoUser)
return
@ -208,7 +208,7 @@ class Topic(callbacks.Privmsg):
else:
(topic, name) = match.groups()
try:
username = ircdb.users.getUserName(msg.prefix)
username = ircdb.users.getUser(msg.prefix).name
except KeyError:
username = msg.nick
if name and name != username and \

View File

@ -130,8 +130,7 @@ if __name__ == '__main__':
filenames.extend(os.listdir(dir))
plugins = []
for filename in filenames:
if filename.endswith('.py') and \
filename.lower() != filename:
if filename.endswith('.py') and filename[0].isupper():
plugins.append(os.path.splitext(filename)[0])
plugins.sort()
if yn('Would you like to see a list of the available modules?') == 'y':
@ -201,12 +200,13 @@ if __name__ == '__main__':
if yn('Would you like to add an owner user?') == 'y':
owner = something('What should the owner\'s username be?')
password = something('What should the owner\'s password be?')
user = ircdb.IrcUser()
(id, user) = ircdb.users.newUser()
user.setPassword(password)
user.names.add(owner)
user.addCapability('owner')
while yn('Would you like to add a hostmask for the owner?') == 'y':
user.addHostmask(something('What hostmask?'))
ircdb.users.setUser(owner, user)
ircdb.users.setUser(id, user)
###
# Configuration variables in conf.py.

View File

@ -136,9 +136,10 @@ class AdminCommands(privmsgs.CapabilityCheckingPrivmsg):
if ircdb.checkCapability(msg.prefix, capability) or \
'!' in capability:
try:
u = ircdb.users.getUser(name)
u.addCapability(capability)
ircdb.users.setUser(name, u)
id = ircdb.users.getUserId(name)
user = ircdb.users.getUser(id)
user.addCapability(capability)
ircdb.users.setUser(id, user)
irc.reply(msg, conf.replySuccess)
except KeyError:
irc.error(msg, conf.replyNoUser)
@ -156,9 +157,10 @@ class AdminCommands(privmsgs.CapabilityCheckingPrivmsg):
if ircdb.checkCapability(msg.prefix, capability) or \
'!' in capability:
try:
u = ircdb.users.getUser(name)
u.addCapability(capability)
ircdb.users.setUser(name, u)
id = ircdb.users.getUserId(name)
user = ircdb.users.getUser(id)
user.addCapability(capability)
ircdb.users.setUser(id, user)
irc.reply(msg, conf.replySuccess)
except KeyError:
irc.error(msg, conf.replyNoUser)

View File

@ -256,9 +256,10 @@ class ChannelCommands(callbacks.Privmsg):
capability = ircdb.makeChannelCapability(channel, capability)
if ircdb.checkCapability(msg.prefix, neededcapability):
try:
u = ircdb.users.getUser(name)
u.addCapability(capability)
ircdb.users.setUser(name, u)
id = ircdb.users.getUserId(name)
user = ircdb.users.getUser(id)
user.addCapability(capability)
ircdb.users.setUser(id, user)
irc.reply(msg, conf.replySuccess)
except KeyError:
irc.error(msg, conf.replyNoUser)
@ -280,9 +281,10 @@ class ChannelCommands(callbacks.Privmsg):
capability = ircdb.makeChannelCapability(channel, capability)
if ircdb.checkCapability(msg.prefix, neededcapability):
try:
u = ircdb.users.getUser(name)
u.removeCapability(capability)
ircdb.users.setUser(name, u)
id = ircdb.users.getUser(name)
user = ircdb.users.getUser(id)
user.removeCapability(capability)
ircdb.users.setUser(id, user)
irc.reply(msg, conf.replySuccess)
except KeyError:
irc.error(msg, conf.replyNoUser)

View File

@ -36,6 +36,7 @@ Provides commands useful to users in general. This plugin is loaded by default.
import string
import conf
import utils
import ircdb
import ircutils
import privmsgs
@ -61,16 +62,20 @@ class UserCommands(callbacks.Privmsg):
if ircutils.isChannel(msg.args[0]):
irc.error(msg, conf.replyRequiresPrivacy)
return
if ircdb.users.hasUser(name):
irc.error(msg, 'That name is already registered.')
try:
ircdb.users.getUserId(name)
irc.error(msg, 'That name is alrady assigned to someone.')
return
except KeyError:
pass
if ircutils.isUserHostmask(name):
irc.error(msg, 'Hostmasks aren\'t valid usernames.')
return
user = ircdb.IrcUser()
(id, user) = ircdb.users.newUser()
user.name = name
user.setPassword(password)
user.addHostmask(msg.prefix)
ircdb.users.setUser(name, user)
ircdb.users.setUser(id, user)
irc.reply(msg, conf.replySuccess)
def addhostmask(self, irc, msg, args):
@ -92,20 +97,20 @@ class UserCommands(callbacks.Privmsg):
irc.error(msg, s)
return
try:
user = ircdb.users.getUser(name)
id = ircdb.users.getUserId(name)
user = ircdb.users.getUser(id)
except KeyError:
irc.error(msg, conf.replyNoUser)
return
try:
name = ircdb.users.getUserName(hostmask)
s = 'That hostmask is already registered to %s.' % name
irc.error(msg, s)
_ = ircdb.users.getUserId(hostmask)
irc.error(msg, 'That hostmask is already registered.')
return
except KeyError:
pass
if user.checkHostmask(msg.prefix) or user.checkPassword(password):
user.addHostmask(hostmask)
ircdb.users.setUser(name, user)
ircdb.users.setUser(id, user)
irc.reply(msg, conf.replySuccess)
else:
irc.error(msg, conf.replyIncorrectAuth)
@ -122,13 +127,14 @@ class UserCommands(callbacks.Privmsg):
if not self._checkNotChannel(irc, msg, password):
return
try:
user = ircdb.users.getUser(name)
id = ircdb.users.getUserId(name)
user = ircdb.users.getUser(id)
except KeyError:
irc.error(msg, conf.replyNoUser)
return
if user.checkHostmask(msg.prefix) or user.checkPassword(password):
user.removeHostmask(hostmask)
ircdb.users.setUser(name, user)
ircdb.users.setUser(id, user)
irc.reply(msg, conf.replySuccess)
else:
irc.error(msg, conf.replyIncorrectAuth)
@ -144,13 +150,14 @@ class UserCommands(callbacks.Privmsg):
if not self._checkNotChannel(irc, msg, oldpassword+newpassword):
return
try:
user = ircdb.users.getUser(name)
id = ircdb.users.getUserId(name)
user = ircdb.users.getUser(id)
except KeyError:
irc.error(msg, conf.replyNoUser)
return
if user.checkPassword(oldpassword):
user.setPassword(newpassword)
ircdb.users.setUser(name, user)
ircdb.users.setUser(id, user)
irc.reply(msg, conf.replySuccess)
else:
irc.error(msg, conf.replyIncorrectAuth)
@ -169,8 +176,8 @@ class UserCommands(callbacks.Privmsg):
irc.error(msg, conf.replyNoUser)
return
try:
name = ircdb.users.getUserName(hostmask)
irc.reply(msg, name)
user = ircdb.users.getUser(hostmask)
irc.reply(msg, user.name)
except KeyError:
irc.error(msg, conf.replyNoUser)
@ -197,11 +204,7 @@ class UserCommands(callbacks.Privmsg):
isn't specified, returns the hostmasks of the user calling the command.
"""
if not args:
try:
name = ircdb.users.getUserName(msg.prefix)
except KeyError:
irc.error(msg, conf.replyNoUser)
return
name = msg.prefix
else:
name = privmsgs.getArgs(args)
try:
@ -219,13 +222,14 @@ class UserCommands(callbacks.Privmsg):
if not self._checkNotChannel(irc, msg):
return
try:
u = ircdb.users.getUser(name)
id = ircdb.users.getUserId(name)
user = ircdb.users.getUser(id)
except KeyError:
irc.error(msg, conf.replyNoUser)
return
if u.checkPassword(password):
u.setAuth(msg.prefix)
ircdb.users.setUser(name, u)
if user.checkPassword(password):
user.setAuth(msg.prefix)
ircdb.users.setUser(id, user)
irc.reply(msg, conf.replySuccess)
else:
irc.error(msg, conf.replyIncorrectAuth)
@ -236,13 +240,13 @@ class UserCommands(callbacks.Privmsg):
Un-identifies the user.
"""
try:
u = ircdb.users.getUser(msg.prefix)
name = ircdb.users.getUserName(msg.prefix)
id = ircdb.users.getUserId(msg.prefix)
user = ircdb.users.getUser(id)
except KeyError:
irc.error(msg, conf.replyNoUser)
return
u.unsetAuth()
ircdb.users.setUser(name, u)
user.unsetAuth()
ircdb.users.setUser(id, user)
irc.reply(msg, conf.replySuccess)
def whoami(self, irc, msg, args):
@ -251,8 +255,8 @@ class UserCommands(callbacks.Privmsg):
Returns the name of the user calling the command.
"""
try:
name = ircdb.users.getUserName(msg.prefix)
irc.reply(msg, name)
user = ircdb.users.getUser(msg.prefix)
irc.reply(msg, user.name)
except KeyError:
irc.error(msg, conf.replyNotRegistered)

View File

@ -182,7 +182,8 @@ Name: """ % (world.version, sys.version.translate(string.ascii, '\r\n'))
try:
name = self.buffer
self.buffer = ''
self.u = ircdb.users.getUser(name)
id = ircdb.users.getUserId(name)
self.u = ircdb.users.getUser(id)
self.prompt = 'Password: '
except KeyError:
self.push('Unknown user.\n')

View File

@ -34,11 +34,11 @@ from fix import *
import os
import sets
import time
import atexit
import string
import conf
import debug
import utils
import world
import ircutils
@ -158,9 +158,10 @@ class UserCapabilitySet(CapabilitySet):
class IrcUser(object):
"""This class holds the capabilities and authentications for a user.
"""
def __init__(self, ignore=False, password='', auth=None,
def __init__(self, ignore=False, password='', name='',
capabilities=(), hostmasks=None):
self.auth = auth # 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.ignore = ignore # A boolean deciding if the person is ignored.
self.password = password # password (plaintext? hashed?)
self.capabilities = UserCapabilitySet()
@ -172,10 +173,10 @@ class IrcUser(object):
self.hostmasks = hostmasks
def __repr__(self):
return '%s(ignore=%s, auth=%r, password=%r, '\
return '%s(ignore=%s, password=%r, name=%r, '\
'capabilities=%r, hostmasks=%r)\n' %\
(self.__class__.__name__, self.ignore, self.auth,
self.password, self.capabilities, self.hostmasks)
(self.__class__.__name__, self.ignore, self.password,
self.name, self.capabilities, self.hostmasks)
def addCapability(self, capability):
self.capabilities.add(capability)
@ -315,103 +316,139 @@ class IrcChannel(object):
return True
return False
class UsersDictionary(object):
class UsersDB(object):
def __init__(self, filename):
self.filename = filename
fd = file(filename, 'r')
s = fd.read()
fd.close()
Set = sets.Set
ignore(Set) # Make PyChecker happy.
self.dict = eval(normalize(s))
self.cache = {} # hostmasks to nicks.
self.revcache = ircutils.IrcDict() # nicks to hostmasks.
def resetCache(self, s):
if s in self.cache:
# it's a hostmask.
name = self.cache[s]
del self.cache[s]
if os.path.exists(filename):
fd = file(filename, 'r')
s = fd.read()
fd.close()
IrcSet = ircutils.IrcSet
(self.nextId, self.users) = eval(normalize(s))
else:
# it's already a name.
name = s
# name should always be in self.revcache, this should never KeyError.
if name in self.revcache:
for hostmask in self.revcache[name]:
del self.cache[hostmask]
del self.revcache[name]
def setCache(self, hostmask, name):
self.cache[hostmask] = name
self.revcache.setdefault(name, []).append(hostmask)
def getUser(self, s):
if ircutils.isUserHostmask(s):
name = self.getUserName(s)
else:
name = s
return self.dict[name]
def setUser(self, s, u):
# First, invalidate the cache for this user.
self.resetCache(s)
if ircutils.isUserHostmask(s):
name = self.getUserName(s)
else:
name = s
for hostmask in u.hostmasks:
try:
username = self.getUserName(hostmask)
if username != name:
raise ValueError, 'User has hostmasks already matching ' \
'another user\'s hostmasks.'
except KeyError:
pass
self.dict[name] = u
def hasUser(self, s):
return (s in self.dict)
def delUser(self, s):
if ircutils.isUserHostmask(s):
name = self.getUserName(s)
else:
name = s
self.resetCache(name)
try:
del self.dict[name]
except KeyError:
pass
def getUserName(self, s):
assert ircutils.isUserHostmask(s), 'string must be a hostmask'
if s in self.cache:
return self.cache[s]
else:
for (name, user) in self.dict.iteritems():
if user.checkHostmask(s):
self.cache[s] = name
self.revcache.setdefault(name,[]).append(s)
return name
raise KeyError, s
def flush(self):
fd = file(self.filename, 'w')
fd.write(repr(self.dict))
fd.close()
self.nextId = 1
self.users = [IrcUser(capabilities=['owner'],
password=utils.mktemp())]
self._nameCache = {}
self._hostmaskCache = {}
def reload(self):
self.__init__(self.filename)
def flush(self):
fd = file(self.filename, 'w')
fd.write(repr((self.nextId, self.users)))
fd.close()
def getUserId(self, s):
if ircutils.isUserHostmask(s):
try:
return self._hostmaskCache[s]
except KeyError:
ids = []
for (id, user) in enumerate(self.users):
if user is None:
continue
if user.checkHostmask(s):
ids.append(id)
if len(ids) == 1:
id = ids[0]
self._hostmaskCache[s] = id
self._hostmaskCache.setdefault(id, sets.Set()).add(s)
return id
elif len(ids) == 0:
raise KeyError, s
else:
raise ValueError, 'Ids %r matched.' % ids
else: # Not a hostmask, must be a name.
try:
return self._nameCache[s]
except KeyError:
for (id, user) in enumerate(self.users):
if user is None:
continue
if s == user.name:
self._nameCache[s] = id
self._nameCache.setdefault(id, sets.Set()).add(s)
return id
else:
raise KeyError, s
def getUser(self, id):
if not isinstance(id, int):
# Must be a string. Get the UserId first.
id = self.getUserId(id)
try:
ret = self.users[id]
if ret is None:
raise KeyError, id
return ret
except IndexError:
raise KeyError, id
def hasUser(self, id):
try:
self.getUser(id)
return True
except KeyError:
return False
def setUser(self, id, user):
assert isinstance(id, int), 'setUser takes an integer userId.'
if not 0 <= id < len(self.users) or self.users[id] is None:
raise KeyError, id
try:
if self.getUserId(user.name) != id:
raise ValueError, \
'%s is already registered to someone else.' % user.name
except KeyError:
pass
for hostmask in user.hostmasks:
try:
if self.getUserId(hostmask) != id:
raise ValueError, \
'%s is already registered to someone else.'% hostmask
except KeyError:
continue
if id in self._nameCache:
for name in self._nameCache[id]:
del self._nameCache[name]
del self._nameCache[id]
if id in self._hostmaskCache:
for hostmask in self._hostmaskCache[id]:
del self._hostmaskCache[hostmask]
del self._hostmaskCache[id]
### FIXME: what if the new hostmasks overlap with another hostmask?
self.users[id] = user
def delUser(self, id):
if not 0 <= id < len(self.users) or self.users[id] is None:
raise KeyError, id
self.users[id] = None
for name in self._nameCache.get(id, []):
del self._nameCache[name]
for hostmask in self._hostmaskCache.get(id, []):
del self._hostmaskCache[hostmask]
def newUser(self):
user = IrcUser()
id = self.nextId
self.nextId += 1
self.users.append(user)
return (id, user)
class ChannelsDictionary(object):
def __init__(self, filename):
self.filename = filename
fd = file(filename, 'r')
s = fd.read()
fd.close()
Set = sets.Set
self.dict = eval(normalize(s))
if os.path.exists(filename):
fd = file(filename, 'r')
s = fd.read()
fd.close()
Set = sets.Set
self.dict = eval(normalize(s))
else:
self.dict = {}
def getChannel(self, channel):
channel = channel.lower()
@ -438,26 +475,9 @@ class ChannelsDictionary(object):
###
# Later, I might add some special handling for botnet.
###
if not os.path.exists(conf.userfile):
fd = open(conf.userfile, 'w')
fd.write('{}')
fd.close()
users = UsersDictionary(conf.userfile)
if not os.path.exists(conf.channelfile):
fd = file(conf.channelfile, 'w')
fd.write('{}')
fd.close()
users = UsersDB(conf.userfile)
channels = ChannelsDictionary(conf.channelfile)
def flushUsers():
for (name, u) in users.dict.iteritems():
u.unsetAuth()
users.flush()
atexit.register(flushUsers)
atexit.register(channels.flush)
world.flushers.append(users.flush)
world.flushers.append(channels.flush)
@ -473,7 +493,8 @@ def checkIgnored(hostmask, recipient='', users=users, channels=channels):
if ircutils.hostmaskPatternEqual(ignore, hostmask):
return True
try:
user = users.getUser(hostmask)
id = users.getUserId(hostmask)
user = users.getUser(id)
except KeyError:
# If there's no user...
if ircutils.isChannel(recipient):
@ -507,7 +528,8 @@ def checkCapability(hostmask, capability, users=users, channels=channels):
#debug.printf('world.startup is active.')
return _x(capability, True)
try:
u = users.getUser(hostmask)
id = users.getUserId(hostmask)
u = users.getUser(id)
except KeyError:
#debug.printf('user could not be found.')
if isChannelCapability(capability):
@ -582,13 +604,5 @@ def checkCapabilities(hostmask, capabilities, requireAll=False):
else:
return False
def getUser(irc, s):
if ircutils.isUserHostmask(s):
return users.getUserName(s)
else:
if users.hasUser(s):
return s
else:
return users.getUserName(irc.state.nickToHostmask(s))
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:

View File

@ -438,8 +438,10 @@ class Irc(object):
# it to abuse our 'owner' power we give to ourselves. Ergo, on
# outgoing messages that change our nick, we pre-emptively
# delete the 'owner' user we setup for ourselves.
if ircdb.users.hasUser(self.nick):
ircdb.users.delUser(self.nick)
user = ircdb.users.getUser(0)
user.unsetAuth()
user.hostmasks = []
ircdb.users.setUser(0, user)
return msg
else:
return None
@ -455,10 +457,10 @@ class Irc(object):
args=msg.args)
# First, make sure self.nick is always consistent with the server.
if msg.command == 'NICK' and msg.nick == self.nick:
if ircdb.users.hasUser(self.nick):
ircdb.users.delUser(self.nick)
if ircdb.users.hasUser(self.prefix):
ircdb.users.delUser(self.prefix)
user = ircdb.users.getUser(0)
user.unsetAuth()
user.hostmasks = []
ircdb.users.setUser(0, user)
self.nick = msg.args[0]
(nick, user, domain) = ircutils.splitHostmask(msg.prefix)
self.prefix = '%s!%s@%s' % (self.nick, user, domain)
@ -472,17 +474,12 @@ class Irc(object):
self.sendMsg(ircmsgs.nick(self._nickmods.pop(0) % self.nick))
if msg.nick == self.nick:
self.prefix = msg.prefix
if ircdb.users.hasUser(self.nick):
u = ircdb.users.getUser(self.nick)
if not u.hasHostmask(msg.prefix):
u.addHostmask(msg.prefix)
ircdb.users.setUser(self.nick, u)
else:
u = ircdb.IrcUser(capabilities=['owner'],
password=utils.mktemp(),
hostmasks=[msg.prefix])
ircdb.users.setUser(self.nick, u)
atexit.register(lambda: catch(ircdb.users.delUser(self.nick)))
user = ircdb.users.getUser(0)
user.hostmasks = []
user.name = self.nick
user.addHostmask(msg.prefix)
user.setPassword(utils.mktemp())
ircdb.users.setUser(0, user)
if msg.command == 'ERROR':
if msg.args[0].startswith('Closing Link'):
if hasattr(self.driver, 'scheduleReconnect'):

View File

@ -103,7 +103,8 @@ class MyShell(Shell):
debug.printf(repr(username))
debug.printf(repr(password))
try:
u = ircdb.users.getUser(username)
id = ircdb.users.getUserId(username)
u = ircdb.users.getUser(id)
debug.printf(u)
if u.checkPassword(password) and u.checkCapability('owner'):
debug.printf('returning True')

View File

@ -255,34 +255,32 @@ class IrcChannelTestCase(unittest.TestCase):
c.removeBan(banmask)
self.failIf(c.checkIgnored(prefix))
class UsersDictionaryTestCase(unittest.TestCase):
filename = 'UsersDictionaryTestCase.conf'
class UsersDBTestCase(unittest.TestCase):
filename = 'UsersDBTestCase.conf'
def setUp(self):
fd = file(self.filename, 'w')
fd.write('{}\n')
fd.close()
self.users = ircdb.UsersDictionary(self.filename)
def tearDown(self):
os.remove(self.filename)
try:
os.remove(self.filename)
except:
pass
self.users = ircdb.UsersDB(self.filename)
def testGetSetDelUser(self):
self.assertRaises(KeyError, self.users.getUser, 'foo')
self.assertRaises(KeyError, self.users.getUser, 'foo!bar@baz')
u = ircdb.IrcUser()
(id, u) = self.users.newUser()
hostmask = 'foo!bar@baz'
banmask = ircutils.banmask(hostmask)
u.addHostmask(banmask)
self.users.setUser('foo', u)
u.name = 'foo'
self.users.setUser(id, u)
self.assertEqual(self.users.getUser('foo'), u)
self.assertEqual(self.users.getUser(hostmask), u)
self.assertEqual(self.users.getUser(banmask), u)
# The UsersDictionary shouldn't allow users to be added whose hostmasks
# The UsersDB shouldn't allow users to be added whose hostmasks
# match another user's already in the database.
self.assertRaises(ValueError, self.users.setUser, 'bar', u)
u.removeHostmask(banmask)
u.addHostmask('*!*@*')
self.assertRaises(ValueError, self.users.setUser, 'biff', u)
(id, u2) = self.users.newUser()
u2.addHostmask('*!*@*')
self.assertRaises(ValueError, self.users.setUser, id, u2)
class CheckCapabilityTestCase(unittest.TestCase):
@ -304,40 +302,44 @@ class CheckCapabilityTestCase(unittest.TestCase):
channelanticap = ircdb.IrcChannel()
channelanticap.addCapability(anticap)
def setUp(self):
fd = file(self.filename, 'w')
fd.write('{}\n')
fd.close()
self.users = ircdb.UsersDictionary(self.filename)
try:
os.remove(self.filename)
except:
pass
self.users = ircdb.UsersDB(self.filename)
self.channels = ircdb.ChannelsDictionary(self.filename)
owner = ircdb.IrcUser()
(id, owner) = self.users.newUser()
owner.name = 'owner'
owner.addCapability('owner')
owner.addHostmask(self.owner)
self.users.setUser('owner', owner)
nothing = ircdb.IrcUser()
self.users.setUser(id, owner)
(id, nothing) = self.users.newUser()
nothing.name = 'nothing'
nothing.addHostmask(self.nothing)
self.users.setUser('nothing', nothing)
justfoo = ircdb.IrcUser()
self.users.setUser(id, nothing)
(id, justfoo) = self.users.newUser()
justfoo.name = 'justfoo'
justfoo.addCapability(self.cap)
justfoo.addHostmask(self.justfoo)
self.users.setUser('justfoo', justfoo)
antifoo = ircdb.IrcUser()
self.users.setUser(id, justfoo)
(id, antifoo) = self.users.newUser()
antifoo.name = 'antifoo'
antifoo.addCapability(self.anticap)
antifoo.addHostmask(self.antifoo)
self.users.setUser('antifoo', antifoo)
justchanfoo = ircdb.IrcUser()
self.users.setUser(id, antifoo)
(id, justchanfoo) = self.users.newUser()
justchanfoo.name = 'justchanfoo'
justchanfoo.addCapability(self.chancap)
justchanfoo.addHostmask(self.justchanfoo)
self.users.setUser('justchanfoo', justchanfoo)
antichanfoo = ircdb.IrcUser()
self.users.setUser(id, justchanfoo)
(id, antichanfoo) = self.users.newUser()
antichanfoo.name = 'antichanfoo'
antichanfoo.addCapability(self.antichancap)
antichanfoo.addHostmask(self.antichanfoo)
self.users.setUser('antichanfoo', antichanfoo)
self.users.setUser(id, antichanfoo)
channel = ircdb.IrcChannel()
self.channels.setChannel(self.channel, channel)
def tearDown(self):
os.remove(self.filename)
def checkCapability(self, hostmask, capability):
return ircdb.checkCapability(hostmask, capability,
self.users, self.channels)