mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-26 20:59:27 +01:00
Updated ircdb to have persistent user ids.
This commit is contained in:
parent
a0e0ca2c5f
commit
41d266f207
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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):
|
||||
|
@ -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 \
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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')
|
||||
|
256
src/ircdb.py
256
src/ircdb.py
@ -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:
|
||||
|
@ -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'):
|
||||
|
@ -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')
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user