From 0654fb3737febf3d9836cdd2a98352c34c447a6f Mon Sep 17 00:00:00 2001 From: Florence Blanc-Renaud Date: Fri, 25 Aug 2023 15:34:22 +0200 Subject: [PATCH] idp: add the ipaidpuser objectclass when needed The ipaidpuser objectclass is required for the attribute ipaidpsub. When a user is created or modified with --idp-user-id, the operation must ensure that the objectclass is added if missing. Add a test for user creation and user modification with --idp-user-id. Fixes: https://pagure.io/freeipa/issue/9433 Signed-off-by: Florence Blanc-Renaud Reviewed-By: Alexander Bokovoy --- ipaserver/plugins/baseuser.py | 11 +++++++-- ipatests/test_xmlrpc/test_user_plugin.py | 30 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py index 61fc20ac6..b66016305 100644 --- a/ipaserver/plugins/baseuser.py +++ b/ipaserver/plugins/baseuser.py @@ -612,7 +612,10 @@ class baseuser_add(LDAPCreate): if entry_attrs.get('ipauserauthtype', None): add_missing_object_class(ldap, u'ipauserauthtypeclass', dn, entry_attrs, update=False) - if entry_attrs.get('ipaidpconfiglink', None): + if ( + entry_attrs.get('ipaidpconfiglink', None) + or entry_attrs.get('ipaidpsub', None) + ): add_missing_object_class(ldap, 'ipaidpuser', dn, entry_attrs, update=False) @@ -720,7 +723,7 @@ class baseuser_mod(LDAPUpdate): # Some attributes may require additional object classes special_attrs = {'ipasshpubkey', 'ipauserauthtype', 'userclass', 'ipatokenradiusconfiglink', 'ipatokenradiususername', - 'ipaidpconfiglink'} + 'ipaidpconfiglink', 'ipaidpsub'} if special_attrs.intersection(entry_attrs): if 'objectclass' in entry_attrs: obj_classes = entry_attrs['objectclass'] @@ -749,6 +752,10 @@ class baseuser_mod(LDAPUpdate): answer = self.api.Object['radiusproxy'].get_dn_if_exists(cl) entry_attrs['ipatokenradiusconfiglink'] = answer + if 'ipaidpsub' in entry_attrs: + if 'ipaidpuser' not in obj_classes: + entry_attrs['objectclass'].append('ipaidpuser') + if 'ipaidpconfiglink' in entry_attrs: cl = entry_attrs['ipaidpconfiglink'] if cl: diff --git a/ipatests/test_xmlrpc/test_user_plugin.py b/ipatests/test_xmlrpc/test_user_plugin.py index 974d256d9..f48011b1d 100644 --- a/ipatests/test_xmlrpc/test_user_plugin.py +++ b/ipatests/test_xmlrpc/test_user_plugin.py @@ -166,6 +166,20 @@ def user_radius(request, xmlrpc_setup): return tracker.make_fixture(request) +@pytest.fixture(scope='class') +def user_idp(request, xmlrpc_setup): + """ User tracker fixture for testing users with idp user id """ + tracker = UserTracker(name='idpuser', givenname='idp', + sn='user', ipaidpsub='myidpuserid') + tracker.track_create() + tracker.attrs.update(ipaidpsub=['myidpuserid']) + tracker.attrs.update(objectclass=fuzzy_set_optional_oc( + objectclasses.user + [u'ipaidpuser'], + 'ipantuserattrs'), + ) + return tracker.make_fixture(request) + + @pytest.fixture(scope='class') def group(request, xmlrpc_setup): tracker = GroupTracker(name=u'group1') @@ -557,6 +571,15 @@ class TestUpdate(XMLRPC_test): )): command() + def test_update_add_idpsub(self, user): + """ Test user-mod --idp-user-id""" + user.ensure_exists() + command = user.make_update_command( + updates=dict(ipaidpsub=u'myidp_user_id') + ) + command() + user.delete() + @pytest.mark.tier1 class TestCreate(XMLRPC_test): @@ -796,6 +819,13 @@ class TestCreate(XMLRPC_test): )): testuser.create() + def test_create_with_idpsub(self, user_idp): + """ Test creation of a user with --idp-user-id""" + command = user_idp.make_create_command() + result = command() + user_idp.check_create(result, ['ipaidpsub']) + user_idp.delete() + @pytest.mark.tier1 class TestUserWithGroup(XMLRPC_test):