URL: https://github.com/freeipa/freeipa/pull/413
Author: dkupka
 Title: #413: Complete stageuser API
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/413/head:pr413
git checkout pr413
From ab000acb3d8efec9ffce82bb9a8ed139143b612d Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Wed, 18 Jan 2017 13:24:29 +0100
Subject: [PATCH 1/7] stageuser: Add stageuser-{add,remove}-cert

Move {add,remove}-cert implementation from user to baseuser and inherit
{,stage}user-{add,remove}-cert from it.

https://fedorahosted.org/freeipa/ticket/6623
---
 API.txt                        | 24 ++++++++++++++++++++++++
 ipaserver/plugins/baseuser.py  | 36 +++++++++++++++++++++++++++++++++++-
 ipaserver/plugins/stageuser.py | 14 ++++++++++++++
 ipaserver/plugins/user.py      | 42 +++++-------------------------------------
 4 files changed, 78 insertions(+), 38 deletions(-)

diff --git a/API.txt b/API.txt
index 543cec5..182daa8 100644
--- a/API.txt
+++ b/API.txt
@@ -4751,6 +4751,17 @@ option: Str('version?')
 output: Entry('result')
 output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
 output: PrimaryKey('value')
+command: stageuser_add_cert/1
+args: 1,5,3
+arg: Str('uid', cli_name='login')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Flag('no_members', autofill=True, default=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Bytes('usercertificate+', alwaysask=True, cli_name='certificate')
+option: Str('version?')
+output: Entry('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: PrimaryKey('value')
 command: stageuser_add_manager/1
 args: 1,5,3
 arg: Str('uid', cli_name='login')
@@ -4882,6 +4893,17 @@ option: Str('version?')
 output: Entry('result')
 output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
 output: PrimaryKey('value')
+command: stageuser_remove_cert/1
+args: 1,5,3
+arg: Str('uid', cli_name='login')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Flag('no_members', autofill=True, default=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Bytes('usercertificate+', alwaysask=True, cli_name='certificate')
+option: Str('version?')
+output: Entry('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: PrimaryKey('value')
 command: stageuser_remove_manager/1
 args: 1,5,3
 arg: Str('uid', cli_name='login')
@@ -6661,10 +6683,12 @@ default: sidgen_was_run/1
 default: stageuser/1
 default: stageuser_activate/1
 default: stageuser_add/1
+default: stageuser_add_cert/1
 default: stageuser_add_manager/1
 default: stageuser_del/1
 default: stageuser_find/1
 default: stageuser_mod/1
+default: stageuser_remove_cert/1
 default: stageuser_remove_manager/1
 default: stageuser_show/1
 default: sudocmd/1
diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py
index 85ad417..75cf7d8 100644
--- a/ipaserver/plugins/baseuser.py
+++ b/ipaserver/plugins/baseuser.py
@@ -26,7 +26,7 @@
 from .baseldap import (
     DN, LDAPObject, LDAPCreate, LDAPUpdate, LDAPSearch, LDAPDelete,
     LDAPRetrieve, LDAPAddAttribute, LDAPRemoveAttribute, LDAPAddMember,
-    LDAPRemoveMember)
+    LDAPRemoveMember, LDAPAddAttributeViaOption, LDAPRemoveAttributeViaOption)
 from ipaserver.plugins.service import (
    validate_certificate, validate_realm, normalize_principal)
 from ipalib.request import context
@@ -694,3 +694,37 @@ class baseuser_remove_principal(LDAPRemoveAttribute):
     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
         ensure_last_krbprincipalname(ldap, entry_attrs, *keys)
         return dn
+
+
+class baseuser_add_cert(LDAPAddAttributeViaOption):
+    attribute = 'usercertificate'
+
+    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys,
+                     **options):
+        self.obj.convert_usercertificate_pre(entry_attrs)
+
+        return dn
+
+    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
+        assert isinstance(dn, DN)
+
+        self.obj.convert_usercertificate_post(entry_attrs, **options)
+
+        return dn
+
+
+class baseuser_remove_cert(LDAPRemoveAttributeViaOption):
+    attribute = 'usercertificate'
+
+    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys,
+                     **options):
+        self.obj.convert_usercertificate_pre(entry_attrs)
+
+        return dn
+
+    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
+        assert isinstance(dn, DN)
+
+        self.obj.convert_usercertificate_post(entry_attrs, **options)
+
+        return dn
diff --git a/ipaserver/plugins/stageuser.py b/ipaserver/plugins/stageuser.py
index afd402e..b2f75a1 100644
--- a/ipaserver/plugins/stageuser.py
+++ b/ipaserver/plugins/stageuser.py
@@ -39,6 +39,8 @@
     baseuser_show,
     NO_UPG_MAGIC,
     baseuser_output_params,
+    baseuser_add_cert,
+    baseuser_remove_cert,
     baseuser_add_manager,
     baseuser_remove_manager)
 from ipalib.request import context
