root/trunk/wifidog-auth/wifidog/classes/Server.php @ 1392

Revision 1392, 18.2 KB (checked in by benoitg, 4 years ago)

* Fix SQL query in last commit (mixed patches)

Line 
1<?php
2
3/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5// +-------------------------------------------------------------------+
6// | WiFiDog Authentication Server                                     |
7// | =============================                                     |
8// |                                                                   |
9// | The WiFiDog Authentication Server is part of the WiFiDog captive  |
10// | portal suite.                                                     |
11// +-------------------------------------------------------------------+
12// | PHP version 5 required.                                           |
13// +-------------------------------------------------------------------+
14// | Homepage:     http://www.wifidog.org/                             |
15// | Source Forge: http://sourceforge.net/projects/wifidog/            |
16// +-------------------------------------------------------------------+
17// | This program is free software; you can redistribute it and/or     |
18// | modify it under the terms of the GNU General Public License as    |
19// | published by the Free Software Foundation; either version 2 of    |
20// | the License, or (at your option) any later version.               |
21// |                                                                   |
22// | This program is distributed in the hope that it will be useful,   |
23// | but WITHOUT ANY WARRANTY; without even the implied warranty of    |
24// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     |
25// | GNU General Public License for more details.                      |
26// |                                                                   |
27// | You should have received a copy of the GNU General Public License |
28// | along with this program; if not, contact:                         |
29// |                                                                   |
30// | Free Software Foundation           Voice:  +1-617-542-5942        |
31// | 59 Temple Place - Suite 330        Fax:    +1-617-542-2652        |
32// | Boston, MA  02111-1307,  USA       gnu@gnu.org                    |
33// |                                                                   |
34// +-------------------------------------------------------------------+
35
36/**
37 * @package    WiFiDogAuthServer
38 * @author     Max Horvath <max.horvath@freenet.de>
39 * @author     Benoit Grégoire <bock@step.polymtl.ca>
40 * @copyright  2007 Benoit Grégoire, Technologies Coeus inc.
41 * @version    Subversion $Id: $
42 * @link       http://www.wifidog.org/
43 */
44
45/**
46 * Load required classes
47 */
48require_once('classes/GenericObject.php');
49require_once('classes/Security.php');
50define('SERVER_ID', 'SERVER_ID');
51/**
52 * Administration interface for configuring Server wide settings for the server WiFiDog is running on
53 *
54 * @package    WiFiDogAuthServer
55 * @author     Benoit Grégoire <bock@step.polymtl.ca>
56 * @copyright  2007 Benoit Grégoire, Technologies Coeus inc.
57 */
58class Server extends GenericDataObject
59{
60    /** Object cache for the object factory (getObject())*/
61    private static $instanceArray = array();
62
63    /**
64     * Constructor
65     *
66     * @param string $p_server_id Id of the server
67
68     */
69    private function __construct($p_server_id)
70    {
71
72        $db = AbstractDb::getObject();
73
74        // Init values
75        $row = null;
76
77        $serverId = $db->escapeString($p_server_id);
78        $sql = "SELECT * FROM server WHERE server_id='$serverId'";
79        $db->execSqlUniqueRes($sql, $row, false);
80
81        if ($row == null) {
82            throw new Exception("The server with id $serverId could not be found in the database!");
83        }
84
85        $this->_row = $row;
86
87        $this->_id = $db->escapeString($row['server_id']);
88    }
89
90    public function __toString() {
91        return _("Main server object");
92    }
93    /** Get an instance of the object
94     *
95     * @param string $id The object id
96     *
97     * @return object The object, or null if there was an error (an exception
98     *                is also thrown)
99     *
100     * @see GenericObject
101
102     */
103    public static function &getObject($id)
104    {
105        if(!isset(self::$instanceArray[$id]))
106        {
107            self::$instanceArray[$id] = new self($id);
108        }
109        return self::$instanceArray[$id];
110    }
111
112    /**
113     * Get the server object (there is only one)
114     *
115     * @return object A VirtualHost object, NEVER returns null
116     *
117     * @static
118     * @access public
119     */
120    public static function &getServer()
121    {
122        return self::getObject(SERVER_ID);
123    }
124    /**
125     * Create a new Content object in the database
126     *
127     * @param string $server_id The server id of the new server. If absent,
128     *                           will be assigned a guid.
129     *
130     * @return mixed The newly created object, or null if there was an error
131     *
132     * @see GenericObject
133     *
134     * @static
135     * @access public
136     */
137    public static function createNewObject($server_id = null)
138    {
139
140        $db = AbstractDb::getObject();
141
142        if (empty($server_id)) {
143            $server_id = get_guid();
144        }
145
146        $server_id = $db->escapeString($server_id);
147
148        $sql = "INSERT INTO servers (server_id) VALUES ('$server_id')";
149
150        if (!$db->execSqlUpdate($sql, false)) {
151            throw new Exception(_('Unable to insert the new server in the database!'));
152        }
153
154        $_object = self::getObject($server_id);
155
156        return $_object;
157
158    }
159
160    /** Get an interface to create a new object.
161     * @return html markup
162     */
163    public static function getCreateNewObjectUI()
164    {
165        throw new Exception ("Unsupported method");
166    }
167
168    /** Process the new object interface.
169     *  Will       return the new object if the user has the credentials
170     * necessary (Else an exception is thrown) and and the form was fully
171     * filled (Else the object returns null).
172     * @return the node object or null if no new node was created.
173     */
174    static function processCreateNewObjectUI()
175    {
176        throw new Exception ("Unsupported method");
177    }
178
179
180
181    /**
182     * Set as the default server
183     *
184     * @param VirtualHost $vhost
185     *
186     * @return bool True on success, false on failure
187     */
188    public function setDefaultVirtualHost(VirtualHost $vhost)
189    {
190
191        $db = AbstractDb::getObject();
192        $vhostIdStr = $db->escapeString($vhost->getId());
193        // Init values
194        $_retVal = false;
195
196        if ($vhostIdStr != VirtualHost::getDefaultVirtualHost()->getId()) {
197            $sql  = "UPDATE server SET default_virtual_host = '$vhostIdStr';\n";
198            $_retVal = $db->execSqlUpdate($sql, false);
199            $this->refresh();
200        }
201
202        return $_retVal;
203    }
204    /**
205     * Retrieves the servers's creation date
206     *
207     * @return string Creation date of server
208     *
209     * @access public
210     */
211    public function getCreationDate()
212    {
213        return $this->_row['creation_date'];
214    }
215
216    /**
217     * Retreives the admin interface of this object
218     *
219     * @return string The HTML fragment for this interface
220     */
221    public function getAdminUI()
222    {
223        Security::requirePermission(Permission::P('SERVER_PERM_EDIT_SERVER_CONFIG'), $this);
224        // Init values
225        $db = AbstractDb::getObject();
226        $html = '';
227
228        $html .= "<fieldset class='admin_container ".get_class($this)."'>\n";
229        $html .= "<legend>"._("Server management")."</legend>\n";
230        $html .= "<ul class='admin_element_list'>\n";
231        // server_id
232        /*$value = htmlspecialchars($this->getId(), ENT_QUOTES);
233
234        $html .= "<li class='admin_element_item_container'>\n";
235        $html .= "<div class='admin_element_label'>" . _("Server ID") . ":</div>\n";
236        $html .= "<div class='admin_element_data'>\n";
237        $html .= $value;
238        $html .= "</div>\n";
239        $html .= "</li>\n";*/
240
241        // creation_date
242        $name = "server_" . $this->getId() . "_creation_date";
243        $value = htmlspecialchars($this->getCreationDate(), ENT_QUOTES);
244
245        $html .= "<li class='admin_element_item_container'>\n";
246        $html .= "<div class='admin_element_label'>" . _("Creation date") . ":</div>\n";
247        $html .= "<div class='admin_element_data'>\n";
248        $html .= $value."\n";
249        $html .= "</div>\n";
250        $html .= "</li>\n";
251
252        //timezone check
253
254        $html .= "<li class='admin_element_item_container'>\n";
255        $html .= "<div class='admin_element_label'>" . _("Timezone check:  The following must be in the same timezone") . ":</div>\n";
256        $html .= "<div class='admin_element_data'>\n";
257        $html .= "<p>";
258        $db->execSqlUniqueRes("SHOW timezone", $row, false);
259        $html .= " ".sprintf(_("Timezone from postgresql: %s"), $row['TimeZone'])."</p>"; // Version < 5.0.0
260        $date_default_timezone_get = 'date_default_timezone_get';
261        is_callable($date_default_timezone_get)?$phpTimezone = date_default_timezone_get():$phpTimezone = "Requires PHP 5.1 to tell";
262        $html .= " ".sprintf(_("Timezone from PHP: %s"), $phpTimezone)."</p>"; // Version < 5.0.0
263
264        $html .= "</div>\n";
265        $html .= "</li>\n";
266
267        /*
268         * Authentication options
269         */
270        $title = _("Authentication");
271        $data = InterfaceElements::generateInputCheckbox("use_global_auth","", _("Use the users of default Virtual Host's network across all networks on the server."), $this->getUseGlobalUserAccounts(), "use_global_auth");
272
273        $html .= InterfaceElements::generateAdminSectionContainer("server_authentication_options",$title, $data);
274       
275        /*
276         * Access rights
277         */
278        if (true) {
279            require_once('classes/Stakeholder.php');
280            $html_access_rights = Stakeholder::getAssignStakeholdersUI($this);
281            $html .= InterfaceElements::generateAdminSectionContainer("access_rights", _("Access rights"), $html_access_rights);
282        }
283       
284        $html .= "</ul>\n";
285        $html .= "</fieldset>\n";
286        return $html;
287    }
288
289    /**
290     * Process admin interface of this object
291     *
292     * @return void
293     */
294    public function processAdminUI()
295    {
296        require_once('classes/User.php');
297        Security::requirePermission(Permission::P('SERVER_PERM_EDIT_SERVER_CONFIG'), $this);
298        // Authentication
299        if (isset($_REQUEST['use_global_auth']))
300                $this->setUseGlobalUserAccounts($_REQUEST['use_global_auth']);
301        else
302                $this->setUseGlobalUserAccounts(false);
303        // Access rights
304        require_once('classes/Stakeholder.php');
305        Stakeholder::processAssignStakeholdersUI($this, $errMsg);
306        if(!empty($errMsg)) {
307            echo $errMsg;
308        }
309    }
310
311    /**
312     * Delete this Object form the it's storage mechanism
313     *
314     * @param string &$errmsg Returns an explanation of the error on failure
315     *
316     * @return bool True on success, false on failure or access denied
317     */
318    public function delete(&$errmsg)
319    {
320        $errmsg = _('The server can never be deleted!');
321        return false;
322    }
323    /** Menu hook function */
324    static public function hookMenu() {
325        $items = array();
326        $server = self::getServer();
327        if(Security::hasPermission(Permission::P('SERVER_PERM_EDIT_SERVER_CONFIG'), $server))
328        {
329            $items[] = array('path' => 'server/admin',
330            'title' => _("Server configuration"),
331            'url' => BASE_URL_PATH.htmlspecialchars("admin/generic_object_admin.php?object_class=Server&action=edit&object_id=".SERVER_ID."")
332                );
333        }
334        $items[] = array('path' => 'server',
335        'title' => _('Server administration'),
336        'type' => MENU_ITEM_GROUPING);
337
338        return $items;
339    }
340    /**
341     * Reloads the object from the database
342     *
343     * Should normally be called after a set operation
344     *
345     * @return void     */
346    protected function refresh()
347    {
348        $this->__construct($this->_id);
349    }
350
351    /**
352     * Getter for UseGlobalUserAccounts
353     *
354     * @return bool
355     */
356    public function getUseGlobalUserAccounts()
357    {
358        if (array_key_exists('use_global_auth',$this->_row))
359                return $this->_row['use_global_auth']=='t';
360        else
361                return False;
362    } 
363
364    /**
365     * Setter for UseGlobalUserAccounts
366     *
367     * @param bool $value       New value
368     *
369     * @return bool True on success, false on failure
370     */
371    public function setUseGlobalUserAccounts($value)
372    {
373        $db = AbstractDb::getObject();
374        $value = $value? true:false;
375        // Init values
376        $retVal = true;
377
378        if ($value != $this->getUseGlobalUserAccounts()) {
379            $value = $value ? 'true' : 'false';
380            $retVal = $db->execSqlUpdate("UPDATE server SET use_global_auth = {$value} WHERE server_id = '{$this->getId()}'", false);
381            $this->refresh();
382        }
383
384        return $retVal;
385    } 
386
387    /**
388     * Find out how many users are online on the whole server (Actually the number of active connections.
389     * This result is possibly incorrect, as it donesn't treat annonymous connections, or multiple connections differently
390     * @return int Number of online users
391     *
392     * @access public
393     */
394    public function getTotalNumOnlineUsers()
395    {
396        $db = AbstractDb::getObject();
397        // Init values
398        $retval = array ();
399        $row = null;
400        $sql = "SELECT COUNT(token_id) as count FROM tokens JOIN connections USING (token_id) WHERE tokens.token_status='".TOKEN_INUSE."'";     
401        $db->execSqlUniqueRes($sql, $row, false);
402        return $row['count'];
403    }
404
405    /**
406     * Find out how many users are valid in this server's database
407     *
408     * @return int Number of valid users
409     */
410    public function getTotalNumValidUsers()
411    {
412
413        $db = AbstractDb::getObject();
414
415        // Init values
416        $retval = 0;
417        $row = null;
418        $useCache = false;
419        $cachedData = null;
420
421        // Create new cache objects (valid for 1 minute)
422        $cache = new Cache('server_num_valid_users', "default", 60);
423
424        // Check if caching has been enabled.
425        if ($cache->isCachingEnabled) {
426            $cachedData = $cache->getCachedData();
427
428            if ($cachedData) {
429                // Return cached data.
430                $useCache = true;
431                $retval = $cachedData;
432            }
433        }
434
435        if (!$useCache) {
436            // Get number of valid users
437            $network_id = $db->escapeString($this->_id);
438            $db->execSqlUniqueRes("SELECT COUNT(user_id) FROM users WHERE account_status = ".ACCOUNT_STATUS_ALLOWED, $row, false);
439            // String has been found
440            $retval = $row['count'];
441
442            // Check if caching has been enabled.
443            if ($cache->isCachingEnabled) {
444                // Save data into cache, because it wasn't saved into cache before.
445                $cache->saveCachedData($retval);
446            }
447        }
448
449        return $retval;
450    }
451
452    /**
453     * Find out how many nodes are deployed in this server's database
454     *
455     * @return int Number of deployed nodes
456     */
457    public function getTotalNumDeployedNodes()
458    {
459
460        $db = AbstractDb::getObject();
461
462        // Init values
463        $retval = 0;
464        $row = null;
465        $useCache = false;
466        $cachedData = null;
467
468        // Create new cache objects (valid for 5 minutes)
469        $cache = new Cache('server_num_deployed_nodes', "default", 300);
470
471        // Check if caching has been enabled.
472        if ($cache->isCachingEnabled) {
473            $cachedData = $cache->getCachedData();
474
475            if ($cachedData) {
476                // Return cached data.
477                $useCache = true;
478                $retval = $cachedData;
479            }
480        }
481
482        if (!$useCache) {
483            // Get number of deployed nodes
484            $network_id = $db->escapeString($this->_id);
485            $db->execSqlUniqueRes("SELECT COUNT(node_id) FROM nodes WHERE (node_deployment_status = 'DEPLOYED' OR node_deployment_status = 'NON_WIFIDOG_NODE')", $row, false);
486
487            // String has been found
488            $retval = $row['count'];
489
490            // Check if caching has been enabled.
491            if ($cache->isCachingEnabled) {
492                // Save data into cache, because it wasn't saved into cache before.
493                $cache->saveCachedData($retval);
494            }
495        }
496
497        return $retval;
498    }
499
500    /**
501     * Find out how many deployed nodes are online in this server's database
502     *
503     * @param bool $nonMonitoredOnly Return number of non-monitored nodes only
504     *
505     * @return int Number of deployed nodes which are online
506     */
507    public function getNumOnlineNodes($nonMonitoredOnly = false)
508    {
509
510        $db = AbstractDb::getObject();
511
512        // Init values
513        $retval = 0;
514        $row = null;
515        $useCache = false;
516        $cachedData = null;
517
518        // Create new cache objects (valid for 5 minutes)
519        if ($nonMonitoredOnly) {
520            $cache = new Cache('server_num_online_nodes_non_monitored', "default", 300);
521        } else {
522            $cache = new Cache('server_num_online_nodes', "default", 300);
523        }
524
525        // Check if caching has been enabled.
526        if ($cache->isCachingEnabled) {
527            $cachedData = $cache->getCachedData();
528
529            if ($cachedData) {
530                // Return cached data.
531                $useCache = true;
532                $retval = $cachedData;
533            }
534        }
535
536        if (!$useCache) {
537            // Get number of online nodes
538            $network_id = $db->escapeString($this->_id);
539
540            if ($nonMonitoredOnly) {
541                $db->execSqlUniqueRes("SELECT COUNT(node_id) FROM nodes WHERE node_deployment_status = 'NON_WIFIDOG_NODE' AND ((CURRENT_TIMESTAMP-last_heartbeat_timestamp) >= interval '5 minutes')", $row, false);
542            } else {
543                $db->execSqlUniqueRes("SELECT COUNT(node_id) FROM nodes WHERE (node_deployment_status = 'DEPLOYED' OR node_deployment_status = 'NON_WIFIDOG_NODE') AND ((CURRENT_TIMESTAMP-last_heartbeat_timestamp) < interval '5 minutes')", $row, false);
544            }
545
546            // String has been found
547            $retval = $row['count'];
548
549            // Check if caching has been enabled.
550            if ($cache->isCachingEnabled) {
551                // Save data into cache, because it wasn't saved into cache before.
552                $cache->saveCachedData($retval);
553            }
554        }
555
556        return $retval;
557    }
558}
559
560/*
561 * Local variables:
562 * tab-width: 4
563 * c-basic-offset: 4
564 * c-hanging-comment-ender-p: nil
565 * End:
566 */
Note: See TracBrowser for help on using the browser.