mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-19 08:59:27 +01:00
Added RFE #801859: no-hostmask (secure) option for users.
This commit is contained in:
parent
9cbc766b7c
commit
36984d3fa5
@ -315,6 +315,39 @@ class UserCommands(callbacks.Privmsg):
|
||||
except KeyError:
|
||||
irc.error(msg, conf.replyNotRegistered)
|
||||
|
||||
def setsecure(self, irc, msg, args):
|
||||
"""<password> [<True|False>]
|
||||
|
||||
Sets the secure flag on the user of the person sending the message.
|
||||
Requires that the person's hostmask be in the list of hostmasks for
|
||||
that user in addition to the password being correct. When the secure
|
||||
flag is set, the user *must* identify before he can be recognized.
|
||||
If a specific True/False value is not given, it inverts the current
|
||||
value.
|
||||
"""
|
||||
if not self._checkNotChannel(irc, msg, password):
|
||||
return
|
||||
try:
|
||||
id = ircdb.users.getUserId(msg.prefix)
|
||||
user = ircdb.users.getUser(id)
|
||||
except KeyError:
|
||||
irc.error(msg, conf.replyNotRegistered)
|
||||
(password, value) = privmsgs.getArgs(args, optional=1)
|
||||
if value == '':
|
||||
value = not user.secure
|
||||
elif value.lower() in ('true', 'false'):
|
||||
value = eval(value.capitalize())
|
||||
else:
|
||||
irc.error(msg, '%s is not a valid boolean value.' % value)
|
||||
return
|
||||
if user.checkPassword(password) and \
|
||||
user.checkHostmask(msg.prefix, useAuth=False):
|
||||
user.secure = value
|
||||
ircdb.users.setUser(id, user)
|
||||
irc.reply(msg, 'Secure flag set to %s' % value)
|
||||
else:
|
||||
irc.error(msg, conf.replyIncorrectAuth)
|
||||
|
||||
|
||||
Class = UserCommands
|
||||
|
||||
|
14
src/ircdb.py
14
src/ircdb.py
@ -171,10 +171,11 @@ class IrcUser(object):
|
||||
"""This class holds the capabilities and authentications for a user.
|
||||
"""
|
||||
def __init__(self, ignore=False, password='', name='',
|
||||
capabilities=(), hostmasks=None):
|
||||
capabilities=(), hostmasks=None, secure=False):
|
||||
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.secure = secure # A boolean describing if hostmasks *must* match.
|
||||
self.password = password # password (plaintext? hashed?)
|
||||
self.capabilities = UserCapabilitySet()
|
||||
for capability in capabilities:
|
||||
@ -186,9 +187,9 @@ class IrcUser(object):
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(ignore=%s, password=%r, name=%r, '\
|
||||
'capabilities=%r, hostmasks=%r)\n' %\
|
||||
'capabilities=%r, hostmasks=%r, secure=%r)\n' %\
|
||||
(self.__class__.__name__, self.ignore, self.password,
|
||||
self.name, self.capabilities, self.hostmasks)
|
||||
self.name, self.capabilities, self.hostmasks, self.secure)
|
||||
|
||||
def addCapability(self, capability):
|
||||
self.capabilities.add(capability)
|
||||
@ -211,8 +212,8 @@ class IrcUser(object):
|
||||
def checkPassword(self, password):
|
||||
return (self.password == password)
|
||||
|
||||
def checkHostmask(self, hostmask):
|
||||
if self.auth and (hostmask == self.auth[1]):
|
||||
def checkHostmask(self, hostmask, useAuth=True):
|
||||
if useAuth and self.auth and (hostmask == self.auth[1]):
|
||||
return True
|
||||
for pat in self.hostmasks:
|
||||
if ircutils.hostmaskPatternEqual(pat, hostmask):
|
||||
@ -558,6 +559,9 @@ def checkCapability(hostmask, capability, users=users, channels=channels):
|
||||
return _x(capability, True)
|
||||
try:
|
||||
u = users.getUser(hostmask)
|
||||
if u.secure and not u.checkHostmask(hostmask, useAuth=False):
|
||||
debug.printf('Secure user with non-matching hostmask.')
|
||||
raise KeyError
|
||||
except KeyError:
|
||||
#debug.printf('user could not be found.')
|
||||
if isChannelCapability(capability):
|
||||
|
@ -307,6 +307,7 @@ class CheckCapabilityTestCase(unittest.TestCase):
|
||||
antifoo = 'antifoo!antifoo@antifoo'
|
||||
justchanfoo = 'justchanfoo!justchanfoo@justchanfoo'
|
||||
antichanfoo = 'antichanfoo!antichanfoo@antichanfoo'
|
||||
securefoo = 'securefoo!securefoo@securefoo'
|
||||
channel = '#channel'
|
||||
cap = 'foo'
|
||||
anticap = ircdb.makeAntiCapability(cap)
|
||||
@ -325,35 +326,49 @@ class CheckCapabilityTestCase(unittest.TestCase):
|
||||
pass
|
||||
self.users = ircdb.UsersDB(self.filename)
|
||||
self.channels = ircdb.ChannelsDictionary(self.filename)
|
||||
|
||||
(id, owner) = self.users.newUser()
|
||||
owner.name = 'owner'
|
||||
owner.addCapability('owner')
|
||||
owner.addHostmask(self.owner)
|
||||
self.users.setUser(id, owner)
|
||||
|
||||
(id, nothing) = self.users.newUser()
|
||||
nothing.name = 'nothing'
|
||||
nothing.addHostmask(self.nothing)
|
||||
self.users.setUser(id, nothing)
|
||||
|
||||
(id, justfoo) = self.users.newUser()
|
||||
justfoo.name = 'justfoo'
|
||||
justfoo.addCapability(self.cap)
|
||||
justfoo.addHostmask(self.justfoo)
|
||||
self.users.setUser(id, justfoo)
|
||||
|
||||
(id, antifoo) = self.users.newUser()
|
||||
antifoo.name = 'antifoo'
|
||||
antifoo.addCapability(self.anticap)
|
||||
antifoo.addHostmask(self.antifoo)
|
||||
self.users.setUser(id, antifoo)
|
||||
|
||||
(id, justchanfoo) = self.users.newUser()
|
||||
justchanfoo.name = 'justchanfoo'
|
||||
justchanfoo.addCapability(self.chancap)
|
||||
justchanfoo.addHostmask(self.justchanfoo)
|
||||
self.users.setUser(id, justchanfoo)
|
||||
|
||||
(id, antichanfoo) = self.users.newUser()
|
||||
antichanfoo.name = 'antichanfoo'
|
||||
antichanfoo.addCapability(self.antichancap)
|
||||
antichanfoo.addHostmask(self.antichanfoo)
|
||||
self.users.setUser(id, antichanfoo)
|
||||
|
||||
(id, securefoo) = self.users.newUser()
|
||||
securefoo.name = 'securefoo'
|
||||
securefoo.addCapability(self.cap)
|
||||
securefoo.secure = True
|
||||
securefoo.addHostmask(self.securefoo)
|
||||
self.users.setUser(id, securefoo)
|
||||
|
||||
channel = ircdb.IrcChannel()
|
||||
self.channels.setChannel(self.channel, channel)
|
||||
|
||||
@ -428,6 +443,19 @@ class CheckCapabilityTestCase(unittest.TestCase):
|
||||
self.failUnless(self.checkCapability(self.antichanfoo,
|
||||
self.antichancap))
|
||||
|
||||
def testSecurefoo(self):
|
||||
self.failUnless(self.checkCapability(self.securefoo, self.cap))
|
||||
id = self.users.getUserId(self.securefoo)
|
||||
u = self.users.getUser(id)
|
||||
u.setAuth(self.securefoo)
|
||||
self.users.setUser(id, u)
|
||||
try:
|
||||
originalConfDefaultAllow = conf.defaultAllow
|
||||
conf.defaultAllow = False
|
||||
self.failIf(self.checkCapability('a' + self.securefoo, self.cap))
|
||||
finally:
|
||||
conf.defaultAllow = originalConfDefaultAllow
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user