@@ -744,3 +746,15 @@ class stageuser_add_manager(baseuser_add_manager):
 @register()
 class stageuser_remove_manager(baseuser_remove_manager):
     __doc__ = _("Remove a manager to the stage user entry")
+
+
+@register()
+class stageuser_add_cert(baseuser_add_cert):
+    __doc__ = _("Add one or more certificates to the stageuser entry")
+    msg_summary = _('Added certificates to stageuser "%(value)s"')
+
+
+@register()
+class stageuser_remove_cert(baseuser_remove_cert):
+    __doc__ = _("Remove one or more certificates to the stageuser entry")
+    msg_summary = _('Removed certificates from stageuser "%(value)s"')
diff --git a/ipaserver/plugins/user.py b/ipaserver/plugins/user.py
index 6440548..1ef71d2 100644
--- a/ipaserver/plugins/user.py
+++ b/ipaserver/plugins/user.py
@@ -43,6 +43,8 @@
     fix_addressbook_permission_bindrule,
     baseuser_add_manager,
     baseuser_remove_manager,
+    baseuser_add_cert,
+    baseuser_remove_cert,
     baseuser_add_principal,
     baseuser_remove_principal)
 from .idviews import remove_ipaobject_overrides
@@ -53,9 +55,7 @@
     LDAPCreate,
     LDAPSearch,
     LDAPQuery,
-    LDAPMultiQuery,
-    LDAPAddAttributeViaOption,
-    LDAPRemoveAttributeViaOption)
+    LDAPMultiQuery)
 from . import baseldap
 from ipalib.request import context
 from ipalib import _, ngettext
@@ -1157,47 +1157,15 @@ def execute(self, *keys, **options):
 
 
 @register()
-class user_add_cert(LDAPAddAttributeViaOption):
+class user_add_cert(baseuser_add_cert):
     __doc__ = _('Add one or more certificates to the user entry')
     msg_summary = _('Added certificates to user "%(value)s"')
-    attribute = 'usercertificate'
-
-    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys,
-                     **options):
-        dn = self.obj.get_either_dn(*keys, **options)
-
-        self.obj.convert_usercertificate_pre(entry_attrs)
-
-        return dn
-
-    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-        assert isinstance(dn, DN)
-
-        self.obj.convert_usercertificate_post(entry_attrs, **options)
-
-        return dn
 
 
 @register()
-class user_remove_cert(LDAPRemoveAttributeViaOption):
+class user_remove_cert(baseuser_remove_cert):
     __doc__ = _('Remove one or more certificates to the user entry')
     msg_summary = _('Removed certificates from user "%(value)s"')
-    attribute = 'usercertificate'
-
-    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys,
-                     **options):
-        dn = self.obj.get_either_dn(*keys, **options)
-
-        self.obj.convert_usercertificate_pre(entry_attrs)
-
-        return dn
-
-    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-        assert isinstance(dn, DN)
-
-        self.obj.convert_usercertificate_post(entry_attrs, **options)
-
-        return dn
 
 
 @register()

From 331bf987a71a7b1c5e38580aed6fe301154fc294 Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Wed, 18 Jan 2017 13:25:11 +0100
Subject: [PATCH 2/7] stageuser: Add stageuser-{add,remove}-principal

https://fedorahosted.org/freeipa/ticket/6623
---
 API.txt                        | 24 ++++++++++++++++++++++++
 ipaserver/plugins/stageuser.py | 14 ++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/API.txt b/API.txt
index 182daa8..128d184 100644
--- a/API.txt
+++ b/API.txt
@@ -4773,6 +4773,17 @@ option: Str('version?')
 output: Output('completed', type=[<type 'int'>])
 output: Output('failed', type=[<type 'dict'>])
 output: Entry('result')
