On 10/19/2015 01:38 PM, Martin Basti wrote:


On 16.10.2015 15:43, Milan Kubík wrote:
On 09/30/2015 02:47 PM, Martin Basti wrote:









On 09/24/2015 02:49 PM, Milan Kubík
wrote:


Hi
all,




an update for CA ACL tests!




I, with help from M. Babinsky, managed to find a way how to change
the identity during acceptance cest run, which allows


to test CA ACLs (and perhaps other areas with some form of access
controll).




This allowed me to write a test for CA ACLs and certificate
profiles that checks if the ACL/profile is being used and
enforced.


The first several tests are based on Fraser's blogpost using SMIME
profile [1].




The master and ipa-4-2 branches diverged a bit, so I had to change
two commits when rebasing to ipa-4-2 branch.




Commits should be applied in the order (including rebased patches
I sent in an earlier email):




master:


    * 12 - 17




ipa-4-2:


    * 18, 13 - 15, 19, 17




For convenience:


patches on top of master:
https://github.com/apophys/freeipa/tree/acl-profile-functional


patches on top of ipa-4-2:
https://github.com/apophys/freeipa/tree/acl-42






[1]:
https://blog-ftweedal.rhcloud.com/2015/08/user-certificates-and-custom-profiles-with-freeipa-4-2/



Cheers,


Milan










NACK



0)

rpm file does not contain test_xmlrpc/data directory, please modify
setup.py.in.



1)

Code contains to much todo for my taste.



2)

Please do not use filter function, use dict comprehension.








Hi,

updated patches and the numbering mess somehow curbed. The patches are rebased on top of current master and ipa-4-2.

0) fixed by 0021

1) docs for tracker extended, added more test cases

2) changed


--
Milan Kubik
I have a few comments:

1)
+# TODO: rewrite these into Tracker instances
+@pytest.fixture(scope='class')
+def smime_user(request):
+    api.Command.user_add(uid=u'alice', givenname=u'Alice', sn=u'SMIME',
+                         userpassword=u'Change123')
+
+    unlock_principal_password('alice', 'Change123', 'Secret123')
+
+    def fin():
+        api.Command.user_del(u'alice')
+    request.addfinalizer(fin)
+
+    return u'alice'

I do not like hardcoded password value, as this password is used in many places in the test, I sugest to use a module variable
Done

2)
+class TestSignWithChangedProfile(XMLRPC_test):
+    """ Test to verify that the updated profile is used."""
+    pass  # import invalid profile, try to sign, expect fail

IMO something is missing here, a test maybe?

Done by using profile with constraint that CSR cannot meet.
3)
# noqa
Please remove "# noqa" commets from commits

Done.

--
Milan Kubik

From d3599a45ecb7d3bc8e5364fde239769291672ca2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Milan=20Kub=C3=ADk?= <mku...@redhat.com>
Date: Fri, 7 Aug 2015 15:54:18 +0200
Subject: [PATCH 3/6] tests: add test to check the default ACL

Also includes basic ACL manipulation and adding
and removing members to/from the acl.

https://fedorahosted.org/freeipa/ticket/57
---
 ipatests/test_xmlrpc/test_caacl_plugin.py | 135 ++++++++++++++++++++++++++++--
 1 file changed, 128 insertions(+), 7 deletions(-)

diff --git a/ipatests/test_xmlrpc/test_caacl_plugin.py b/ipatests/test_xmlrpc/test_caacl_plugin.py
index 6cf835b229f70797e32bcfd2309cfa7be5732f51..33268d6dde115ce040e55eaae08a7fe1299ad112 100644
--- a/ipatests/test_xmlrpc/test_caacl_plugin.py
+++ b/ipatests/test_xmlrpc/test_caacl_plugin.py
@@ -6,20 +6,20 @@
 Test the `ipalib.plugins.caacl` module.
 """
 
-import os
-
 import pytest
 
-from ipapython import ipautil
-from ipalib import errors, x509
-from ipapython.dn import DN
+from ipalib import errors
 from ipatests.test_xmlrpc.ldaptracker import Tracker
 from ipatests.test_xmlrpc.xmlrpc_test import (XMLRPC_test, fuzzy_caacldn,
-                                              fuzzy_uuid, fuzzy_ipauniqueid,
-                                              raises_exact)
+                                              fuzzy_uuid, fuzzy_ipauniqueid)
+
 from ipatests.test_xmlrpc import objectclasses
 from ipatests.util import assert_deepequal
 
+# reuse the fixture
+from ipatests.test_xmlrpc.test_certprofile_plugin import default_profile
+from ipatests.test_xmlrpc.test_stageuser_plugin import StageUserTracker
+
 
 class CAACLTracker(Tracker):
     """Tracker class for CA ACL LDAP object.
@@ -376,3 +376,124 @@ class CAACLTracker(Tracker):
         command = self.make_command(u'caacl_disable', self.name)
         self.attrs.update({u'ipaenabledflag': [u'FALSE']})
         command()
