From 2c5f34d6f3d9ddac30b980724f4eb3dad285882c Mon Sep 17 00:00:00 2001 From: Anuj Borah Date: Mar 06 2019 01:01:24 +0000 Subject: Issue: 50253 - Making an nsManagedRoleDefinition type in src/lib389/lib389/idm/nsrole.py Making an nsManagedRoleDefinition type in src/lib389/lib389/idm/nsrole.py https://pagure.io/389-ds-base/issue/50253 Reviewed by: William Brown, thierry bordaz --- diff --git a/dirsrvtests/tests/suites/acl/acivattr_test.py b/dirsrvtests/tests/suites/acl/acivattr_test.py index 96011df..c4f9b9c 100644 --- a/dirsrvtests/tests/suites/acl/acivattr_test.py +++ b/dirsrvtests/tests/suites/acl/acivattr_test.py @@ -15,7 +15,7 @@ from lib389.cos import CosTemplate, CosClassicDefinition from lib389.topologies import topology_st as topo from lib389.idm.nscontainer import nsContainer from lib389.idm.domain import Domain -from lib389.idm.nsrole import nsFilterRoles +from lib389.idm.role import FilterRoles @@ -55,7 +55,7 @@ def _add_user(request, topo): ou = OrganizationalUnit(topo.standalone, "ou=sales,o=acivattr,{}".format(DEFAULT_SUFFIX)) ou.create(properties={'ou': 'sales'}) - roles = nsFilterRoles(topo.standalone, DNBASE) + roles = FilterRoles(topo.standalone, DNBASE) roles.create(properties={'cn':'FILTERROLEENGROLE', 'nsRoleFilter':'cn=eng*'}) roles.create(properties={'cn': 'FILTERROLESALESROLE', 'nsRoleFilter': 'cn=sales*'}) diff --git a/dirsrvtests/tests/suites/cos/cos_test.py b/dirsrvtests/tests/suites/cos/cos_test.py index 98bed4d..6a24537 100644 --- a/dirsrvtests/tests/suites/cos/cos_test.py +++ b/dirsrvtests/tests/suites/cos/cos_test.py @@ -10,7 +10,7 @@ import pytest, os, ldap from lib389.cos import CosClassicDefinition, CosClassicDefinitions, CosTemplate from lib389._constants import DEFAULT_SUFFIX from lib389.topologies import topology_st as topo -from lib389.idm.nsrole import nsFilterRoles +from lib389.idm.role import FilterRoles from lib389.idm.nscontainer import nsContainer from lib389.idm.user import UserAccount @@ -35,7 +35,7 @@ def test_positive(topo): 6. Operation should success """ # Adding ns filter role - roles = nsFilterRoles(topo.standalone, DEFAULT_SUFFIX) + roles = FilterRoles(topo.standalone, DEFAULT_SUFFIX) roles.create(properties={'cn': 'FILTERROLEENGROLE', 'nsRoleFilter': 'cn=eng*'}) # adding ns container diff --git a/dirsrvtests/tests/suites/roles/basic_test.py b/dirsrvtests/tests/suites/roles/basic_test.py index 6289d74..1d3079a 100644 --- a/dirsrvtests/tests/suites/roles/basic_test.py +++ b/dirsrvtests/tests/suites/roles/basic_test.py @@ -8,11 +8,12 @@ import pytest, os from lib389._constants import PW_DM, DEFAULT_SUFFIX -from lib389.idm.user import UserAccount +from lib389.idm.user import UserAccount, UserAccounts from lib389.idm.organization import Organization from lib389.idm.organizationalunit import OrganizationalUnit from lib389.topologies import topology_st as topo -from lib389.idm.nsrole import nsFilterRoles +from lib389.idm.role import FilterRoles, ManagedRole, ManagedRoles +from lib389.idm.domain import Domain DNBASE = "o=acivattr,{}".format(DEFAULT_SUFFIX) @@ -26,7 +27,7 @@ FILTERROLESALESROLE = "cn=FILTERROLESALESROLE,{}".format(DNBASE) FILTERROLEENGROLE = "cn=FILTERROLEENGROLE,{}".format(DNBASE) -def test_nsrole(topo): +def test_filterrole(topo): ''' :id: 8ada4064-786b-11e8-8634-8c16451d917b :setup: server @@ -50,7 +51,7 @@ def test_nsrole(topo): ou = OrganizationalUnit(topo.standalone, "ou=sales,o=acivattr,{}".format(DEFAULT_SUFFIX)) ou.create(properties=properties) - roles = nsFilterRoles(topo.standalone, DNBASE) + roles = FilterRoles(topo.standalone, DNBASE) roles.create(properties={'cn': 'FILTERROLEENGROLE', 'nsRoleFilter': 'cn=eng*'}) roles.create(properties={'cn': 'FILTERROLESALESROLE', 'nsRoleFilter': 'cn=sales*'}) @@ -119,6 +120,71 @@ def test_nsrole(topo): UserAccount(topo.standalone, DN).delete() +def test_managedrole(topo): + ''' + :id: d52a9c00-3bf6-11e9-9b7b-8c16451d917b + :setup: server + :steps: + 1. Add test entry + 2. Add ACI + 3. Search managed role entries + :expectedresults: + 1. Entry should be added + 2. Operation should succeed + 3. Operation should succeed + ''' + # Create Managed role entry + roles = ManagedRoles(topo.standalone, DEFAULT_SUFFIX) + role = roles.create(properties={"cn": 'ROLE1'}) + + # Create user and Assign the role to the entry + uas = UserAccounts(topo.standalone, DEFAULT_SUFFIX, rdn=None) + uas.create(properties={ + 'uid': 'Fail', + 'cn': 'Fail', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'Fail', + 'nsRoleDN': role.dn, + 'userPassword': PW_DM + }) + + # Create user and do not Assign any role to the entry + uas.create( + properties={ + 'uid': 'Success', + 'cn': 'Success', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'Success', + 'userPassword': PW_DM + }) + + # Assert that Manage role entry is created and its searchable + assert ManagedRoles(topo.standalone, DEFAULT_SUFFIX).list()[0].dn == 'cn=ROLE1,dc=example,dc=com' + + # Set an aci that will deny ROLE1 manage role + Domain(topo.standalone, DEFAULT_SUFFIX).add('aci', '(targetattr=*)(version 3.0; aci "role aci"; deny(all) roledn="ldap:///{}";)'.format(role.dn),) + + # Crate a connection with cn=Fail which is member of ROLE1 + conn = UserAccount(topo.standalone, "uid=Fail,{}".format(DEFAULT_SUFFIX)).bind(PW_DM) + # Access denied to ROLE1 members + assert 0 == len(ManagedRoles(conn, DEFAULT_SUFFIX).list()) + + # Now create a connection with cn=Success which is not a member of ROLE1 + conn = UserAccount(topo.standalone, "uid=Success,{}".format(DEFAULT_SUFFIX)).bind(PW_DM) + # Access allowed here + assert 1 == len(ManagedRoles(conn, DEFAULT_SUFFIX).list()) + + for i in uas.list(): + i.delete() + + for i in roles.list(): + i.delete() + + if __name__ == "__main__": CURRENT_FILE = os.path.realpath(__file__) pytest.main("-s -v %s" % CURRENT_FILE) diff --git a/src/lib389/lib389/idm/nsrole.py b/src/lib389/lib389/idm/nsrole.py deleted file mode 100644 index 482837d..0000000 --- a/src/lib389/lib389/idm/nsrole.py +++ /dev/null @@ -1,70 +0,0 @@ -# --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2019 Red Hat, Inc. -# All rights reserved. -# -# License: GPL (version 3 or any later version). -# See LICENSE for details. -# --- END COPYRIGHT BLOCK ---- - - -from lib389._mapped_object import DSLdapObject, DSLdapObjects - - -class nsFilterRole(DSLdapObject): - """A single instance of nsfilter entry to create nsFIltered role. - - :param instance: An instance - :type instance: lib389.DirSrv - :param dn: Entry DN - :type dn: str - Usages: - user1 = 'cn=anuj,ou=people,dc=example,ed=com' - user2 = 'cn=unknownuser,ou=people,dc=example,ed=com' - role=nsFilterRole(topo.standalone,'cn=NameofRole,ou=People,dc=example,dc=com') - role_props={'cn':'Anuj', 'nsRoleFilter':'cn=anuj*'} - role.create(properties=role_props, basedn=SUFFIX) - The user1 entry matches the filter (possesses the cn=anuj* attribute with the value anuj) - therefore, it is a member of this filtered role automatically. - """ - def __init__(self, instance, dn=None): - super(nsFilterRole, self).__init__(instance, dn) - self._rdn_attribute = 'cn' - self._create_objectclasses = [ - 'top', - 'nsRoleDefinition', - 'nsComplexRoleDefinition', - 'nsFilteredRoleDefinition' - ] - - -class nsFilterRoles(DSLdapObjects): - """DSLdapObjects that represents all nsfiltertrole entries in suffix. - - This instance is used mainly for search operation nsfiltred role - - :param instance: An instance - :type instance: lib389.DirSrv - :param basedn: Suffix DN - :type basedn: str - :param rdn: The DN that will be combined wit basedn - :type rdn: str - Usages: - role_props={'cn':'Anuj', 'nsRoleFilter':'cn=*'} - nsFilterRoles(topo.standalone, DEFAULT_SUFFIX).create(properties=role_props) - nsFilterRoles(topo.standalone, DEFAULT_SUFFIX).list() - user1 = 'cn=anuj,ou=people,dc=example,ed=com' - user2 = 'uid=unknownuser,ou=people,dc=example,ed=com' - The user1 entry matches the filter (possesses the cn=* attribute with the value cn) - therefore, it is a member of this filtered role automatically. - """ - def __init__(self, instance, basedn): - super(nsFilterRoles, self).__init__(instance) - self._objectclasses = [ - 'top', - 'nsRoleDefinition', - 'nsComplexRoleDefinition', - 'nsFilteredRoleDefinition' - ] - self._filterattrs = ['cn'] - self._basedn = basedn - self._childobject = nsFilterRole diff --git a/src/lib389/lib389/idm/role.py b/src/lib389/lib389/idm/role.py new file mode 100644 index 0000000..91699d4 --- /dev/null +++ b/src/lib389/lib389/idm/role.py @@ -0,0 +1,115 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2019 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK ---- + + +from lib389._mapped_object import DSLdapObject, DSLdapObjects + + +class FilterRole(DSLdapObject): + """A single instance of FilterRole entry to create FilterRole role. + + :param instance: An instance + :type instance: lib389.DirSrv + :param dn: Entry DN + :type dn: str + Usages: + user1 = 'cn=anuj,ou=people,dc=example,ed=com' + user2 = 'cn=unknownuser,ou=people,dc=example,ed=com' + role=FilterRole(topo.standalone,'cn=NameofRole,ou=People,dc=example,dc=com') + role_props={'cn':'Anuj', 'nsRoleFilter':'cn=anuj*'} + role.create(properties=role_props, basedn=SUFFIX) + The user1 entry matches the filter (possesses the cn=anuj* attribute with the value anuj) + therefore, it is a member of this filtered role automatically. + """ + def __init__(self, instance, dn=None): + super(FilterRole, self).__init__(instance, dn) + self._rdn_attribute = 'cn' + self._create_objectclasses = [ + 'top', + 'nsRoleDefinition', + 'nsComplexRoleDefinition', + 'nsFilteredRoleDefinition' + ] + + +class FilterRoles(DSLdapObjects): + """DSLdapObjects that represents all filtertrole entries in suffix. + + This instance is used mainly for search operation filtred role + + :param instance: An instance + :type instance: lib389.DirSrv + :param basedn: Suffix DN + :type basedn: str + :param rdn: The DN that will be combined wit basedn + :type rdn: str + Usages: + role_props={'cn':'Anuj', 'nsRoleFilter':'cn=*'} + FilterRoles(topo.standalone, DEFAULT_SUFFIX).create(properties=role_props) + FilterRoles(topo.standalone, DEFAULT_SUFFIX).list() + user1 = 'cn=anuj,ou=people,dc=example,ed=com' + user2 = 'uid=unknownuser,ou=people,dc=example,ed=com' + The user1 entry matches the filter (possesses the cn=* attribute with the value cn) + therefore, it is a member of this filtered role automatically. + """ + def __init__(self, instance, basedn): + super(FilterRoles, self).__init__(instance) + self._objectclasses = [ + 'top', + 'nsRoleDefinition', + 'nsComplexRoleDefinition', + 'nsFilteredRoleDefinition' + ] + self._filterattrs = ['cn'] + self._basedn = basedn + self._childobject = FilterRole + + +class ManagedRole(DSLdapObject): + """A single instance of ManagedRole entry to create ManagedRole role. + + :param instance: An instance + :type instance: lib389.DirSrv + :param dn: Entry DN + :type dn: str + + """ + def __init__(self, instance, dn=None): + super(ManagedRole, self).__init__(instance, dn) + self._rdn_attribute = 'cn' + self._create_objectclasses = [ + 'top', + 'nsRoleDefinition', + 'nsSimpleRoleDefinition', + 'nsManagedRoleDefinition' + ] + + +class ManagedRoles(DSLdapObjects): + """DSLdapObjects that represents all ManagedRoles entries in suffix. + + This instance is used mainly for search operation ManagedRoles role + + :param instance: An instance + :type instance: lib389.DirSrv + :param basedn: Suffix DN + :type basedn: str + :param rdn: The DN that will be combined wit basedn + :type rdn: str + """ + def __init__(self, instance, basedn): + super(ManagedRoles, self).__init__(instance) + self._objectclasses = [ + 'top', + 'nsRoleDefinition', + 'nsSimpleRoleDefinition', + 'nsManagedRoleDefinition' + ] + self._filterattrs = ['cn'] + self._basedn = basedn + self._childobject = ManagedRole \ No newline at end of file