+command: stageuser_add_principal/1
+args: 2,4,3
+arg: Str('uid', cli_name='login')
+arg: Principal('krbprincipalname+', alwaysask=True, autofill=True, cli_name='principal')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Flag('no_members', autofill=True, default=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Str('version?')
+output: Entry('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: PrimaryKey('value')
 command: stageuser_del/1
 args: 1,2,3
 arg: Str('uid+', cli_name='login')
@@ -4915,6 +4926,17 @@ option: Str('version?')
 output: Output('completed', type=[<type 'int'>])
 output: Output('failed', type=[<type 'dict'>])
 output: Entry('result')
+command: stageuser_remove_principal/1
+args: 2,4,3
+arg: Str('uid', cli_name='login')
+arg: Principal('krbprincipalname+', alwaysask=True, autofill=True, cli_name='principal')
+option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Flag('no_members', autofill=True, default=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False)
+option: Str('version?')
+output: Entry('result')
+output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+output: PrimaryKey('value')
 command: stageuser_show/1
 args: 1,5,3
 arg: Str('uid', cli_name='login')
@@ -6685,11 +6707,13 @@ default: stageuser_activate/1
 default: stageuser_add/1
 default: stageuser_add_cert/1
 default: stageuser_add_manager/1
+default: stageuser_add_principal/1
 default: stageuser_del/1
 default: stageuser_find/1
 default: stageuser_mod/1
 default: stageuser_remove_cert/1
 default: stageuser_remove_manager/1
+default: stageuser_remove_principal/1
 default: stageuser_show/1
 default: sudocmd/1
 default: sudocmd_add/1
diff --git a/ipaserver/plugins/stageuser.py b/ipaserver/plugins/stageuser.py
index b2f75a1..5602514 100644
--- a/ipaserver/plugins/stageuser.py
+++ b/ipaserver/plugins/stageuser.py
@@ -41,6 +41,8 @@
     baseuser_output_params,
     baseuser_add_cert,
     baseuser_remove_cert,
+    baseuser_add_principal,
+    baseuser_remove_principal,
     baseuser_add_manager,
     baseuser_remove_manager)
 from ipalib.request import context
@@ -758,3 +760,15 @@ class stageuser_add_cert(baseuser_add_cert):
 class stageuser_remove_cert(baseuser_remove_cert):
     __doc__ = _("Remove one or more certificates to the stageuser entry")
     msg_summary = _('Removed certificates from stageuser "%(value)s"')
+
+
+@register()
+class stageuser_add_principal(baseuser_add_principal):
+    __doc__ = _('Add new principal alias to the stageuser entry')
+    msg_summary = _('Added new aliases to stageuser "%(value)s"')
+
+
+@register()
+class stageuser_remove_principal(baseuser_remove_principal):
+    __doc__ = _('Remove principal alias from the stageuser entry')
+    msg_summary = _('Removed aliases from stageuser "%(value)s"')

From 9a049cc8c4562481d49bb22b2821d2e5a8a7b7e2 Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Mon, 23 Jan 2017 10:38:34 +0100
Subject: [PATCH 3/7] ipalib.x509: Handle missing SAN gracefully

When extension is not present None is returned instead of empty iterable
or exception thrown.
---
 ipalib/x509.py | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/ipalib/x509.py b/ipalib/x509.py
index 87d46ae..03f870e 100644
--- a/ipalib/x509.py
+++ b/ipalib/x509.py
@@ -435,8 +435,12 @@ def get_san_general_names(cert):
         asn1Spec=rfc2459.TBSCertificate()
     )[0]
     OID_SAN = univ.ObjectIdentifier('2.5.29.17')
+    # One would expect KeyError or empty iterable when the key ('extensions'
+    # in this particular case) is not pressent in the certificate but pyasn1
+    # returns None here
+    extensions = tbs['extensions'] or []
     gns = []
-    for ext in tbs['extensions']:
+    for ext in extensions:
         if ext['extnID'] == OID_SAN:
             der = decoder.decode(
                 ext['extnValue'], asn1Spec=univ.OctetString())[0]

From da06fb7cd02a31381043a1a4b66e7af635d982c4 Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Wed, 25 Jan 2017 12:43:22 +0100
Subject: [PATCH 4/7] tests: add-remove-cert: Use harcoded certificates instead
 of requesting them

Requesting certificates for test purposes is not necessary as we allow to
upload arbitrary certificate to the user, host or service. Also requesting
certificate from dogtag takes some time and the test is slower for no good
reason.
More it's not posible to request certificate for stageuser even though it's
possible to upload certificates to stageusers now.

https://fedorahosted.org/freeipa/ticket/6623
---
 ipatests/test_xmlrpc/test_add_remove_cert_cmd.py | 86 ++++++++++++++++++++++--
 1 file changed, 81 insertions(+), 5 deletions(-)

