[Freeipa-devel] [PATCH] edit nested groups

Kevin McCarthy kmccarth at redhat.com
Thu Sep 27 21:55:35 UTC 2007


This patch adds nested groups support to the UI.  'nough said.  :-)

Depends on freeipa-221-groupedit_use_dns.patch

-Kevin

-------------- next part --------------
# HG changeset patch
# User Kevin McCarthy <kmccarth at redhat.com>
# Date 1190929895 25200
# Node ID a716a9835fd763d700d4f697f9ea20328344c64b
# Parent  d9bfdc313e9522daeaa5cfdcc9295da12190003d
Adds nested group handling to the view and edit group pages.
Renames the ajax seach page, because it's tightly bound to the group edit page.
This isn't super polished, but the basic functionality is there.

diff -r d9bfdc313e95 -r a716a9835fd7 ipa-server/ipa-gui/ipagui/controllers.py
--- a/ipa-server/ipa-gui/ipagui/controllers.py	Thu Sep 27 11:27:33 2007 -0700
+++ b/ipa-server/ipa-gui/ipagui/controllers.py	Thu Sep 27 14:51:35 2007 -0700
@@ -224,26 +224,6 @@ class Root(controllers.RootController):
 
         return dict(users=users, uid=uid, fields=forms.user.UserFields())
 
-    @expose("ipagui.templates.userlistajax")
-    @identity.require(identity.not_anonymous())
-    def userlist_ajax(self, **kw):
-        """Searches for users and displays list of results in a table.
-           This method is used for ajax calls."""
-        client.set_krbccache(os.environ["KRB5CCNAME"])
-        users = []
-        searchlimit = 100
-        uid = kw.get('uid')
-        if uid != None and len(uid) > 0:
-            try:
-                users = client.find_users(uid.encode('utf-8'), None, searchlimit)
-                counter = users[0]
-                users = users[1:]
-            except ipaerror.IPAError, e:
-                turbogears.flash("User list failed: " + str(e))
-
-        return dict(users=users, uid=uid, fields=forms.user.UserFields(),
-                counter=counter)
-
 
     @expose("ipagui.templates.usershow")
     @identity.require(identity.not_anonymous())
@@ -433,6 +413,40 @@ class Root(controllers.RootController):
         except ipaerror.IPAError, e:
             turbogears.flash("Group add failed: " + str(e) + "<br/>" + str(e.detail))
             return dict(form=group_new_form, tg_template='ipagui.templates.groupnew')
+
+    @expose("ipagui.templates.groupeditsearch")
+    @identity.require(identity.not_anonymous())
+    def groupedit_search(self, **kw):
+        """Searches for users+groups and displays list of results in a table.
+           This method is used for the ajax search on the group edit page.
+           It's not re-usable because the ajax/dom manipulation is tightly
+           bound to the groupedit page"""
+        client.set_krbccache(os.environ["KRB5CCNAME"])
+        users = []
+        groups = []
+        counter = 0
+        searchlimit = 100
+        criteria = kw.get('criteria')
+        if criteria != None and len(criteria) > 0:
+            try:
+                users = client.find_users(criteria.encode('utf-8'), None, searchlimit)
+                users_counter = users[0]
+                users = users[1:]
+
+                groups = client.find_groups(criteria.encode('utf-8'), None,
+                        searchlimit)
+                groups_counter = groups[0]
+                groups = groups[1:]
+
+                if users_counter < 0 or groups_counter < 0:
+                    counter = -1
+                else:
+                    counter = users_counter + groups_counter
+            except ipaerror.IPAError, e:
+                turbogears.flash("search failed: " + str(e))
+
+        return dict(users=users, groups=groups, criteria=criteria,
+                counter=counter)
 
 
     @expose("ipagui.templates.groupedit")
@@ -461,13 +475,15 @@ class Root(controllers.RootController):
                 member_dns = [member_dns]
 
             # TODO: convert this into an efficient (single) function call
