예제 #1
0
class TestACLController(unittest.TestCase):
    def setUp(self):
        self.tempdir = tempfile.mkdtemp()
        self.acl = ACLController(self.tempdir + "/acl.db")

    def tearDown(self):
        shutil.rmtree(self.tempdir)

    def testCreateDeleteUsers(self):
        self.acl.add_user('bill')
        self.acl.add_user('bob')
        self.acl.add_user('anna')
        self.acl.add_user('linda')

        self.assertRaises(Exception, self.acl.add_user, 'linda')
        self.assertRaises(Exception, self.acl.del_user, 'user_that_doesnt_exist')

    def testAddDelHostMask(self):
        self.acl.add_user('theuser')
        self.acl.user_add_hostmask('theuser', '*[email protected]')
        self.acl.user_add_hostmask('theuser', '*[email protected]')

        self.assertRaises(Exception, self.acl.user_add_hostmask, 'theuser', 'invalid hostmask')
        self.assertRaises(Exception, self.acl.user_add_hostmask, 'theuser', '*!*invalid hostmask')
        self.assertRaises(Exception, self.acl.user_add_hostmask, 'theuser', 'invalid!hostmask')
        self.assertRaises(Exception, self.acl.user_add_hostmask, 'theuser', '')
        self.assertRaises(Exception, self.acl.user_add_hostmask, 'user_that_doesnt_exist', 'anyhostmask')
        self.assertRaises(Exception, self.acl.user_del_hostmask, 'user_that_doesnt_exist', 'anyhostmask')
        self.assertRaises(Exception, self.acl.user_del_hostmask, 'theuser', 'hostmask_that_doesnt_exist')

        self.acl.user_del_hostmask('theuser', '*[email protected]')

    def testAddDelGroups(self):
        self.acl.add_group("mygroup")
        self.acl.del_group("mygroup")

        self.acl.add_group("duplicate")
        self.assertRaises(Exception, self.acl.add_group, "duplicate")

        self.assertRaises(Exception, self.acl.del_group, "nonexistant")

    def testMatchHostmasks(self):
        self.acl.add_user('theuser')
        self.acl.user_add_hostmask('theuser', '[email protected]')

        self.acl.add_user('superuser')
        self.acl.user_add_hostmask('superuser', '[email protected]')

        self.acl.add_user('baduser')
        self.acl.user_add_hostmask('baduser', '[email protected]')

        identityNormal = IRCUser('[email protected]')
        identitySuper  = IRCUser('[email protected]')
        identityBad    = IRCUser('[email protected]')

        self.assertRaises(Exception, self.acl.access_allow, 'secret', 'nosuchuser')
        self.acl.access_allow('secret', 'superuser')

        self.assertFalse(self.acl.check_access(identityNormal, 'secret'))
        self.assertTrue(self.acl.check_access(identitySuper, 'secret'))
        self.assertFalse(self.acl.check_access(identitySuper, 'SECRET'))
        self.assertFalse(self.acl.check_access(identitySuper, 'secret2'))

        # Test group access
        self.acl.add_group('superusers')
        self.acl.group_add_user('superuser', 'superusers')

        self.acl.add_group('normalusers')
        self.acl.group_add_user('theuser', 'normalusers')

        # "any"-group
        self.acl.access_allow('foreveryone', 'any')
        self.assertTrue(self.acl.check_access(identityNormal, 'foreveryone'))

        # Exclusion (Ticket #1)
        #self.assertTrue(self.acl.check_access(identityBad, 'foreveryone'))
        #self.acl.access_deny('foreveryone', 'baduser')
        #self.assertFalse(self.acl.check_access(identityBad, 'foreveryone'))

        # Group membership
        self.acl.access_allow('supersecret', 'superusers')
        self.assertTrue(self.acl.check_access(identitySuper, 'supersecret'))
        self.assertFalse(self.acl.check_access(identityNormal, 'supersecret'))
        self.assertFalse(self.acl.check_access(identityBad, 'supersecret'))

    def testMasterAccess(self):
        config = ConfigController()
        config.load_defaults()
        config.get('masters').append("*[email protected]")

        identityMaster = IRCUser('[email protected]')
        identityNormal = IRCUser('[email protected]')

        self.assertTrue(self.acl.check_access(identityMaster, 'something'))
        self.assertFalse(self.acl.check_access(identityNormal, 'something'))