+
+
+@pytest.fixture(scope='class')
+def default_acl(request):
+    name = u'hosts_services_caIPAserviceCert'
+    tracker = CAACLTracker(name, service_category=u'all', host_category=u'all')
+    tracker.track_create()
+    tracker.attrs.update(
+        {u'ipamembercertprofile_certprofile': [u'caIPAserviceCert']})
+    return tracker
+
+
+@pytest.fixture(scope='class')
+def crud_acl(request):
+    name = u'crud-acl'
+    tracker = CAACLTracker(name)
+
+    return tracker.make_fixture(request)
+
+
+@pytest.fixture(scope='class')
+def category_acl(request):
+    name = u'category_acl'
+    tracker = CAACLTracker(name, ipacertprofile_category=u'all',
+                           user_category=u'all', service_category=u'all',
+                           host_category=u'all')
+
+    return tracker.make_fixture(request)
+
+
+@pytest.fixture(scope='class')
+def staged_user(request):
+    name = u'st-user'
+    tracker = StageUserTracker(name, u'stage', u'test')
+
+    return tracker.make_fixture(request)
+
+
+class TestDefaultACL(XMLRPC_test):
+    def test_default_acl_present(self, default_acl):
+        default_acl.retrieve()
+
+
+class TestCAACLbasicCRUD(XMLRPC_test):
+    def test_create(self, crud_acl):
+        crud_acl.create()
+
+    def test_delete(self, crud_acl):
+        crud_acl.delete()
+
+    def test_disable(self, crud_acl):
+        crud_acl.ensure_exists()
+        crud_acl.disable()
+        crud_acl.retrieve()
+
+    def test_disable_twice(self, crud_acl):
+        crud_acl.disable()
+        crud_acl.retrieve()
+
+    def test_enable(self, crud_acl):
+        crud_acl.enable()
+        crud_acl.retrieve()
+
+    def test_enable_twice(self, crud_acl):
+        crud_acl.enable()
+        crud_acl.retrieve()
+
+    def test_find(self, crud_acl):
+        crud_acl.find()
+
+
+class TestCAACLMembers(XMLRPC_test):
+    def test_category_member_exclusivity(self, category_acl, default_profile):
+        category_acl.create()
+        default_profile.ensure_exists()
+        with pytest.raises(errors.MutuallyExclusiveError):
+            category_acl.add_profile(default_profile.name, track=False)
+
+    def test_mod_delete_category(self, category_acl):
+        updates = dict(
+            hostcategory=None,
+            servicecategory=None,
+            ipacertprofilecategory=None,
+            usercategory=None)
+        category_acl.update(updates)
+
+    def test_add_profile(self, category_acl, default_profile):
+        category_acl.add_profile(certprofile=default_profile.name)
+        category_acl.retrieve()
+
+    def test_remove_profile(self, category_acl, default_profile):
+        category_acl.remove_profile(certprofile=default_profile.name)
+        category_acl.retrieve()
+
+    def test_add_invalid_value_service(self, category_acl, default_profile):
+        res = category_acl.add_service(service=default_profile.name, track=False)
+        assert len(res['failed']) == 1
+
+    # the same for other types
+
+    def test_add_invalid_value_user(self, category_acl, default_profile):
+        res = category_acl.add_user(user=default_profile.name, track=False)
+        assert len(res['failed']) == 1
+
+        res = category_acl.add_user(group=default_profile.name, track=False)
+        assert len(res['failed']) == 1
+
+    def test_add_invalid_value_host(self, category_acl, default_profile):
+        res = category_acl.add_host(host=default_profile.name, track=False)
+        assert len(res['failed']) == 1
+
+        res = category_acl.add_host(hostgroup=default_profile.name, track=False)
+        assert len(res['failed']) == 1
+
+    def test_add_invalid_value_profile(self, category_acl):
+        res = category_acl.add_profile(certprofile=category_acl.name, track=False)
+        assert len(res['failed']) == 1
+
+    def test_add_staged_user_to_acl(self, category_acl, staged_user):
+        res = category_acl.add_user(user=staged_user.name, track=False)
+        assert len(res['failed']) == 1
-- 
2.6.1

From 70ee06aee56cbfa5248785bf75bfe9881f5d36d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Milan=20Kub=C3=ADk?= <mku...@redhat.com>
Date: Tue, 22 Sep 2015 15:22:25 +0200
Subject: [PATCH 6/6] ipatests: CA ACL and cert profile functional test

https://fedorahosted.org/freeipa/ticket/57
---
 ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl       | 108 ++++++++++
 .../test_xmlrpc/test_caacl_profile_enforcement.py  | 239 +++++++++++++++++++++
 2 files changed, 347 insertions(+)
 create mode 100644 ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl
 create mode 100644 ipatests/test_xmlrpc/test_caacl_profile_enforcement.py

