Rather than manually adding users to the default ipa users group configure automember to do it for us.

This was quite simple for new installs but a bit complex on upgrades so I implemented it as an update plugin.

I also added a unit test for the config module. The majority of config is ignored for now. I'm afraid we'd run into too many false positives if we test each element, and most of these just store data so there isn't a lot that can go wrong.

rob
>From 663901cf6c19d1d879853b4a46860ff5b4b484f6 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcrit...@redhat.com>
Date: Mon, 12 Dec 2011 22:58:57 -0500
Subject: [PATCH] Configure default user's group with automember

This adds an update plugin that ensures that the automember rule is
properly created for the default group.

A small test case was added for the config plugin.

https://fedorahosted.org/freeipa/ticket/1952
---
 ipalib/plugins/config.py                           |   18 ++-
 ipalib/plugins/user.py                             |    4 +-
 .../install/plugins/automember_default_user.py     |   55 +++++++
 tests/test_xmlrpc/test_config_plugin.py            |  170 ++++++++++++++++++++
 4 files changed, 243 insertions(+), 4 deletions(-)
 create mode 100644 ipaserver/install/plugins/automember_default_user.py
 create mode 100644 tests/test_xmlrpc/test_config_plugin.py

diff --git a/ipalib/plugins/config.py b/ipalib/plugins/config.py
index 0c238ac983c721d86b7ebf96ceb8670214e6f2ba..4f9e43bfc39c30fde394b8310868c9c50b5ddc40 100644
--- a/ipalib/plugins/config.py
+++ b/ipalib/plugins/config.py
@@ -201,7 +201,23 @@ class config_mod(LDAPUpdate):
         if 'ipadefaultprimarygroup' in entry_attrs:
             group=entry_attrs['ipadefaultprimarygroup']
             try:
-                api.Command['group_show'](group)
+                # We need to do the following:
+                #  1. Make sure the new group exists
+                #  2. Remove the uid=^.* condition from the current group
+                #  3. Create a automember rule for the new group
+                #  4. Add a uid=^.* condition to the new group
+                api.Command.group_show(group)
+                config = ldap.get_ipa_config()[1]
+                kw = dict(type=u'group', key=u'uid', automemberinclusiveregex=u'^.*')
+                try:
+                    api.Command.automember_remove_condition(config.get('ipadefaultprimarygroup')[0], **kw)
+                except errors.NotFound:
+                    pass
+                try:
+                    api.Command.automember_add(group, **kw)
+                except errors.DuplicateEntry:
+                    pass
+                api.Command.automember_add_condition(group, **kw)
             except errors.NotFound:
                 raise errors.NotFound(message=_("The group doesn't exist"))
         kw = {}
diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
index 70a111dd34c66ff22f906834a1348c65dbfd1bd5..173282d575a208b70e3674e19c711a6ee5ee0d38 100644
--- a/ipalib/plugins/user.py
+++ b/ipalib/plugins/user.py
@@ -459,10 +459,8 @@ class user_add(LDAPCreate):
 
     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
         config = ldap.get_ipa_config()[1]
-        # add the user we just created into the default primary group
+        # Automember adds our user to the default group for us.
         def_primary_group = config.get('ipadefaultprimarygroup')
-        group_dn = self.api.Object['group'].get_dn(def_primary_group)
-        ldap.add_entry_to_group(dn, group_dn)
         if self.api.env.wait_for_attr:
             newentry = wait_for_value(ldap, dn, 'memberOf', def_primary_group)
             entry_from_entry(entry_attrs, newentry)