예제 #2
0
class ACLCommands(Plugin):
    def __init__(self):
        self.author = "Jim Persson"
        self.name = "ACL Commands (Core)"

        self.acl = ACLController()
        self.parseTree = {
            "add": {
                "user":  {"$username"  : self.add_user},
                "group": {"$groupname" : self.add_group},
            },

            "del": {
                "user":  {"$username"  : self.del_user},
                "group": {"$groupname" : self.del_group},
            },

            "user": {
                "$username": {
                    "show": self.show_user,
                    "addmask": {"$hostmask": self.user_add_hostmask},
                    "delmask": {"$hostmask": self.user_del_hostmask}
                }
            },

            "group": {
                "$groupname": {
                    "show": self.show_group,
                    "adduser": {"$username": self.group_add_user},
                    "deluser": {"$username": self.group_del_user}
                }
            },

            "access": {
                "$context": {
                    "allow":  {"$aro": self.access_allow},
                    "deny" :  {"$aro": self.access_deny},
                    "remove": {"$aro": self.access_remove},
                    "clear": self.access_clear
                }
            },

            "show": {
                "users": self.get_users,
                "groups": self.get_groups
            }
        }

        self.event.register_command("acl", self.cmd_acl, True)

    def add_user(self, username):
        self.acl.add_user(username)
        return ["Added user %s" % username]

    def add_group(self, groupname):
        self.acl.add_group(groupname)
        return ["Added group %s" % groupname]

    def del_user(self, username):
        self.acl.del_user(username)
        return ["Deleted user %s" % username]

    def del_group(self, groupname):
        self.acl.del_group(groupname)
        return ["Deleted group %s" % groupname]

    def user_add_hostmask(self, username, hostmask):
        self.acl.user_add_hostmask(username, hostmask)
        return ["Added hostmask %s to user %s" % (hostmask, username)]

    def user_del_hostmask(self, username, hostmask):
        self.acl.user_del_hostmask(username, hostmask)
        return ["Removed hostmask %s to user %s" % (hostmask, username)]

    def group_add_user(self, username, groupname):
        self.acl.group_add_user(username, groupname)
        return ["User %s is now a member of group %s" % (username, groupname)]

    def group_del_user(self, username, groupname):
        self.acl.group_del_user(username, groupname)
        return ["User %s is no longer a member of group %s" % (username, groupname)]

    def show_user(self, username):
        info = self.acl.get_user_info(username)

        data = []

        data += ["User: %s" % username]

        data += ["Associated Hostmasks:"]
        result = info["hostmasks"]
        if len(result) == 0:
            haveHostmask = False
            data += ["  None"]
        else:
            haveHostmask = True
            for row in result:
                data += ["  " + row]

        data += ["Group Memberships:"]
        result = info["groups"]
        if result is None:
            data += ["  None"]
        else:
            for row in result:
                data += ["  " + row]

        data += ["Command Access:"]
        if haveHostmask:
            result = info["access"]
            for (context, group) in result:
                if group is None:
                    data += ["  %s (direct access)" % (context)]
                else:
                    data += ["  %s (member in '%s')" % (context, group)]
        else:
            data += ["  No hostmasks for this user, unable to grant access"]

        return data

    def show_group(self, groupname):
        members = self.acl.get_group_members(groupname)

        users = TableFormatter([""]*5, "Group Members")
        members.sort()
        members.reverse()
        while len(members) != 0:
            row = []
            for _ in range(0, 5):
                if len(members) != 0:
                    user = members.pop()
                    row.append(user)

            row += [""]*(5-len(row))
            users.add_row(row)

        return users.get_table()

    def get_users(self):
        users = self.acl.get_users()

        return ["Found %d users:" % len(users)] + users

    def get_groups(self):
        groups = self.acl.get_groups()

        return ["Found %d groups" % len(groups)] + groups

    def access_allow(self, context, aro):
        self.acl.access_allow(context, aro)

        return ["%s now have access to '%s'" % (aro, context)]

    def access_deny(self, context, aro):
        self.acl.access_deny(context, aro)

        return ["Denied access to '%s' for %s'" % (context, aro)]

    def access_remove(self, context, aro):
        self.acl.access_remove(context, aro)

        return ["Ok"]

    def access_clear(self, context):
        self.acl.access_clear(context)

        return ["Ok"]

    def cmd_acl(self, irc, params):
        """
        Available operations
            add [user|group] <name>
            del [user|group] <name>
            user <username> [show | addmask <hostmask> | delmask <hostmask>]
            group <groupname> [show | adduser <username> | deluser <username>]
            access <context> [allow|deny|remove] <group_or_user>
            access <context> clear
            show [users|groups]"""

        try:
            result = CommandParser(self.parseTree).parse(str(params))
            if result:
                for line in result:
                    irc.reply(line)

        except CommandError as e:
            irc.reply(e)

        except Exception as e:
            irc.reply(e)