diff --git a/ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl b/ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl
new file mode 100644
index 0000000000000000000000000000000000000000..da94c25e574af6cfe7230073195a541eb7f04fd8
--- /dev/null
+++ b/ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl
@@ -0,0 +1,108 @@
+auth.instance_id=raCertAuth
+classId=caEnrollImpl
+desc=Certificate for S-MIME extension
+enable=true
+enableBy=ipara
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+input.list=i1,i2
+name=SMIME certificate profile
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=serverCertSet
+policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+policyset.serverCertSet.1.constraint.params.accept=true
+policyset.serverCertSet.1.constraint.params.pattern=CN=refuse sign
+policyset.serverCertSet.1.default.class_id=subjectNameDefaultImpl
+policyset.serverCertSet.1.default.name=Subject Name Default
+policyset.serverCertSet.1.default.params.name=CN=$request.req_subject_name.cn$, O={iparealm}
+policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.serverCertSet.2.constraint.name=Validity Constraint
+policyset.serverCertSet.2.constraint.params.notAfterCheck=false
+policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
+policyset.serverCertSet.2.constraint.params.range=740
+policyset.serverCertSet.2.default.class_id=validityDefaultImpl
+policyset.serverCertSet.2.default.name=Validity Default
+policyset.serverCertSet.2.default.params.range=731
+policyset.serverCertSet.2.default.params.startTime=0
+policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.serverCertSet.3.constraint.name=Key Constraint
+policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.serverCertSet.3.constraint.params.keyType=RSA
+policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.serverCertSet.3.default.name=Key Default
+policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.4.constraint.name=No Constraint
+policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.4.default.name=Authority Key Identifier Default
+policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.5.constraint.name=No Constraint
+policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.serverCertSet.5.default.name=AIA Extension Default
+policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=http://ipa-ca.{ipadomain}/ca/ocsp
+policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
+policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
+policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.serverCertSet.6.default.name=Key Usage Default
+policyset.serverCertSet.6.default.params.keyUsageCritical=true
+policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.7.constraint.name=No Constraint
+policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
+policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.4
+policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.serverCertSet.8.constraint.name=No Constraint
+policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.serverCertSet.8.default.name=Signing Alg
+policyset.serverCertSet.8.default.params.signingAlg=-
+policyset.serverCertSet.9.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.9.constraint.name=No Constraint
+policyset.serverCertSet.9.default.class_id=crlDistributionPointsExtDefaultImpl
+policyset.serverCertSet.9.default.name=CRL Distribution Points Extension Default
+policyset.serverCertSet.9.default.params.crlDistPointsCritical=false
+policyset.serverCertSet.9.default.params.crlDistPointsEnable_0=true
+policyset.serverCertSet.9.default.params.crlDistPointsIssuerName_0=CN=Certificate Authority,o=ipaca
+policyset.serverCertSet.9.default.params.crlDistPointsIssuerType_0=DirectoryName
+policyset.serverCertSet.9.default.params.crlDistPointsNum=1
+policyset.serverCertSet.9.default.params.crlDistPointsPointName_0=http://ipa-ca.{ipadomain}/ipa/crl/MasterCRL.bin
+policyset.serverCertSet.9.default.params.crlDistPointsPointType_0=URIName
+policyset.serverCertSet.9.default.params.crlDistPointsReasons_0=
+policyset.serverCertSet.10.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.10.constraint.name=No Constraint
+policyset.serverCertSet.10.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.10.default.name=Subject Key Identifier Extension Default
+policyset.serverCertSet.10.default.params.critical=false
+policyset.serverCertSet.11.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.11.constraint.name=No Constraint
+policyset.serverCertSet.11.default.class_id=userExtensionDefaultImpl
+policyset.serverCertSet.11.default.name=User Supplied Extension Default
+policyset.serverCertSet.11.default.params.userExtOID=2.5.29.17
+policyset.serverCertSet.list=1,2,3,4,5,6,7,8,9,10,11
+visible=false
diff --git a/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py
new file mode 100644
index 0000000000000000000000000000000000000000..fb4388ad3b443e958ae563f3f85c2d824fdf88ae
--- /dev/null
+++ b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py
@@ -0,0 +1,239 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2015  FreeIPA Contributors see COPYING for license
+#
+
+import os
+import pytest
+import tempfile
+
+from ipalib import api, errors
+from ipatests.util import (
+    prepare_config, unlock_principal_password, change_principal)
+from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test
+from ipatests.test_xmlrpc.test_certprofile_plugin import CertprofileTracker
+from ipatests.test_xmlrpc.test_caacl_plugin import CAACLTracker
+
+from ipapython.ipautil import run
+
+BASE_DIR = os.path.dirname(__file__)
+
+SMIME_PROFILE_TEMPLATE = os.path.join(BASE_DIR, 'data/smime.cfg.tmpl')
+SMIME_MOD_CONSTR_PROFILE_TEMPLATE = os.path.join(BASE_DIR, 'data/smime-mod.cfg.tmpl')
+ALICE_OPENSSL_CONFIG_TEMPLATE = os.path.join(BASE_DIR, 'data/alice.conf.tmpl')
+ALICE_RSA_PRIVATE_KEY_PATH = os.path.join(BASE_DIR, 'data/alice-key.pem')
+
+CERT_SUBJECT_BASE = (
+    api.Command.config_show()
+    ['result']['ipacertificatesubjectbase'][0]
+)
+
+SMIME_USER_INIT_PW = u'Change123'
+SMIME_USER_PW = u'Secret123'
+
+# environment preparation
+
+def _prepare_csr(key, config_template, template_values):
+    csr_file = tempfile.NamedTemporaryFile(mode='w', delete=False)
+    csr_file.close()
+
+    run(['openssl', 'req', '-new', '-key', key, '-out', csr_file.name,
+         '-config', prepare_config(config_template, template_values)], )
+
+    return csr_file
+
+
+@pytest.fixture(scope='class')
+def correct_csr(request):
+    csr_path = _prepare_csr(
+        ALICE_RSA_PRIVATE_KEY_PATH,
+        ALICE_OPENSSL_CONFIG_TEMPLATE,
+        dict(
+            ipacertbase=CERT_SUBJECT_BASE,
+            ipadomain=api.env.domain))
+
+    def fin():
+        csr_path.unlink(csr_path.name)
+    request.addfinalizer(fin)
+
+    with open(csr_path.name) as f:
+        csr = f.read()
+
+    return unicode(csr)
+
+
+@pytest.fixture(scope='class')
+def smime_profile(request):
+    profile_path = prepare_config(
+            SMIME_PROFILE_TEMPLATE,
+            dict(ipadomain=api.env.domain, iparealm=api.env.realm))
+
+    tracker = CertprofileTracker(u'smime', store=True,
+                                 desc=u"S/MIME certificate profile",
+                                 profile=profile_path)
+
+    return tracker.make_fixture(request)
+
+
+@pytest.fixture(scope='class')
+def smime_acl(request):
+    tracker = CAACLTracker(u'smime_acl')
+
+    return tracker.make_fixture(request)
+
+
+# TODO: rewrite these into Tracker instances
+@pytest.fixture(scope='class')
+def smime_user(request):
+    api.Command.user_add(uid=u'alice', givenname=u'Alice', sn=u'SMIME',
+                         userpassword=SMIME_USER_INIT_PW)
+
+    unlock_principal_password('alice', SMIME_USER_INIT_PW, SMIME_USER_PW)
+
+    def fin():
+        api.Command.user_del(u'alice')
+    request.addfinalizer(fin)
+
+    return u'alice'
+
+
+@pytest.fixture(scope='class')
+def smime_group(request):
+    api.Command.group_add(u'smime_users')
+
+    def fin():
+        api.Command.group_del(u'smime_users')
+    request.addfinalizer(fin)
+
+    return u'smime_users'
+
+
+class TestCertSignMIME(XMLRPC_test):
+
+    def test_cert_import(self, smime_profile):
+        smime_profile.ensure_exists()
+
+    def test_create_acl(self, smime_acl):
+        smime_acl.ensure_exists()
+
+    def test_add_profile_to_acl(self, smime_acl, smime_profile):
+        smime_acl.add_profile(certprofile=smime_profile.name)
+
+    # rewrite to trackers, prepare elsewhere
+    def test_add_user_to_group(self, smime_group, smime_user):
+        api.Command.group_add_member(smime_group, user=smime_user)
+
+    def test_add_group_to_acl(self, smime_group, smime_acl):
+        smime_acl.add_user(group=smime_group)
+
+    def test_sign_smime_csr(self, smime_profile, correct_csr, smime_user):
+        with change_principal(smime_user, "Secret123"):
+            api.Command.cert_request(correct_csr, principal=smime_user,
+                                     profile_id=smime_profile.name)
+
+
+class TestSignWithDisabledACL(XMLRPC_test):
+
+    def test_import_profile_and_acl(self, smime_profile, smime_acl):
+        smime_profile.ensure_exists()
+        smime_acl.ensure_missing()
+        smime_acl.ensure_exists()
+
+    def test_add_profile_to_acl(self, smime_acl, smime_profile):
+        smime_acl.add_profile(certprofile=smime_profile.name)
+
+    # rewrite to trackers, prepare elsewhere
+    def test_add_user_to_group(self, smime_group, smime_user):
+        api.Command.group_add_member(smime_group, user=smime_user)
+
+    def test_add_group_to_acl(self, smime_group, smime_acl):
+        smime_acl.add_user(group=smime_group)
+
+    def test_disable_acl(self, smime_acl):
+        smime_acl.disable()
+
+    def test_signing_with_disabled_acl(self, correct_csr, smime_acl,
+                                       smime_profile, smime_user):
+
+        with change_principal(smime_user, SMIME_USER_PW):
+            with pytest.raises(errors.ACIError):
+                api.Command.cert_request(
+                    correct_csr, profile_id=smime_profile.name,
+                    principal=smime_user)
+
+    def test_admin_overrides_disabled_acl(self, correct_csr, smime_acl,
+                                          smime_profile, smime_user):
+        api.Command.cert_request(
+            correct_csr, profile_id=smime_profile.name,
+            principal=smime_user)
+
+
+class TestSignWithoutGroupMembership(XMLRPC_test):
+
+    def test_import_profile_and_acl(self, smime_profile, smime_acl):
+        smime_profile.ensure_exists()
+        smime_acl.ensure_missing()
+        smime_acl.ensure_exists()
+
+    def test_add_profile_to_acl(self, smime_acl, smime_profile):
+        smime_acl.add_profile(certprofile=smime_profile.name)
+
+    def test_add_group_to_acl(self, smime_group, smime_acl, smime_user):
+        # smime user should not be a member of this group
+        #
+        # adding smime_user fixture to ensure it exists
+        smime_acl.add_user(group=smime_group)
+
+    def test_signing_with_non_member_principal(self, correct_csr, smime_acl,
+                                               smime_profile, smime_user):
+
+        with change_principal(smime_user, SMIME_USER_PW):
+            with pytest.raises(errors.ACIError):
+                api.Command.cert_request(
+                    correct_csr,
+                    profile_id=smime_profile.name,
+                    principal=smime_user)
+
+    def test_admin_overrides_group_membership(self, correct_csr, smime_acl,
+                                              smime_profile, smime_user):
+        api.Command.cert_request(
+            correct_csr, profile_id=smime_profile.name,
+            principal=smime_user)
+
+
+class TestSignWithChangedProfile(XMLRPC_test):
+    """ Test to verify that the updated profile is used.
+
+    The profile change requires different CN in CSR
+    than the one configured. This leads to rejection
+    based on not meeting the profile constraints.
+    """
+
+    def test_prepare_env(self, smime_profile, smime_acl):
+        smime_profile.ensure_exists()
+        smime_acl.ensure_exists()
+
+        smime_acl.add_profile(certprofile=smime_profile.name)
+
+    def test_prepare_user_and_group(self, smime_group, smime_user, smime_acl):
+        api.Command.group_add_member(smime_group, user=smime_user)
+        smime_acl.add_user(group=smime_group)
+
+    def test_modify_smime_profile(self, smime_profile):
+        updated_profile_path = prepare_config(SMIME_MOD_CONSTR_PROFILE_TEMPLATE,
+                                              dict(
+                                                   ipadomain=api.env.domain,
+                                                   iparealm=api.env.realm))
+
+        with open(updated_profile_path) as f:
+            updated_profile = unicode(f.read())
+
+        updates = {u'file': updated_profile}
+        update_smime_profile = smime_profile.make_update_command(updates)
+        update_smime_profile()
+
+    def test_sign_smime_csr(self, smime_profile, correct_csr, smime_user):
+        with change_principal(smime_user, "Secret123"):
+            with pytest.raises(errors.CertificateOperationError):
+                api.Command.cert_request(correct_csr, principal=smime_user,
+                                         profile_id=smime_profile.name)
-- 
2.6.1