diff --git a/ipaserver/install/plugins/automember_default_user.py b/ipaserver/install/plugins/automember_default_user.py
new file mode 100644
index 0000000000000000000000000000000000000000..9be9d535b5cecd5cb17aede94aeaa68357c2fa37
--- /dev/null
+++ b/ipaserver/install/plugins/automember_default_user.py
@@ -0,0 +1,55 @@
+# Authors:
+#   Rob Crittenden <rcrit...@redhat.com>
+#
+# Copyright (C) 2011  Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from ipaserver.install.plugins import PRE_UPDATE, MIDDLE
+from ipaserver.install.plugins.baseupdate import PreUpdate
+from ipaserver.install.plugins import baseupdate
+from ipalib import api, errors
+
+class update_automember_default_user_pre(PreUpdate):
+    """
+    Create the automember default group entry if it doesn't exist.
+
+    Examine the IPA configuration to determine the default user group then
+    create the automember rule from that.
+    """
+    order=MIDDLE
+
+    def execute(self, **options):
+        ldap = self.obj.backend
+
+        config = ldap.get_ipa_config()[1]
+        def_group = config.get('ipadefaultprimarygroup')[0]
+        kw = dict(type=u'group')
+        try:
+            api.Command.automember_show(def_group, **kw)
+            self.log.info('automember %s exists' % def_group)
+        except errors.NotFound:
+            if options.get('live_run', False):
+                self.log.info('Adding automember %s' % def_group)
+                api.Command.automember_add(def_group, **kw)
+                kw['automemberinclusiveregex'] = u'^.*'
+                kw['key'] = u'uid'
+                api.Command.automember_add_condition(def_group, **kw)
+            else:
+                self.log.info('Not live run, skip adding automember %s' % def_group)
+
+        return (False, False, [])
+
+api.register(update_automember_default_user_pre)
diff --git a/tests/test_xmlrpc/test_config_plugin.py b/tests/test_xmlrpc/test_config_plugin.py
new file mode 100644
index 0000000000000000000000000000000000000000..4bd5fd0e2870c0c8d0b24287b4c4e741435d4c36
--- /dev/null
+++ b/tests/test_xmlrpc/test_config_plugin.py
@@ -0,0 +1,170 @@
+# Authors:
+#   Rob Crittenden <rcrit...@redhat.com>
+#
+# Copyright (C) 2011  Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+Test the `ipalib/plugins/configpy` module.
+"""
+
+from ipalib import api, errors
+from tests.test_xmlrpc import objectclasses
+from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_string
+from ipalib.dn import *
+
+# config is a bit of a special case. This is something likely to
+# be changed frequently by devs so simply comparing to a known good
+# isn't going to work very well. I'm going to skip those simpler
+# cases for now and focus on the more complex interactions.
+
+class test_group(Declarative):
+    cleanup_commands = [
+        ('automember_del', [u'editors'], {'type': u'group'}),
+    ]
+
+    tests = [
+
+        dict(
+            desc='Set config default group to non-existent group',
+            command=(
+                'config_mod', [], dict(ipadefaultprimarygroup=u'notfound')
+            ),
+            expected=errors.NotFound(reason='no such entry'),
+        ),
+
+
+        dict(
+            desc='Set default group to editors',
+            command=('config_mod', [], dict(ipadefaultprimarygroup=u'editors')),
+            expected=dict(
+                value=u'',
+                summary=None,
+                result=dict(
+                    ipadefaultloginshell=[fuzzy_string],
+                    ipacertificatesubjectbase=[fuzzy_string],
+                    ipausersearchfields=[fuzzy_string],
+                    ipaselinuxusermapdefault=[fuzzy_string],
+                    ipadefaultprimarygroup=[u'editors'],
+                    ipapwdexpadvnotify=[fuzzy_digits],
+                    ipagroupsearchfields=[fuzzy_string],
+                    ipadefaultemaildomain=[fuzzy_string],
+                    ipahomesrootdir=[fuzzy_string],
+                    ipasearchtimelimit=[fuzzy_digits],
+                    ipamigrationenabled=[fuzzy_string],
+                    ipasearchrecordslimit=[fuzzy_digits],
+                    ipamaxusernamelength=[fuzzy_digits],
+                    ipaselinuxusermaporder=[fuzzy_string]
+                ),
+            ),
+        ),
+
+
+        dict(
+            desc='Verify that automember for default is correct',
+            command=('automember_show', [u'editors'], dict(type=u'group')),
+            expected=dict(
+                value=u'editors',
+                summary=None,
+                result=dict(
+                    cn=[u'editors'],
+                    automembertargetgroup=[u'cn=editors,cn=groups,cn=accounts,dc=greyoak,dc=com'],
+                    automemberinclusiveregex=[u'uid=^.*'],
+                    dn=lambda x: DN(x) == \
+                        DN(('cn','editors'),('cn','group'),('cn','automember'),
+                           ('cn','etc'),api.env.basedn),
+                ),
+            ),
+        ),
+
+
+        dict(
+            desc='Verify that automember regex was removed from ipausers',
+            command=('automember_show', [u'ipausers'], dict(type=u'group')),
+            expected=dict(
+                value=u'ipausers',
+                summary=None,
+                result=dict(
+                    cn=[u'ipausers'],
+                    automembertargetgroup=[u'cn=ipausers,cn=groups,cn=accounts,dc=greyoak,dc=com'],
+                    dn=lambda x: DN(x) == \
+                        DN(('cn','ipausers'),('cn','group'),('cn','automember'),
+                           ('cn','etc'),api.env.basedn),
+                ),
+            ),
+        ),
+
+
+        dict(
+            desc='Set default group back to ipausers',
+            command=('config_mod', [], dict(ipadefaultprimarygroup=u'ipausers')),
+            expected=dict(
+                value=u'',
+                summary=None,
+                result=dict(
+                    ipadefaultloginshell=[fuzzy_string],
+                    ipacertificatesubjectbase=[fuzzy_string],
+                    ipausersearchfields=[fuzzy_string],
+                    ipaselinuxusermapdefault=[fuzzy_string],
+                    ipadefaultprimarygroup=[u'ipausers'],
+                    ipapwdexpadvnotify=[fuzzy_digits],
+                    ipagroupsearchfields=[fuzzy_string],
+                    ipadefaultemaildomain=[fuzzy_string],
+                    ipahomesrootdir=[fuzzy_string],
+                    ipasearchtimelimit=[fuzzy_digits],
+                    ipamigrationenabled=[fuzzy_string],
+                    ipasearchrecordslimit=[fuzzy_digits],
+                    ipamaxusernamelength=[fuzzy_digits],
+                    ipaselinuxusermaporder=[fuzzy_string]
+                ),
+            ),
+        ),
+
+
+        dict(
+            desc='Verify that automember for default is correct',
+            command=('automember_show', [u'ipausers'], dict(type=u'group')),
+            expected=dict(
+                value=u'ipausers',
+                summary=None,
+                result=dict(
+                    cn=[u'ipausers'],
+                    automembertargetgroup=[u'cn=ipausers,cn=groups,cn=accounts,dc=greyoak,dc=com'],
+                    automemberinclusiveregex=[u'uid=^.*'],
+                    dn=lambda x: DN(x) == \
+                        DN(('cn','ipausers'),('cn','group'),('cn','automember'),
+                           ('cn','etc'),api.env.basedn),
+                ),
+            ),
+        ),
+
+
+        dict(
+            desc='Verify that automember regex was removed from editors',
+            command=('automember_show', [u'editors'], dict(type=u'group')),
+            expected=dict(
+                value=u'editors',
+                summary=None,
+                result=dict(
+                    cn=[u'editors'],
+                    automembertargetgroup=[u'cn=editors,cn=groups,cn=accounts,dc=greyoak,dc=com'],
+                    dn=lambda x: DN(x) == \
+                        DN(('cn','editors'),('cn','group'),('cn','automember'),
+                           ('cn','etc'),api.env.basedn),
+                ),
+            ),
+        ),
+
+    ]
-- 
1.7.6

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

Reply via email to