Hi,

the following two patches make sure that sshpubkeys work both with -mod and 
-add commands of ipaoverrideuser objects. Also covers the use cases with unit 
tests.

https://fedorahosted.org/freeipa/ticket/4868

Tomas
From ec60a1c2cd04a71725cf86c5926f749795cfe20a Mon Sep 17 00:00:00 2001
From: Tomas Babej <tba...@redhat.com>
Date: Mon, 26 Jan 2015 16:27:56 +0100
Subject: [PATCH] idviews: Make sure ssh public key can be set on
 ipauseroverride-add

Clears up and generalizes ssh public key handling so that it
can be used in ipaoverrideuser-add as well as ipaoverrideuser-mod
commands.

Also properly deals with the situation when user removes the
ssh public key from the override, where original implementation
would leave stray objectclasses behind.

https://fedorahosted.org/freeipa/ticket/4868
---
 ipalib/plugins/idviews.py | 57 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 50 insertions(+), 7 deletions(-)

diff --git a/ipalib/plugins/idviews.py b/ipalib/plugins/idviews.py
index df6b80fee6239c97e2133885234408c2816b3774..887616dd044e2c79dfabcbbef5ce5cde7b0508c6 100644
--- a/ipalib/plugins/idviews.py
+++ b/ipalib/plugins/idviews.py
@@ -729,6 +729,51 @@ class idoverrideuser(baseidoverride):
                                                      anchor)
         entry_attrs['ipaOriginalUid'] = original_uid
 
+    def handle_sshpubkey_update(self, dn, ldap, entry_attrs, modify=False):
+        """
+        Handles adding sshpubkey value on idoverrideuser-add or
+        idoverrideuser-mod. Makes sure that 'ipasshuser' objectclass
+        is added/removed.
+        """
+
+        def get_objectclasses():
+            """
+            Returns a list of objectclasses that will be saved in the entry
+            after this modification. Modifing this list changes the actual
+            list of objeclasses being assigned to the entry.
+            """
+
+            # If objectclasses are not in entry_attrs, fetch them from LDAP
+            # and inject them there
+            if 'objectclass' not in entry_attrs and modify:
+                fromldap = ldap.get_entry(dn, ['objectclass'])['objectclass']
+                entry_attrs['objectclass'] = fromldap
+            elif 'objectclass' not in entry_attrs:
+                entry_attrs['objectclass'] = [c for c in self.object_class]
+
+            return entry_attrs['objectclass']
+
+        # Let's deal with this only if modification to ipasshpubkey attribute
+        # is being performed
+        if 'ipasshpubkey' not in entry_attrs:
+            return
+
+        classes = get_objectclasses()
+        sshpubkey_removed = entry_attrs['ipasshpubkey'] is None
+
+        if sshpubkey_removed:
+            # If sshpubkey value is being removed, remove the ipasshuser class
+            # and ipaSshGroupOfPubKeys (superclass of ipasshuser) class too
+            if 'ipasshuser' in classes:
+                del classes[classes.index('ipasshuser')]
+            if 'ipaSshGroupOfPubKeys' in classes:
+                del classes[classes.index('ipaSshGroupOfPubKeys')]
+        else:
+            # If sshpubkey value is being added, make sure ipasshuser class
+            # is present too
+            if 'ipasshuser' not in classes:
+                classes.append('ipasshuser')
+
 
 @register()
 class idoverridegroup(baseidoverride):
@@ -788,6 +833,9 @@ class idoverrideuser_add(baseidoverride_add):
 
         # Update the ipaOriginalUid
         self.obj.update_original_uid_reference(entry_attrs)
+
+        # Handle the objectclass changes related to sshpubkey
+        self.obj.handle_sshpubkey_update(dn, ldap, entry_attrs)
         return dn
 
     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
@@ -816,14 +864,9 @@ class idoverrideuser_mod(baseidoverride_mod):
         # Update the ipaOriginalUid
         self.obj.set_anchoruuid_from_dn(dn, entry_attrs)
         self.obj.update_original_uid_reference(entry_attrs)
-        if 'objectclass' in entry_attrs:
-            obj_classes = entry_attrs['objectclass']
-        else:
-            _entry_attrs = ldap.get_entry(dn, ['objectclass'])
-            obj_classes = entry_attrs['objectclass'] = _entry_attrs['objectclass']
 
-        if 'ipasshpubkey' in entry_attrs and 'ipasshuser' not in obj_classes:
-            obj_classes.append('ipasshuser')
+        # Handle the objectclass changes related to sshpubkey
+        self.obj.handle_sshpubkey_update(dn, ldap, entry_attrs, modify=True)
         return dn
 
     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-- 
2.1.0

From 50766894a633b07fa90e68ce9bd5771b387521f0 Mon Sep 17 00:00:00 2001
From: Tomas Babej <tba...@redhat.com>
Date: Mon, 26 Jan 2015 16:29:29 +0100
Subject: [PATCH] ipatests: Add coverage for adding and removing sshpubkeys in
 ID overrides

Adds xmlrpc tests for:
  - Adding a user ID override with sshpubkey
  - Modifying a user ID override to contain sshpubkey
  - Removing a sshpubkey value from a user ID override

