From 6714c45603a03ac8c2f1ef289aa390639676bdb5 Mon Sep 17 00:00:00 2001 From: Anuj Borah Date: Feb 14 2019 02:31:25 +0000 Subject: Issue: 50170 - composable object types for nsRole in lib389 Composable object types for nsRole in lib389 https://pagure.io/389-ds-base/issue/50170 Reviewed by: Ludwig Krispenz, William Brown, thierry bordaz --- diff --git a/dirsrvtests/tests/suites/roles/basic_test.py b/dirsrvtests/tests/suites/roles/basic_test.py new file mode 100644 index 0000000..6289d74 --- /dev/null +++ b/dirsrvtests/tests/suites/roles/basic_test.py @@ -0,0 +1,124 @@ +# --- 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 --- + +import pytest, os +from lib389._constants import PW_DM, DEFAULT_SUFFIX +from lib389.idm.user import UserAccount +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 + + +DNBASE = "o=acivattr,{}".format(DEFAULT_SUFFIX) +ENG_USER = "cn=enguser1,ou=eng,{}".format(DNBASE) +SALES_UESER = "cn=salesuser1,ou=sales,{}".format(DNBASE) +ENG_MANAGER = "cn=engmanager1,ou=eng,{}".format(DNBASE) +SALES_MANAGER = "cn=salesmanager1,ou=sales,{}".format(DNBASE) +SALES_OU = "ou=sales,{}".format(DNBASE) +ENG_OU = "ou=eng,{}".format(DNBASE) +FILTERROLESALESROLE = "cn=FILTERROLESALESROLE,{}".format(DNBASE) +FILTERROLEENGROLE = "cn=FILTERROLEENGROLE,{}".format(DNBASE) + + +def test_nsrole(topo): + ''' + :id: 8ada4064-786b-11e8-8634-8c16451d917b + :setup: server + :steps: + 1. Add test entry + 2. Add ACI + 3. Search nsconsole role + :expectedresults: + 1. Entry should be added + 2. Operation should succeed + 3. Operation should succeed + ''' + Organization(topo.standalone).create(properties={"o": "acivattr"}, basedn=DEFAULT_SUFFIX) + properties = { + 'ou': 'eng', + } + + ou = OrganizationalUnit(topo.standalone, "ou=eng,o=acivattr,{}".format(DEFAULT_SUFFIX)) + ou.create(properties=properties) + properties = {'ou': 'sales'} + ou = OrganizationalUnit(topo.standalone, "ou=sales,o=acivattr,{}".format(DEFAULT_SUFFIX)) + ou.create(properties=properties) + + roles = nsFilterRoles(topo.standalone, DNBASE) + roles.create(properties={'cn': 'FILTERROLEENGROLE', 'nsRoleFilter': 'cn=eng*'}) + roles.create(properties={'cn': 'FILTERROLESALESROLE', 'nsRoleFilter': 'cn=sales*'}) + + properties = { + 'uid': 'salesuser1', + 'cn': 'salesuser1', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'salesuser1', + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, 'cn=salesuser1,ou=sales,o=acivattr,{}'.format(DEFAULT_SUFFIX)) + user.create(properties=properties) + + properties = { + 'uid': 'salesmanager1', + 'cn': 'salesmanager1', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'salesmanager1', + 'userPassword': PW_DM, + } + user = UserAccount(topo.standalone, 'cn=salesmanager1,ou=sales,o=acivattr,{}'.format(DEFAULT_SUFFIX)) + user.create(properties=properties) + + properties = { + 'uid': 'enguser1', + 'cn': 'enguser1', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'enguser1', + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone,'cn=enguser1,ou=eng,o=acivattr,{}'.format(DEFAULT_SUFFIX)) + user.create(properties=properties) + + properties = { + 'uid': 'engmanager1', + 'cn': 'engmanager1', + 'sn': 'user', + 'uidNumber': '1000', + 'gidNumber': '2000', + 'homeDirectory': '/home/' + 'engmanager1', + 'userPassword': PW_DM + } + user = UserAccount(topo.standalone, 'cn=engmanager1,ou=eng,o=acivattr,{}'.format(DEFAULT_SUFFIX)) + user.create(properties=properties) + + #user with cn=sales* will automatically memeber of nsfilterrole cn=filterrolesalesrole,o=acivattr,dc=example,dc=com + assert UserAccount(topo.standalone, 'cn=salesuser1,ou=sales,o=acivattr,dc=example,dc=com').get_attr_val_utf8( + 'nsrole') == 'cn=filterrolesalesrole,o=acivattr,dc=example,dc=com' + # same goes to SALES_MANAGER + assert UserAccount(topo.standalone, SALES_MANAGER).get_attr_val_utf8( + 'nsrole') == 'cn=filterrolesalesrole,o=acivattr,dc=example,dc=com' + # user with cn=eng* will automatically memeber of nsfilterrole cn=filterroleengrole,o=acivattr,dc=example,dc=com + assert UserAccount(topo.standalone, 'cn=enguser1,ou=eng,o=acivattr,dc=example,dc=com').get_attr_val_utf8( + 'nsrole') == 'cn=filterroleengrole,o=acivattr,dc=example,dc=com' + # same goes to ENG_MANAGER + assert UserAccount(topo.standalone, ENG_MANAGER).get_attr_val_utf8( + 'nsrole') == 'cn=filterroleengrole,o=acivattr,dc=example,dc=com' + for DN in [ENG_USER, SALES_UESER, ENG_MANAGER, SALES_MANAGER, FILTERROLESALESROLE, FILTERROLEENGROLE, ENG_OU, + SALES_OU, DNBASE]: + UserAccount(topo.standalone, DN).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 new file mode 100644 index 0000000..482837d --- /dev/null +++ b/src/lib389/lib389/idm/nsrole.py @@ -0,0 +1,70 @@ +# --- 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