[Freeipa-devel] [PATCH] basic group list/show/edit

Kevin McCarthy kmccarth at redhat.com
Wed Sep 12 17:37:58 UTC 2007


This is the initial framework for group list/show/edit.  Just wanted to
get it out of the way in an initial patch so the interesting stuff is
more apparent later.

Lot's still to do - specifically group member management and search
improvements (ala user search).

-Kevin

-------------- next part --------------
# HG changeset patch
# User Kevin McCarthy <kmccarth at redhat.com>
# Date 1189618831 25200
# Node ID c87fc8161f0439834fdbd8c1d381c7cb25f65ed4
# Parent  0bf55b38d551f2fae8902b9c882e1c5802ea5c62
Group edit page

diff -r 0bf55b38d551 -r c87fc8161f04 ipa-server/ipa-gui/ipagui/controllers.py
--- a/ipa-server/ipa-gui/ipagui/controllers.py	Tue Sep 11 02:48:53 2007 -0400
+++ b/ipa-server/ipa-gui/ipagui/controllers.py	Wed Sep 12 10:40:31 2007 -0700
@@ -34,6 +34,8 @@ client = ipa.ipaclient.IPAClient(True)
 
 user_fields = ['*', 'nsAccountLock']
 
+group_fields = ['*']
+
 def restrict_post():
     if cherrypy.request.method != "POST":
         turbogears.flash("This method only accepts posts")
@@ -58,7 +60,7 @@ class Root(controllers.RootController):
         if kw.get('searchtype') == "Users":
             return self.userlist(uid=kw.get('searchvalue'))
         else:
-            return self.index()
+            return self.grouplist(criteria=kw.get('searchvalue'))
 
 
 
@@ -160,9 +162,9 @@ class Root(controllers.RootController):
             if kw.get('userpassword'):
                 new_user.setValue('userpassword', kw.get('userpassword'))
             if kw.get('uidnumber'):
-                new_user.setValue('uidnumber', kw.get('uidnumber'))
+                new_user.setValue('uidnumber', str(kw.get('uidnumber')))
             if kw.get('gidnumber'):
-                new_user.setValue('gidnumber', kw.get('gidnumber'))
+                new_user.setValue('gidnumber', str(kw.get('gidnumber')))
 
             #
             # this is a hack until we decide on the policy for names/cn/sn/givenName
@@ -183,7 +185,7 @@ class Root(controllers.RootController):
     @expose("ipagui.templates.userlist")
     @identity.require(identity.not_anonymous())
     def userlist(self, **kw):
-        """Retrieve a list of all users and display them in one huge list"""
+        """Searches for users and displays list of results"""
         client.set_principal(identity.current.user_name)
         users = None
         counter = 0
@@ -379,6 +381,88 @@ class Root(controllers.RootController):
             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.groupedit")
+    @identity.require(identity.not_anonymous())
+    def groupedit(self, cn, tg_errors=None):
+        """Displays the edit group form"""
+        if tg_errors:
+            turbogears.flash("There was a problem with the form!")
+
+        client.set_principal(identity.current.user_name)
+        group = client.get_group_by_cn(cn, group_fields)
+        group_dict = group.toDict()
+
+        # store a copy of the original group for the update later
+        group_data = b64encode(dumps(group_dict))
+        group_dict['group_orig'] = group_data
+        return dict(form=group_edit_form, group=group_dict)
+
+    @expose()
+    @identity.require(identity.not_anonymous())
+    def groupupdate(self, **kw):
+        """Updates an existing group"""
+        restrict_post()
+        client.set_principal(identity.current.user_name)
+        if kw.get('submit') == 'Cancel Edit':
+            turbogears.flash("Edit group cancelled")
+            raise turbogears.redirect('/groupshow', cn=kw.get('cn'))
+
+        tg_errors, kw = self.groupupdatevalidate(**kw)
+        if tg_errors:
+            return dict(form=group_edit_form, group=kw,
+                        tg_template='ipagui.templates.groupedit')
+
+        try:
+            orig_group_dict = loads(b64decode(kw.get('group_orig')))
+
+            new_group = ipa.group.Group(orig_group_dict)
+            new_group.setValue('description', kw.get('description'))
+            if kw.get('gidnumber'):
+                new_group.setValue('gidnumber', str(kw.get('gidnumber')))
+
+            rv = client.update_group(new_group)
+            turbogears.flash("%s updated!" % kw['cn'])
+            raise turbogears.redirect('/groupshow', cn=kw['cn'])
+        except ipaerror.IPAError, e:
+            turbogears.flash("User update failed: " + str(e))
+            return dict(form=group_edit_form, group=kw,
+                        tg_template='ipagui.templates.groupedit')
+
+    @expose("ipagui.templates.grouplist")
+    @identity.require(identity.not_anonymous())
+    def grouplist(self, **kw):
+        """Search for groups and display results"""
+        client.set_principal(identity.current.user_name)
+        groups = None
+        # counter = 0
+        criteria = kw.get('criteria')
+        if criteria != None and len(criteria) > 0:
+            try:
+                groups = client.find_groups(criteria.encode('utf-8'))
+                # counter = groups[0]
+                # groups = groups[1:]
+                # if counter == -1:
+                #     turbogears.flash("These results are truncated.<br />" +
+                #                     "Please refine your search and try again.")
+            except ipaerror.IPAError, e:
+                turbogears.flash("Find groups failed: " + str(e))
+                raise turbogears.redirect("/grouplist")
+
+        return dict(groups=groups, criteria=criteria, fields=forms.group.GroupFields())
+
+    @expose("ipagui.templates.groupshow")
+    @identity.require(identity.not_anonymous())
+    def groupshow(self, cn):
+        """Retrieve a single group for display"""
+        client.set_principal(identity.current.user_name)
+        try:
+            group = client.get_group_by_cn(cn, group_fields)
+            return dict(group=group.toDict(), fields=forms.group.GroupFields())
+        except ipaerror.IPAError, e:
+            turbogears.flash("Group show failed: " + str(e))
+            raise turbogears.redirect("/")
+
     @validate(form=group_new_form)
     @identity.require(identity.not_anonymous())
     def groupcreatevalidate(self, tg_errors=None, **kw):
