Changeset 1261

Show
Ignore:
Timestamp:
07/21/07 00:59:33 (6 years ago)
Author:
benoitg
Message:
  • At long last, implement #9: Automatic new node creation. When attempting to login from an unknown node, the user (if he has the permissions) will be prompted to create the node, or "steal" en existing one (for hardware swaps).
  • Refactor Node:getSelectNodeUI().
  • Menu.php: Fix small oversight causing menu not to clear.
Location:
trunk/wifidog-auth
Files:
11 modified

Legend:

Unmodified
Added
Removed
  • trunk/wifidog-auth/CHANGELOG

    r1260 r1261  
    1 # $Id: $ 
    2  
     1# $Id$ 
     2 
     32007-07-20 Benoit Grégoire  <bock@step.polymtl.ca> 
     4        * At long last, implement #9:  Automatic new node creation.  When attempting to login from an unknown node, the user (if he has the permissions) will be prompted to create the node, or "steal" en existing one (for hardware swaps). 
     5        * Refactor Node:getSelectNodeUI(). 
     6        * Menu.php:  Fix small oversight causing menu not to clear. 
     7         
    382007-07-19 Benoit Grégoire  <bock@step.polymtl.ca> 
    49        UIUserList fixes: 
  • trunk/wifidog-auth/sql/wifidog-postgres-initial-data.sql

    r1250 r1261  
    215215-- 
    216216 
    217 INSERT INTO schema_info (tag, value) VALUES ('schema_version', '54'); 
     217INSERT INTO schema_info (tag, value) VALUES ('schema_version', '56'); 
    218218 
    219219 
  • trunk/wifidog-auth/sql/wifidog-postgres-schema.sql

    r1250 r1261  
    532532    is_splash_only_node boolean DEFAULT false, 
    533533    custom_portal_redirect_url text, 
    534     gw_id text NOT NULL 
     534    gw_id text NOT NULL, 
     535    last_heartbeat_sys_uptime integer, 
     536    last_heartbeat_wifidog_uptime integer, 
     537    last_heartbeat_sys_memfree integer, 
     538    last_heartbeat_sys_load real 
    535539); 
    536540 
     
    11581162 
    11591163-- 
     1164-- Name: idx_connections_timestamp_in; Type: INDEX; Schema: public; Owner: -; Tablespace:  
     1165-- 
     1166 
     1167CREATE INDEX idx_connections_timestamp_in ON connections USING btree (timestamp_in); 
     1168 
     1169 
     1170-- 
    11601171-- Name: idx_connections_user_id; Type: INDEX; Schema: public; Owner: -; Tablespace:  
    11611172-- 
  • trunk/wifidog-auth/wifidog/admin/generic_object_admin.php

    r1249 r1261  
    202202        $html .= _("Node"); 
    203203        $html .= ": "; 
    204         $html .= Node :: getSelectNodeUI($name); 
     204        $html .= Node :: getSelectUI($name); 
    205205 
    206206        if (method_exists($object, "getUserUI")) { 
     
    274274            case "Node" : 
    275275                $newLongText = $addLongText; 
    276                 $objectSelector = Node :: getSelectNodeUI('object_id', null, null, null, "table"); 
     276                $userData['typeInterface'] = "table"; 
     277                $objectSelector = Node :: getSelectUI('object_id', $userData); 
    277278                $displayEditButton = false; 
    278279                break; 
  • trunk/wifidog-auth/wifidog/classes/Content/ContentGroup/ContentGroupElement.php

    r1249 r1261  
    355355        $html .= "<li class='admin_element_item_container'>\n"; 
    356356 
    357         $sql_additional_where = "AND node_id NOT IN (SELECT node_id FROM content_group_element_has_allowed_nodes WHERE content_group_element_id='$this->id')"; 
     357        $userDataNode['additionalWhere'] = "AND node_id NOT IN (SELECT node_id FROM content_group_element_has_allowed_nodes WHERE content_group_element_id='$this->id')"; 
    358358        $name = "content_group_element_{$this->id}_new_allowed_node"; 
    359         $html .= Node :: getSelectNodeUI($name, null, $sql_additional_where); 
     359        $html .= Node :: getSelectUI($name, $userDataNode); 
    360360        $name = "content_group_element_{$this->id}_new_allowed_node_submit"; 
    361361        $html .= "<input type='submit' name='$name' value='" . _("Add new allowed node") . "'>"; 
     
    440440        if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == true) { 
    441441            $name = "content_group_element_{$this->id}_new_allowed_node"; 
    442             $node = Node :: processSelectNodeUI($name); 
     442            $node = Node :: processSelectUI($name); 
    443443            $node_id = $node->GetId(); 
    444444            $db->execSqlUpdate("INSERT INTO content_group_element_has_allowed_nodes (content_group_element_id, node_id) VALUES ('$this->id', '$node_id')", FALSE); 
  • trunk/wifidog-auth/wifidog/classes/Menu.php

    r1256 r1261  
    230230        } 
    231231        $html .= "</ul>\n"; 
    232                 $html .= "<br/ class='clear'>\n"; 
     232                $html .= "<br/ class='clearbr'>\n"; 
    233233        //echo htmlspecialchars($userData['html']); 
    234234        return $html; 
  • trunk/wifidog-auth/wifidog/classes/Network.php

    r1255 r1261  
    221221     *                                     programmer to recognise it's 
    222222     *                                     generated html form 
    223      * @param object $preSelectedObject Network object: The network to be 
    224      *                                     pre-selected in the form object 
    225      * @param string $additionalWhere     Additional SQL conditions for the 
    226      *                                     networks to select 
    227      * @param string $allowEmpty     boolean Allow not selecting any network 
     223     *  
     224     * @param string $userData=null Array of contextual data optionally sent to the method. 
     225     *  The function must still function if none of it is present. 
     226     * 
     227     * This method understands: 
     228     *  $userData['preSelectedObject'] An optional object to pre-select. 
     229     *  $userData['additionalWhere'] Additional SQL conditions for the 
     230     *                                    objects to select 
     231     *  $userData['allowEmpty'] boolean Allow not selecting any object 
    228232     * @return string HTML markup 
    229233 
  • trunk/wifidog-auth/wifidog/classes/Node.php

    r1260 r1261  
    278278     * @param $user_prefix A identifier provided by the programmer to recognise it's generated html form 
    279279     * 
    280      * @param $sql_additional_where Addidional where conditions to restrict the candidate objects 
    281      * @param $type_interface:  select, select_multiple or table 
    282      * @param $selectedNodes; Node object or array of node objects to be pre-selected (not 
     280     * @param string $userData=null Array of contextual data optionally sent to the method. 
     281     *  The function must still function if none of it is present. 
     282     * This method understands: 
     283     *  $userData['preSelectedObject'] An optional object to pre-select. 
     284     *  $userData['additionalWhere'] Additional SQL conditions for the 
     285     *                                    objects to select 
     286     *  $userData['additionalJoin'] Additional SQL JOIN conditions for the 
     287     *                                    objects to select 
     288     *  $userData['preSelectedObjects'] An optional object or array of objects to pre-select. (not 
    283289     * supported by type_interface=table) 
     290     *  $userData['typeInterface'] select, select_multiple or table.  Default is "select" 
     291     * 
    284292     * * @return html markup 
    285293     */ 
    286     public static function getSelectNodeUI($user_prefix, $sql_additional_join = null, $sql_additional_where = null,$selectedNodes = null, $type_interface = "select") 
    287     { 
     294    public static function getSelectUI($user_prefix, $userData=null) 
     295    { 
     296        !empty($userData['additionalJoin'])?$sql_additional_join=$userData['additionalJoin']:$sql_additional_join=null; 
     297        !empty($userData['additionalWhere'])?$sql_additional_where=$userData['additionalWhere']:$sql_additional_where=null; 
     298        !empty($userData['preSelectedObjects'])?$selectedNodes=$userData['preSelectedObjects']:$selectedNodes=null; 
     299        !empty($userData['typeInterface'])?$type_interface=$userData['typeInterface']:$type_interface="select"; 
     300 
    288301        $db = AbstractDb::getObject(); 
    289302        $html = ''; 
     
    380393     * @return the node object 
    381394     */ 
    382     static function processSelectNodeUI($user_prefix) 
     395    static function processSelectUI($user_prefix) 
    383396    { 
    384397        $object = null; 
     
    455468        return $retval; 
    456469    } 
     470 
     471 
     472    /** Get an interface to deal with missing nodes.  If the user has the permissions, he will be asked to create a new node for that gateway id, or assign that gateway id to an existing node. 
     473     * @param $gwId The unknown gwId 
     474     * @return html markup 
     475     */ 
     476    public static function getStealOrCreateNewUI($gwId) 
     477    { 
     478        $permissionArray[]=array(Permission::P('NETWORK_PERM_EDIT_ANY_NODE_CONFIG'), null); 
     479        $permissionArray[]=array(Permission::P('NODE_PERM_EDIT_GATEWAY_ID'), null); 
     480        Security::requireAnyPermission($permissionArray); 
     481        $db = AbstractDb::getObject(); 
     482        $html = ''; 
     483        $allowedNetworks = Security::getObjectsWithPermission(Permission::P('NETWORK_PERM_EDIT_ANY_NODE_CONFIG')); 
     484        $allowedNodes = Security::getObjectsWithPermission(Permission::P('NODE_PERM_EDIT_GATEWAY_ID')); 
     485        $html .= "<p>"._("Here is what you can do to fix this:")."</p>\n"; 
     486        $html .= "<ul>\n"; 
     487        if($allowedNetworks) { 
     488            //Add a new node for unknown node id 
     489            $html .= "<li>".sprintf(_("You can create a new node with %s as it's associated gateway id.  This is typical for new installations."), $gwId)."<br/>\n"; 
     490 
     491            $networkAdditionalWhere=" AND (FALSE\n"; 
     492            foreach ($allowedNetworks as $network) { 
     493                $idStr = $db->escapeString($network->getId()); 
     494                $networkAdditionalWhere .= " OR network_id='$idStr'\n"; 
     495            } 
     496            $networkAdditionalWhere .= ")\n"; 
     497            $userData['preSelectedObject']=null; 
     498            $userData['allowEmpty']=true; 
     499            $userData['additionalWhere']=$networkAdditionalWhere; 
     500            $name = "{$gwId}_new_node_network"; 
     501            $networkSelectUI = Network :: getSelectUI($name, $userData); 
     502            $html .= sprintf(_("Add a new node in %s"), $networkSelectUI)." \n"; 
     503            $name = "{$gwId}_new_node_submit"; 
     504            $value = _("Add node"); 
     505            $html .= "<input type='submit' size='10' name='{$name}' value='$value'>\n"; 
     506            $html .= "</li>\n"; 
     507        } 
     508 
     509        if($allowedNetworks || $allowedNodes){ 
     510            //"Steal" an existing node for this ID (typically for hardware replacement) 
     511            $html .= "<li>".sprintf(_("You can \"steal\" an existing node.  The node's gateway id will be replaced with %s.  This is typical when replacing hardware."), $gwId)."<br/>\n"; 
     512            if($allowedNetworks) { 
     513                $additionalWhere=$networkAdditionalWhere; 
     514            } 
     515            else { 
     516                $additionalWhere=" AND (FALSE\n"; 
     517                foreach ($allowedNetworks as $network) { 
     518                    $idStr = $db->escapeString($node->getId()); 
     519                    $additionalWhere .= " OR node_id='$idStr'\n"; 
     520                } 
     521                $additionalWhere .= ")\n"; 
     522            } 
     523 
     524            $userData['preSelectedObject']=null; 
     525            $userData['allowEmpty']=true; 
     526            $userData['additionalWhere']=$additionalWhere; 
     527            $name = "{$gwId}_steal_node"; 
     528            $html .= Node :: getSelectUI($name, $userData); 
     529            $name = "{$gwId}_steal_node_submit"; 
     530            $value = _("Steal node"); 
     531            $html .= "<input type='submit' size='10' name='{$name}' value='$value'>\n"; 
     532            $html .= "</li>\n"; 
     533        } 
     534        $html .= "</ul>\n"; 
     535        return $html; 
     536 
     537    } 
     538 
     539    /** 
     540     * Process the interface to deal with missing nodes. 
     541     * @param $gwId The unknown gwId 
     542     * @param $nodeIsNew Output parameter.  Will be set to true if a new node was created to resolve the situation 
     543     * @return the created or stolen node object, or null if none was created (or stolen). 
     544     */ 
     545    public static function processStealOrCreateNewUI($gwId, &$nodeIsNew=null) 
     546    { 
     547        // Init values 
     548        $retval = null; 
     549        $nodeIsNew = false; 
     550        $name = "{$gwId}_new_node_submit"; 
     551        if(!empty($_REQUEST[$name])) { 
     552            //Create new node 
     553            $name = "{$gwId}_new_node_network"; 
     554            $network = Network :: processSelectUI($name); 
     555            if($network) { 
     556                Security::requirePermission(Permission::P('NETWORK_PERM_EDIT_ANY_NODE_CONFIG'), $network); 
     557                //echo  _("Adding node"); 
     558                $node = Node::createNewObject($gwId, $network); 
     559                $nodeIsNew = true; 
     560                $retval = $node; 
     561            } 
     562        } 
     563        $name = "{$gwId}_steal_node_submit"; 
     564        if(!empty($_REQUEST[$name])){ 
     565            //"Steal" an existing node for this ID (typically for hardware replacement) 
     566            $name = "{$gwId}_steal_node"; 
     567            $node = Node :: processSelectUI($name); 
     568            if($node) { 
     569                $permissionArray[]=array(Permission::P('NETWORK_PERM_EDIT_ANY_NODE_CONFIG'), $node->getNetwork()); 
     570                $permissionArray[]=array(Permission::P('NODE_PERM_EDIT_GATEWAY_ID'), $node); 
     571                Security::requireAnyPermission($permissionArray); 
     572                //echo _("Stealing node $node"); 
     573                $node->setGatewayId($gwId); 
     574                $retval = $node; 
     575            } 
     576        } 
     577 
     578 
     579        return $retval; 
     580    } 
     581 
     582 
    457583 
    458584    /** 
  • trunk/wifidog-auth/wifidog/classes/Security.php

    r1249 r1261  
    7676                $permission = $permissionsCheck[0]; 
    7777                $targetObject = $permissionsCheck[1]; 
    78                 $object_class = get_class($targetObject); 
    79                 if($permission->getTargetObjectClass()!=$object_class) { 
    80                     throw new Exception(sprintf("Tried to check if an object of class %s has a permission of type %s",$object_class, $permission->getTargetObjectClass())); 
    81                 } 
    82                 $table = strtolower($object_class).'_stakeholders'; 
    83                 $object_id = $db->escapeString($targetObject->getId()); 
     78                $objectClass = $permission->getTargetObjectClass(); 
     79                if($targetObject) { 
     80                    if($objectClass!=get_class($targetObject)) { 
     81                        throw new Exception(sprintf("Tried to check if an object of class %s has a permission of type %s",$objectClass, get_class($targetObject))); 
     82                    } 
     83                    $objectId = $db->escapeString($targetObject->getId()); 
     84                    $objectSqlAnd = "\n AND object_id = '$objectId' \n"; 
     85                } 
     86                else { 
     87                    $objectSqlAnd = ''; 
     88                } 
     89                $table = strtolower($objectClass).'_stakeholders'; 
    8490                $permissionIdStr = $db->escapeString($permission->getId()); 
    85  
    86  
    87                 $sqlSelect = "SELECT permission_id FROM $table JOIN role_has_permissions USING (role_id) WHERE object_id = '$object_id' AND user_id='{$user->getId()}' AND permission_id = '$permissionIdStr'"; 
     91                $sqlSelect = "SELECT permission_id FROM $table JOIN role_has_permissions USING (role_id) WHERE user_id='{$user->getId()}' $objectSqlAnd AND permission_id = '$permissionIdStr'"; 
    8892                if($operator == 'OR') { 
    8993                    $first?$sql .= " ($sqlSelect)\n":$sql .= ", ($sqlSelect)\n"; 
     
    122126    /* Check if the current user has the requested permission 
    123127     * @param permission The permission to check 
    124      * @param $targetObject The Object on which the permssion applies (Network, Server, etc.) 
    125      * @param user User object, optional, if unspecified, the current user is used.  Note that there may be no current user (annonymous) 
    126      */ 
    127     public static function hasPermission(Permission $permission, $targetObject, $user=null) 
     128     * @param $targetObject The Object on which the permssion applies (Network, Server, etc.)  If null, the user must have this permission on at least one object 
     129     * @param user User object, optional, if unspecified, the current user is used.  Note that there may be no current user (annonymous) 
     130     */ 
     131    public static function hasPermission(Permission $permission, $targetObject=null, $user=null) 
    128132    { 
    129133        return self::hasPermissionsHelper(array(array($permission, $targetObject)), 'AND', $user); 
    130134    } 
    131      
    132         /* Check if the current user has ANY of the requested permission 
     135 
     136    /* Check if the current user has ANY of the requested permission 
    133137     * @param $permissionsArray An two dimensionnal array of permissions to check 
    134138     * permissionsArray[]=array($permission, $targetObject); 
     
    149153        return self::hasPermissionsHelper($permissionsArray, 'AND', $user); 
    150154    } 
    151      
     155 
    152156    /* require that the user has the current permission, otherwise, throw up an interface to deal with the proplem 
    153157     * @param permission The permission to check 
    154      * @param $targetObject The Object on which the permssion applies (Network, Server, etc.) 
    155      * @param user User object, optional, if unspecified, the current user is used.  Note that there may be no current user (annonymous) 
    156      */ 
    157     public static function requirePermission(Permission $permission, $targetObject) 
     158     * @param $targetObject The Object on which the permission applies (Network, Server, etc.).  If null, the user must have this permission on at least one object 
     159     * @param user User object, optional, if unspecified, the current user is used.  Note that there may be no current user (annonymous) 
     160     */ 
     161    public static function requirePermission(Permission $permission, $targetObject=null) 
    158162    { 
    159163        $hasPermission = self::hasPermission($permission, $targetObject, User::getCurrentUser()); 
     
    177181        return true; 
    178182    } 
    179      
     183 
    180184    /* Require that the user has ALL of the requested permissions 
    181185     * @param $permissionsArray A two dimensionnal array of permissions to check 
     
    191195        return true; 
    192196    } 
    193      
     197 
    194198    private static function handleMissingPermissions(Array $permissionsArray) 
    195199    { 
     
    199203            $targetObject = $permissionsCheck[1]; 
    200204            if(!self::hasPermission($permission, $targetObject)) { 
    201                 $missingPerms .= sprintf(_("%s (%s) on  %s object %s")."<br/>\n", $permission->getId(), $permission->getDescription(), get_class($targetObject), (string)$targetObject); 
     205                $missingPerms .= sprintf(_("%s (%s) on  %s: %s")."<br/>\n", $permission->getId(), $permission->getDescription(), $permission->getTargetObjectClass(), $targetObject?(string)$targetObject:_('Any')); 
    202206            } 
    203207        } 
     
    205209        throw new SecurityException($msg); 
    206210    } 
    207      
     211 
    208212    /* Returns an array of objects for which the user has the specified permission 
    209213     * @param permission The permission to check 
  • trunk/wifidog-auth/wifidog/classes/Statistics.php

    r1249 r1261  
    387387        $selectedNodes = $this->getSelectedNodes(); 
    388388        $sql = "SELECT nodes.node_id, nodes.name from nodes $sql_join WHERE 1=1 ORDER BY lower(nodes.node_id)"; 
    389         $html .= Node :: getSelectNodeUI($name, $sql_join, null, $selectedNodes, "select_multiple"); 
     389        $userData['preSelectedObjects']=$selectedNodes; 
     390                $userData['sqlJoin']=$sql_join; 
     391                                $userData['typeInterface']="select_multiple"; 
     392        $html .= Node :: getSelectUI($name, $userData); 
    390393        return $html; 
    391394    } 
  • trunk/wifidog-auth/wifidog/login/index.php

    r1249 r1261  
    132132    try { 
    133133        $node = Node::getObjectByGatewayId($gw_id); 
    134         if($node) 
    135         { 
    136             $session->set(SESS_NODE_ID_VAR, $node->getId()); 
     134    } 
     135 
     136    catch (Exception $e) { 
     137        $returnedNodeIsNew = false; 
     138        $node = Node::processStealOrCreateNewUI($gw_id, $returnedNodeIsNew); 
     139 
     140        if(!$node){ 
     141            $ui = MainUI::getObject(); 
     142            $ui->addContent('main_area_middle', '<p class=errormsg>'.$e->getMessage()."</p>\n", 1); 
     143            $stealNodeForm=null; 
     144            $stealNodeForm.="<form action='' method='POST'>\n"; 
     145            $stealNodeForm.=Node::getStealOrCreateNewUI($gw_id); 
     146            $stealNodeForm.="</form>\n"; 
     147            $ui->addContent('main_area_middle',$stealNodeForm,2); 
     148            $ui->display(); 
     149            exit; 
    137150        } 
    138     } 
    139  
    140     catch (Exception $e) { 
    141         $ui = MainUI::getObject(); 
    142         $ui->displayError($e->getMessage()); 
    143         exit; 
    144     } 
    145  
     151        else { 
     152            if($returnedNodeIsNew) { 
     153                $url = BASE_URL_PATH."admin/generic_object_admin.php?object_class=Node&action=edit&object_id=".$node->getId(); 
     154                header("Location: {$url}"); 
     155                exit; 
     156            } 
     157        } 
     158    } 
     159    if($node) 
     160    { 
     161        $session->set(SESS_NODE_ID_VAR, $node->getId()); 
     162    } 
    146163    $network = $node->getNetwork(); 
    147164} else {