diff --git a/ipatests/test_xmlrpc/test_add_remove_cert_cmd.py b/ipatests/test_xmlrpc/test_add_remove_cert_cmd.py
index 7706133..631d898 100644
--- a/ipatests/test_xmlrpc/test_add_remove_cert_cmd.py
+++ b/ipatests/test_xmlrpc/test_add_remove_cert_cmd.py
@@ -113,15 +113,91 @@ def setup_class(cls):
 
         # list of certificates to add to entry
         cls.certs = [
-            get_testcert(DN(('CN', cls.entity_subject)), cls.entity_principal)
-            for _i in range(3)
+            u"MIICszCCAZugAwIBAgICM24wDQYJKoZIhvcNAQELBQAwIzEUMBIGA1UEChML\r\n"
+            "RVhBTVBMRS5PUkcxCzAJBgNVBAMTAkNBMB4XDTE3MDExOTEwMjUyOVoXDTE3M\r\n"
+            "DQxOTEwMjUyOVowFjEUMBIGA1UEAxMLc3RhZ2V1c2VyLTEwggEiMA0GCSqGSI\r\n"
+            "b3DQEBAQUAA4IBDwAwggEKAoIBAQCq03FRQQBvq4HwYMKP8USLZuOkKzuIs2V\r\n"
+            "Pt8k/+nO1dADrzMogKDiUDjCwYoG2UM/sj6P+PJUUCNDLh5eRRI+aR5VE5y2a\r\n"
+            "K95iCsj1ByDWrugAUXgr8GUUr+UbaGc0XxHCMnQBkYhzbXY3u91KYRRh5l3lx\r\n"
+            "RSICcVeJFJ/tiMS14Vsor1DWykHGz1wm0Zjwg1XDV3oea+uwrSz5Pa6RNPlgC\r\n"
+            "+GGW6B7+8qC2XdSSEwvY7y1SAGgqyOxN/FLwvqqMDNU0uX7fww587uZ57IfYz\r\n"
+            "b8Xn5DAprRFNk40FDc46rMlkPBT+Tij1I0jedD8h2e6WEa7JRU6SGToYDbRm4\r\n"
+            "RL9xAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAHqm1jXzYer9oSjYs9qh1jWpM\r\n"
+            "vTcN+0/z1uuX++Wezh3lG7IzYtypbZNxlXDECyrkUh+9oxzMJqdlZ562ko2br\r\n"
+            "uK6X5csbbM9uVsUva8NCsPPfZXDhrYaMKFvQGFY4pO3uhFGhccob037VN5Ifm\r\n"
+            "aKGM8aJ40cw2PQh38QPDdemizyVCThQ9Pcr+WgWKiG+t2Gd9NldJRLEhky0bW\r\n"
+            "2fc4zWZVbGq5nFXy1k+d/bgkHbVzf255eFZOKKy0NgZwig+uSlhVWPJjS4Z1w\r\n"
+            "LbpBKxTZp/xD0yEARs0u1ZcCELO/BkgQM50EDKmahIM4mdCs/7j1B/DdWs2i3\r\n"
+            "5lnbjxYYiUiyA=",
+            u"MIICszCCAZugAwIBAgICJGMwDQYJKoZIhvcNAQELBQAwIzEUMBIGA1UEChML\r\n"
+            "RVhBTVBMRS5PUkcxCzAJBgNVBAMTAkNBMB4XDTE3MDExOTEwMjcyN1oXDTE3M\r\n"
+            "DQxOTEwMjcyN1owFjEUMBIGA1UEAxMLc3RhZ2V1c2VyLTIwggEiMA0GCSqGSI\r\n"
+            "b3DQEBAQUAA4IBDwAwggEKAoIBAQDsEuTITzsRiUHXb8LxduokAEHwStCveKV\r\n"
+            "i8aVFBYQCRbpoXcoTfBISWvdmF3WOkIUfR1O0qrm0s3CPMAyWdTrnCI/45/Cc\r\n"
+            "FNDpGKPf+izN1t+WSrr6gCoz24y5ALyUEG5FSvHdDcIn+hY9Qvg3cRLxY9M4W\r\n"
+            "XmtR6p+d48v08nSSJXprgXS6ZiVvN7QGQfNRNDNoQZLmP9tQ/XvgJuiBMPj2N\r\n"
+            "aUFM8AwDnxGcvzExgaFlX0OKS6hymsUG60PeF0H0aYDgVH/0DKK+mZEA2FNbR\r\n"
+            "JIQt5Vk+c5aBvPrOfRLKrsQQ/zhtNOxk8Q0G+cwlzANCqbV7EzUFEFEtonnOP\r\n"
+            "tzY7AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIPcStKnxv6bdPiL2I7f4B/ME\r\n"
+            "BEV+kFnzu1msfkh1iouiKmM4ZkXLiqInKxEBwWNmhpRFoxKWaI3DjYtf/PYH/\r\n"
+            "guHipZvLIrVgfxlf/5ldXeoa7IHZ9hzvrG3WuYG6SHoJw6yaA6Vn8j8Q3r/kG\r\n"
+            "/1SLZpRpoq0EuhD7V/aHvxr/aiFnU4Fh2VaQd2ICOK2qBFQnoL5QyySVEJ7GA\r\n"
+            "RmajT3BqAASoixEqfMWYv2AqZnJ84JoI4reP0uZGjz5Cy32xQuenQckr8Faki\r\n"
+            "p28buFp46C34AWifbRERE396xocc9/Oc7dx9DyjeYqa9CuNo/pYlC4r8QCOkm\r\n"
+            "0xMWjoGcVUtUw=",
+            u"MIICszCCAZugAwIBAgICFpYwDQYJKoZIhvcNAQELBQAwIzEUMBIGA1UEChML\r\n"
+            "RVhBTVBMRS5PUkcxCzAJBgNVBAMTAkNBMB4XDTE3MDExOTEwMjczMVoXDTE3M\r\n"
+            "DQxOTEwMjczMVowFjEUMBIGA1UEAxMLc3RhZ2V1c2VyLTMwggEiMA0GCSqGSI\r\n"
+            "b3DQEBAQUAA4IBDwAwggEKAoIBAQDEIMvN8aElxMSyfqIj91nDuuvli/RKNhF\r\n"
+            "sIU32c7NJVF7kthvltmEwIVKKCE1Yji3GRWXBuZlSz5eSyDaqqpOpdYsVjYaz\r\n"
+            "XfWA5kjL8vGkoVt97SQ0TEkSOlinnjuo2unjU33RcruRp4rqeQE8EPBlAXYJr\r\n"
+            "+iK5Y+RF9Mz047ba097wUUX85QeEp1LWwYbLZleNFK1BwsmSL5Js+GcKEBEdi\r\n"
+            "KS/OfidTz7Hf7KICLo+iZlbG3lNLFQMvWFG8bzTeOgZ5OLDeBRzG6cSZK0Q3A\r\n"
+            "18uVg0jf0rv/nsOO/JQRK1FufvmOL2Xp7lqLFaAIuQqH1OuAq6MHfuaxwpdiU\r\n"
+            "yzVfAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAs0K12ugVJ4t7/iUdddTmS+v\r\n"
+            "8FEEL92fWgU1bQHR/gMa2by9SIqS1KZVBc5JpJePqVf/S35Gt4o7sE3rbbmZm\r\n"
+            "mhGDL8D+BmGHjxdhENLyk6rvHOm+TDgM7nQK0FbPekMzkbsFxfw9R7iq8cnZD\r\n"
+            "7Y1T5e2N+WMzx6Jf/ner32V9CTfFbGP84G0+kqyqo7vp59VIwyHpC0L/0bh8W\r\n"
+            "YjFKNCPMbnZpO3212dNCaIMp0Kugi9D4kXAeM3unQ2/p5pN7Vgo+Xl9hioN5g\r\n"
+            "As+3SQR2pArUmr8RtjvfH/PxE8scWtRCCH4aBhfklrCHK+rpUzh4PXqhXGYJC\r\n"
+            "TmYzsAw/Z7vnY=",
         ]
 
         # list of certificates for testing of removal of non-existent certs
         cls.nonexistent_certs = [
-            get_testcert(DN(('CN', cls.entity_subject)), cls.entity_principal)
-            for _j in range(2)
-            ]
+            u"MIICszCCAZugAwIBAgICYDAwDQYJKoZIhvcNAQELBQAwIzEUMBIGA1UEChML\r\n"
+            "RVhBTVBMRS5PUkcxCzAJBgNVBAMTAkNBMB4XDTE3MDExOTEwMjczNVoXDTE3M\r\n"
+            "DQxOTEwMjczNVowFjEUMBIGA1UEAxMLc3RhZ2V1c2VyLTQwggEiMA0GCSqGSI\r\n"
+            "b3DQEBAQUAA4IBDwAwggEKAoIBAQDAw12yHMBzQd27/Zv5STUlrkgGaClC4/U\r\n"
+            "+HxjHSHxFJLStYgK9DrXpRIqnkdwAr7rftlhFiRkqFE4GNGNAlhUlnkn0YTvD\r\n"
+            "59ucnpSRC7kjkrHAb1fWDNE3VYQOOF93CObOOAciNEl/K0HXqXxxYkhF6cz+m\r\n"
+            "N1gGd6oOtCu+G1vCoM25X3nlQdgOJtI8X2/MDvZ+nJVRqscsjeNnM0+A1Q1Cf\r\n"
+            "u2ukiqYgiQVYAa88hpADhXEF+hht3iIiw53GgD1Bb5xFm+OKpwBSegRJOjraj\r\n"
+            "XeWpr1ZN44JCTuFmAxwaNzynpYjrDbWXoLzbXEhyPbtT1jui6A1rRhEpc9Tyd\r\n"
+            "Wb4rAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAMe/xoqCmmSV/8x+hawb216sv\r\n"
+            "5CX6+WKMlLJTsmB586fQoJWJecn3Wg7DB1vfLeffayh9b+7g0w0OZnaUJlPNH\r\n"
+            "T6x5P29jH9J6fGOu3CIafCpvEXyamJKyQD6tER3l4iRBzoqW74BQh3W6rQnVs\r\n"
+            "lvM07LlQA0PB9RXYNvEmTCJKOtzA7wcARukvss9VS9oBfxjFgcGDKfMPPNaH9\r\n"
+            "IGEZi8QwEnOsSpLUobWPhRENbxwTMwlMspk9QG7NvTfisqFRXkAov0R/rHPqr\r\n"
+            "AXJTZmkPP+MhrsrbnT0CV2f6bxPkvXknuf+7Xi3h900BLQOSY+jqmtmGrYjln\r\n"
+            "tsqX1gL4y2e98=",
+            u"MIICszCCAZugAwIBAgICeicwDQYJKoZIhvcNAQELBQAwIzEUMBIGA1UEChML\r\n"
+            "RVhBTVBMRS5PUkcxCzAJBgNVBAMTAkNBMB4XDTE3MDExOTEwMjczOVoXDTE3M\r\n"
+            "DQxOTEwMjczOVowFjEUMBIGA1UEAxMLc3RhZ2V1c2VyLTUwggEiMA0GCSqGSI\r\n"
+            "b3DQEBAQUAA4IBDwAwggEKAoIBAQCd1VDwUwkwieLqngX1q2HoOe/tKnPxnr/\r\n"
+            "DrjbXAwFxEDcp7lfIUXALy33YZTAUGaNhlKzL+5sL3O5RcebSywBvw9Cpg9O4\r\n"
+            "lLPeAwdgnCHpNMaBjFL9/ySnwrIH0Hpx7chUXt1zz+z4ia1i7ZfVWHlP3D+pu\r\n"
+            "dR8MdzKH+1irtLcVL8ESfIqVsLGf0qV3wi2znqFsul6+e1MLE/RVXFoCmEX7J\r\n"
+            "5mJ77aFm6GgpXR7O3UAGl1NAfbZUz1Itt/NSrx8lHAYur4tUPQPEEa8XSe/B8\r\n"
+            "hG5J1inw6jm94vvpi2a3GOU6eDz4q0nM0/Rbia212tdbpyKdkm4aCQkoyhrJR\r\n"
+            "+DhvAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADd5V5BMVY4zBRQiLZ2x+7seD\r\n"
+            "oT7ewyYW6Kk9oMlk7JWXgNyAG5/561vSkKIBkQG2CTRD3dAX7SbUwkxP7/a9g\r\n"
+            "ozJN3VOrLBUDhxyesr3cMuIU9XVyPezT3KapQjXkxzmJKiRNPc/fope4Xx5uc\r\n"
+            "UwYa6lm9QVCD4gnNElf+RexpI3VwkjmAWS3cvsKRFFNbZCS5gpCM/rOX76m4l\r\n"
+            "YcBSA8B+jb0FkOJt3u9fwtoMbhv5kdjEDGNWmG1kJ86ybqeWj12BpKGh4G6m4\r\n"
+            "E8ROnyuBt8Bolk4jqR3uCPfD4T+HpkttqrznRaGvroD020pEjtU22sAKkhBZQ\r\n"
+            "2Wbfkc49wxqpY=",
+        ]
 
         # cert subset to remove from entry
         cls.certs_subset = cls.certs[:2]