diff -r 0bf55b38d551 -r c87fc8161f04 ipa-server/ipa-gui/ipagui/forms/group.py
--- a/ipa-server/ipa-gui/ipagui/forms/group.py	Tue Sep 11 02:48:53 2007 -0400
+++ b/ipa-server/ipa-gui/ipagui/forms/group.py	Wed Sep 12 10:40:31 2007 -0700
@@ -32,13 +32,15 @@ class GroupNewForm(widgets.Form):
 
 
 class GroupEditValidator(validators.Schema):
-    gidnumber = widgets.TextField(name="gidnumber", label="GID")
-    description = widgets.TextField(name="description", label="Description")
+    gidnumber = validators.Int(not_empty=False)
+    description = validators.String(not_empty=False)
 
 class GroupEditForm(widgets.Form):
     params = ['group']
 
-    fields = [GroupFields.gidnumber, GroupFields.description]
+    fields = [GroupFields.gidnumber, GroupFields.description,
+              GroupFields.cn_hidden,
+              GroupFields.group_orig]
 
     validator = GroupEditValidator()
 
diff -r 0bf55b38d551 -r c87fc8161f04 ipa-server/ipa-gui/ipagui/templates/groupedit.kid
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ipa-server/ipa-gui/ipagui/templates/groupedit.kid	Wed Sep 12 10:40:31 2007 -0700
@@ -0,0 +1,21 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#"
+    py:extends="'grouplayout.kid'">
+<head>
+    <meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/>
+    <title>Edit Group</title>
+</head>
+<body>
+  <div>
+    <div style="float:right">
+      <input type="checkbox"
+          onclick="toggleProtectedFields(this);">
+        <span class="small">edit protected fields</span>
+      </input>
+    </div>
+    <h2>Edit Group</h2>
+  </div>
+
+  ${form.display(action="groupupdate", value=group)}
+</body>
+</html>
diff -r 0bf55b38d551 -r c87fc8161f04 ipa-server/ipa-gui/ipagui/templates/groupeditform.kid
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid	Wed Sep 12 10:40:31 2007 -0700
@@ -0,0 +1,82 @@
+<div xmlns:py="http://purl.org/kid/ns#"
+  class="simpleroster">
+  <form action="${action}" name="${name}" method="${method}" class="tableform">
+
+  <script type="text/javascript">
+    function toggleProtectedFields(checkbox) {
+      gidnumberField = document.getElementById('form_gidnumber');
+      if (checkbox.checked) {
+        gidnumberField.disabled = false;
+      } else {
+        gidnumberField.disabled = true;
+      }
+    }
+  </script>
+
+    <div py:for="field in hidden_fields"
+      py:replace="field.display(value_for(field), **params_for(field))" 
+      />
+
+    <div class="formsection">Group Details</div>
+    <table class="formtable" cellpadding="2" cellspacing="0" border="0">
+      <tr>
+        <th>
+          <label class="fieldlabel" for="${group.cn.field_id}"
+            py:content="group.cn.label" />:
+        </th>
+        <td>
+          <!-- <span py:replace="group.cn.display(value_for(group.cn))" />
+          <span py:if="tg.errors.get('cn')" class="fielderror"
+              py:content="tg.errors.get('cn')" /> -->
+          ${value_for(group.cn)}
+
+        </td>
+      </tr>
+
+      <tr>
+        <th>
+          <label class="fieldlabel" for="${group.description.field_id}"
+            py:content="group.description.label" />:
+        </th>
+        <td>
+          <span py:replace="group.description.display(value_for(group.description))" />
+          <span py:if="tg.errors.get('description')" class="fielderror"
+              py:content="tg.errors.get('description')" />
+
+        </td>
+      </tr>
+
+      <tr>
+        <th>
+          <label class="fieldlabel" for="${group.gidnumber.field_id}"
+            py:content="group.gidnumber.label" />:
+        </th>
+        <td>
+          <span py:replace="group.gidnumber.display(value_for(group.gidnumber))" />
+          <span py:if="tg.errors.get('gidnumber')" class="fielderror"
+              py:content="tg.errors.get('gidnumber')" />
+
+          <script type="text/javascript">
+              document.getElementById('form_gidnumber').disabled = true;
+          </script>
+        </td>
+      </tr>
+    </table>
+
+    <table class="formtable" cellpadding="2" cellspacing="0" border="0">
+      <tr>
+        <th>
+          <br />
+          <input type="submit" class="submitbutton" name="submit"
+              value="Update Group"/>
+        </th>
+        <td>
+          <br />
+          <input type="submit" class="submitbutton" name="submit"
+              value="Cancel Edit" />
+        </td>
+      </tr>
+    </table>
+
+  </form>
+</div>
diff -r 0bf55b38d551 -r c87fc8161f04 ipa-server/ipa-gui/ipagui/templates/grouplist.kid
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ipa-server/ipa-gui/ipagui/templates/grouplist.kid	Wed Sep 12 10:40:31 2007 -0700
@@ -0,0 +1,43 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#"
+    py:extends="'grouplayout.kid'">
+<head>
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/>
+<title>Find Groups</title>
+</head>
+<body>
+    <div id="search">
+        <form action="${tg.url('/grouplist')}" method="post">
+            <input id="criteria" type="text" name="criteria" value="${criteria}" />
+            <input type="submit" value="Find Groups"/>
+        </form>
+        <script type="text/javascript">
+            document.getElementById("criteria").focus();
+        </script>
+    </div>
+    <div py:if='(groups != None) and (len(groups) > 0)'>
+        <h2>${len(groups)} results returned:</h2>
+        <table id="resultstable">
+            <tr>
+                <th>
+                    <label class="fieldlabel" py:content="fields.cn.label" />
+                </th>
+                <th>
+                    <label class="fieldlabel" py:content="fields.description.label" />
+                </th>
+            </tr>
+            <tr py:for="group in groups">
+                <td>
+                    <a href="${tg.url('/groupshow',cn=group.cn)}">${group.cn}</a>
+                </td>
+                <td>
+                    ${group.description}
+                </td>
+            </tr>
+        </table>
+    </div>
+    <div py:if='(groups != None) and (len(groups) == 0)'>
+        <h2>No results found for "${criteria}"</h2>
+    </div>
+</body>
+</html>
diff -r 0bf55b38d551 -r c87fc8161f04 ipa-server/ipa-gui/ipagui/templates/groupnew.kid
--- a/ipa-server/ipa-gui/ipagui/templates/groupnew.kid	Tue Sep 11 02:48:53 2007 -0400
+++ b/ipa-server/ipa-gui/ipagui/templates/groupnew.kid	Wed Sep 12 10:40:31 2007 -0700
@@ -1,6 +1,6 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#"
-    py:extends="'userlayout.kid'">
+    py:extends="'grouplayout.kid'">
 <head>
     <meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/>
     <title>Add Group</title>