From 7f3f746567a69597167fa0c8c8efb6e89d08dfd3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Milan=20Kub=C3=ADk?= <mku...@redhat.com>
Date: Fri, 7 Aug 2015 15:54:18 +0200
Subject: [PATCH 3/6] tests: add test to check the default ACL

Also includes basic ACL manipulation and adding
and removing members to/from the acl.

https://fedorahosted.org/freeipa/ticket/57
---
 ipatests/test_xmlrpc/test_caacl_plugin.py | 135 ++++++++++++++++++++++++++++--
 1 file changed, 128 insertions(+), 7 deletions(-)

diff --git a/ipatests/test_xmlrpc/test_caacl_plugin.py b/ipatests/test_xmlrpc/test_caacl_plugin.py
index 6cf835b229f70797e32bcfd2309cfa7be5732f51..33268d6dde115ce040e55eaae08a7fe1299ad112 100644
--- a/ipatests/test_xmlrpc/test_caacl_plugin.py
+++ b/ipatests/test_xmlrpc/test_caacl_plugin.py
@@ -6,20 +6,20 @@
 Test the `ipalib.plugins.caacl` module.
 """
 
-import os
-
 import pytest
 
-from ipapython import ipautil
-from ipalib import errors, x509
-from ipapython.dn import DN
+from ipalib import errors
 from ipatests.test_xmlrpc.ldaptracker import Tracker
 from ipatests.test_xmlrpc.xmlrpc_test import (XMLRPC_test, fuzzy_caacldn,
-                                              fuzzy_uuid, fuzzy_ipauniqueid,
-                                              raises_exact)
+                                              fuzzy_uuid, fuzzy_ipauniqueid)
+
 from ipatests.test_xmlrpc import objectclasses
 from ipatests.util import assert_deepequal
 
+# reuse the fixture
+from ipatests.test_xmlrpc.test_certprofile_plugin import default_profile
+from ipatests.test_xmlrpc.test_stageuser_plugin import StageUserTracker
+
 
 class CAACLTracker(Tracker):
     """Tracker class for CA ACL LDAP object.