-            member_users = map(
-                    lambda dn: client.get_user_by_dn(dn, ['givenname', 'sn', 'uid']),
+            # Note: this isn't quite right, since it can be users and groups.
+            members = map(
+                    lambda dn: client.get_user_by_dn(dn, ['dn', 'givenname', 'sn',
+                        'uid', 'cn']),
                     member_dns)
 
             # Map users into an array of dicts, which can be serialized
             # (so we don't have to do this on each round trip)
-            member_dicts = map(lambda user: user.toDict(), member_users)
+            member_dicts = map(lambda member: member.toDict(), members)
 
             # store a copy of the original group for the update later
             group_data = b64encode(dumps(group_dict))
@@ -526,7 +542,7 @@ class Root(controllers.RootController):
                 #
                 kw['group_orig'] = b64encode(dumps(new_group.toDict()))
         except ipaerror.IPAError, e:
-            turbogears.flash("User update failed: " + str(e))
+            turbogears.flash("Group update failed: " + str(e))
             return dict(form=group_edit_form, group=kw, members=member_dicts,
                         tg_template='ipagui.templates.groupedit')
 
@@ -543,7 +559,7 @@ class Root(controllers.RootController):
                         utf8_encode_values(dnadds), kw.get('cn'))
                 kw['dnadd'] = failed_adds
         except ipaerror.IPAError, e:
-            turbogears.flash("User update failed: " + str(e))
+            turbogears.flash("Group update failed: " + str(e))
             return dict(form=group_edit_form, group=kw, members=member_dicts,
                         tg_template='ipagui.templates.groupedit')
 
@@ -560,7 +576,7 @@ class Root(controllers.RootController):
                         utf8_encode_values(dndels), kw.get('cn'))
                 kw['dndel'] = failed_dels
         except ipaerror.IPAError, e:
-            turbogears.flash("User update failed: " + str(e))
+            turbogears.flash("Group update failed: " + str(e))
             return dict(form=group_edit_form, group=kw, members=member_dicts,
                         tg_template='ipagui.templates.groupedit')
 
@@ -627,10 +643,12 @@ class Root(controllers.RootController):
                 member_dns = [member_dns]
 
             # TODO: convert this into an efficient (single) function call
-            member_users = map(
-                    lambda dn: client.get_user_by_dn(dn, ['givenname', 'sn', 'uid']),
+            # Note: this isn't quite right, since it can be users and groups.
+            members = map(
+                    lambda dn: client.get_user_by_dn(dn, ['dn', 'givenname', 'sn',
+                        'uid', 'cn']),
                     member_dns)
-            member_dicts = map(lambda user: user.toDict(), member_users)
+            member_dicts = map(lambda member: member.toDict(), members)
 
             return dict(group=group_dict, fields=forms.group.GroupFields(),
                     members = member_dicts)
diff -r d9bfdc313e95 -r a716a9835fd7 ipa-server/ipa-gui/ipagui/templates/groupeditform.kid
--- a/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid	Thu Sep 27 11:27:33 2007 -0700
+++ b/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid	Thu Sep 27 14:51:35 2007 -0700
@@ -8,7 +8,7 @@ from ipagui.helpers import ipahelper
 ?>
 
 
-  <?python searchurl = tg.url('/userlist_ajax') ?>
+  <?python searchurl = tg.url('/groupedit_search') ?>
 
   <script type="text/javascript">
     // this is used for round-trip recontruction of the names.
@@ -47,7 +47,7 @@ from ipagui.helpers import ipahelper
       Element.remove(effect.element);
     }
 