From 35b24e80c516114c6204053d4beb4bc4bf5bd5ac Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Wed, 25 Jan 2017 12:43:32 +0100
Subject: [PATCH 5/7] tests: Stageuser-{add,remove}-cert

https://fedorahosted.org/freeipa/ticket/6623
---
 ipatests/test_xmlrpc/test_add_remove_cert_cmd.py | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/ipatests/test_xmlrpc/test_add_remove_cert_cmd.py b/ipatests/test_xmlrpc/test_add_remove_cert_cmd.py
index 631d898..d057047 100644
--- a/ipatests/test_xmlrpc/test_add_remove_cert_cmd.py
+++ b/ipatests/test_xmlrpc/test_add_remove_cert_cmd.py
@@ -403,6 +403,25 @@ def remove_caacl(cls):
 
 
 @pytest.mark.tier1
+class TestCertManipCmdStageuser(CertManipCmdTestBase):
+    entity_class = 'stageuser'
+    entity_pkey = u'suser'
+    entity_subject = entity_pkey
+    entity_principal = u'suser'
+    non_existent_entity = u'nonexistentstageuser'
+
+    cmd_options = dict(
+        entity_add=dict(givenname=u'Stage', sn=u'User'),
+    )
+
+    cert_add_cmd = api.Command.stageuser_add_cert
+    cert_del_cmd = api.Command.stageuser_remove_cert
+
+    cert_add_summary = u'Added certificates to stageuser "%s"'
+    cert_del_summary = u'Removed certificates from stageuser "%s"'
+
+
+@pytest.mark.tier1
 class TestCertManipCmdHost(CertManipCmdTestBase):
     entity_class = 'host'
     entity_pkey = u'host.example.com'

