From 0416ebe05bf919335bd1b2e341843f6ff63e184b Mon Sep 17 00:00:00 2001 From: kakwa Date: Sat, 16 May 2015 23:52:59 +0200 Subject: [PATCH] unit test + admin roles fix * adding various unit tests * now admin roles are inherited (ex admin-lv2 is admin -> admin-lv3 is admin * adding an exception when requesting groups for none existant role --- conf/roles.yml | 2 +- ldapcherry/exceptions.py | 5 +++++ ldapcherry/roles.py | 24 +++++++++++++++++++----- tests/test_Roles.py | 37 +++++++++++++++++++++++++++++++++++-- 4 files changed, 60 insertions(+), 8 deletions(-) diff --git a/conf/roles.yml b/conf/roles.yml index 0f0714e..9201be3 100644 --- a/conf/roles.yml +++ b/conf/roles.yml @@ -1,6 +1,5 @@ admin-lv3: display_name: Administrators Level 3 - LC_admins: True backends: ldap: groups: @@ -16,6 +15,7 @@ admin-lv3: admin-lv2: display_name: Administrators Level 2 + LC_admins: True backends: ldap: groups: diff --git a/ldapcherry/exceptions.py b/ldapcherry/exceptions.py index a9361d2..2f47509 100644 --- a/ldapcherry/exceptions.py +++ b/ldapcherry/exceptions.py @@ -23,6 +23,11 @@ class DumplicateRoleKey(Exception): self.role = role self.log = "duplicate role key <%(role)s> in role file" % { 'role' : role} +class MissingRole(Exception): + def __init__(self, role): + self.role = role + self.log = "role <%(role)s> does not exist in role file" % { 'role' : role} + class DumplicateRoleContent(Exception): def __init__(self, role1, role2): self.role1 = role1 diff --git a/ldapcherry/roles.py b/ldapcherry/roles.py index 438fcd5..81e6c26 100644 --- a/ldapcherry/roles.py +++ b/ldapcherry/roles.py @@ -11,7 +11,7 @@ import sys from sets import Set from ldapcherry.pyyamlwrapper import loadNoDump from ldapcherry.pyyamlwrapper import DumplicatedKey -from ldapcherry.exceptions import DumplicateRoleKey, MissingKey, DumplicateRoleContent, MissingRolesFile +from ldapcherry.exceptions import DumplicateRoleKey, MissingKey, DumplicateRoleContent, MissingRolesFile, MissingRole import yaml class CustomDumper(yaml.SafeDumper): @@ -38,6 +38,12 @@ class Roles: self.admin_roles = [] self._nest() + def _set_admin(self, role): + for r in role['subroles']: + self.admin_roles.append(r) + self._set_admin(role['subroles'][r]) + + def _is_parent(self, roleid1, roleid2): """Test if roleid1 is contained inside roleid2""" @@ -82,10 +88,6 @@ class Roles: for backend in role['backends']: self.backends.add(backend) - # Create the list of roles which are ldapcherry admins - if 'LC_admins' in role and role['LC_admins']: - self.admin_roles.append(roleid) - # Create the nested groups for roleid in self.roles_raw: role = self.roles_raw[roleid] @@ -117,6 +119,16 @@ class Roles: if p in parents: self.roles[p] = nest(p) + for roleid in self.roles: + role = self.roles[roleid] + # Create the list of roles which are ldapcherry admins + if 'LC_admins' in role and role['LC_admins']: + self.admin_roles.append(roleid) + self._set_admin(role) + + def get_admin_roles(self): + return self.admin_roles + def dump_nest(self): """dump the nested role hierarchy""" return yaml.dump(self.roles, Dumper=CustomDumper) @@ -188,6 +200,8 @@ class Roles: def get_groups(self, role): """get the list of groups from role""" + if not role in self.roles_raw: + raise MissingRole(role) return self.roles_raw[role]['backends'] def is_admin(self, roles): diff --git a/tests/test_Roles.py b/tests/test_Roles.py index be66a5b..f469ffb 100644 --- a/tests/test_Roles.py +++ b/tests/test_Roles.py @@ -8,7 +8,7 @@ import pytest import sys from sets import Set from ldapcherry.roles import Roles -from ldapcherry.exceptions import DumplicateRoleKey, MissingKey, DumplicateRoleContent, MissingRolesFile +from ldapcherry.exceptions import DumplicateRoleKey, MissingKey, DumplicateRoleContent, MissingRolesFile, MissingRole from ldapcherry.pyyamlwrapper import DumplicatedKey, RelationError class TestError(object): @@ -42,7 +42,6 @@ class TestError(object): else: raise AssertionError("expected an exception") - def testNoFile(self): try: inv = Roles('./tests/cfg/dontexist') @@ -59,6 +58,40 @@ class TestError(object): else: raise AssertionError("expected an exception") + def testGetGroup(self): + inv = Roles('./tests/cfg/roles.yml') + res = inv.get_groups('users') + expected = { + 'ad': {'groups': ['Domain Users']}, + 'ldap': {'groups': ['cn=users,ou=group,dc=example,dc=com']} + } + assert res == expected + + def testGetGroupMissingRole(self): + inv = Roles('./tests/cfg/roles.yml') + try: + res = inv.get_groups('notarole') + except MissingRole: + return + else: + raise AssertionError("expected an exception") + + def testAdminRoles(self): + inv = Roles('./tests/cfg/roles.yml') + res = inv.get_admin_roles() + expected = ['admin-lv2', 'admin-lv3'] + assert res == expected + + def testIsAdmin(self): + inv = Roles('./tests/cfg/roles.yml') + res = inv.is_admin(['admin-lv3', 'users']) + assert res == True + + def testIsNotAdmin(self): + inv = Roles('./tests/cfg/roles.yml') + res = inv.is_admin(['users']) + assert res == False + def testGetRole(self): inv = Roles('./tests/cfg/roles.yml') groups = {