https://fedorahosted.org/freeipa/ticket/4868
---
 ipatests/test_xmlrpc/test_idviews_plugin.py | 64 ++++++++++++++++++++++++++++-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/ipatests/test_xmlrpc/test_idviews_plugin.py b/ipatests/test_xmlrpc/test_idviews_plugin.py
index e4e7e553bb2f6e0fa5ad07fcd7ca99400ba90b93..a3333c11abd384cb37458d105e811a21ba0c3d28 100644
--- a/ipatests/test_xmlrpc/test_idviews_plugin.py
+++ b/ipatests/test_xmlrpc/test_idviews_plugin.py
@@ -55,6 +55,17 @@ host2 = u'testhost2'
 host3 = u'testhost3'
 host4 = u'testhost4'
 
+sshpubkey = (u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGAX3xAeLeaJggwTqMjxNwa6X'
+              'HBUAikXPGMzEpVrlLDCZtv00djsFTBi38PkgxBJVkgRWMrcBsr/35lq7P6w8KGI'
+              'wA8GI48Z0qBS2NBMJ2u9WQ2hjLN6GdMlo77O0uJY3251p12pCVIS/bHRSq8kHO2'
+              'No8g7KA9fGGcagPfQH+ee3t7HUkpbQkFTmbPPN++r3V8oVUk5LxbryB3UIIVzNm'
+              'cSIn3JrXynlvui4MixvrtX6zx+O/bBo68o8/eZD26QrahVbA09fivrn/4h3TM01'
+              '9Eu/c2jOdckfU3cHUV/3Tno5d6JicibyaoDDK7S/yjdn5jhaz8MSEayQvFkZkiF'
+              '0L public key test')
+sshpubkeyfp = (u'13:67:6B:BF:4E:A2:05:8E:AE:25:8B:A1:31:DE:6F:1B '
+                'public key test (ssh-rsa)')
+ssh_classes = [u'ipasshuser', u'ipaSshGroupOfPubKeys']
+
 
 # Test helpers
 def get_idview_dn(name):
@@ -523,6 +534,54 @@ class test_idviews(Declarative):
         ),
 
         dict(
+            desc='Modify User ID override "%s" to override '
+                 'sshpubkey' % idoverrideuser1,
+            command=(
+                'idoverrideuser_mod',
+                [idview1, idoverrideuser1],
+                dict(ipasshpubkey=sshpubkey, all=True)
+            ),
+            expected=dict(
+                value=idoverrideuser1,
+                summary=u'Modified an User ID override "%s"' % idoverrideuser1,
+                result=dict(
+                    dn=get_override_dn(idview1, idoverrideuser1),
+                    objectclass=objectclasses.idoverrideuser + ssh_classes,
+                    ipaanchoruuid=[idoverrideuser1],
+                    ipaoriginaluid=[idoverrideuser1],
+                    description=[u'description'],
+                    homedirectory=[u'/home/newhome'],
+                    uid=[u'newlogin'],
+                    ipasshpubkey=[sshpubkey],
+                    sshpubkeyfp=[sshpubkeyfp],
+                )
+            ),
+        ),
+
+        dict(
+            desc='Modify User ID override "%s" to not override '
+                 'sshpubkey' % idoverrideuser1,
+            command=(
+                'idoverrideuser_mod',
+                [idview1, idoverrideuser1],
+                dict(ipasshpubkey=None, all=True)
+            ),
+            expected=dict(
+                value=idoverrideuser1,
+                summary=u'Modified an User ID override "%s"' % idoverrideuser1,
+                result=dict(
+                    dn=get_override_dn(idview1, idoverrideuser1),
+                    objectclass=objectclasses.idoverrideuser,
+                    ipaanchoruuid=[idoverrideuser1],
+                    ipaoriginaluid=[idoverrideuser1],
+                    description=[u'description'],
+                    homedirectory=[u'/home/newhome'],
+                    uid=[u'newlogin'],
+                )
+            ),
+        ),
+
+        dict(
             desc='Remove User ID override "%s"' % idoverrideuser1,
             command=('idoverrideuser_del', [idview1, idoverrideuser1], {}),
             expected=dict(
@@ -541,6 +600,7 @@ class test_idviews(Declarative):
                      homedirectory=u'/home/newhome',
                      uid=u'newlogin',
                      uidnumber=12345,
+                     ipasshpubkey=sshpubkey,
                 )
             ),
             expected=dict(
@@ -548,13 +608,15 @@ class test_idviews(Declarative):
                 summary=u'Added User ID override "%s"' % idoverrideuser1,
                 result=dict(
                     dn=get_override_dn(idview1, idoverrideuser1),
-                    objectclass=objectclasses.idoverrideuser,
+                    objectclass=objectclasses.idoverrideuser + ssh_classes,
                     ipaanchoruuid=[idoverrideuser1],
                     ipaoriginaluid=[idoverrideuser1],
                     description=[u'description'],
                     homedirectory=[u'/home/newhome'],
                     uidnumber=[u'12345'],
                     uid=[u'newlogin'],
+                    ipasshpubkey=[sshpubkey],
+                    sshpubkeyfp=[sshpubkeyfp],
                 )
             ),
         ),
-- 
2.1.0

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to