From f2016b4c9c81fcac5ccf456aea479435d2015b29 Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Thu, 19 Jan 2017 09:27:52 +0100
Subject: [PATCH 6/7] tests: kerberos_principal_aliases: Deduplicate tests

https://fedorahosted.org/freeipa/ticket/6623
---
 .../test_xmlrpc/test_kerberos_principal_aliases.py | 62 +++++++++++-----------
 1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/ipatests/test_xmlrpc/test_kerberos_principal_aliases.py b/ipatests/test_xmlrpc/test_kerberos_principal_aliases.py
index a1973af..95d23ac 100644
--- a/ipatests/test_xmlrpc/test_kerberos_principal_aliases.py
+++ b/ipatests/test_xmlrpc/test_kerberos_principal_aliases.py
@@ -85,13 +85,6 @@ def krbalias_user_c(request):
     return tracker.make_fixture(request)
 
 
-@pytest.fixture(scope='function')
-def krbalias_host(request):
-    tracker = HostTracker(u'testhost-krb')
-
-    return tracker.make_fixture(request)
-
-
 @pytest.fixture
 def krb_service_host(request):
     tracker = HostTracker(u'krb-srv-host')
@@ -108,6 +101,12 @@ def krbalias_service(request, krb_service_host):
     return tracker.make_fixture(request)
 
 
