On Tue, Jun 21, 2016 at 05:01:35PM +0200, Milan Kubík wrote: > Hi Fraser and list, > > I have made changes to the test plan on the wiki [1] according to the > information in "[Testplan review] Sub CAs" thread. > > I also implemented the tests in the test plan: > > patch 0038 - CATracker and CA CRUD test > patch 0039 - extension to CA ACL test > patch 0040 - functional test with ACLs and certificate profile, reusing my > previous S/MIME based tests. This patch also tests for the cert-request > behavior when profile ID or CA cn are ommited. > > The tests ATM do not verify the Issuer name in the certificate itself, just > from the ipa entry of the certificate. > The approach you are using::
assert cert_info['result']['issuer'] == smime_signing_ca.ipasubjectdn is not quite as you describe (these are virtual attributes, not attributes of an actual entry); but the approach is valid. > Fraser, could you please verify my reasoning behind the test cases for > cert-request in the patch 40? > The tests look OK. With the default CA / default profiles, is there appropriate isolation between test cases to ensure that if, e.g. some other test case adds/modifies CA ACLs such that these expected-to-fail tests now pass, that this does not affect the TestCertSignMIMEwithSubCA test case? Thanks, Fraser > [1]: http://www.freeipa.org/page/V4/Sub-CAs/Test_Plan > > Cheers > > -- > Milan Kubik > > From 83153e3c7c4a28ba170633054b59b2d6a70807c0 Mon Sep 17 00:00:00 2001 > From: =?UTF-8?q?Milan=20Kub=C3=ADk?= <mku...@redhat.com> > Date: Fri, 17 Jun 2016 12:20:55 +0200 > Subject: [PATCH 1/3] ipatests: Tracker implementation for Sub CA feature > > The patch implements Tracker subclass for CA plugin > and the basic CRUD tests for the plugin entries. > > https://fedorahosted.org/freeipa/ticket/4559 > --- > ipatests/test_xmlrpc/objectclasses.py | 5 + > ipatests/test_xmlrpc/test_ca_plugin.py | 176 > ++++++++++++++++++++++++++++++ > ipatests/test_xmlrpc/tracker/ca_plugin.py | 126 +++++++++++++++++++++ > ipatests/test_xmlrpc/xmlrpc_test.py | 3 + > 4 files changed, 310 insertions(+) > create mode 100644 ipatests/test_xmlrpc/test_ca_plugin.py > create mode 100644 ipatests/test_xmlrpc/tracker/ca_plugin.py > > diff --git a/ipatests/test_xmlrpc/objectclasses.py > b/ipatests/test_xmlrpc/objectclasses.py > index > 134a08803f3abca1124c4d26274d9e3fc981b941..1ea020b18f975f717eb9d9d5399d8e9fb40264cb > 100644 > --- a/ipatests/test_xmlrpc/objectclasses.py > +++ b/ipatests/test_xmlrpc/objectclasses.py > @@ -222,3 +222,8 @@ caacl = [ > u'ipaassociation', > u'ipacaacl' > ] > + > +ca = [ > + u'top', > + u'ipaca', > +] > diff --git a/ipatests/test_xmlrpc/test_ca_plugin.py > b/ipatests/test_xmlrpc/test_ca_plugin.py > new file mode 100644 > index > 0000000000000000000000000000000000000000..a638a0c9a5a611687d4ae707f4b067bef2ef2229 > --- /dev/null > +++ b/ipatests/test_xmlrpc/test_ca_plugin.py > @@ -0,0 +1,176 @@ > +# > +# Copyright (C) 2016 FreeIPA Contributors see COPYING for license > +# > + > +""" > +Test the `ipalib.plugins.ca` module. > +""" > + > +import pytest > + > +from ipalib import errors > +from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test, fuzzy_issuer > + > +from ipatests.test_xmlrpc.tracker.certprofile_plugin import > CertprofileTracker > +from ipatests.test_xmlrpc.tracker.caacl_plugin import CAACLTracker > +from ipatests.test_xmlrpc.tracker.ca_plugin import CATracker > + > + > +@pytest.fixture(scope='module') > +def default_profile(request): > + name = 'caIPAserviceCert' > + desc = u'Standard profile for network services' > + tracker = CertprofileTracker(name, store=True, desc=desc) > + tracker.track_create() > + return tracker > + > + > +@pytest.fixture(scope='module') > +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='module') > +def default_ca(request): > + name = u'ipa' > + desc = u'IPA CA' > + tracker = CATracker(name, fuzzy_issuer, desc=desc) > + tracker.track_create() > + return tracker > + > + > +@pytest.fixture(scope='class') > +def crud_subca(request): > + name = u'crud-subca' > + subject = u'CN=crud subca test,O=crud testing inc' > + tracker = CATracker(name, subject) > + > + return tracker.make_fixture(request) > + > + > +@pytest.fixture(scope='class') > +def subject_conflict_subca(request): > + name = u'crud-subca-2' > + subject = u'CN=crud subca test,O=crud testing inc' > + tracker = CATracker(name, subject) > + > + return tracker.make_fixture(request) > + > + > +@pytest.mark.tier0 > +class TestDefaultCA(XMLRPC_test): > + def test_default_ca_present(self, default_ca): > + default_ca.retrieve() > + > + def test_default_ca_delete(self, default_ca): > + with pytest.raises(errors.ProtectedEntryError): > + default_ca.delete() > + > + > +@pytest.mark.tier1 > +class TestCAbasicCRUD(XMLRPC_test): > + > + ATTR_ERROR_MSG = u'attribute is not configurable' > + > + def test_create(self, crud_subca): > + crud_subca.create() > + > + def test_retrieve(self, crud_subca): > + crud_subca.retrieve() > + > + def test_retrieve_all(self, crud_subca): > + crud_subca.retrieve(all=True) > + > + def test_delete(self, crud_subca): > + crud_subca.delete() > + > + def test_find(self, crud_subca): > + crud_subca.ensure_exists() > + crud_subca.find() > + > + def test_modify_description(self, crud_subca): > + new_desc = u'updated CA description' > + crud_subca.update( > + dict( > + description=new_desc, > + ), > + expected_updates=dict( > + description=[new_desc] > + ) > + ) > + > + def test_modify_issuerdn(self, crud_subca): > + bogus_issuer = u'ipacaissuerdn="cn=phony issuer,o=phony industries' > + cmd = crud_subca.make_update_command( > + updates=dict(setattr=bogus_issuer) > + ) > + > + with pytest.raises(errors.ValidationError) as error: > + cmd() > + > + assert self.ATTR_ERROR_MSG in str(error.value) > + > + def test_modify_subjectdn(self, crud_subca): > + bogus_subject = u'ipacasubjectdn="cn=phony subject,o=phony > industries' > + cmd = crud_subca.make_update_command( > + updates=dict(setattr=bogus_subject) > + ) > + > + with pytest.raises(errors.ValidationError) as error: > + cmd() > + > + assert self.ATTR_ERROR_MSG in str(error.value) > + > + def test_delete_subjectdn(self, crud_subca): > + cmd = crud_subca.make_update_command( > + updates=dict(delattr=u'ipacasubjectdn=%s' > + % crud_subca.ipasubjectdn) > + ) > + > + with pytest.raises(errors.ValidationError) as error: > + cmd() > + > + assert self.ATTR_ERROR_MSG in str(error.value) > + > + def test_add_bogus_subjectdn(self, crud_subca): > + bogus_subject = u'ipacasubjectdn="cn=phony subject,o=phony > industries' > + cmd = crud_subca.make_update_command( > + updates=dict(addattr=bogus_subject) > + ) > + > + with pytest.raises(errors.ValidationError) as error: > + cmd() > + > + assert self.ATTR_ERROR_MSG in str(error.value) > + > + def test_add_bogus_issuerdn(self, crud_subca): > + bogus_issuer = u'ipacaissuerdn="cn=phony issuer,o=phony industries' > + cmd = crud_subca.make_update_command( > + updates=dict(addattr=bogus_issuer) > + ) > + > + with pytest.raises(errors.ValidationError) as error: > + cmd() > + > + assert self.ATTR_ERROR_MSG in str(error.value) > + > + def test_create_subca_with_conflicting_name(self, crud_subca): > + crud_subca.ensure_exists() > + > + cmd = crud_subca.make_create_command() > + with pytest.raises(errors.DuplicateEntry): > + cmd() > + > + @pytest.mark.xfail(reason='https://fedorahosted.org/freeipa/ticket/5981', > + strict=True) > + def test_create_subca_with_subject_conflict( > + self, crud_subca, subject_conflict_subca): > + crud_subca.ensure_exists() > + > + with pytest.raises(errors.DuplicateEntry): > + subject_conflict_subca.create() > diff --git a/ipatests/test_xmlrpc/tracker/ca_plugin.py > b/ipatests/test_xmlrpc/tracker/ca_plugin.py > new file mode 100644 > index > 0000000000000000000000000000000000000000..7586c771c028df9343bcf7fcdd538c19c494ed1a > --- /dev/null > +++ b/ipatests/test_xmlrpc/tracker/ca_plugin.py > @@ -0,0 +1,126 @@ > +# > +# Copyright (C) 2016 FreeIPA Contributors see COPYING for license > +# > +from __future__ import absolute_import > + > +import six > + > +from ipapython.dn import DN > +from ipatests.test_xmlrpc.tracker.base import Tracker > +from ipatests.util import assert_deepequal > +from ipatests.test_xmlrpc.xmlrpc_test import fuzzy_issuer, fuzzy_caid > +from ipatests.test_xmlrpc import objectclasses > + > + > +if six.PY3: > + unicode = str > + > + > +class CATracker(Tracker): > + """Implementation of a Tracker class for CA plugin.""" > + > + retrieve_keys = { > + 'dn', 'cn', 'ipacaid', 'ipacasubjectdn', 'ipacaissuerdn', > 'description' > + } > + retrieve_all_keys = {'objectclass'} | retrieve_keys > + create_keys = retrieve_all_keys > + update_keys = retrieve_keys - {'dn'} > + > + def __init__(self, name, subject, desc=u"Test generated CA", > + default_version=None): > + super(CATracker, self).__init__(default_version=default_version) > + self.attrs = {} > + self.ipasubjectdn = subject > + self.description = desc > + > + self.dn = DN(('cn', name), > + self.api.env.container_ca, > + self.api.env.basedn) > + > + def make_create_command(self, force=True): > + """Make function that creates the plugin entry object.""" > + return self.make_command( > + 'ca_add', self.name, ipacasubjectdn=self.ipasubjectdn, > + description=self.description > + ) > + > + def check_create(self, result): > + assert_deepequal(dict( > + value=self.name, > + summary=u'Created CA "{}"'.format(self.name), > + result=dict(self.filter_attrs(self.create_keys)) > + ), result) > + > + def track_create(self): > + self.attrs = dict( > + dn=unicode(self.dn), > + cn=[self.name], > + description=[self.description], > + ipacasubjectdn=[self.ipasubjectdn], > + ipacaissuerdn=[fuzzy_issuer], > + ipacaid=[fuzzy_caid], > + objectclass=objectclasses.ca > + ) > + self.exists = True > + > + def make_delete_command(self): > + """Make function that deletes the plugin entry object.""" > + return self.make_command('ca_del', self.name) > + > + def check_delete(self, result): > + assert_deepequal(dict( > + value=[self.name], > + summary=u'Deleted CA "{}"'.format(self.name), > + result=dict(failed=[]) > + ), result) > + > + def make_retrieve_command(self, all=False, raw=False): > + """Make function that retrieves the entry using ${CMD}_show""" > + return self.make_command('ca_show', self.name, all=all, raw=raw) > + > + def check_retrieve(self, result, all=False, raw=False): > + """Check the plugin's `show` command result""" > + if all: > + expected = self.filter_attrs(self.retrieve_all_keys) > + else: > + expected = self.filter_attrs(self.retrieve_keys) > + > + assert_deepequal(dict( > + value=self.name, > + summary=None, > + result=expected > + ), result) > + > + def make_find_command(self, *args, **kwargs): > + """Make function that finds the entry using ${CMD}_find > + > + Note that the name (or other search terms) needs to be specified > + in arguments. > + """ > + return self.make_command('ca_find', *args, **kwargs) > + > + def check_find(self, result, all=False, raw=False): > + """Check the plugin's `find` command result""" > + if all: > + expected = self.filter_attrs(self.retrieve_all_keys) > + else: > + expected = self.filter_attrs(self.retrieve_keys) > + > + assert_deepequal(dict( > + count=1, > + truncated=False, > + summary=u'1 CA matched', > + result=[expected] > + ), result) > + > + def make_update_command(self, updates): > + """Make function that modifies the entry using ${CMD}_mod""" > + return self.make_command('ca_mod', self.name, **updates) > + > + def check_update(self, result, extra_keys=()): > + """Check the plugin's `find` command result""" > + assert_deepequal(dict( > + value=self.name, > + summary=u'Modified CA "{}"'.format(self.name), > + result=self.filter_attrs(self.update_keys | set(extra_keys)) > + ), result) > diff --git a/ipatests/test_xmlrpc/xmlrpc_test.py > b/ipatests/test_xmlrpc/xmlrpc_test.py > index > c3bba9abf1079469126d4423425a32c74f886895..ddfe9c17c5ca110bc5eb66dead618383b861eda9 > 100644 > --- a/ipatests/test_xmlrpc/xmlrpc_test.py > +++ b/ipatests/test_xmlrpc/xmlrpc_test.py > @@ -81,6 +81,9 @@ fuzzy_caacldn = Fuzzy( > '(?i)ipauniqueid=%s,cn=caacls,cn=ca,%s' % (uuid_re, api.env.basedn) > ) > > +# Matches internal CA ID > +fuzzy_caid = fuzzy_uuid > + > # Matches fuzzy ipaUniqueID DN group (RDN) > fuzzy_ipauniqueid = Fuzzy('(?i)ipauniqueid=%s' % uuid_re) > > -- > 2.9.0 > > From e81e5074c439071019fb12627ff8f0945ba2f9d1 Mon Sep 17 00:00:00 2001 > From: =?UTF-8?q?Milan=20Kub=C3=ADk?= <mku...@redhat.com> > Date: Tue, 21 Jun 2016 13:45:54 +0200 > Subject: [PATCH 2/3] ipatests: Extend CAACL suite to cover Sub CA members > > https://fedorahosted.org/freeipa/ticket/4559 > --- > ipatests/test_xmlrpc/test_caacl_plugin.py | 26 ++++++++++++++++++++++++-- > ipatests/test_xmlrpc/tracker/caacl_plugin.py | 26 +++++++++++++++++++++----- > 2 files changed, 45 insertions(+), 7 deletions(-) > > diff --git a/ipatests/test_xmlrpc/test_caacl_plugin.py > b/ipatests/test_xmlrpc/test_caacl_plugin.py > index > f20b02b295024313008be7b75bdcae2ade70b4ff..dce12e484e4fa3a57fcd54fd9ffb60419fd161a4 > 100644 > --- a/ipatests/test_xmlrpc/test_caacl_plugin.py > +++ b/ipatests/test_xmlrpc/test_caacl_plugin.py > @@ -14,6 +14,7 @@ from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test > from ipatests.test_xmlrpc.tracker.certprofile_plugin import > CertprofileTracker > from ipatests.test_xmlrpc.tracker.caacl_plugin import CAACLTracker > from ipatests.test_xmlrpc.tracker.stageuser_plugin import StageUserTracker > +from ipatests.test_xmlrpc.tracker.ca_plugin import CATracker > > > @pytest.fixture(scope='class') > @@ -48,12 +49,19 @@ 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') > + host_category=u'all', ipaca_category=u'all') > > return tracker.make_fixture(request) > > > @pytest.fixture(scope='class') > +def caacl_test_ca(request): > + name = u'caacl-test-ca' > + subject = u'CN=caacl test subca,O=test industries inc.' > + return CATracker(name, subject).make_fixture(request) > + > + > +@pytest.fixture(scope='class') > def staged_user(request): > name = u'st-user' > tracker = StageUserTracker(name, u'stage', u'test') > @@ -109,7 +117,8 @@ class TestCAACLMembers(XMLRPC_test): > hostcategory=None, > servicecategory=None, > ipacertprofilecategory=None, > - usercategory=None) > + usercategory=None, > + ipacacategory=None) > category_acl.update(updates) > > def test_add_profile(self, category_acl, default_profile): > @@ -120,6 +129,15 @@ class TestCAACLMembers(XMLRPC_test): > category_acl.remove_profile(certprofile=default_profile.name) > category_acl.retrieve() > > + def test_add_ca(self, category_acl, caacl_test_ca): > + caacl_test_ca.ensure_exists() > + category_acl.add_ca(ca=caacl_test_ca.name) > + category_acl.retrieve() > + > + def test_remove_ca(self, category_acl, caacl_test_ca): > + category_acl.remove_ca(ca=caacl_test_ca.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 > @@ -144,6 +162,10 @@ class TestCAACLMembers(XMLRPC_test): > res = category_acl.add_profile(certprofile=category_acl.name, > track=False) > assert len(res['failed']) == 1 > > + def test_add_invalid_value_ca(self, category_acl): > + res = category_acl.add_ca(ca=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 > diff --git a/ipatests/test_xmlrpc/tracker/caacl_plugin.py > b/ipatests/test_xmlrpc/tracker/caacl_plugin.py > index > afe7ee0c071b6346d9a21337d8e486ff8b2891cc..79c892d27e88b3b263915cc0bf843a1235b4836e > 100644 > --- a/ipatests/test_xmlrpc/tracker/caacl_plugin.py > +++ b/ipatests/test_xmlrpc/tracker/caacl_plugin.py > @@ -35,10 +35,11 @@ class CAACLTracker(Tracker): > u'memberuser_user', u'memberuser_group', > u'memberhost_host', u'memberhost_hostgroup', > u'memberservice_service', > - u'ipamembercertprofile_certprofile'} > + u'ipamembercertprofile_certprofile', > + u'ipamemberca_ca'} > category_keys = { > u'ipacacategory', u'ipacertprofilecategory', u'usercategory', > - u'hostcategory', u'servicecategory'} > + u'hostcategory', u'servicecategory', u'ipacacategory'} > retrieve_keys = { > u'dn', u'cn', u'description', u'ipaenabledflag', > u'ipamemberca', u'ipamembercertprofile', u'memberuser', > @@ -51,14 +52,15 @@ class CAACLTracker(Tracker): > update_keys = create_keys - {u'dn'} > > def __init__(self, name, ipacertprofile_category=None, > user_category=None, > - service_category=None, host_category=None, description=None, > - default_version=None): > + service_category=None, host_category=None, > + ipaca_category=None, description=None, > default_version=None): > super(CAACLTracker, self).__init__(default_version=default_version) > > self._name = name > self.description = description > self._categories = dict( > ipacertprofilecategory=ipacertprofile_category, > + ipacacategory=ipaca_category, > usercategory=user_category, > servicecategory=service_category, > hostcategory=host_category) > @@ -200,7 +202,7 @@ class CAACLTracker(Tracker): > # implemented in standalone test > # > # The methods implemented here will be: > - # caacl_{add,remove}_{host, service, certprofile, user [, subca]} > + # caacl_{add,remove}_{host, service, certprofile, user, ca} > > def _add_acl_component(self, command_name, keys, track): > """ Add a resource into ACL rule and track it. > @@ -356,6 +358,20 @@ class CAACLTracker(Tracker): > > return self._remove_acl_component(u'caacl_remove_profile', options, > track) > > + def add_ca(self, ca=None, track=True): > + options = { > + u'ipamemberca_ca': > + {u'ca': ca}} > + > + return self._add_acl_component(u'caacl_add_ca', options, track) > + > + def remove_ca(self, ca=None, track=True): > + options = { > + u'ipamemberca_ca': > + {u'ca': ca}} > + > + return self._remove_acl_component(u'caacl_remove_ca', options, track) > + > def enable(self): > command = self.make_command(u'caacl_enable', self.name) > self.attrs.update({u'ipaenabledflag': [u'TRUE']}) > -- > 2.9.0 > > From b3e43108f1822fd83c602a7eecec933889531d1b Mon Sep 17 00:00:00 2001 > From: =?UTF-8?q?Milan=20Kub=C3=ADk?= <mku...@redhat.com> > Date: Tue, 21 Jun 2016 15:57:58 +0200 > Subject: [PATCH 3/3] ipatests: Test Sub CA with CAACL and certificate profile > > Test the Sub CA feature by signing a CSR with custom > certificate profile. > > The test also covers 'cert-request' fallback behaviour > for missing 'cacn' and 'profile-id' options by reusing > the fixtures from the module. > > https://fedorahosted.org/freeipa/ticket/4559 > --- > .../test_xmlrpc/test_caacl_profile_enforcement.py | 110 > +++++++++++++++++++++ > 1 file changed, 110 insertions(+) > > diff --git a/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py > b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py > index > 11c040966003e2ea86149359c8aacb953e9fdd37..a70d81d885cdf0b4c8bbbdaa7d6f69bfbd84719c > 100644 > --- a/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py > +++ b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py > @@ -15,6 +15,7 @@ from ipatests.util import ( > from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test > from ipatests.test_xmlrpc.tracker.certprofile_plugin import > CertprofileTracker > from ipatests.test_xmlrpc.tracker.caacl_plugin import CAACLTracker > +from ipatests.test_xmlrpc.tracker.ca_plugin import CATracker > > from ipapython.ipautil import run > > @@ -250,3 +251,112 @@ class TestSignWithChangedProfile(XMLRPC_test): > with pytest.raises(errors.CertificateOperationError): > api.Command.cert_request(csr, principal=smime_user, > profile_id=smime_profile.name) > + > + > +@pytest.fixture(scope='class') > +def smime_signing_ca(request): > + name = u'smime-signing-ca' > + subject = u'CN=SMIME CA,O=test industries Inc.' > + return CATracker(name, subject).make_fixture(request) > + > + > +@pytest.mark.tier1 > +class TestCertSignMIMEwithSubCA(XMLRPC_test): > + """ Test Certificate Signing with Sub CA > + > + The test covers following areas: > + > + * signing a CSR with custom certificate profile > + using a designated Sub CA > + * Verify that the Issuer of the signed certificate > + is the reqested CA > + * Verify that when not set, cert-request uses the default CA. > + This it verified by violating an ACL > + * Verify that when not set, cert-request uses the default > + certificate profile. > + > + The latter two test cases are implemented in this module > + as not to replicate the fixtures to cert plugin test module. > + """ > + > + def test_cert_import(self, smime_profile): > + smime_profile.ensure_exists() > + > + def test_create_acl(self, smime_acl): > + smime_acl.ensure_exists() > + > + def test_create_subca(self, smime_signing_ca): > + smime_signing_ca.ensure_exists() > + > + def test_add_profile_to_acl(self, smime_acl, smime_profile): > + smime_acl.add_profile(certprofile=smime_profile.name) > + > + def test_add_subca_to_acl(self, smime_acl, smime_signing_ca): > + smime_acl.add_ca(smime_signing_ca.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, smime_user, > smime_signing_ca): > + csr = generate_user_csr(smime_user) > + with change_principal(smime_user, SMIME_USER_PW): > + api.Command.cert_request(csr, principal=smime_user, > + profile_id=smime_profile.name, > + cacn=smime_signing_ca.name) > + > + def test_sign_smime_csr_full_principal( > + self, smime_profile, smime_user, smime_signing_ca): > + csr = generate_user_csr(smime_user) > + smime_user_principal = '@'.join((smime_user, api.env.realm)) > + with change_principal(smime_user, SMIME_USER_PW): > + api.Command.cert_request(csr, principal=smime_user_principal, > + profile_id=smime_profile.name, > + cacn=smime_signing_ca.name) > + > + def test_verify_cert_issuer_dn_is_subca( > + self, smime_profile, smime_user, smime_signing_ca): > + csr = generate_user_csr(smime_user) > + smime_user_principal = '@'.join((smime_user, api.env.realm)) > + with change_principal(smime_user, SMIME_USER_PW): > + cert_info = api.Command.cert_request( > + csr, principal=smime_user_principal, > + profile_id=smime_profile.name, cacn=smime_signing_ca.name) > + > + assert cert_info['result']['issuer'] == smime_signing_ca.ipasubjectdn > + > + def test_sign_smime_csr_fallback_to_default_CA( > + self, smime_profile, smime_user, smime_signing_ca): > + """ Attempt to sign a CSR without CA specified. > + > + The request will satisfy SMIME_ACL via the profile ID, > + however not specifying the CA will fallback to the IPA CA > + for which SMIME profile isn't enabled, thus violating ACL. > + """ > + csr = generate_user_csr(smime_user) > + smime_user_principal = '@'.join((smime_user, api.env.realm)) > + > + with pytest.raises(errors.ACIError): > + with change_principal(smime_user, SMIME_USER_PW): > + api.Command.cert_request(csr, principal=smime_user_principal, > + profile_id=smime_profile.name) > + > + def test_sign_smime_csr_fallback_to_default_cert_profile( > + self, smime_profile, smime_user, smime_signing_ca): > + """ Attempt to sign a CSR without certificate profile specified. > + > + Similar to previous test case. > + By specifying only the CA to use, profile will fallback to > + the default caIPAserviceCert profile which is not enabled > + via ACL to be used with the CA, thus failing the request. > + """ > + csr = generate_user_csr(smime_user) > + smime_user_principal = '@'.join((smime_user, api.env.realm)) > + > + with pytest.raises(errors.ACIError): > + with change_principal(smime_user, SMIME_USER_PW): > + api.Command.cert_request(csr, principal=smime_user_principal, > + cacn=smime_signing_ca.name) > -- > 2.9.0 > -- 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