-    function adduser(dn, cn) {
+    function addmember(dn, cn) {
       dn_to_cn_hash[dn] = cn;
 
       if ((added_hash[dn] == 1) || (member_hash[dn] == 1)) {
@@ -80,8 +80,8 @@ from ipagui.helpers import ipahelper
       return newdiv
     }
 
-    function adduserHandler(element, dn, cn) {
-      var newdiv = adduser(dn, cn)
+    function addmemberHandler(element, dn, cn) {
+      var newdiv = addmember(dn, cn)
       if (newdiv != null) {
         new Effect.Fade(Element.up(element));
         new Effect.Appear(newdiv);
@@ -89,7 +89,7 @@ from ipagui.helpers import ipahelper
       }
     }
 
-    function removeuser(dn, cn) {
+    function removemember(dn, cn) {
       dn_to_cn_hash[dn] = cn;
 
       var newdiv = document.createElement('div');
@@ -118,8 +118,8 @@ from ipagui.helpers import ipahelper
       return newdiv
     }
 
-    function removeuserHandler(element, dn, cn) {
-      var newdiv = removeuser(dn, cn);
+    function removememberHandler(element, dn, cn) {
+      var newdiv = removemember(dn, cn);
       new Effect.Fade(Element.up(element));
       new Effect.Appear(newdiv);
       /* Element.up(element).remove(); */
@@ -145,7 +145,7 @@ from ipagui.helpers import ipahelper
       new Ajax.Updater('searchresults',
           '${searchurl}',
           {  asynchronous:true,
-             parameters: { uid: $('uid').value },
+             parameters: { criteria: $('criteria').value },
              evalScripts: true });
       return false;
     }
@@ -224,16 +224,17 @@ from ipagui.helpers import ipahelper
           member_dn_esc = ipahelper.javascript_string_escape(member_dn)
 
           member_uid = member.get('uid')
-          member_uid_esc = ipahelper.javascript_string_escape(member_uid)
-
-          member_name = "%s %s" % (member.get('givenname', ''),
-                                   member.get('sn', ''))
-          member_name_esc = ipahelper.javascript_string_escape(member_name)
+          if member_uid:
+              member_cn = "%s %s (%s)" % (member.get('givenName'),
+                                          member.get('sn'),
+                                          member.get('uid'))
+          else:
+              member_cn = "%s [group]" % member.get('cn')
+          member_cn_esc = ipahelper.javascript_string_escape(member_cn)
           ?>
-          ${member_name} (${member_uid})
+          ${member_cn}
           <a href="#" 
-            onclick="removeuserHandler(this, '${member_dn_esc}',
-                                       '${member_name_esc} (${member_uid_esc})');
+            onclick="removememberHandler(this, '${member_dn_esc}', '${member_cn_esc}');
                      return false;"
           >remove</a>
           <script type="text/javascript">
@@ -249,7 +250,7 @@ from ipagui.helpers import ipahelper
     </div>
 
     <div style="clear:both">
-      <div class="formsection">Add Persons</div>
+      <div class="formsection">Add Members</div>
 
       <div class="floatlist">
         <div class="floatheader">To Add:</div>
@@ -259,9 +260,9 @@ from ipagui.helpers import ipahelper
 
       <div>
         <div id="search">
-          <input id="uid" type="text" name="uid"
+          <input id="criteria" type="text" name="criteria"
             onkeypress="return enterDoSearch(event);" />
-          <input type="button" value="Find Users"
+          <input type="button" value="Find"
             onclick="return doSearch();"
           />
         </div>
@@ -320,7 +321,7 @@ from ipagui.helpers import ipahelper
     ?>
     var dn = "${dnadd_esc}";
     var cn = dn_to_cn_hash[dn];
-    var newdiv = adduser(dn, cn);
+    var newdiv = addmember(dn, cn);
     if (newdiv != null) {
       newdiv.style.display = 'block';
     }
@@ -332,7 +333,7 @@ from ipagui.helpers import ipahelper
     ?>
     var dn = "${dndel_esc}";
     var cn = dn_to_cn_hash[dn];
-    var newdiv = removeuser(dn, cn);
+    var newdiv = removemember(dn, cn);
     newdiv.style.display = 'block';
     orig_div_id = dn_to_member_div_id[dn]
     $(orig_div_id).style.display = 'none';
diff -r d9bfdc313e95 -r a716a9835fd7 ipa-server/ipa-gui/ipagui/templates/groupeditsearch.kid
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ipa-server/ipa-gui/ipagui/templates/groupeditsearch.kid	Thu Sep 27 14:51:35 2007 -0700
@@ -0,0 +1,59 @@
+<div xmlns:py="http://purl.org/kid/ns#">
+
+<?python
+from ipagui.helpers import ipahelper
+?>
+    <div id="search-results-count">
+    </div>
+    <?python
+    criteria_esc = ipahelper.javascript_string_escape(criteria)
+    ?>
+    <script type="text/javascript">
+      search_string = "${criteria_esc}";
+      results_counter = 0;
+    </script>
+    <?python search_div_counter = 1 ?>
+    <div py:for="entities in (users, groups)">
+      <div py:if='(entities != None) and (len(entities) > 0)'>
+          <div py:for="entity in entities" id="search-${search_div_counter}">
+            <?python
+            ent_dn_esc = ipahelper.javascript_string_escape(entity.dn)
+            ent_uid = entity.uid
+            if ent_uid:
+                ent_cn = "%s %s (%s)" % (entity.givenName, entity.sn, entity.uid)
+            else:
+                ent_cn = "%s [group]" % entity.cn
+            ent_cn_esc = ipahelper.javascript_string_escape(ent_cn)
+            ?>
+            <script type="text/javascript">
+              if ((added_hash["${ent_dn_esc}"] == 1) ||
+                  (member_hash["${ent_dn_esc}"] == 1)) {
+                $("search-${search_div_counter}").style.display = 'none';
+              } else {
+                results_counter = results_counter + 1;
+              }
+            </script>
+            ${ent_cn}
+            <a href=""
+              onclick="addmemberHandler(this, '${ent_dn_esc}', '${ent_cn_esc}');
+                      return false;"
+            >add</a>
+            <?python
+            search_div_counter = search_div_counter + 1
+            ?>
+          </div>
+      </div>
+    </div>
+    <script type="text/javascript">
+      if (results_counter == 0) {
+        var message = "No results found for " + search_string;
+      } else {
+        var message =  results_counter + " results found:";
+      }
+      $('search-results-count').appendChild(document.createTextNode(message));
+    </script>
+    <script py:if="counter < 0">
+      $('search-results-count').appendChild(document.createTextNode(
+        " (truncated)"));
+    </script>
+</div>
diff -r d9bfdc313e95 -r a716a9835fd7 ipa-server/ipa-gui/ipagui/templates/groupshow.kid
--- a/ipa-server/ipa-gui/ipagui/templates/groupshow.kid	Thu Sep 27 11:27:33 2007 -0700
+++ b/ipa-server/ipa-gui/ipagui/templates/groupshow.kid	Thu Sep 27 14:51:35 2007 -0700
@@ -35,12 +35,19 @@
     <div class="formsection">Group Members</div>
     <div py:for="member in members">
       <?python
-      member_name = "%s %s" % (member.get('givenname', ''),
-                               member.get('sn', ''))
+
       member_uid = member.get('uid')
+      if member_uid:
+          member_cn = "%s %s" % (member.get('givenName'), member.get('sn'))
+          member_desc = "(%s)" % member_uid
+          view_url = tg.url('usershow', uid=member_uid)
+      else:
+          member_cn = "%s" % member.get('cn')
+          member_desc = "[group]"
+          view_url = tg.url('groupshow', cn=member_cn)
       ?>
-      <a href="${tg.url('usershow', uid=member_uid)}"
-        >${member_name}</a> (${member_uid})
+      <a href="${view_url}"
+        >${member_cn}</a> ${member_desc}
     </div>
 
     <br/>
diff -r d9bfdc313e95 -r a716a9835fd7 ipa-server/ipa-gui/ipagui/templates/userlistajax.kid
--- a/ipa-server/ipa-gui/ipagui/templates/userlistajax.kid	Thu Sep 27 11:27:33 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-<div xmlns:py="http://purl.org/kid/ns#">
-
-<?python
-from ipagui.helpers import ipahelper
-?>
-    <div id="search-results-count">
-    </div>
-    <?python
-    criteria_esc = ipahelper.javascript_string_escape(uid)
-    ?>
-    <script type="text/javascript">
-      search_string = "${criteria_esc}";
-      results_counter = 0;
-    </script>
-    <?python search_div_counter = 1 ?>
-    <div py:if='(users != None) and (len(users) > 0)'>
-        <div py:for="user in users" id="search-${search_div_counter}">
-          <?python
-          user_dn_esc = ipahelper.javascript_string_escape(user.dn)
-          user_uid_esc = ipahelper.javascript_string_escape(user.uid)
-          user_cn_esc = ipahelper.javascript_string_escape(user.cn)
-          ?>
-          <script type="text/javascript">
-            if ((added_hash["${user_dn_esc}"] == 1) ||
-                (member_hash["${user_dn_esc}"] == 1)) {
-              $("search-${search_div_counter}").style.display = 'none';
-            } else {
-              results_counter = results_counter + 1;
-            }
-          </script>
-          ${user.givenName} ${user.sn} (${user.uid})
-          <a href=""
-            onclick="adduserHandler(this, '${user_dn_esc}',
-                                   '${user_cn_esc} (${user_uid_esc})');
-                     return false;"
-          >add</a>
-          <?python
-          search_div_counter = search_div_counter + 1
-          ?>
-        </div>
-    </div>
-    <script type="text/javascript">
-      if (results_counter == 0) {
-        var message = "No results found for " + search_string;
-      } else {
-        var message =  results_counter + " results found:";
-      }
-      $('search-results-count').appendChild(document.createTextNode(message));
-    </script>
-    <script py:if="counter < 0">
-      $('search-results-count').appendChild(document.createTextNode(
-        " (truncated)"));
-    </script>
-</div>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 4054 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/freeipa-devel/attachments/20070927/d678511e/attachment.bin>


More information about the Freeipa-devel mailing list