@@ -376,3 +376,124 @@ class CAACLTracker(Tracker):
         command = self.make_command(u'caacl_disable', self.name)
         self.attrs.update({u'ipaenabledflag': [u'FALSE']})
         command()
+
+
+@pytest.fixture(scope='class')
+def default_acl(request):
+    name = u'hosts_services_caIPAserviceCert'
+    tracker = CAACLTracker(name, service_category=u'all', host_category=u'all')
+    tracker.track_create()
+    tracker.attrs.update(
+        {u'ipamembercertprofile_certprofile': [u'caIPAserviceCert']})
+    return tracker
+
+
+@pytest.fixture(scope='class')
+def crud_acl(request):
+    name = u'crud-acl'
+    tracker = CAACLTracker(name)
+
+    return tracker.make_fixture(request)
+
+
+@pytest.fixture(scope='class')
+def category_acl(request):
+    name = u'category_acl'
+    tracker = CAACLTracker(name, ipacertprofile_category=u'all',
+                           user_category=u'all', service_category=u'all',
+                           host_category=u'all')
+
+    return tracker.make_fixture(request)
+
+
+@pytest.fixture(scope='class')
+def staged_user(request):
+    name = u'st-user'
+    tracker = StageUserTracker(name, u'stage', u'test')
+
+    return tracker.make_fixture(request)
+
+
+class TestDefaultACL(XMLRPC_test):
+    def test_default_acl_present(self, default_acl):
+        default_acl.retrieve()
+
+
+class TestCAACLbasicCRUD(XMLRPC_test):
+    def test_create(self, crud_acl):
+        crud_acl.create()
+
+    def test_delete(self, crud_acl):
+        crud_acl.delete()
+
+    def test_disable(self, crud_acl):
+        crud_acl.ensure_exists()
+        crud_acl.disable()
+        crud_acl.retrieve()
+
+    def test_disable_twice(self, crud_acl):
+        crud_acl.disable()
+        crud_acl.retrieve()
+
+    def test_enable(self, crud_acl):
+        crud_acl.enable()
+        crud_acl.retrieve()
+
+    def test_enable_twice(self, crud_acl):
+        crud_acl.enable()
+        crud_acl.retrieve()
+
+    def test_find(self, crud_acl):
+        crud_acl.find()
+
+
+class TestCAACLMembers(XMLRPC_test):
+    def test_category_member_exclusivity(self, category_acl, default_profile):
+        category_acl.create()
+        default_profile.ensure_exists()
+        with pytest.raises(errors.MutuallyExclusiveError):
+            category_acl.add_profile(default_profile.name, track=False)
+
+    def test_mod_delete_category(self, category_acl):
+        updates = dict(
+            hostcategory=None,
+            servicecategory=None,
+            ipacertprofilecategory=None,
+            usercategory=None)
+        category_acl.update(updates)
+
+    def test_add_profile(self, category_acl, default_profile):
+        category_acl.add_profile(certprofile=default_profile.name)
+        category_acl.retrieve()
+
+    def test_remove_profile(self, category_acl, default_profile):
+        category_acl.remove_profile(certprofile=default_profile.name)
+        category_acl.retrieve()
+
+    def test_add_invalid_value_service(self, category_acl, default_profile):
+        res = category_acl.add_service(service=default_profile.name, track=False)
+        assert len(res['failed']) == 1
+
+    # the same for other types
+
+    def test_add_invalid_value_user(self, category_acl, default_profile):
+        res = category_acl.add_user(user=default_profile.name, track=False)
+        assert len(res['failed']) == 1
+
+        res = category_acl.add_user(group=default_profile.name, track=False)
+        assert len(res['failed']) == 1
+
+    def test_add_invalid_value_host(self, category_acl, default_profile):
+        res = category_acl.add_host(host=default_profile.name, track=False)
+        assert len(res['failed']) == 1
+
+        res = category_acl.add_host(hostgroup=default_profile.name, track=False)
+        assert len(res['failed']) == 1
+
+    def test_add_invalid_value_profile(self, category_acl):
+        res = category_acl.add_profile(certprofile=category_acl.name, track=False)
+        assert len(res['failed']) == 1
+
+    def test_add_staged_user_to_acl(self, category_acl, staged_user):
+        res = category_acl.add_user(user=staged_user.name, track=False)
+        assert len(res['failed']) == 1
-- 
2.6.1

