Beispiel #1
0
function viewNodes()
{
    global $user;
    # FIXME change activeNode if current one has been deleted
    $mode = processInputVar("mode", ARG_STRING);
    $tmp = processInputVar("openNodes", ARG_STRING);
    if ($tmp != "") {
        $openNodes = explode(":", $tmp);
    } else {
        if (!empty($_COOKIE["VCLNODES"])) {
            $openNodes = explode(":", $_COOKIE["VCLNODES"]);
        } else {
            $openNodes = array(DEFAULT_PRIVNODE);
        }
    }
    $topNodes = getChildNodes();
    if (count($topNodes)) {
        $keys = array_keys($topNodes);
        $defaultActive = array_shift($keys);
    }
    $activeNode = processInputVar("activeNode", ARG_NUMERIC);
    if (empty($activeNode)) {
        if (!empty($_COOKIE["VCLACTIVENODE"]) && nodeExists($_COOKIE['VCLACTIVENODE'])) {
            $activeNode = $_COOKIE["VCLACTIVENODE"];
        } else {
            $activeNode = $defaultActive;
        }
    }
    $hasNodeAdmin = checkUserHasPriv("nodeAdmin", $user["id"], $activeNode);
    # tree
    print "<H2>Privilege Tree</H2>\n";
    /*if($mode == "submitAddChildNode") {
    		print "<font color=\"#008000\">Node successfully added to tree";
    		print "</font><br><br>\n";
    	}
    	if($mode == "submitDeleteNode") {
    		print "<font color=\"#008000\">Nodes successfully deleted from tree";
    		print "</font><br><br>\n";
    	}*/
    print "<dojo:TreeSelector widgetId=treeSelector eventNames=select:nodeSelected></dojo:TreeSelector>\n";
    #print "<dojo:TreeRPCController RPCUrl=local widgetId=treeController></dojo:TreeRPCController>\n";
    print "<div dojoType=Tree widgetId=privTree selector=treeSelector>\n";
    recursivePrintNodes2($topNodes, $openNodes, $activeNode);
    print "</div>\n";
    print "<div id=treebuttons>\n";
    if ($hasNodeAdmin) {
        $openNodes = implode(":", $openNodes);
        print "<TABLE>\n";
        print "  <TR valign=top>\n";
        print "    <TD><FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
        print "    <button id=addNodeBtn dojoType=Button ";
        print "onClick=\"showAddNodePane(); return false;\">";
        print "Add Child</button>\n";
        print "    </FORM></TD>\n";
        print "    <TD><FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
        print "    <button id=deleteNodeBtn dojoType=Button onClick=\"dojo.widget.byId('deleteDialog').show();\">";
        print "Delete Node and Children</button>\n";
        print "    </FORM></TD>\n";
        print "  </TR>\n";
        print "</TABLE>\n";
    }
    print "</div>\n";
    $cont = addContinuationsEntry('selectNode');
    print "<INPUT type=hidden id=nodecont value=\"{$cont}\">\n";
    # privileges
    print "<H2>Privileges at Selected Node</H2>\n";
    $node = $activeNode;
    if ($openNodes == "") {
        $openNodes = DEFAULT_PRIVNODE;
    }
    $nodeInfo = getNodeInfo($node);
    $privs = getNodePrivileges($node);
    $cascadePrivs = getNodeCascadePrivileges($node);
    $usertypes = getTypes("users");
    $i = 0;
    $hasUserGrant = checkUserHasPriv("userGrant", $user["id"], $node, $privs, $cascadePrivs);
    $hasResourceGrant = checkUserHasPriv("resourceGrant", $user["id"], $node, $privs, $cascadePrivs);
    print "<div id=nodePerms>\n";
    # users
    print "<A name=\"users\"></a>\n";
    print "<div id=usersDiv>\n";
    print "<H3>Users</H3>\n";
    print "<FORM id=usersform action=\"" . BASEURL . SCRIPT . "#users\" method=post>\n";
    $users = array();
    if (count($privs["users"]) || count($cascadePrivs["users"])) {
        print "<TABLE border=1 summary=\"\">\n";
        print "  <TR>\n";
        print "    <TD></TD>\n";
        print "    <TH bgcolor=gray style=\"color: black;\">Block<br>Cascaded<br>Rights</TH>\n";
        print "    <TH bgcolor=\"#008000\" style=\"color: black;\">Cascade<br>to Child<br>Nodes</TH>\n";
        foreach ($usertypes["users"] as $type) {
            $img = getImageText($type);
            print "    <TD>{$img}</TD>\n";
        }
        print "  </TR>\n";
        $users = array_unique(array_merge(array_keys($privs["users"]), array_keys($cascadePrivs["users"])));
        sort($users);
        foreach ($users as $_user) {
            printUserPrivRow($_user, $i, $privs["users"], $usertypes["users"], $cascadePrivs["users"], 'user', !$hasUserGrant);
            $i++;
        }
        print "</TABLE>\n";
        print "<div id=lastUserNum class=hidden>" . ($i - 1) . "</div>\n";
        if ($hasUserGrant) {
            $cont = addContinuationsEntry('AJchangeUserPrivs');
            print "<INPUT type=hidden id=changeuserprivcont value=\"{$cont}\">\n";
        }
    } else {
        print "There are no user privileges at the selected node.<br>\n";
    }
    if ($hasUserGrant) {
        print "<BUTTON id=addUserBtn dojoType=Button onclick=\"showAddUserPane(); return false;\">";
        print "Add User</button>\n";
    }
    print "</FORM>\n";
    print "</div>\n";
    # groups
    print "<A name=\"groups\"></a>\n";
    print "<div id=usergroupsDiv>\n";
    print "<H3>User Groups</H3>\n";
    if (count($privs["usergroups"]) || count($cascadePrivs["usergroups"])) {
        print "<FORM action=\"" . BASEURL . SCRIPT . "#groups\" method=post>\n";
        print "<div id=firstUserGroupNum class=hidden>{$i}</div>";
        print "<TABLE border=1 summary=\"\">\n";
        print "  <TR>\n";
        print "    <TD></TD>\n";
        print "    <TH bgcolor=gray style=\"color: black;\">Block<br>Cascaded<br>Rights</TH>\n";
        #$img = getImageText("Block Cascaded Rights");
        #print "    <TD>$img</TD>\n";
        print "    <TH bgcolor=\"#008000\" style=\"color: black;\">Cascade<br>to Child<br>Nodes</TH>\n";
        #$img = getImageText("Cascade to Child Nodes");
        #print "    <TD>$img</TD>\n";
        foreach ($usertypes["users"] as $type) {
            $img = getImageText($type);
            print "    <TH>{$img}</TH>\n";
        }
        print "  </TR>\n";
        $groups = array_unique(array_merge(array_keys($privs["usergroups"]), array_keys($cascadePrivs["usergroups"])));
        sort($groups);
        foreach ($groups as $group) {
            printUserPrivRow($group, $i, $privs["usergroups"], $usertypes["users"], $cascadePrivs["usergroups"], 'group', !$hasUserGrant);
            $i++;
        }
        print "</TABLE>\n";
        print "<div id=lastUserGroupNum class=hidden>" . ($i - 1) . "</div>";
        if ($hasUserGrant) {
            $cont = addContinuationsEntry('AJchangeUserGroupPrivs');
            print "<INPUT type=hidden id=changeusergroupprivcont value=\"{$cont}\">\n";
        }
    } else {
        print "There are no user group privileges at the selected node.<br>\n";
        $groups = array();
    }
    if ($hasUserGrant) {
        print "<BUTTON id=addGroupBtn dojoType=Button onclick=\"showAddUserGroupPane(); return false;\">";
        print "Add Group</button>\n";
    }
    print "</FORM>\n";
    print "</div>\n";
    # resources
    $resourcetypes = array("available", "administer", "manageGroup");
    print "<A name=\"resources\"></a>\n";
    print "<div id=resourcesDiv>\n";
    print "<H3>Resources</H3>\n";
    print "<FORM id=resourceForm action=\"" . BASEURL . SCRIPT . "#resources\" method=post>\n";
    if (count($privs["resources"]) || count($cascadePrivs["resources"])) {
        print "<TABLE border=1 summary=\"\">\n";
        print "  <TR>\n";
        print "    <TH>Group<br>Name</TH>\n";
        print "    <TH>Group<br>Type</TH>\n";
        print "    <TH bgcolor=gray style=\"color: black;\">Block<br>Cascaded<br>Rights</TH>\n";
        print "    <TH bgcolor=\"#008000\" style=\"color: black;\">Cascade<br>to Child<br>Nodes</TH>\n";
        foreach ($resourcetypes as $type) {
            $img = getImageText("{$type}");
            print "    <TH>{$img}</TH>\n";
        }
        print "  </TR>\n";
        $resources = array_unique(array_merge(array_keys($privs["resources"]), array_keys($cascadePrivs["resources"])));
        sort($resources);
        $resourcegroups = getResourceGroups();
        $resgroupmembers = getResourceGroupMembers();
        foreach ($resources as $resource) {
            printResourcePrivRow($resource, $i, $privs["resources"], $resourcetypes, $resourcegroups, $resgroupmembers, $cascadePrivs["resources"], !$hasResourceGrant);
            $i++;
        }
        print "</TABLE>\n";
        if ($hasResourceGrant) {
            $cont = addContinuationsEntry('AJchangeResourcePrivs');
            print "<INPUT type=hidden id=changeresourceprivcont value=\"{$cont}\">\n";
        }
    } else {
        print "There are no resource group privileges at the selected node.<br>\n";
        $resources = array();
    }
    if ($hasResourceGrant) {
        print "<BUTTON id=addResourceBtn dojoType=Button onclick=\"showAddResourceGroupPane(); return false;\">";
        print "Add Resource Group</button>\n";
    }
    print "</FORM>\n";
    print "</div>\n";
    print "</div>\n";
    print "<div dojoType=FloatingPane\n";
    print "      id=addUserPane\n";
    print "      title=\"Add User Permission\"\n";
    print "      constrainToContainer=false\n";
    print "      hasShadow=true\n";
    print "      resizable=true\n";
    print "      style=\"width: 520px; height: 410px; position: absolute; left: 15; top: 250px; display: none\"\n";
    print ">\n";
    print "<H2>Add User</H2>\n";
    print "<div id=addPaneNodeName></div>\n";
    print "<TABLE border=1 summary=\"\">\n";
    print "  <TR>\n";
    print "    <TD></TD>\n";
    print "    <TH bgcolor=gray style=\"color: black;\">Block<br>Cascaded<br>Rights</TH>\n";
    print "    <TH bgcolor=\"#008000\" style=\"color: black;\">Cascade<br>to Child<br>Nodes</TH>\n";
    foreach ($usertypes["users"] as $type) {
        $img = getImageText($type);
        print "    <TD>{$img}</TD>\n";
    }
    print "  </TR>\n";
    print "  <TR>\n";
    print "    <TD><INPUT type=text id=newuser name=newuser size=15";
    print "></TD>\n";
    # block rights
    $count = count($usertypes) + 1;
    print "    <TD align=center bgcolor=gray><INPUT type=checkbox ";
    print "dojoType=Checkbox id=blockchk name=block></TD>\n";
    #cascade rights
    print "    <TD align=center bgcolor=\"#008000\" id=usercell0:0>";
    print "<INPUT type=checkbox dojoType=Checkbox id=userck0:0 name=cascade ";
    print "></TD>\n";
    # normal rights
    $j = 1;
    foreach ($usertypes["users"] as $type) {
        print "    <TD align=center id=usercell0:{$j}><INPUT type=checkbox ";
        print "dojoType=Checkbox name=\"{$type}\" id=userck0:{$j}></TD>\n";
        $j++;
    }
    print "  </TR>\n";
    print "</TABLE>\n";
    print "<div id=addUserPrivStatus></div>\n";
    print "<TABLE summary=\"\"><TR>\n";
    print "<TD><button id=submitAddUserBtn dojoType=Button onclick=\"submitAddUser();\">";
    print "Submit New User</button></TD>\n";
    print "<TD><button id=cancelAddUserBtn dojoType=Button onclick=\"addUserPaneHide();\">";
    print "Cancel</button></TD>\n";
    print "</TR></TABLE>\n";
    $cont = addContinuationsEntry('AJsubmitAddUserPriv');
    print "<INPUT type=hidden id=addusercont value=\"{$cont}\">\n";
    print "</div>\n";
    print "<div dojoType=FloatingPane\n";
    print "      id=addUserGroupPane\n";
    print "      title=\"Add User Group Permission\"\n";
    print "      constrainToContainer=false\n";
    print "      hasShadow=true\n";
    print "      resizable=true\n";
    print "      style=\"width: 520px; height: 410px; position: absolute; left: 15; top: 450px; display: none\"\n";
    print ">\n";
    print "<H2>Add User Group</H2>\n";
    print "<div id=addGroupPaneNodeName></div>\n";
    print "<TABLE border=1 summary=\"\">\n";
    print "  <TR>\n";
    print "    <TD></TD>\n";
    print "    <TH bgcolor=gray style=\"color: black;\">Block<br>Cascaded<br>Rights</TH>\n";
    print "    <TH bgcolor=\"#008000\" style=\"color: black;\">Cascade<br>to Child<br>Nodes</TH>\n";
    foreach ($usertypes["users"] as $type) {
        $img = getImageText($type);
        print "    <TD>{$img}</TD>\n";
    }
    print "  </TR>\n";
    print "  <TR>\n";
    print "    <TD>\n";
    # FIXME should $groups be only the user's groups?
    $groups = getUserGroups(0, $user['affiliationid']);
    if (array_key_exists(82, $groups)) {
        unset($groups[82]);
    }
    # remove None group
    printSelectInput("newgroupid", $groups, -1, 0, 0, 'newgroupid');
    print "    </TD>\n";
    # block rights
    print "    <TD align=center bgcolor=gray><INPUT type=checkbox ";
    print "dojoType=Checkbox id=blockgrpchk name=blockgrp></TD>\n";
    #cascade rights
    print "    <TD align=center bgcolor=\"#008000\" id=grpcell0:0>";
    print "<INPUT type=checkbox dojoType=Checkbox id=usergrpck0:0 ";
    print "name=cascadegrp></TD>\n";
    # normal rights
    $j = 1;
    foreach ($usertypes["users"] as $type) {
        print "    <TD align=center id=usergrpcell0:{$j}><INPUT type=checkbox ";
        print "dojoType=Checkbox name=\"{$type}\" id=usergrpck0:{$j}></TD>\n";
        $j++;
    }
    print "  </TR>\n";
    print "</TABLE>\n";
    print "<div id=addUserGroupPrivStatus></div>\n";
    print "<TABLE summary=\"\"><TR>\n";
    print "<TD><button id=submitAddGroupBtn dojoType=Button onclick=\"submitAddUserGroup();\">";
    print "Submit New User Group</button></TD>\n";
    print "<TD><button id=cancelAddGroupBtn dojoType=Button onclick=\"addUserGroupPaneHide();\">";
    print "Cancel</button></TD>\n";
    print "</TR></TABLE>\n";
    $cont = addContinuationsEntry('AJsubmitAddUserGroupPriv');
    print "<INPUT type=hidden id=addusergroupcont value=\"{$cont}\">\n";
    print "</div>\n";
    print "<div dojoType=FloatingPane\n";
    print "      id=addResourceGroupPane\n";
    print "      title=\"Add Resource Group Permission\"\n";
    print "      constrainToContainer=false\n";
    print "      hasShadow=true\n";
    print "      resizable=true\n";
    print "      style=\"width: 520px; height: 410px; position: absolute; left: 15; top: 450px; display: none\"\n";
    print ">\n";
    print "<H2>Add Resource Group</H2>\n";
    print "<div id=addResourceGroupPaneNodeName></div>\n";
    print "<TABLE border=1 summary=\"\">\n";
    print "  <TR>\n";
    print "    <TD></TD>\n";
    print "    <TH bgcolor=gray style=\"color: black;\">Block<br>Cascaded<br>Rights</TH>\n";
    print "    <TH bgcolor=\"#008000\" style=\"color: black;\">Cascade<br>to Child<br>Nodes</TH>\n";
    $resourcetypes = array("available", "administer", "manageGroup");
    foreach ($resourcetypes as $type) {
        $img = getImageText("{$type}");
        print "    <TH>{$img}</TH>\n";
    }
    print "  </TR>\n";
    print "  <TR>\n";
    print "    <TD>\n";
    $resources = array();
    $privs = array("computerAdmin", "mgmtNodeAdmin", "imageAdmin", "scheduleAdmin");
    $resourcesgroups = getUserResources($privs, array("manageGroup"), 1);
    foreach (array_keys($resourcesgroups) as $type) {
        foreach ($resourcesgroups[$type] as $id => $group) {
            $resources[$id] = $type . "/" . $group;
        }
    }
    printSelectInput("newresourcegroupid", $resources, -1, 0, 0, 'newresourcegroupid');
    print "    </TD>\n";
    # block rights
    print "    <TD align=center bgcolor=gray><INPUT type=checkbox ";
    print "dojoType=Checkbox id=blockresgrpck name=blockresgrp></TD>\n";
    #cascade rights
    print "    <TD align=center bgcolor=\"#008000\" id=resgrpcell0:0>";
    print "<INPUT type=checkbox dojoType=Checkbox id=resgrpck0:0 ";
    print "name=cascaderesgrp></TD>\n";
    # normal rights
    print "    <TD align=center id=resgrpcell0:1><INPUT type=checkbox ";
    print "dojoType=Checkbox name=available id=resgrpck0:1></TD>\n";
    print "    <TD align=center id=resgrpcell0:2><INPUT type=checkbox ";
    print "dojoType=Checkbox name=administer id=resgrpck0:2></TD>\n";
    print "    <TD align=center id=resgrpcell0:3><INPUT type=checkbox ";
    print "dojoType=Checkbox name=manageGroup id=resgrpck0:3></TD>\n";
    print "  </TR>\n";
    print "</TABLE>\n";
    print "<div id=addResourceGroupPrivStatus></div>\n";
    print "<TABLE summary=\"\"><TR>\n";
    print "<TD><button dojoType=Button onclick=\"submitAddResourceGroup();\">";
    print "Submit New Resource Group</button></TD>\n";
    print "<TD><button dojoType=Button onclick=\"addResourceGroupPaneHide();\">";
    print "Cancel</button></TD>\n";
    print "</TR></TABLE>\n";
    $cont = addContinuationsEntry('AJsubmitAddResourcePriv');
    print "<INPUT type=hidden id=addresourcegroupcont value=\"{$cont}\">\n";
    print "</div>\n";
    print "<div dojoType=FloatingPane\n";
    print "      id=addNodePane\n";
    print "      title=\"Add Child Node\"\n";
    print "      constrainToContainer=false\n";
    print "      hasShadow=true\n";
    print "      resizable=true\n";
    print "      style=\"width: 280px; height: 200px; position: absolute; left: 15; top: 150px; display: none\"\n";
    print ">\n";
    print "<H2>Add Child Node</H2>\n";
    print "<div id=addChildNodeName></div>\n";
    print "<strong>New Node:</strong> <INPUT type=text id=childNodeName>\n";
    print "<div id=addChildNodeStatus></div>\n";
    print "<TABLE summary=\"\"><TR>\n";
    print "<TD><button id=submitAddNodeBtn dojoType=Button onclick=\"submitAddChildNode();\">";
    print "Create Child</button></TD>\n";
    print "<TD><button id=cancelAddNodeBtn dojoType=Button onclick=\"addNodePaneHide();\">";
    print "Cancel</button></TD>\n";
    print "</TR></TABLE>\n";
    $cont = addContinuationsEntry('AJsubmitAddChildNode');
    print "<INPUT type=hidden id=addchildcont value=\"{$cont}\"\n>";
    print "</div>\n";
    print "<div dojoType=dialog id=deleteDialog bgColor=white bgOpacity=0.5 toggle=fade toggleDuration=250>\n";
    print "Delete the following node and all of its children?<br><br>\n";
    print "<div id=deleteNodeName></div><br>\n";
    print "<div align=center>\n";
    print "<TABLE summary=\"\"><TR>\n";
    print "<TD><button id=submitDeleteNodeBtn dojoType=Button onClick=\"deleteNode();\">";
    print "Delete Nodes</button></TD>\n";
    print "<TD><button id=cancelDeleteNodeBtn dojoType=Button ";
    print "onClick=\"dojo.widget.byId('deleteDialog').hide();\">Cancel</button>";
    print "</TD>\n";
    print "</TR></TABLE>\n";
    $cont = addContinuationsEntry('AJsubmitDeleteNode');
    print "<INPUT type=hidden id=delchildcont value=\"{$cont}\"\n>";
    print "</div>\n";
    print "</div>\n";
    print "<div dojoType=dialog id=workingDialog bgColor=white bgOpacity=0.5 toggle=fade toggleDuration=250>\n";
    print "Loading...\n";
    print "</div>\n";
}
Beispiel #2
0
function viewNodes()
{
    global $user;
    if (!empty($_COOKIE["VCLACTIVENODE"]) && nodeExists($_COOKIE['VCLACTIVENODE'])) {
        $activeNode = $_COOKIE["VCLACTIVENODE"];
    } else {
        $topNodes = getChildNodes();
        if (!count($topNodes)) {
            abort(53);
        }
        $keys = array_keys($topNodes);
        $defaultActive = array_shift($keys);
        $activeNode = $defaultActive;
    }
    $hasNodeAdmin = checkUserHasPriv("nodeAdmin", $user["id"], $activeNode);
    $hasManagePerms = checkUserHasPerm('Manage Additional User Group Permissions');
    # tree
    if ($hasManagePerms) {
        print "<div id=\"mainTabContainer\" dojoType=\"dijit.layout.TabContainer\"\n";
        print "     style=\"width:750px;height:600px\">\n";
        print "<div id=\"privtreetab\" dojoType=\"dijit.layout.ContentPane\" title=\"Privilege Tree\">\n";
    }
    print "<H2>Privilege Tree</H2>\n";
    $cont = addContinuationsEntry('JSONprivnodelist');
    print "<div dojoType=\"dojo.data.ItemFileWriteStore\" url=\"" . BASEURL . SCRIPT . "?continuation={$cont}\" jsid=\"nodestore\" id=\"nodestore\"></div>\n";
    print "<div class=privtreediv>\n";
    print "<div dojoType=\"dijit.Tree\" store=\"nodestore\" showRoot=\"false\" id=privtree>\n";
    print "  <script type=\"dojo/connect\" event=\"focusNode\" args=\"node\">\n";
    print "    nodeSelect(node);\n";
    print "  </script>\n";
    print "  <script type=\"dojo/method\" event=\"_onExpandoClick\" args=\"message\">\n";
    print "    var node = message.node;\n";
    print "    var addclass = 0;\n";
    print "    var focusid = node.tree.lastFocused.item.name;\n";
    print "    if(node.isExpanded){\n";
    print "      if(isChildFocused(focusid, node.item.children)) {\n";
    print "        this.focusNode(node);\n";
    print "        addclass = 1;\n";
    print "      }\n";
    print "      this._collapseNode(node);\n";
    print "    }else{\n";
    print "      this._expandNode(node);\n";
    print "    }\n";
    print "    if(addclass || node.item.name == focusid)\n";
    print "      dojo.addClass(node.labelNode, 'privtreeselected');\n";
    print "  </script>\n";
    print "  <script type=\"dojo/connect\" event=\"startup\" args=\"item\">\n";
    print "    focusFirstNode({$activeNode});\n";
    print "  </script>\n";
    print "</div>\n";
    print "</div>\n";
    print "<div id=treebuttons>\n";
    if ($hasNodeAdmin) {
        print "<TABLE summary=\"\" cellspacing=\"\" cellpadding=\"\">\n";
        print "  <TR valign=top>\n";
        print "    <TD><FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
        print "    <button id=addNodeBtn dojoType=\"dijit.form.Button\">\n";
        print "      Add Child\n";
        print "      <script type=\"dojo/method\" event=onClick>\n";
        print "        showPrivPane('addNodePane');\n";
        print "        return false;\n";
        print "      </script>\n";
        print "    </button>\n";
        print "    </FORM></TD>\n";
        print "    <TD><FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
        print "    <button id=deleteNodeBtn dojoType=\"dijit.form.Button\">\n";
        print "      Delete Node and Children\n";
        print "      <script type=\"dojo/method\" event=onClick>\n";
        print "        dijit.byId('deleteDialog').show();\n";
        print "        return false;\n";
        print "      </script>\n";
        print "    </button>\n";
        print "    </FORM></TD>\n";
        print "    <TD><FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
        print "    <button id=renameNodeBtn dojoType=\"dijit.form.Button\">\n";
        print "      Rename Node\n";
        print "      <script type=\"dojo/method\" event=onClick>\n";
        print "        dijit.byId('renameDialog').show();\n";
        print "        return false;\n";
        print "      </script>\n";
        print "    </button>\n";
        print "    </FORM></TD>\n";
        print "    <td></td>\n";
        print "  </TR>\n";
        print "</TABLE>\n";
    }
    print "</div>\n";
    $cont = addContinuationsEntry('selectNode');
    print "<INPUT type=hidden id=nodecont value=\"{$cont}\">\n";
    # privileges
    print "<H2>Privileges at Selected Node</H2>\n";
    $node = $activeNode;
    $nodeInfo = getNodeInfo($node);
    $privs = getNodePrivileges($node);
    $cascadePrivs = getNodeCascadePrivileges($node);
    $usertypes = getTypes("users");
    $i = 0;
    $hasUserGrant = checkUserHasPriv("userGrant", $user["id"], $node, $privs, $cascadePrivs);
    $hasResourceGrant = checkUserHasPriv("resourceGrant", $user["id"], $node, $privs, $cascadePrivs);
    print "<div id=nodePerms>\n";
    # users
    print "<A name=\"users\"></a>\n";
    print "<div id=usersDiv>\n";
    print "<H3>Users</H3>\n";
    print "<FORM id=usersform action=\"" . BASEURL . SCRIPT . "#users\" method=post>\n";
    $users = array();
    if (count($privs["users"]) || count($cascadePrivs["users"])) {
        print "<TABLE border=1 summary=\"\">\n";
        print "  <TR>\n";
        print "    <TD></TD>\n";
        print "    <TH bgcolor=gray style=\"color: black;\">Block<br>Cascaded<br>Rights</TH>\n";
        print "    <TH bgcolor=\"#008000\" style=\"color: black;\">Cascade<br>to Child<br>Nodes</TH>\n";
        foreach ($usertypes["users"] as $type) {
            if ($type == 'configAdmin') {
                continue;
            }
            $img = getImageText($type);
            print "    <TD>{$img}</TD>\n";
        }
        print "  </TR>\n";
        $users = array_unique(array_merge(array_keys($privs["users"]), array_keys($cascadePrivs["users"])));
        sort($users);
        foreach ($users as $_user) {
            printUserPrivRow($_user, $i, $privs["users"], $usertypes["users"], $cascadePrivs["users"], 'user', !$hasUserGrant);
            $i++;
        }
        print "</TABLE>\n";
        print "<div id=lastUserNum class=hidden>" . ($i - 1) . "</div>\n";
        if ($hasUserGrant) {
            $cont = addContinuationsEntry('AJchangeUserPrivs');
            print "<INPUT type=hidden id=changeuserprivcont value=\"{$cont}\">\n";
        }
    } else {
        print "There are no user privileges at the selected node.<br>\n";
    }
    if ($hasUserGrant) {
        print "<button id=addUserBtn dojoType=\"dijit.form.Button\">\n";
        print "  Add User\n";
        print "  <script type=\"dojo/method\" event=onClick>\n";
        print "    showPrivPane('addUserPane');\n";
        print "    return false;\n";
        print "  </script>\n";
        print "</button>\n";
    }
    print "</FORM>\n";
    print "</div>\n";
    # groups
    print "<A name=\"groups\"></a>\n";
    print "<div id=usergroupsDiv>\n";
    print "<H3>User Groups</H3>\n";
    if (count($privs["usergroups"]) || count($cascadePrivs["usergroups"])) {
        print "<FORM action=\"" . BASEURL . SCRIPT . "#groups\" method=post>\n";
        print "<div id=firstUserGroupNum class=hidden>{$i}</div>";
        print "<TABLE border=1 summary=\"\">\n";
        print "  <TR>\n";
        print "    <TD></TD>\n";
        print "    <TH bgcolor=gray style=\"color: black;\">Block<br>Cascaded<br>Rights</TH>\n";
        print "    <TH bgcolor=\"#008000\" style=\"color: black;\">Cascade<br>to Child<br>Nodes</TH>\n";
        foreach ($usertypes["users"] as $type) {
            if ($type == 'configAdmin') {
                continue;
            }
            $img = getImageText($type);
            print "    <TH>{$img}</TH>\n";
        }
        print "  </TR>\n";
        $groupids = array_unique(array_merge(array_keys($privs["usergroups"]), array_keys($cascadePrivs["usergroups"])));
        $allids = implode(',', $groupids);
        $query = "SELECT id " . "FROM usergroup " . "WHERE id IN ({$allids}) " . "ORDER BY name";
        $qh = doQuery($query);
        $orderedgroups = array();
        while ($row = mysql_fetch_assoc($qh)) {
            $orderedgroups[] = $row['id'];
        }
        foreach ($orderedgroups as $id) {
            printUserPrivRow($id, $i, $privs["usergroups"], $usertypes["users"], $cascadePrivs["usergroups"], 'group', !$hasUserGrant);
            $i++;
        }
        print "</TABLE>\n";
        print "<div id=lastUserGroupNum class=hidden>" . ($i - 1) . "</div>";
        if ($hasUserGrant) {
            $cont = addContinuationsEntry('AJchangeUserGroupPrivs');
            print "<INPUT type=hidden id=changeusergroupprivcont value=\"{$cont}\">\n";
        }
        $cont = addContinuationsEntry('jsonGetUserGroupMembers');
        print "<INPUT type=hidden id=ugmcont value=\"{$cont}\">\n";
    } else {
        print "There are no user group privileges at the selected node.<br>\n";
        $groups = array();
    }
    if ($hasUserGrant) {
        print "<button id=addGroupBtn dojoType=\"dijit.form.Button\">\n";
        print "  Add Group\n";
        print "  <script type=\"dojo/method\" event=onClick>\n";
        print "    showPrivPane('addUserGroupPane');\n";
        print "    return false;\n";
        print "  </script>\n";
        print "</button>\n";
    }
    print "</FORM>\n";
    print "</div>\n";
    # resources
    $resourcetypes = getResourcePrivs();
    print "<A name=\"resources\"></a>\n";
    print "<div id=resourcesDiv>\n";
    print "<H3>Resources</H3>\n";
    print "<FORM id=resourceForm action=\"" . BASEURL . SCRIPT . "#resources\" method=post>\n";
    if (count($privs["resources"]) || count($cascadePrivs["resources"])) {
        print "<TABLE border=1 summary=\"\">\n";
        print "  <TR>\n";
        print "    <TH>Group<br>Name</TH>\n";
        print "    <TH>Group<br>Type</TH>\n";
        print "    <TH bgcolor=gray style=\"color: black;\">Block<br>Cascaded<br>Rights</TH>\n";
        print "    <TH bgcolor=\"#008000\" style=\"color: black;\">Cascade<br>to Child<br>Nodes</TH>\n";
        foreach ($resourcetypes as $type) {
            if ($type == 'block' || $type == 'cascade') {
                continue;
            }
            $img = getImageText("{$type}");
            print "    <TH>{$img}</TH>\n";
        }
        print "  </TR>\n";
        $resources = array_unique(array_merge(array_keys($privs["resources"]), array_keys($cascadePrivs["resources"])));
        sort($resources);
        $resourcegroups = getResourceGroups();
        $resgroupmembers = getResourceGroupMembers();
        foreach ($resources as $resource) {
            $data = getResourcePrivRowHTML($resource, $i, $privs["resources"], $resourcetypes, $resourcegroups, $resgroupmembers, $cascadePrivs["resources"], !$hasResourceGrant);
            print $data['html'];
            print "<script language=\"Javascript\">\n";
            print "dojo.addOnLoad(function () {setTimeout(\"{$data['javascript']}\", 500)});\n";
            print "</script>\n";
            $i++;
        }
        print "</TABLE>\n";
        if ($hasResourceGrant) {
            $cont = addContinuationsEntry('AJchangeResourcePrivs');
            print "<INPUT type=hidden id=changeresourceprivcont value=\"{$cont}\">\n";
        }
        $cont = addContinuationsEntry('jsonGetResourceGroupMembers');
        print "<INPUT type=hidden id=rgmcont value=\"{$cont}\">\n";
    } else {
        print "There are no resource group privileges at the selected node.<br>\n";
        $resources = array();
    }
    if ($hasResourceGrant) {
        print "<button id=addResourceBtn dojoType=\"dijit.form.Button\">\n";
        print "  Add Resource Group\n";
        print "  <script type=\"dojo/method\" event=onClick>\n";
        print "    showPrivPane('addResourceGroupPane');\n";
        print "    return false;\n";
        print "  </script>\n";
        print "</button>\n";
    }
    print "</FORM>\n";
    print "</div>\n";
    print "</div>\n";
    # ----------------------------- dialogs ----------------------------
    print "<div dojoType=dijit.Dialog\n";
    print "      id=addUserPane\n";
    print "      title=\"Add User Permission\"\n";
    print "      duration=250\n";
    print "      draggable=true>\n";
    print "    <script type=\"dojo/connect\" event=onCancel>\n";
    print "      addUserPaneHide();\n";
    print "    </script>\n";
    print "<H2>Add User</H2>\n";
    print "<div id=addPaneNodeName></div>\n";
    print "<TABLE border=1 summary=\"\">\n";
    print "  <TR>\n";
    print "    <TD></TD>\n";
    print "    <TH bgcolor=gray style=\"color: black;\">Block<br>Cascaded<br>Rights</TH>\n";
    print "    <TH bgcolor=\"#008000\" style=\"color: black;\">Cascade<br>to Child<br>Nodes</TH>\n";
    foreach ($usertypes["users"] as $type) {
        $img = getImageText($type);
        print "    <TD>{$img}</TD>\n";
    }
    print "  </TR>\n";
    print "  <TR>\n";
    print "    <TD><INPUT type=text id=newuser name=newuser size=15";
    print "></TD>\n";
    # block rights
    $count = count($usertypes) + 1;
    print "    <TD align=center bgcolor=gray><INPUT type=checkbox ";
    print "dojoType=dijit.form.CheckBox id=blockchk name=block></TD>\n";
    #cascade rights
    print "    <TD align=center bgcolor=\"#008000\" id=usercell0:0>";
    print "<INPUT type=checkbox dojoType=dijit.form.CheckBox id=userck0:0 ";
    print "name=cascade></TD>\n";
    # normal rights
    $j = 1;
    foreach ($usertypes["users"] as $type) {
        print "    <TD align=center id=usercell0:{$j}><INPUT type=checkbox ";
        print "dojoType=dijit.form.CheckBox name=\"{$type}\" id=userck0:{$j}></TD>\n";
        $j++;
    }
    print "  </TR>\n";
    print "</TABLE>\n";
    print "<div id=addUserPrivStatus></div>\n";
    print "<TABLE summary=\"\"><TR>\n";
    print "<TD>\n";
    print "  <button id=submitAddUserBtn dojoType=\"dijit.form.Button\">\n";
    print "    Submit New User\n";
    print "    <script type=\"dojo/method\" event=onClick>\n";
    print "      submitAddUser();\n";
    print "    </script>\n";
    print "  </button>\n";
    print "</TD>\n";
    print "<TD>\n";
    print "  <button id=cancelAddUserBtn dojoType=\"dijit.form.Button\">\n";
    print "    Cancel\n";
    print "    <script type=\"dojo/method\" event=onClick>\n";
    print "      addUserPaneHide();\n";
    print "    </script>\n";
    print "  </button>\n";
    print "</TD>\n";
    print "</TR></TABLE>\n";
    $cont = addContinuationsEntry('AJsubmitAddUserPriv');
    print "<INPUT type=hidden id=addusercont value=\"{$cont}\">\n";
    print "</div>\n";
    print "<div dojoType=dijit.Dialog\n";
    print "      id=addUserGroupPane\n";
    print "      title=\"Add User Group Permission\"\n";
    print "      duration=250\n";
    print "      draggable=true>\n";
    print "    <script type=\"dojo/connect\" event=onCancel>\n";
    print "      addUserGroupPaneHide();\n";
    print "    </script>\n";
    print "<H2>Add User Group</H2>\n";
    print "<div id=addGroupPaneNodeName></div>\n";
    print "<TABLE border=1 summary=\"\">\n";
    print "  <TR>\n";
    print "    <TD></TD>\n";
    print "    <TH bgcolor=gray style=\"color: black;\">Block<br>Cascaded<br>Rights</TH>\n";
    print "    <TH bgcolor=\"#008000\" style=\"color: black;\">Cascade<br>to Child<br>Nodes</TH>\n";
    foreach ($usertypes["users"] as $type) {
        $img = getImageText($type);
        print "    <TD>{$img}</TD>\n";
    }
    print "  </TR>\n";
    print "  <TR>\n";
    print "    <TD>\n";
    # FIXME should $groups be only the user's groups?
    $groups = getUserGroups(0, $user['affiliationid']);
    printSelectInput("newgroupid", $groups, -1, 0, 0, 'newgroupid');
    print "    </TD>\n";
    # block rights
    print "    <TD align=center bgcolor=gray><INPUT type=checkbox ";
    print "dojoType=dijit.form.CheckBox id=blockgrpchk name=blockgrp></TD>\n";
    #cascade rights
    print "    <TD align=center bgcolor=\"#008000\" id=grpcell0:0>";
    print "<INPUT type=checkbox dojoType=dijit.form.CheckBox id=usergrpck0:0 ";
    print "name=cascadegrp></TD>\n";
    # normal rights
    $j = 1;
    foreach ($usertypes["users"] as $type) {
        print "    <TD align=center id=usergrpcell0:{$j}><INPUT type=checkbox ";
        print "dojoType=dijit.form.CheckBox name=\"{$type}\" id=usergrpck0:{$j}></TD>\n";
        $j++;
    }
    print "  </TR>\n";
    print "</TABLE>\n";
    print "<div id=addUserGroupPrivStatus></div>\n";
    print "<TABLE summary=\"\"><TR>\n";
    print "<TD>\n";
    print "  <button id=submitAddGroupBtn dojoType=\"dijit.form.Button\">\n";
    print "    Submit New User Group\n";
    print "    <script type=\"dojo/method\" event=onClick>\n";
    print "      submitAddUserGroup();\n";
    print "    </script>\n";
    print "  </button>\n";
    print "</TD>\n";
    print "<TD>\n";
    print "  <button id=cancelAddGroupBtn dojoType=\"dijit.form.Button\">\n";
    print "    Cancel\n";
    print "    <script type=\"dojo/method\" event=onClick>\n";
    print "      addUserGroupPaneHide();\n";
    print "    </script>\n";
    print "  </button>\n";
    print "</TD>\n";
    print "</TR></TABLE>\n";
    $cont = addContinuationsEntry('AJsubmitAddUserGroupPriv');
    print "<INPUT type=hidden id=addusergroupcont value=\"{$cont}\">\n";
    print "</div>\n";
    print "<div dojoType=dijit.Dialog\n";
    print "      id=addResourceGroupPane\n";
    print "      title=\"Add Resource Group Permission\"\n";
    print "      duration=250\n";
    print "      draggable=true>\n";
    print "    <script type=\"dojo/connect\" event=onCancel>\n";
    print "      addResourceGroupPaneHide();\n";
    print "    </script>\n";
    print "<H2>Add Resource Group</H2>\n";
    print "<div id=addResourceGroupPaneNodeName></div>\n";
    print "<TABLE border=1 summary=\"\">\n";
    print "  <TR>\n";
    print "    <TD></TD>\n";
    print "    <TH bgcolor=gray style=\"color: black;\">Block<br>Cascaded<br>Rights</TH>\n";
    print "    <TH bgcolor=\"#008000\" style=\"color: black;\">Cascade<br>to Child<br>Nodes</TH>\n";
    foreach ($resourcetypes as $type) {
        if ($type == 'block' || $type == 'cascade') {
            continue;
        }
        $img = getImageText("{$type}");
        print "    <TH>{$img}</TH>\n";
    }
    print "  </TR>\n";
    print "  <TR>\n";
    print "    <TD>\n";
    $resources = array();
    $privs = array("computerAdmin", "mgmtNodeAdmin", "imageAdmin", "scheduleAdmin", "serverProfileAdmin");
    $resourcesgroups = getUserResources($privs, array("manageGroup"), 1);
    foreach (array_keys($resourcesgroups) as $type) {
        foreach ($resourcesgroups[$type] as $id => $group) {
            $resources[$id] = $type . "/" . $group;
        }
    }
    printSelectInput("newresourcegroupid", $resources, -1, 0, 0, 'newresourcegroupid');
    print "    </TD>\n";
    # block rights
    print "    <TD align=center bgcolor=gray><INPUT type=checkbox ";
    print "dojoType=dijit.form.CheckBox id=blockresgrpck name=blockresgrp></TD>\n";
    #cascade rights
    print "    <TD align=center bgcolor=\"#008000\" id=resgrpcell0:0>";
    print "<INPUT type=checkbox dojoType=dijit.form.CheckBox id=resgrpck0:0 ";
    print "name=cascaderesgrp></TD>\n";
    # normal rights
    $i = 1;
    foreach ($resourcetypes as $type) {
        if ($type == 'block' || $type == 'cascade') {
            continue;
        }
        print "    <TD align=center id=resgrpcell0:{$i}><INPUT type=checkbox ";
        print "dojoType=dijit.form.CheckBox name={$type} id=resgrpck0:{$i}></TD>\n";
        $i++;
    }
    print "  </TR>\n";
    print "</TABLE>\n";
    print "<div id=addResourceGroupPrivStatus></div>\n";
    print "<TABLE summary=\"\"><TR>\n";
    print "<TD>\n";
    print "  <button dojoType=\"dijit.form.Button\">\n";
    print "    Submit New Resource Group\n";
    print "    <script type=\"dojo/method\" event=onClick>\n";
    print "      submitAddResourceGroup();\n";
    print "    </script>\n";
    print "  </button>\n";
    print "</TD>\n";
    print "<TD>\n";
    print "  <button dojoType=\"dijit.form.Button\">\n";
    print "    Cancel\n";
    print "    <script type=\"dojo/method\" event=onClick>\n";
    print "      addResourceGroupPaneHide();\n";
    print "    </script>\n";
    print "  </button>\n";
    print "</TD>\n";
    print "</TR></TABLE>\n";
    $cont = addContinuationsEntry('AJsubmitAddResourcePriv');
    print "<INPUT type=hidden id=addresourcegroupcont value=\"{$cont}\">\n";
    print "</div>\n";
    print "<div dojoType=dijit.Dialog\n";
    print "     id=addNodePane\n";
    print "     title=\"Add Child Node\"\n";
    print "     duration=250\n";
    print "     draggable=true>\n";
    print "<H2>Add Child Node</H2>\n";
    print "<div id=addChildNodeName></div>\n";
    print "<strong>New Node:</strong>\n";
    print "<input type=text id=childNodeName dojoType=dijit.form.TextBox>\n";
    print "  <script type=\"dojo/connect\" event=onKeyPress args=\"e\">\n";
    print "    if(e.keyCode == dojo.keys.ENTER) {\n";
    print "      submitAddChildNode();\n";
    print "    }\n";
    print "  </script>\n";
    print "</input>\n";
    print "<div id=addChildNodeStatus></div>\n";
    print "<TABLE summary=\"\"><TR>\n";
    print "<TD>\n";
    print "  <button id=submitAddNodeBtn dojoType=\"dijit.form.Button\">\n";
    print "    Create Child\n";
    print "    <script type=\"dojo/method\" event=onClick>\n";
    print "      submitAddChildNode();\n";
    print "    </script>\n";
    print "  </button>\n";
    print "</TD>\n";
    print "<TD>\n";
    print "  <button id=cancelAddNodeBtn dojoType=\"dijit.form.Button\">\n";
    print "    Cancel\n";
    print "    <script type=\"dojo/method\" event=onClick>\n";
    print "      dojo.byId('childNodeName').value = '';\n";
    print "      dojo.byId('addChildNodeStatus').innerHTML = '';\n";
    print "      dijit.byId('addNodePane').hide();\n";
    print "    </script>\n";
    print "  </button>\n";
    print "</TD>\n";
    print "</TR></TABLE>\n";
    $cont = addContinuationsEntry('AJsubmitAddChildNode');
    print "<INPUT type=hidden id=addchildcont value=\"{$cont}\"\n>";
    print "</div>\n";
    print "<div dojoType=dijit.Dialog\n";
    print "     id=deleteDialog\n";
    print "     title=\"Delete Node(s)\"\n";
    print "     duration=250\n";
    print "     draggable=true>\n";
    print "Delete the following node and all of its children?<br><br>\n";
    print "<div id=deleteNodeName></div><br>\n";
    print "<div align=center>\n";
    print "<TABLE summary=\"\"><TR>\n";
    print "<TD>\n";
    print "  <button id=submitDeleteNodeBtn dojoType=\"dijit.form.Button\">\n";
    print "    Delete Nodes\n";
    print "    <script type=\"dojo/method\" event=onClick>\n";
    print "      deleteNodes();\n";
    print "    </script>\n";
    print "  </button>\n";
    print "</TD>\n";
    print "<TD>\n";
    print "  <button id=cancelDeleteNodeBtn dojoType=\"dijit.form.Button\">\n";
    print "    Cancel\n";
    print "    <script type=\"dojo/method\" event=onClick>\n";
    print "      dijit.byId('deleteDialog').hide();\n";
    print "    </script>\n";
    print "  </button>\n";
    print "</TD>\n";
    print "</TR></TABLE>\n";
    $cont = addContinuationsEntry('AJsubmitDeleteNode');
    print "<INPUT type=hidden id=delchildcont value=\"{$cont}\"\n>";
    print "</div>\n";
    print "</div>\n";
    print "<div dojoType=dijit.Dialog\n";
    print "     id=renameDialog\n";
    print "     title=\"Rename Node\"\n";
    print "     duration=250\n";
    print "     draggable=true>\n";
    print "Enter a new name for the selected node:<br><br>\n";
    print "<div id=renameNodeName></div><br>\n";
    print "<strong>New Name:</strong>\n";
    print "<input type=text id=newNodeName dojoType=dijit.form.TextBox>\n";
    print "  <script type=\"dojo/connect\" event=onKeyPress args=\"e\">\n";
    print "    if(e.keyCode == dojo.keys.ENTER) {\n";
    print "      renameNode();\n";
    print "    }\n";
    print "  </script>\n";
    print "</input>\n";
    print "<div id=renameNodeStatus></div>\n";
    print "<div align=center>\n";
    print "<TABLE summary=\"\"><TR>\n";
    print "<TD>\n";
    print "  <button id=submitRenameNodeBtn dojoType=\"dijit.form.Button\">\n";
    print "    Rename Node\n";
    print "    <script type=\"dojo/method\" event=onClick>\n";
    print "      renameNode();\n";
    print "    </script>\n";
    print "  </button>\n";
    print "</TD>\n";
    print "<TD>\n";
    print "  <button id=cancelRenameNodeBtn dojoType=\"dijit.form.Button\">\n";
    print "    Cancel\n";
    print "    <script type=\"dojo/method\" event=onClick>\n";
    print "      dijit.byId('renameDialog').hide();\n";
    print "    </script>\n";
    print "  </button>\n";
    print "</TD>\n";
    print "</TR></TABLE>\n";
    $cont = addContinuationsEntry('AJsubmitRenameNode');
    print "<INPUT type=hidden id=renamecont value=\"{$cont}\"\n>";
    print "</div>\n";
    print "</div>\n";
    print "<div dojoType=dijit.Dialog id=workingDialog duration=250 refocus=False>\n";
    print "Loading...\n";
    print "  <script type=\"dojo/connect\" event=_setup>\n";
    print "    dojo.addClass(dijit.byId('workingDialog').titleBar, 'hidden');\n";
    print "  </script>\n";
    print "</div>\n";
    if (!$hasManagePerms) {
        return;
    }
    print "</div>\n";
    # end privtree tab
    print "<div id=\"userpermtab\" dojoType=\"dijit.layout.ContentPane\" title=\"Additional User Permissions\">\n";
    print "<h2>Additional User Group Permissions</h2>\n";
    print "There are additional permisssions that can be assigned to user<br>\n";
    print "groups that are not specific to any nodes in the privilege tree.<br>\n";
    print "Use this portion of the site to manage those permissions.<br><br>\n";
    printSelectInput("editusergroupid", $groups, -1, 0, 0, 'editusergroupid', 'onChange="hideUserGroupPrivs();"');
    $cont = addContinuationsEntry('AJpermSelectUserGroup');
    print "<button dojoType=\"dijit.form.Button\">\n";
    print "  Manage User Group Permissions\n";
    print "  <script type=\"dojo/method\" event=onClick>\n";
    print "    selectUserGroup('{$cont}');\n";
    print "  </script>\n";
    print "</button>\n";
    print "<div id=\"extrapermsdiv\">\n";
    print "<table summary=\"\">\n";
    print "<tr>\n";
    print "<td nowrap>\n";
    print "<div id=\"usergroupprivs\" class=\"groupprivshidden\">\n";
    $privtypes = getUserGroupPrivTypes();
    foreach ($privtypes as $id => $type) {
        print "<span onMouseOver=\"showUserGroupPrivHelp('{$type['help']}', {$id});\" \n";
        print "onMouseOut=\"clearUserGroupPrivHelp({$id});\" id=\"grouptypespan{$id}\">\n";
        print "<input id=\"grouptype{$id}\" dojoType=\"dijit.form.CheckBox\" ";
        print "value=\"1\" name=\"{$id}\"><label for=\"grouptype{$id}\">{$type['name']}";
        print "</label></span><br>\n";
    }
    print "</div>\n";
    print "</td>\n";
    print "<td id=\"groupprivhelpcell\">\n";
    print "<fieldset style=\"height: 100%\";>\n";
    print "<legend>Permission Description</legend>\n";
    print "<div id=\"groupprivhelp\"></div>\n";
    print "</fieldset>\n";
    print "</td>\n";
    print "</tr>\n";
    print "</table><br><br>\n";
    print "Copy permissions from user group: ";
    printSelectInput("copyusergroupid", $groups, -1, 0, 0, 'copyusergroupid');
    $cont = addContinuationsEntry('AJpermSelectUserGroup');
    print "<button dojoType=\"dijit.form.Button\" id=\"usergroupcopyprivsbtn\" disabled>\n";
    print "  Copy Permissions\n";
    print "  <script type=\"dojo/method\" event=onClick>\n";
    print "    copyUserGroupPrivs('{$cont}');\n";
    print "  </script>\n";
    print "</button><br><br>\n";
    $cont = addContinuationsEntry('AJsaveUserGroupPrivs');
    print "<button dojoType=\"dijit.form.Button\" id=\"usergroupsaveprivsbtn\" disabled>\n";
    print "  Save Selected Permissions\n";
    print "  <script type=\"dojo/method\" event=onClick>\n";
    print "    saveUserGroupPrivs('{$cont}');\n";
    print "  </script>\n";
    print "</button><br>\n";
    print "<span id=\"userpermsubmitstatus\"></span>\n";
    print "</div>\n";
    print "</div>\n";
    # end userperm tab
    print "</div>\n";
    # end tab container
}