URL: https://github.com/freeipa/freeipa/pull/3098
Author: wladich
 Title: #3098: [Backport][ipa-4-6] ipatests: new tests for ipa-winsync-migrate 
utility
Action: opened

PR body:
"""
Manual backport of #3018

Fixes https://pagure.io/freeipa/issue/7857
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/3098/head:pr3098
git checkout pr3098
From d9a0146130e6b39d4089bba2579a738dbb9c5a79 Mon Sep 17 00:00:00 2001
From: Sergey Orlov <sor...@redhat.com>
Date: Tue, 9 Apr 2019 18:59:37 +0200
Subject: [PATCH] ipatests: new tests for ipa-winsync-migrate utility

Fixes https://pagure.io/freeipa/issue/7857
---
 .../test_integration/test_winsyncmigrate.py   | 236 ++++++++++++++++++
 1 file changed, 236 insertions(+)
 create mode 100644 ipatests/test_integration/test_winsyncmigrate.py

diff --git a/ipatests/test_integration/test_winsyncmigrate.py b/ipatests/test_integration/test_winsyncmigrate.py
new file mode 100644
index 0000000000..e4ff03e6d7
--- /dev/null
+++ b/ipatests/test_integration/test_winsyncmigrate.py
@@ -0,0 +1,236 @@
+#
+# Copyright (C) 2019  FreeIPA Contributors see COPYING for license
+#
+"""
+Module provides tests for the ipa-winsync-migrate command.
+"""
+import os
+import base64
+import re
+
+import pytest
+
+from ipatests.pytest_ipa.integration import tasks
+from ipatests.test_integration.base import IntegrationTest
+
+
+def get_windows_certificate(ad_host):
+    certs_path = '/cygdrive/c/Windows/System32/CertSrv/CertEnroll/'
+    cert_filename = '%s_%s-%s-CA.crt' % (
+        ad_host.hostname, ad_host.domain.name.split('.')[0],
+        ad_host.shortname.upper())
+    return ad_host.get_file_contents(os.path.join(certs_path, cert_filename))
+
+
+def convert_crt_to_cer(data):
+    header = b'-----BEGIN CERTIFICATE-----\n'
+    trailer = b'-----END CERTIFICATE-----\n'
+    return header + base64.encodebytes(data) + trailer
+
+
+def establish_winsync_agreement(master, ad):
+    win_cert = get_windows_certificate(ad)
+    cert_path = master.run_command(['mktemp']).stdout_text.strip()
+    master.put_file_contents(cert_path, convert_crt_to_cer(win_cert))
+    master.run_command(['kdestroy', '-A'])
+    master.run_command([
+        'ipa-replica-manage', 'connect', '--winsync',
+        '--binddn', 'cn=%s,cn=users,%s' % (ad.config.ad_admin_name,
+                                           ad.domain.basedn),
+        '--bindpw', ad.config.ad_admin_password,
+        '--password', master.config.dirman_password,
+        '--cacert', cert_path,
+        '--passsync', 'dummy',
+        ad.hostname, '-v'
+    ])
+    master.run_command(['rm', cert_path])
+
+
+def ipa_output_fields(s):
+    return [line.strip() for line in s.splitlines()]
+
+
+class TestWinsyncMigrate(IntegrationTest):
+    topology = 'star'
+    num_ad_domains = 1
+
+    ipa_group = 'ipa_group'
+    ad_user = 'testuser'
+    test_role = 'test_role'
+    test_hbac_rule = 'test_hbac_rule'
+    test_selinux_map = 'test_selinux_map'
+    test_role_with_nonposix_chars = '$the test,role!'
+    test_role_with_nonposix_chars_normalized = 'the_testrole'
+    collision_role1 = 'collision role'
+    collision_role2 = 'collision, role'
+    collision_role3 = 'collision_role'
+    collision_role_normalized = 'collision_role'
+
+    @classmethod
+    def install(cls, mh):
+        super(TestWinsyncMigrate, cls).install(mh)
+
+        cls.ad = cls.ads[0]  # pylint: disable=no-member
+        cls.trust_test_user = '%s@%s' % (cls.ad_user, cls.ad.domain.name)
+        tasks.configure_dns_for_trust(cls.master, cls.ad)
+        tasks.install_adtrust(cls.master)
+        cls.create_test_objects()
+        establish_winsync_agreement(cls.master, cls.ad)
+        tasks.kinit_admin(cls.master)
+        cls.setup_user_memberships(cls.ad_user)
+        # store user uid and gid
+        result = cls.master.run_command(['getent', 'passwd', cls.ad_user])
+        testuser_regex = (
+            r"^{0}:\*:(\d+):(\d+):{0}:/home/{0}:/bin/sh$".format(
+                cls.ad_user))
+        m = re.match(testuser_regex, result.stdout_text)
+        cls.test_user_uid, cls.test_user_gid = m.groups()
+
+    @classmethod
+    def create_test_objects(cls):
+        tasks.group_add(cls.master, cls.ipa_group)
+
+        for role in [cls.test_role, cls.collision_role1, cls.collision_role2,
+                     cls.collision_role3, cls.test_role_with_nonposix_chars]:
+            cls.master.run_command(['ipa', 'role-add', role])
+
+        cls.master.run_command(['ipa', 'hbacrule-add', cls.test_hbac_rule])
+        cls.master.run_command([
+            'ipa', 'selinuxusermap-add', cls.test_selinux_map,
+            '--selinuxuser', 'guest_u:s0'])
+
+    @classmethod
+    def setup_user_memberships(cls, user):
+        cls.master.run_command(['ipa', 'group-add-member', cls.ipa_group,
+                                '--users', user])
+        for role in [cls.test_role, cls.collision_role1, cls.collision_role2,
+                     cls.collision_role3, cls.test_role_with_nonposix_chars]:
+            cls.master.run_command(['ipa', 'role-add-member', role,
+                                    '--users', user])
+        cls.master.run_command(['ipa', 'hbacrule-add-user',
+                                cls.test_hbac_rule, '--users', user])
+        cls.master.run_command(['ipa', 'selinuxusermap-add-user',
+                                cls.test_selinux_map, '--users', user])
+
+    def check_replication_agreement_exists(self, server_name, should_exist):
+        result = self.master.run_command(
+            ['ipa-replica-manage', 'list', server_name])
+        if should_exist:
+            expected_message = '%s: winsync' % self.ad.hostname
+        else:
+            expected_message = ('Cannot find %s in public server list' %
+                                server_name)
+        assert result.stdout_text.strip() == expected_message
+
+    def test_preconditions(self):
+        self.check_replication_agreement_exists(self.ad.hostname, True)
+        # check user exists at ipa server
+        result = self.master.run_command(['ipa', 'user-show', self.ad_user],
+                                         raiseonerr=False)
+        assert result.returncode == 0
+
+    def test_migration(self):
+        tasks.establish_trust_with_ad(self.master, self.ad.domain.name)
+        result = self.master.run_command([
+            'ipa-winsync-migrate', '-U', '--realm', self.ad.domain.name,
+            '--server', self.ad.hostname])
+        assert ('The ipa-winsync-migrate command was successful'
+                in result.stderr_text)
+        tasks.clear_sssd_cache(self.master)
+
+    def test_replication_agreement_deleted(self):
+        self.check_replication_agreement_exists(self.ad.hostname, False)
+
+    def test_user_deleted_from_ipa_server(self):
+        result = self.master.run_command(['ipa', 'user-show', self.ad_user],
+                                         raiseonerr=False)
+        assert result.returncode == 2
+
+    def test_user_attributes_preserved(self):
+        result = self.master.run_command(['getent', 'passwd',
+                                          self.trust_test_user])
+        passwd_template = (
+            '{trust_user}:*:{uid}:{gid}:{user}:/home/{domain}/{user}:/bin/sh')
+        expected_result = passwd_template.format(
+            user=self.ad_user, uid=self.test_user_uid, gid=self.test_user_gid,
+            domain=self.ad.domain.name, trust_user=self.trust_test_user)
+        assert result.stdout_text.strip() == expected_result
+
+    def test_idoverride(self):
+        result = self.master.run_command([
+            'ipa', 'idoverrideuser-show', '--raw',
+            'Default Trust View', self.trust_test_user])
+        idoverride_fields = [line
+                             for line in ipa_output_fields(result.stdout_text)
+                             if 'ipaanchoruuid:' not in line]
+        expected_fields = [
+            'uid: %s' % self.ad_user,
+            'uidnumber: %s' % self.test_user_uid,
+            'gidnumber: %s' % self.test_user_gid,
+            'gecos: %s' % self.ad_user,
+            'loginshell: /bin/sh'
+
+        ]
+        assert sorted(idoverride_fields) == sorted(expected_fields)
+
+    def test_groups_membership_preserved(self):
+        result = self.master.run_command([
+            'ipa', 'group-show', 'group_%s_winsync_external' % self.ipa_group])
+        output_fields = ipa_output_fields(result.stdout_text)
+        assert 'External member: %s' % self.trust_test_user in output_fields
+        assert 'Member of groups: %s' % self.ipa_group in output_fields
+
+    def test_role_membership_preserved(self):
+        result = self.master.run_command([
+            'ipa', 'group-show', 'role_%s_winsync_external' % self.test_role])
+        output_fields = ipa_output_fields(result.stdout_text)
+        assert 'External member: %s' % self.trust_test_user in output_fields
+        assert 'Roles: %s' % self.test_role
+
+    def test_selinuxusermap_membership_preserved(self):
+        wrapper_group = 'selinux_%s_winsync_external' % self.test_selinux_map
+
+        result = self.master.run_command(['ipa', 'selinuxusermap-show',
+                                          self.test_selinux_map])
+        assert ('User Groups: %s' % wrapper_group
+                in ipa_output_fields(result.stdout_text))
+
+        result = self.master.run_command(['ipa', 'group-show', wrapper_group])
+        assert ('External member: %s' % self.trust_test_user
+                in ipa_output_fields(result.stdout_text))
+
+    def test_hbacrule_membership_preserved(self):
+        result = self.master.run_command([
+            'ipa', 'group-show',
+            'hbacrule_%s_winsync_external' % self.test_hbac_rule])
+        output_fields = ipa_output_fields(result.stdout_text)
+        assert 'External member: %s' % self.trust_test_user in output_fields
+        assert 'Member of HBAC rule: %s' % self.test_hbac_rule in output_fields
+
+    def test_non_posix_chars_in_group_names_replaced(self):
+        result = self.master.run_command([
+            'ipa', 'role-show', self.test_role_with_nonposix_chars])
+        expected_group_name = ('role_%s_winsync_external' %
+                               self.test_role_with_nonposix_chars_normalized)
+        assert ('Member groups: %s' % expected_group_name
+                in ipa_output_fields(result.stdout_text))
+
+    @pytest.mark.xfail(reason='BZ1698118', strict=True)
+    def test_collisions_resolved(self):
+        group = 'role_%s_winsync_external' % self.collision_role_normalized
+        result = self.master.run_command(['ipa', 'group-show', group])
+        output_fields = ipa_output_fields(result.stdout_text)
+        assert 'Roles: %s' % self.collision_role1 in output_fields
+        assert 'External member: %s' % self.trust_test_user in output_fields
+
+        group = 'role_%s_winsync_external1' % self.collision_role_normalized
+        result = self.master.run_command(['ipa', 'group-show', group])
+        output_fields = ipa_output_fields(result.stdout_text)
+        assert 'Roles: %s' % self.collision_role2 in output_fields
+        assert 'External member: %s' % self.trust_test_user in output_fields
+
+        group = 'role_%s_winsync_external2' % self.collision_role_normalized
+        result = self.master.run_command(['ipa', 'group-show', group])
+        output_fields = ipa_output_fields(result.stdout_text)
+        assert 'Roles: %s' % self.collision_role3 in output_fields
+        assert 'External member: %s' % self.trust_test_user in output_fields
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org

Reply via email to