From 30afc8bb4cf272029bb3008fa788556c6e560157 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Milan=20Kub=C3=ADk?= <mku...@redhat.com>
Date: Tue, 22 Sep 2015 15:22:25 +0200
Subject: [PATCH] ipatests: CA ACL and cert profile functional test

https://fedorahosted.org/freeipa/ticket/57
---
 ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl       | 108 ++++++++++
 .../test_xmlrpc/test_caacl_profile_enforcement.py  | 239 +++++++++++++++++++++
 2 files changed, 347 insertions(+)
 create mode 100644 ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl
 create mode 100644 ipatests/test_xmlrpc/test_caacl_profile_enforcement.py

diff --git a/ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl b/ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl
new file mode 100644
index 0000000000000000000000000000000000000000..da94c25e574af6cfe7230073195a541eb7f04fd8
--- /dev/null
+++ b/ipatests/test_xmlrpc/data/smime-mod.cfg.tmpl
@@ -0,0 +1,108 @@
+auth.instance_id=raCertAuth
+classId=caEnrollImpl
+desc=Certificate for S-MIME extension
+enable=true
+enableBy=ipara
+input.i1.class_id=certReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+input.list=i1,i2
+name=SMIME certificate profile
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=serverCertSet
+policyset.serverCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.serverCertSet.1.constraint.name=Subject Name Constraint
+policyset.serverCertSet.1.constraint.params.accept=true
+policyset.serverCertSet.1.constraint.params.pattern=CN=refuse sign
+policyset.serverCertSet.1.default.class_id=subjectNameDefaultImpl
+policyset.serverCertSet.1.default.name=Subject Name Default
+policyset.serverCertSet.1.default.params.name=CN=$request.req_subject_name.cn$, O={iparealm}
+policyset.serverCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.serverCertSet.2.constraint.name=Validity Constraint
+policyset.serverCertSet.2.constraint.params.notAfterCheck=false
+policyset.serverCertSet.2.constraint.params.notBeforeCheck=false
+policyset.serverCertSet.2.constraint.params.range=740
+policyset.serverCertSet.2.default.class_id=validityDefaultImpl
+policyset.serverCertSet.2.default.name=Validity Default
+policyset.serverCertSet.2.default.params.range=731
+policyset.serverCertSet.2.default.params.startTime=0
+policyset.serverCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.serverCertSet.3.constraint.name=Key Constraint
+policyset.serverCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
+policyset.serverCertSet.3.constraint.params.keyType=RSA
+policyset.serverCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.serverCertSet.3.default.name=Key Default
+policyset.serverCertSet.4.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.4.constraint.name=No Constraint
+policyset.serverCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.4.default.name=Authority Key Identifier Default
+policyset.serverCertSet.5.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.5.constraint.name=No Constraint
+policyset.serverCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.serverCertSet.5.default.name=AIA Extension Default
+policyset.serverCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.serverCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.serverCertSet.5.default.params.authInfoAccessADLocation_0=http://ipa-ca.{ipadomain}/ca/ocsp
+policyset.serverCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.serverCertSet.5.default.params.authInfoAccessCritical=false
+policyset.serverCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.serverCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.serverCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.serverCertSet.6.constraint.params.keyUsageCritical=true
+policyset.serverCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.serverCertSet.6.default.name=Key Usage Default
+policyset.serverCertSet.6.default.params.keyUsageCritical=true
+policyset.serverCertSet.6.default.params.keyUsageCrlSign=false
+policyset.serverCertSet.6.default.params.keyUsageDataEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.serverCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.serverCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.serverCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.serverCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.serverCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.serverCertSet.7.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.7.constraint.name=No Constraint
+policyset.serverCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.serverCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.serverCertSet.7.default.params.exKeyUsageCritical=false
+policyset.serverCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.4
+policyset.serverCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.serverCertSet.8.constraint.name=No Constraint
+policyset.serverCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
+policyset.serverCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.serverCertSet.8.default.name=Signing Alg
+policyset.serverCertSet.8.default.params.signingAlg=-
+policyset.serverCertSet.9.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.9.constraint.name=No Constraint
+policyset.serverCertSet.9.default.class_id=crlDistributionPointsExtDefaultImpl
+policyset.serverCertSet.9.default.name=CRL Distribution Points Extension Default
+policyset.serverCertSet.9.default.params.crlDistPointsCritical=false
+policyset.serverCertSet.9.default.params.crlDistPointsEnable_0=true
+policyset.serverCertSet.9.default.params.crlDistPointsIssuerName_0=CN=Certificate Authority,o=ipaca
+policyset.serverCertSet.9.default.params.crlDistPointsIssuerType_0=DirectoryName
+policyset.serverCertSet.9.default.params.crlDistPointsNum=1
+policyset.serverCertSet.9.default.params.crlDistPointsPointName_0=http://ipa-ca.{ipadomain}/ipa/crl/MasterCRL.bin
+policyset.serverCertSet.9.default.params.crlDistPointsPointType_0=URIName
+policyset.serverCertSet.9.default.params.crlDistPointsReasons_0=
+policyset.serverCertSet.10.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.10.constraint.name=No Constraint
+policyset.serverCertSet.10.default.class_id=subjectKeyIdentifierExtDefaultImpl
+policyset.serverCertSet.10.default.name=Subject Key Identifier Extension Default
+policyset.serverCertSet.10.default.params.critical=false
+policyset.serverCertSet.11.constraint.class_id=noConstraintImpl
+policyset.serverCertSet.11.constraint.name=No Constraint
+policyset.serverCertSet.11.default.class_id=userExtensionDefaultImpl
+policyset.serverCertSet.11.default.name=User Supplied Extension Default
+policyset.serverCertSet.11.default.params.userExtOID=2.5.29.17
+policyset.serverCertSet.list=1,2,3,4,5,6,7,8,9,10,11
+visible=false
diff --git a/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py
new file mode 100644
index 0000000000000000000000000000000000000000..fb4388ad3b443e958ae563f3f85c2d824fdf88ae
--- /dev/null
+++ b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py
@@ -0,0 +1,239 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2015  FreeIPA Contributors see COPYING for license
+#
+
+import os
+import pytest
+import tempfile
+
+from ipalib import api, errors
+from ipatests.util import (
+    prepare_config, unlock_principal_password, change_principal)
+from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test
+from ipatests.test_xmlrpc.test_certprofile_plugin import CertprofileTracker
+from ipatests.test_xmlrpc.test_caacl_plugin import CAACLTracker
+
+from ipapython.ipautil import run
+
+BASE_DIR = os.path.dirname(__file__)
+
+SMIME_PROFILE_TEMPLATE = os.path.join(BASE_DIR, 'data/smime.cfg.tmpl')
+SMIME_MOD_CONSTR_PROFILE_TEMPLATE = os.path.join(BASE_DIR, 'data/smime-mod.cfg.tmpl')
+ALICE_OPENSSL_CONFIG_TEMPLATE = os.path.join(BASE_DIR, 'data/alice.conf.tmpl')
+ALICE_RSA_PRIVATE_KEY_PATH = os.path.join(BASE_DIR, 'data/alice-key.pem')
+
+CERT_SUBJECT_BASE = (
+    api.Command.config_show()
+    ['result']['ipacertificatesubjectbase'][0]
+)
+
+SMIME_USER_INIT_PW = u'Change123'
+SMIME_USER_PW = u'Secret123'
+
+# environment preparation
+
+def _prepare_csr(key, config_template, template_values):
+    csr_file = tempfile.NamedTemporaryFile(mode='w', delete=False)
+    csr_file.close()
+
+    run(['openssl', 'req', '-new', '-key', key, '-out', csr_file.name,
+         '-config', prepare_config(config_template, template_values)], )
+
+    return csr_file
+
+
+@pytest.fixture(scope='class')
+def correct_csr(request):
+    csr_path = _prepare_csr(
+        ALICE_RSA_PRIVATE_KEY_PATH,
+        ALICE_OPENSSL_CONFIG_TEMPLATE,
+        dict(
+            ipacertbase=CERT_SUBJECT_BASE,
+            ipadomain=api.env.domain))
+
+    def fin():
+        csr_path.unlink(csr_path.name)
+    request.addfinalizer(fin)
+
+    with open(csr_path.name) as f:
+        csr = f.read()
+
+    return unicode(csr)
+
+
+@pytest.fixture(scope='class')
+def smime_profile(request):
+    profile_path = prepare_config(
+            SMIME_PROFILE_TEMPLATE,
+            dict(ipadomain=api.env.domain, iparealm=api.env.realm))
+
+    tracker = CertprofileTracker(u'smime', store=True,
+                                 desc=u"S/MIME certificate profile",
+                                 profile=profile_path)
+
+    return tracker.make_fixture(request)
+
+
+@pytest.fixture(scope='class')
+def smime_acl(request):
+    tracker = CAACLTracker(u'smime_acl')
+
+    return tracker.make_fixture(request)
+
+
+# TODO: rewrite these into Tracker instances
+@pytest.fixture(scope='class')
+def smime_user(request):
+    api.Command.user_add(uid=u'alice', givenname=u'Alice', sn=u'SMIME',
+                         userpassword=SMIME_USER_INIT_PW)
+
+    unlock_principal_password('alice', SMIME_USER_INIT_PW, SMIME_USER_PW)
+
+    def fin():
+        api.Command.user_del(u'alice')
+    request.addfinalizer(fin)
+
+    return u'alice'
+
+
+@pytest.fixture(scope='class')
+def smime_group(request):
+    api.Command.group_add(u'smime_users')
+
+    def fin():
+        api.Command.group_del(u'smime_users')
+    request.addfinalizer(fin)
+
+    return u'smime_users'
+
+
+class TestCertSignMIME(XMLRPC_test):
+
+    def test_cert_import(self, smime_profile):
+        smime_profile.ensure_exists()
+
+    def test_create_acl(self, smime_acl):
+        smime_acl.ensure_exists()
+
+    def test_add_profile_to_acl(self, smime_acl, smime_profile):
+        smime_acl.add_profile(certprofile=smime_profile.name)
+
+    # rewrite to trackers, prepare elsewhere
+    def test_add_user_to_group(self, smime_group, smime_user):
+        api.Command.group_add_member(smime_group, user=smime_user)
+
+    def test_add_group_to_acl(self, smime_group, smime_acl):
+        smime_acl.add_user(group=smime_group)
+
+    def test_sign_smime_csr(self, smime_profile, correct_csr, smime_user):
+        with change_principal(smime_user, "Secret123"):
+            api.Command.cert_request(correct_csr, principal=smime_user,
+                                     profile_id=smime_profile.name)
+
+
+class TestSignWithDisabledACL(XMLRPC_test):
+
+    def test_import_profile_and_acl(self, smime_profile, smime_acl):
+        smime_profile.ensure_exists()
+        smime_acl.ensure_missing()
+        smime_acl.ensure_exists()
+
+    def test_add_profile_to_acl(self, smime_acl, smime_profile):
+        smime_acl.add_profile(certprofile=smime_profile.name)
+
+    # rewrite to trackers, prepare elsewhere
+    def test_add_user_to_group(self, smime_group, smime_user):
+        api.Command.group_add_member(smime_group, user=smime_user)
+
+    def test_add_group_to_acl(self, smime_group, smime_acl):
+        smime_acl.add_user(group=smime_group)
+
+    def test_disable_acl(self, smime_acl):
+        smime_acl.disable()
+
+    def test_signing_with_disabled_acl(self, correct_csr, smime_acl,
+                                       smime_profile, smime_user):
+
+        with change_principal(smime_user, SMIME_USER_PW):
+            with pytest.raises(errors.ACIError):
+                api.Command.cert_request(
+                    correct_csr, profile_id=smime_profile.name,
+                    principal=smime_user)
+
+    def test_admin_overrides_disabled_acl(self, correct_csr, smime_acl,
+                                          smime_profile, smime_user):
+        api.Command.cert_request(
+            correct_csr, profile_id=smime_profile.name,
+            principal=smime_user)
+
+
+class TestSignWithoutGroupMembership(XMLRPC_test):
+
+    def test_import_profile_and_acl(self, smime_profile, smime_acl):
+        smime_profile.ensure_exists()
+        smime_acl.ensure_missing()
+        smime_acl.ensure_exists()
+
+    def test_add_profile_to_acl(self, smime_acl, smime_profile):
+        smime_acl.add_profile(certprofile=smime_profile.name)
+
+    def test_add_group_to_acl(self, smime_group, smime_acl, smime_user):
+        # smime user should not be a member of this group
+        #
+        # adding smime_user fixture to ensure it exists
+        smime_acl.add_user(group=smime_group)
+
+    def test_signing_with_non_member_principal(self, correct_csr, smime_acl,
+                                               smime_profile, smime_user):
+
+        with change_principal(smime_user, SMIME_USER_PW):
+            with pytest.raises(errors.ACIError):
+                api.Command.cert_request(
+                    correct_csr,
+                    profile_id=smime_profile.name,
+                    principal=smime_user)
+
+    def test_admin_overrides_group_membership(self, correct_csr, smime_acl,
+                                              smime_profile, smime_user):
+        api.Command.cert_request(
+            correct_csr, profile_id=smime_profile.name,
+            principal=smime_user)
+
+
+class TestSignWithChangedProfile(XMLRPC_test):
+    """ Test to verify that the updated profile is used.
+
+    The profile change requires different CN in CSR
+    than the one configured. This leads to rejection
+    based on not meeting the profile constraints.
+    """
+
+    def test_prepare_env(self, smime_profile, smime_acl):
+        smime_profile.ensure_exists()
+        smime_acl.ensure_exists()
+
+        smime_acl.add_profile(certprofile=smime_profile.name)
+
+    def test_prepare_user_and_group(self, smime_group, smime_user, smime_acl):
+        api.Command.group_add_member(smime_group, user=smime_user)
+        smime_acl.add_user(group=smime_group)
+
+    def test_modify_smime_profile(self, smime_profile):
+        updated_profile_path = prepare_config(SMIME_MOD_CONSTR_PROFILE_TEMPLATE,
+                                              dict(
+                                                   ipadomain=api.env.domain,
+                                                   iparealm=api.env.realm))
+
+        with open(updated_profile_path) as f:
+            updated_profile = unicode(f.read())
+
+        updates = {u'file': updated_profile}
+        update_smime_profile = smime_profile.make_update_command(updates)
+        update_smime_profile()
+
+    def test_sign_smime_csr(self, smime_profile, correct_csr, smime_user):
+        with change_principal(smime_user, "Secret123"):
+            with pytest.raises(errors.CertificateOperationError):
+                api.Command.cert_request(correct_csr, principal=smime_user,
+                                         profile_id=smime_profile.name)
-- 
2.6.1

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to