+@pytest.fixture(scope='function')
+def krbalias(request, tracker_cls, tracker_args, tracker_kwargs):
+    tracker = tracker_cls(*tracker_args, **tracker_kwargs)
+    return tracker.make_fixture(request)
+
+
 @pytest.fixture
 def ldapservice(request):
     tracker = ServiceTracker(
@@ -118,29 +117,32 @@ def ldapservice(request):
 
 
 class TestKerberosAliasManipulation(XMLRPC_test):
-
-    def test_add_user_principal_alias(self, krbalias_user):
-        krbalias_user.ensure_exists()
-        krbalias_user.add_principal([u'test-user-alias'])
-        krbalias_user.retrieve()
-
-    def test_remove_user_principal_alias(self, krbalias_user):
-        krbalias_user.ensure_exists()
-        krbalias_user.add_principal([u'test-user-alias'])
-        krbalias_user.remove_principal(u'test-user-alias')
-        krbalias_user.retrieve()
-
-    def test_add_host_principal_alias(self, krbalias_host):
-        krbalias_host.ensure_exists()
-        krbalias_host.add_principal([u'testhost-krb-alias'])
-        krbalias_host.retrieve()
-
-    def test_remove_host_principal_alias(self, krbalias_host):
-        krbalias_host.ensure_exists()
-        krbalias_host.add_principal([u'testhost-krb-alias'])
-        krbalias_host.retrieve()
-        krbalias_host.remove_principal([u'testhost-krb-alias'])
-        krbalias_host.retrieve()
+    add_remove_test_data = [
+        u'testuser-alias',
+        u'testhost-alias',
+    ]
+    tracker_init_data = [
+        (UserTracker, (u'krbalias_user', u'krbalias', u'test',), {},),
+        (HostTracker, (u'testhost-krb',), {},),
+    ]
+
+    tracker_data = [(add_remove_test_data[i],) + tracker_init_data[i]
+                    for i in range(len(tracker_init_data))]
+
+    @pytest.mark.parametrize('alias,tracker_cls,tracker_args,tracker_kwargs',
+                             tracker_data)
+    def test_add_principal_alias(self, alias, krbalias):
+        krbalias.ensure_exists()
+        krbalias.add_principal([alias])
+        krbalias.retrieve()
+
+    @pytest.mark.parametrize('alias,tracker_cls,tracker_args,tracker_kwargs',
+                             tracker_data)
+    def test_remove_principal_alias(self, alias, krbalias):
+        krbalias.ensure_exists()
+        krbalias.add_principal([alias])
+        krbalias.remove_principal(alias)
+        krbalias.retrieve()
 
     def test_add_service_principal_alias(self, krbalias_service):
         krbalias_service.ensure_exists()

From be57bc04f6915478879657352e82f828abd033bc Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Thu, 19 Jan 2017 09:28:58 +0100
Subject: [PATCH 7/7] tests: Add tests for kerberos principal aliases in
 stageuser

https://fedorahosted.org/freeipa/ticket/6623
---
 ipatests/test_xmlrpc/test_kerberos_principal_aliases.py | 3 +++
 ipatests/test_xmlrpc/tracker/stageuser_plugin.py        | 9 ++++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/ipatests/test_xmlrpc/test_kerberos_principal_aliases.py b/ipatests/test_xmlrpc/test_kerberos_principal_aliases.py
index 95d23ac..ed1b159 100644
--- a/ipatests/test_xmlrpc/test_kerberos_principal_aliases.py
+++ b/ipatests/test_xmlrpc/test_kerberos_principal_aliases.py
@@ -15,6 +15,7 @@
 from ipatests.test_xmlrpc.tracker.user_plugin import UserTracker
 from ipatests.test_xmlrpc.tracker.host_plugin import HostTracker
 from ipatests.test_xmlrpc.tracker.service_plugin import ServiceTracker
+from ipatests.test_xmlrpc.tracker.stageuser_plugin import StageUserTracker
 from ipatests.test_xmlrpc.mock_trust import (
     mocked_trust_containers, get_trust_dn, get_trusted_dom_dict,
     encode_mockldap_value)
@@ -120,10 +121,12 @@ class TestKerberosAliasManipulation(XMLRPC_test):
     add_remove_test_data = [
         u'testuser-alias',
         u'testhost-alias',
+        u'teststageuser-alias',
     ]
     tracker_init_data = [
         (UserTracker, (u'krbalias_user', u'krbalias', u'test',), {},),
         (HostTracker, (u'testhost-krb',), {},),
+        (StageUserTracker, (u'krbalias_stageuser', u'krbalias', u'test',), {},),
     ]
 
     tracker_data = [(add_remove_test_data[i],) + tracker_init_data[i]
diff --git a/ipatests/test_xmlrpc/tracker/stageuser_plugin.py b/ipatests/test_xmlrpc/tracker/stageuser_plugin.py
index 27f56d3..fe408af 100644
--- a/ipatests/test_xmlrpc/tracker/stageuser_plugin.py
+++ b/ipatests/test_xmlrpc/tracker/stageuser_plugin.py
@@ -7,6 +7,7 @@
 from ipalib import api, errors
 
 from ipatests.test_xmlrpc.tracker.base import Tracker
+from ipatests.test_xmlrpc.tracker.kerberos_aliases import KerberosAliasMixin
 from ipatests.test_xmlrpc import objectclasses
 from ipatests.test_xmlrpc.xmlrpc_test import (
     Fuzzy, fuzzy_string, fuzzy_dergeneralizedtime, raises_exact)
@@ -28,7 +29,7 @@
                'public key test (ssh-rsa)')
 
 
-class StageUserTracker(Tracker):
+class StageUserTracker(KerberosAliasMixin, Tracker):
     """ Tracker class for staged user LDAP object
 
         Implements helper functions for host plugin.
@@ -292,3 +293,9 @@ def create_from_preserved(self, user):
         self.dn = DN(
             ('uid', self.uid), api.env.container_stageuser, api.env.basedn)
         self.attrs[u'dn'] = self.dn
+
+    def _make_add_alias_cmd(self):
+        return self.make_command('stageuser_add_principal', self.name)
+
+    def _make_remove_alias_cmd(self):
+        return self.make_command('stageuser_remove_principal', self.name)
-- 
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