diff -r 0bf55b38d551 -r c87fc8161f04 ipa-server/ipa-gui/ipagui/templates/groupshow.kid
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ipa-server/ipa-gui/ipagui/templates/groupshow.kid	Wed Sep 12 10:40:31 2007 -0700
@@ -0,0 +1,38 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#"
+    py:extends="'grouplayout.kid'">
+<head>
+    <meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/>
+    <title>View Group</title>
+</head>
+<body>
+    <h2>View Group</h2>
+
+    <div class="formsection">Group Details</div>
+    <table class="formtable" cellpadding="2" cellspacing="0" border="0">
+        <tr>
+          <th>
+            <label class="fieldlabel" py:content="fields.cn.label" />:
+          </th>
+          <td>${group.get("cn")}</td>
+        </tr>
+
+        <tr>
+          <th>
+            <label class="fieldlabel" py:content="fields.description.label" />:
+          </th>
+          <td>${group.get("description")}</td>
+        </tr>
+
+        <tr>
+          <th>
+            <label class="fieldlabel" py:content="fields.gidnumber.label" />:
+          </th>
+          <td>${group.get("gidnumber")}</td>
+        </tr>
+    </table>
+
+    <a href="${tg.url('/groupedit', cn=group.get('cn'))}">edit</a>
+
+</body>
+</html>
diff -r 0bf55b38d551 -r c87fc8161f04 ipa-server/ipa-gui/ipagui/templates/master.kid
--- a/ipa-server/ipa-gui/ipagui/templates/master.kid	Tue Sep 11 02:48:53 2007 -0400
+++ b/ipa-server/ipa-gui/ipagui/templates/master.kid	Wed Sep 12 10:40:31 2007 -0700
@@ -70,7 +70,7 @@
         </p>
         <p>
         <a href="${tg.url('/groupnew')}">Add Group</a><br/>
-        <a href="${tg.url('/groupindex')}">Find Groups</a><br/>
+        <a href="${tg.url('/grouplist')}">Find Groups</a><br/>
         </p>
         <p>
         <a href="${tg.url('/')}">Manage Policy</a><br/>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 2228 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/freeipa-devel/attachments/20070912/8de96f9b/attachment.bin>


More information about the Freeipa-devel mailing list