root/branches/fsheedy/wifidog/classes/User.php @ 1442

Revision 1442, 52.1 KB (checked in by fsheedy, 3 years ago)

Node Bypass abuse dynamic control first draft

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1<?php
2
3
4/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
5
6// +-------------------------------------------------------------------+
7// | WiFiDog Authentication Server                                     |
8// | =============================                                     |
9// |                                                                   |
10// | The WiFiDog Authentication Server is part of the WiFiDog captive  |
11// | portal suite.                                                     |
12// +-------------------------------------------------------------------+
13// | PHP version 5 required.                                           |
14// +-------------------------------------------------------------------+
15// | Homepage:     http://www.wifidog.org/                             |
16// | Source Forge: http://sourceforge.net/projects/wifidog/            |
17// +-------------------------------------------------------------------+
18// | This program is free software; you can redistribute it and/or     |
19// | modify it under the terms of the GNU General Public License as    |
20// | published by the Free Software Foundation; either version 2 of    |
21// | the License, or (at your option) any later version.               |
22// |                                                                   |
23// | This program is distributed in the hope that it will be useful,   |
24// | but WITHOUT ANY WARRANTY; without even the implied warranty of    |
25// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     |
26// | GNU General Public License for more details.                      |
27// |                                                                   |
28// | You should have received a copy of the GNU General Public License |
29// | along with this program; if not, contact:                         |
30// |                                                                   |
31// | Free Software Foundation           Voice:  +1-617-542-5942        |
32// | 59 Temple Place - Suite 330        Fax:    +1-617-542-2652        |
33// | Boston, MA  02111-1307,  USA       gnu@gnu.org                    |
34// |                                                                   |
35// +-------------------------------------------------------------------+
36
37/**
38 * @package    WiFiDogAuthServer
39 * @author     Benoit Grégoire <benoitg@coeus.ca>
40 * @copyright  2005-2006 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/Network.php');
49require_once ('classes/InterfaceElements.php');
50require_once ('classes/ProfileTemplate.php');
51require_once ('classes/Profile.php');
52require_once ('classes/Permission.php');
53/**
54 * Abstract a User
55 *
56 * @package    WiFiDogAuthServer
57 * @author     Benoit Grégoire <benoitg@coeus.ca>
58 * @copyright  2005-2006 Benoit Grégoire, Technologies Coeus inc.
59 */
60class User implements GenericObject {
61    private $_row;
62    private $id;
63    /** Object cache for the object factory (getObject())*/
64    private static $instanceArray = array();
65
66    /** Instantiate a user object
67     * @param $id The user id of the requested user
68     * @return a User object, or null if there was an error
69     */
70    public static function &getObject($id) {
71        if(!isset(self::$instanceArray[$id]))
72        {
73            self::$instanceArray[$id] = new self($id);
74        }
75        return self::$instanceArray[$id];
76    }
77
78    static function createNewObject() {
79        echo "<h1>Use User::createUser() instead</h1>";
80    }
81    /** Get an interface to create a new object.
82     * @return html markup
83     */
84    public static function getCreateNewObjectUI() {
85        return null;
86    }
87
88    /** Process the new object interface.
89     *  Will       return the new object if the user has the credentials
90     * necessary (Else an exception is thrown) and and the form was fully
91     * filled (Else the object returns null).
92     * @return the node object or null if no new node was created.
93     */
94    static function processCreateNewObjectUI() {
95        return self :: createNewObject();
96    }
97    /**
98     * Instantiate the current user
99     *
100     * @return mixed A User object, or null if there was an error
101
102     */
103    public static function getCurrentUser() {
104        require_once ('classes/Session.php');
105        $session = Session::getObject();
106        $sessCurrentUserId = $session->get(SESS_USER_ID_VAR);
107        $user = null;
108        if(!empty($sessCurrentUserId)){
109            try {
110                $user = self :: getObject($sessCurrentUserId);
111                //$user = new User($session->get(SESS_USER_ID_VAR));
112            } catch (Exception $e) {
113                /**If any problem occurs, the user should be considered logged out*/
114                $session->set(SESS_USER_ID_VAR, null);
115            }
116        }
117        return $user;
118    }
119
120    /**
121     * Associates the user passed in parameter with the session
122     *
123     * This should NOT be called by anything except the Authenticators
124     *
125     * @param object $user User a user object, or null
126     *
127     * @return bool True if everything went well setting the session
128
129     */
130    public static function setCurrentUser($user) {
131
132        if (get_class($user) == 'User'){
133            $userId = $user->getId();
134            $passwordHash = $user->getPasswordHash();
135        }
136        else {
137            $userId = null;
138            $passwordHash = null;
139        }
140
141        try {
142            $session = Session::getObject();
143            $session->set(SESS_USER_ID_VAR, $userId);
144            $session->set(SESS_PASSWORD_HASH_VAR, $passwordHash);
145            return true;
146        } catch (Exception $e) {
147            return false;
148        }
149    }
150
151    /** Instantiate a user object
152     * @param $username The username of the user
153     * @param $account_origin Network:  The account origin
154     * @param &$errMsg An error message will be appended to this if the username is not empty, but the user doesn't exist.
155     * @return a User object, or null if there was an error
156     */
157    public static function getUserByUsernameAndOrigin($username, Network $account_origin, &$errMsg = null) {
158        $db = AbstractDb::getObject();
159        $object = null;
160
161        $username_str = $db->escapeString($username);
162        $comparison = ($account_origin->getUsernamesCaseSensitive()? '=': 'ILike');
163        $account_origin_str = $db->escapeString($account_origin->getId());
164        $db->execSqlUniqueRes("SELECT user_id FROM users WHERE username {$comparison} '$username_str' AND account_origin = '$account_origin_str'", $user_info, false);
165
166        if ($user_info != null) {
167            $object = self::getObject($user_info['user_id']);
168        }
169        else if (!empty($username)) {
170            $errMsg .= sprintf(_("There is no user with username %s"),$username);
171        }
172        return $object;
173    }
174   
175                /** Instantiate a user object
176     * @param $username The username of the user
177     * @param $account_origin Network:  The account origin
178     * @param &$errMsg An error message will be appended to this if the username is not empty, but the user doesn't exist.
179     * @return a User object, or null if there was an error
180     */
181    public static function getUserByUsernameOrEmailAndOrigin($usernameOrEmail, Network $account_origin, &$errMsg = null) {
182        $db = AbstractDb::getObject();
183        $object = null;
184
185        $username_str = $db->escapeString($usernameOrEmail);
186        $comparison = ($account_origin->getUsernamesCaseSensitive()? '=': 'ILike');
187        $account_origin_str = $db->escapeString($account_origin->getId());
188        $db->execSqlUniqueRes("SELECT user_id FROM users WHERE (username {$comparison} '$username_str' OR email ILike '$username_str') AND account_origin = '$account_origin_str'", $user_info, false);
189
190        if ($user_info != null) {
191            $object = self::getObject($user_info['user_id']);
192        }
193        else if (!empty($usernameOrEmail)) {
194            $errMsg .= sprintf(_("There is no user with username or email %s"),$usernameOrEmail);
195        }
196        return $object;
197    }
198
199    /** Instantiate a user object
200     * @param $usernameOrEmail The username or the email address of the user
201     * @param &$errMsg An error message will be appended to this if the username is not empty, but the user doesn't exist.
202     * @return a User object, or null if there was an error
203     */
204    public static function getUserByUsernameOrEmail($usernameOrEmail, &$errMsg = null) {
205        $db = AbstractDb::getObject();
206        $object = null;
207
208        $usernameOrEmail_str = $db->escapeString($usernameOrEmail);
209        $db->execSqlUniqueRes("SELECT user_id FROM users WHERE username = '$usernameOrEmail_str' OR email ILike '$usernameOrEmail_str'", $user_info, false);
210
211        if ($user_info != null) {
212            $object = self::getObject($user_info['user_id']);
213        }
214        else if (!empty($usernameOrEmail)) {
215            $errMsg .= sprintf(_("There is no user with username or email %s"),$usernameOrEmail);
216        }
217        return $object;
218    }
219 
220
221   /** Instantiate a user object
222     * @param $url The OpenId url
223     * @return a User object, or null if none matched
224     */
225    public static function getUserByOpenIdUrl($url) {
226        $db = AbstractDb::getObject();
227        $object = null;
228
229        $url_str = $db->escapeString($url);
230        $db->execSqlUniqueRes("SELECT user_id FROM users WHERE open_id_url = '$url_str'", $user_rows, false);
231
232        if ($user_rows != null) {
233            $object = self::getObject($user_rows[0]['user_id']);
234        }
235        return $object;
236    }
237    /** Instantiate a user object
238     * @param $email The email of the user
239     * @param $account_origin Network:  The account origin
240     * @return a User object, or null if there was an error
241     */
242    public static function getUserByEmailAndOrigin($email, Network $account_origin) {
243        $db = AbstractDb::getObject();
244        $object = null;
245
246        $email_str = $db->escapeString($email);
247        $account_origin_str = $db->escapeString($account_origin->getId());
248        $db->execSqlUniqueRes("SELECT user_id FROM users WHERE email ILike '$email_str' AND account_origin = '$account_origin_str'", $user_info, false);
249
250        if ($user_info != null)
251        $object = self::getObject($user_info['user_id']);
252        return $object;
253    }
254
255    /** Returns the hash of the password suitable for storing or comparing in the database.  This hash is the same one as used in NoCat
256     * @return The 32 character hash.
257     */
258    public static function passwordHash($password) {
259        /**
260         * utf8_decode is used for backward compatibility with old passwords
261         * containing special characters.
262         * Conversion from UTF-8 to ISO-8859-1 is done to match the MD5 hash
263         */
264        return base64_encode(pack("H*", md5(utf8_decode($password))));
265    }
266
267    /** Create a new User in the database
268     * @param $id The id to be given to the new user
269     * @return the newly created User object, or null if there was an error
270     */
271    static function createUser($id, $username, Network $account_origin, $email, $password) {
272        $db = AbstractDb::getObject();
273
274        $object = null;
275        $id_str = $db->escapeString($id);
276        $username_str = $db->escapeString($username);
277        $account_origin_str = $db->escapeString($account_origin->getId());
278        $email_str = $db->escapeString($email);
279
280        $password_hash = $db->escapeString(User :: passwordHash($password));
281        $status = ACCOUNT_STATUS_VALIDATION;
282        $token = User :: generateToken();
283
284        $db->execSqlUpdate("INSERT INTO users (user_id,username, account_origin,email,pass,account_status,validation_token,reg_date) VALUES ('$id_str','$username_str','$account_origin_str','$email_str','$password_hash','$status','$token',CURRENT_TIMESTAMP)");
285
286        $object = self::getObject($id);
287        return $object;
288    }
289
290    /*    public static function purgeUnvalidatedUsers($days_since_creation)
291     {
292     $db = AbstractDb::getObject();
293     $days_since_creation = $db->escapeString($days_since_creation);
294
295     //$db->execSqlUpdate("INSERT INTO users (user_id,username, account_origin,email,pass,account_status,validation_token,reg_date) VALUES ('$id_str','$username_str','$account_origin_str','$email_str','$password_hash','$status','$token',CURRENT_TIMESTAMP)");
296     }*/
297
298    /** @param $object_id The id of the user */
299    function __construct($object_id) {
300        $db = AbstractDb::getObject();
301        $this->mDb = & $db;
302        $object_id_str = $db->escapeString($object_id);
303        $sql = "SELECT * FROM users WHERE user_id='{$object_id_str}'";
304        $db->execSqlUniqueRes($sql, $row, false);
305        if ($row == null) {
306            throw new Exception(sprintf(_("User id: %s could not be found in the database"), $object_id_str));
307        }
308        $this->_row = $row;
309        $this->id = $row['user_id'];
310    } //End class
311
312    function getId() {
313        return $this->id;
314    }
315
316    /** Gets the Network to which the user belongs
317     * @return Network object (never returns null)
318     */
319    public function getNetwork() {
320        return Network :: getObject($this->_row['account_origin']);
321    }
322
323    /** Get a user display suitable for a user list.  Will include link to the user profile. */
324    function getListUI() {
325        $html = '';
326        if ($this->isSplashOnlyUser()) {
327            $html .= _("Guest");
328        }
329        else {
330            $nickname = null;
331            $avatar = null;
332            $profile = $this->getAllProfiles();
333            if(!empty($profile)) {
334                // Use the first profile for now
335                $profile = $profile[0];
336
337                $nickname_fields = $profile->getFieldsBySemanticId("foaf:nick");
338                // Try using the first nickname available
339                if(!empty($nickname_fields)) {
340                    $nickname_content = $nickname_fields[0]->getContentField();
341                    if(!empty($nickname_content)) {
342                        // Force non-verbose output
343                        $str = $nickname_content->__toString(false);
344                        if(!empty($str))
345                        $nickname = $str;
346                    }
347                }
348
349                $avatar_fields = $profile->getFieldsBySemanticId("foaf:img");
350                // Try using the first avatar available
351                if(!empty($avatar_fields)) {
352                    $avatar_content = $avatar_fields[0]->getContentField();
353                    if(!empty($avatar_content)) {
354                        $avatar = $avatar_content->getUserUI();
355                    }
356                }
357            }
358
359
360
361            // Display the avatar
362            if(empty($avatar))
363            $html .= Avatar::getDefaultUserUI();
364            else
365            $html .= $avatar;
366
367            // Display the nickname or the username
368            $profiles=$this->getAllProfiles();
369            if($profiles){
370                $html .= "<a href='".BASE_URL_PATH."profile/?user_id=".$this->getId()."' title='".htmlentities(_("View this user's profile."), ENT_QUOTES)."' class='user_nickname'>";
371            }
372            if(empty($nickname))
373            $html .= $this->getUserName();
374            else
375            $html .= $nickname;
376            if($profiles){
377                $html .= "</a>\n";
378            }
379            $profileTemplates = $this->getNetwork()->getAllProfileTemplates();
380            /*if($this==User::getCurrentUser() && $profileTemplates) {
381             $html .= "<div class='user_edit_profile_link'><br/>(<a href='".BASE_SSL_PATH."admin/generic_object_admin.php?object_id=".$this->getId()."&object_class=User&action=edit'>"._("edit profile")."</a>)</div>";
382             }*/
383
384        }
385        return $html;
386    }
387
388    function getOpenIdUrl() {
389        return $this->_row['open_id_url'];
390    }
391
392    function getUsername() {
393        return $this->_row['username'];
394    }
395
396    /** Set the user's username
397     * @param $value The new value
398     * @return true on success, false on failure
399     * @throws exception if the user tries to set a duplicate username
400     */
401    function setUsername($value) {
402        $retval = true;
403        if ($value != $this->getUsername()) {
404            $db = AbstractDb::getObject();
405            $otherUser = User::getUserByUsernameAndOrigin($value, $this->getNetwork());
406            if (!is_null($otherUser)) {
407                throw new exception(sprintf(_("Sorry, the username %s is not available"), $value));
408            }
409            $value = $db->escapeString($value);
410            $retval = @ $db->execSqlUpdate("UPDATE users SET username = '{$value}' WHERE user_id='{$this->id}'", false);
411            $this->refresh();
412        }
413        return $retval;
414    }
415
416    /** Add profile template to this user */
417    public function addProfile(Profile $profile) {
418        $db = AbstractDb::getObject();
419        $profile_id = $db->escapeString($profile->getId());
420        $sql = "INSERT INTO user_has_profiles (user_id, profile_id) VALUES ('$this->id','$profile_id')";
421        return $db->execSqlUpdate($sql, false);
422    }
423
424    /** Remove profile template from this user */
425    public function removeProfile(Profile $profile) {
426        $db = AbstractDb::getObject();
427        $profile_id = $db->escapeString($profile->getId());
428        $sql = "DELETE FROM user_has_profiles WHERE user_id='$this->id' AND profile_id='$profile_id'";
429        return $db->execSqlUpdate($sql, false);
430    }
431
432    /**Get an array of all Profiles linked to this user
433     * @return an array of Profile or an empty arrray */
434    public function getAllProfiles() {
435        $db = AbstractDb::getObject();
436        $retval = array ();
437        $profile_rows = null;
438        $sql = "SELECT profile_id FROM user_has_profiles NATURAL JOIN profiles WHERE user_id='$this->id' ORDER BY creation_date";
439        $db->execSql($sql, $profile_rows, false);
440        if ($profile_rows != null) {
441            foreach ($profile_rows as $profile_row) {
442                $retval[] = Profile :: getObject($profile_row['profile_id']);
443            }
444        }
445        return $retval;
446    }
447
448    public function getEmail() {
449        return $this->_row['email'];
450    }
451
452    public function setEmail($email) {
453        $email_str = $this->mDb->escapeString($email);
454        if (!($update = $this->mDb->execSqlUpdate("UPDATE users SET email='{$email_str}' WHERE user_id='{$this->id}'"))) {
455            throw new Exception(_("Could not update email address."));
456        }
457        $this->_row['email'] = $email; // unescaped
458    }
459
460    function setIsInvisible($value) {
461        $retval = true;
462        if ($value != $this->isAdvertised()) {
463            $db = AbstractDb::getObject();
464            $value ? $value = 'TRUE' : $value = 'FALSE';
465            $retval = $db->execSqlUpdate("UPDATE users SET is_invisible = {$value} WHERE user_id = '{$this->getId()}'", false);
466            $this->refresh();
467        }
468        return $retval;
469    }
470
471    public function isInvisible() {
472        return (($this->_row['is_invisible'] == 't') ? true : false);
473    }
474
475    /**What locale (language) does the user prefer? */
476    public function getPreferedLocale() {
477        $session = Session::getObject();
478        $locale = $this->_row['prefered_locale'];
479        if (empty ($locale) && !empty ($session))
480        $locale = $session->get(SESS_LANGUAGE_VAR);
481        if (empty ($locale))
482        $locale = DEFAULT_LANG;
483        return $locale;
484    }
485
486    public function setPreferedLocale($locale) {
487        $locale_str = $this->mDb->escapeString($locale);
488        if (!($update = $this->mDb->execSqlUpdate("UPDATE users SET prefered_locale='{$locale_str}' WHERE user_id='{$this->id}'"))) {
489            throw new Exception(_("Could not update username locale."));
490        }
491        $this->_row['prefered_locale'] = $locale;
492    }
493
494    /** get the hashed password stored in the database */
495    public function getPasswordHash() {
496        return $this->_row['pass'];
497    }
498
499    /** Get the account status.
500     * @return Possible values are listed in common.php
501     */
502    function getAccountStatus() {
503        return $this->_row['account_status'];
504    }
505
506    function setAccountStatus($status) {
507        $db = AbstractDb::getObject();
508        if($status != $this->getAccountStatus()) {
509            $status_str = $db->escapeString($status);
510            if (!($update = $db->execSqlUpdate("UPDATE users SET account_status='{$status_str}' WHERE user_id='{$this->id}'"))) {
511                throw new Exception(_("Could not update status."));
512            }
513            $this->_row['account_status'] = $status;
514        }
515    }
516
517    /** Is the user valid?  Valid means that the account is validated or hasn't exhausted it's validation period.
518     $errmsg: Returs the reason why the account is or isn't valid */
519    function isUserValid(& $errmsg = null) {
520        global $account_status_to_text;
521        $db = AbstractDb::getObject();
522        $retval = false;
523        $account_status = $this->getAccountStatus();
524        if ($account_status == ACCOUNT_STATUS_ALLOWED) {
525            $retval = true;
526        } else
527        if ($account_status == ACCOUNT_STATUS_VALIDATION) {
528            $sql = "SELECT CASE WHEN ((CURRENT_TIMESTAMP - reg_date) > networks.validation_grace_time) THEN true ELSE false END AS validation_grace_time_expired, EXTRACT(EPOCH FROM networks.validation_grace_time) as validation_grace_time FROM users  JOIN networks ON (users.account_origin = networks.network_id) WHERE (user_id='{$this->id}')";
529            $db->execSqlUniqueRes($sql, $user_info, false);
530
531            if ($user_info['validation_grace_time_expired'] == 't') {
532                $errmsg = sprintf(_("Sorry, your %.0f minutes grace period to retrieve your email and validate your account has now expired. You will have to connect to the internet and validate your account from another location."), $user_info['validation_grace_time']/60);
533                $retval = false;
534            } else {
535                $errmsg = _("Your account is currently valid.");
536                $retval = true;
537            }
538        } else {
539            $errmsg = _("Sorry, your account is not valid: ") . $account_status_to_text[$account_status];
540            $retval = false;
541        }
542        return $retval;
543    }
544
545    public function DEPRECATEDisSuperAdmin() {
546        $db = AbstractDb::getObject();
547        //$this->session->dump();
548
549        $db->execSqlUniqueRes("SELECT * FROM users JOIN server_stakeholders USING (user_id) WHERE (users.user_id='$this->id')", $user_info, false);
550        if (!empty ($user_info)) {
551            return true;
552        } else {
553            return false;
554        }
555
556    }
557
558    /** Is this user the Splash Only User() */
559    public function isSplashOnlyUser() {
560        if ($this->_row['username'] == "SPLASH_ONLY_USER") {
561            return true;
562        } else {
563            return false;
564        }
565    }
566
567    function getValidationToken() {
568        return $this->_row['validation_token'];
569    }
570
571    /** Retrieves the connection history necessary for abuse control
572
573    * @return false if abuse control is disabled */
574
575    static function getAbuseControlConnectionHistory($user = null, $mac = null, $node = null) {
576        if (!$user) {
577            $user = User::getCurrentUser();
578        }
579        if (!$node) {
580            $node = Node::getCurrentNode();//Maybe this should be getCurrentRealNode, but it would make debuging harder
581        }
582        $network = $node->getNetwork();
583
584        $db = AbstractDb::getObject();
585
586        if ($network->getConnectionLimitWindow()) {
587            //$sql =  " SELECT * from connections \n";//For debugging
588            $sql =  " SELECT \n";
589            $sql .= " SUM (incoming+outgoing) AS network_total_bytes, \n";
590            $sql .= " SUM (CASE WHEN node_id = '".$node->getId()."' THEN (incoming+outgoing) END) AS node_total_bytes, \n";
591            $sql .= " SUM (COALESCE(timestamp_out,last_updated) - timestamp_in) AS network_duration, \n";
592            $sql .= " SUM (CASE WHEN node_id = '".$node->getId()."' THEN (COALESCE(timestamp_out,last_updated) - timestamp_in) END) AS node_duration \n";//For real //The coalesce is to make sure the substraction returns a value for active conections, since active connections do not yet have a timestamp_out.  Do NOT coalesce with CURRENT_TIMESTAMP, it could cause real problems for users in case of gateway crash.
593            $sql .= " FROM connections \n";//For real
594            $sql .= " JOIN nodes USING (node_id) \n";
595            $sql .= " JOIN networks USING (network_id) \n";
596            $sql .= " JOIN tokens ON (tokens.token_id = connections.token_id) \n";
597            $sql .= " WHERE 1=1 \n";
598
599            if ($mac) {
600                //Catch some cheaters
601                $mac = $db->escapeString($mac);
602                $mac_sql_or = " OR connections.user_mac = '$mac' ";
603            }
604            else {
605                $mac_sql_or = null;
606            }
607            $sql .= " AND (connections.user_id = '".$user->getId()."' $mac_sql_or ) \n";
608
609            $sql .= " AND (timestamp_in > CURRENT_TIMESTAMP - networks.connection_limit_window OR tokens.token_status = '".TOKEN_INUSE."')";  //Get every connection within the window plus any still active connection, even if it started before the window
610
611            $subselect = $sql;
612            $sql =  " SELECT subselect.*, \n";
613            $sql .= " networks.connection_limit_window, \n";
614            $sql .= " networks.connection_limit_network_max_total_bytes, COALESCE(network_total_bytes>networks.connection_limit_network_max_total_bytes, false) AS network_total_bytes_exceeded_limit, \n";
615            $sql .= " networks.connection_limit_node_max_total_bytes, COALESCE(node_total_bytes>networks.connection_limit_node_max_total_bytes, false) AS node_total_bytes_exceeded_limit, \n";
616            $sql .= " networks.connection_limit_network_max_usage_duration, COALESCE(network_duration>networks.connection_limit_network_max_usage_duration, false) AS network_duration_exceeded_limit, \n";
617            $sql .= " networks.connection_limit_node_max_usage_duration, COALESCE(node_duration>networks.connection_limit_node_max_usage_duration, false) AS node_duration_exceeded_limit \n";
618
619            $sql .= " FROM ($subselect) AS subselect JOIN networks ON (network_id = '".$network->getId()."')";
620
621            $db->execSqlUniqueRes($sql, $connection_limits_report, false);
622            return $connection_limits_report;
623        }
624        else {
625            return false;
626        }
627    }
628
629    /** Takes the same paramaters as getAbuseControlConnectionHistory, and tells you if the abuse limits are busted
630
631    * @return false if abuse control respected, else a string containing the reason(s) for the bust  */
632
633    static function isAbuseControlViolated($user = null, $mac = null, $node = null) {
634        $retval = false;
635        $abuseControlReport = self::getAbuseControlConnectionHistory($user, $mac, $node);
636        if($abuseControlReport) {
637            if (!$user) {
638                $user = User::getCurrentUser();
639            }
640
641            if ($node && $node->getBypassDynamicAbuseControl()) {
642                $retval = false;
643            }
644            elseif ($node && Security::hasPermission(Permission::P('NODE_PERM_BYPASS_DYNAMIC_ABUSE_CONTROL'), $node, $user)) {
645                $retval = false;
646            }
647            else {
648                require_once('classes/Content/UIAllowedBandwidth/UIAllowedBandwidth.php');
649                if($abuseControlReport['network_total_bytes_exceeded_limit']=='t') {
650                    $retval .= sprintf(_("During the last %s period, you transfered %s bytes throughout the network, which exceeds the %s bytes limit for the entire network."), $abuseControlReport['connection_limit_window'], UIAllowedBandwidth::formatSize($abuseControlReport['network_total_bytes']), UIAllowedBandwidth::formatSize($abuseControlReport['connection_limit_network_max_total_bytes']));
651                }
652                if($abuseControlReport['node_total_bytes_exceeded_limit']=='t') {
653                    $retval .= sprintf(_("During the last %s period, you transfered %s bytes at this node, which exceeds the %s bytes limit for this node."), $abuseControlReport['connection_limit_window'], UIAllowedBandwidth::formatSize($abuseControlReport['node_total_bytes']), UIAllowedBandwidth::formatSize($abuseControlReport['connection_limit_node_max_total_bytes']));
654                }
655                if($abuseControlReport['network_duration_exceeded_limit']=='t') {
656                    $retval .= sprintf(_("During the last %s period, you were online for a duration of %s throughout the network, which exceeds the %s limit for the entire network."), $abuseControlReport['connection_limit_window'], $abuseControlReport['network_duration'], $abuseControlReport['connection_limit_network_max_usage_duration']);
657                }
658                if($abuseControlReport['node_duration_exceeded_limit']=='t') {
659                    $retval .= sprintf(_("During the last %s period, you were online for a duration of %s at this node, which exceeds the %s limit for this node."), $abuseControlReport['connection_limit_window'], $abuseControlReport['node_duration'], $abuseControlReport['connection_limit_node_max_usage_duration']);
660                }
661            }
662        }
663        return $retval;
664    }
665    /** Generate a token in the connection table so the user can actually use the internet
666    @return true on success, false on failure
667    */
668    function generateConnectionToken($mac = null) {
669        if ($this->isUserValid()) {
670            $db = AbstractDb::getObject();
671            $session = Session::getObject();
672
673            $token = self :: generateToken();
674            if ($_SERVER['REMOTE_ADDR']) {
675                $node_ip = $db->escapeString($_SERVER['REMOTE_ADDR']);
676            }
677           
678            if ($session && $node_ip && $session->get(SESS_NODE_ID_VAR)) {
679                //echo "$session && $node_ip && {$session->get(SESS_NODE_ID_VAR)}";
680                $node_id = $db->escapeString($session->get(SESS_NODE_ID_VAR));
681                $abuseControlFault = User::isAbuseControlViolated($this, $mac, Node::getObject($node_id));
682                if($abuseControlFault) {
683                    throw new Exception ($abuseControlFault);
684                }
685                $mac = (is_null($mac)?'': $db->escapeString($mac));
686                /*
687                 * Delete all unused tokens for this user, so we don't fill the database
688                 * with them
689                 */
690                $sql = "DELETE FROM connections USING tokens "."WHERE tokens.token_id=connections.token_id AND token_status='".TOKEN_UNUSED."' AND user_id = '".$this->getId()."';\n";
691                // TODO:  Try to find a reusable token before creating a brand new one!
692
693                $sql .= "INSERT INTO tokens (token_owner, token_issuer, token_id, token_status) VALUES ('" . $this->getId() . "', '" . $this->getId() . "', '$token', '" . TOKEN_UNUSED . "');\n";
694                $sql .= "INSERT INTO connections (user_id, token_id, timestamp_in, node_id, node_ip, last_updated, user_mac) VALUES ('" . $this->getId() . "', '$token', CURRENT_TIMESTAMP, '$node_id', '$node_ip', CURRENT_TIMESTAMP, '$mac')";
695                $db->execSqlUpdate($sql, false);
696                $retval = $token;
697            }
698            else {
699                $retval = false;
700            }
701        }
702        else {
703            $retval = false;
704        }
705        return $retval;
706    }
707   
708    /** Generate a token in the connection table so the user can actually use the internet
709    @return true on success, false on failure
710    */
711    function generateConnectionTokenNoSession($node, $node_ip = null, $mac = null ) {
712        if ($this->isUserValid()) {
713            $db = AbstractDb::getObject();
714           
715            $token = self :: generateToken();
716            if ($node_ip && $node) {
717                //echo "$session && $node_ip && {$session->get(SESS_NODE_ID_VAR)}";
718                $node_id = $node->getId();
719                $abuseControlFault = User::isAbuseControlViolated($this, $mac, $node);
720                if($abuseControlFault) {
721                    throw new Exception ($abuseControlFault);
722                }
723                $mac = (is_null($mac)?'': $db->escapeString($mac));
724                /*
725                 * Delete all unused tokens for this user, so we don't fill the database
726                 * with them
727                 */
728                $sql = "DELETE FROM connections USING tokens "."WHERE tokens.token_id=connections.token_id AND token_status='".TOKEN_UNUSED."' AND user_id = '".$this->getId()."';\n";
729                // TODO:  Try to find a reusable token before creating a brand new one!
730
731                $sql .= "INSERT INTO tokens (token_owner, token_issuer, token_id, token_status) VALUES ('" . $this->getId() . "', '" . $this->getId() . "', '$token', '" . TOKEN_UNUSED . "');\n";
732                $sql .= "INSERT INTO connections (user_id, token_id, timestamp_in, node_id, node_ip, last_updated, user_mac) VALUES ('" . $this->getId() . "', '$token', CURRENT_TIMESTAMP, '$node_id', '$node_ip', CURRENT_TIMESTAMP, '$mac')";
733                $db->execSqlUpdate($sql, false);
734                $retval = $token;
735            }
736            else {
737                $retval = false;
738            }
739        }
740        else {
741            $retval = false;
742        }
743        return $retval;
744    }
745
746    function setPassword($password) {
747        $db = AbstractDb::getObject();
748
749        $new_password_hash = User :: passwordHash($password);
750        if (empty($password)) {
751            throw new Exception(_("Password cannot be empty."));
752        }
753
754        if (!($update = $db->execSqlUpdate("UPDATE users SET pass='$new_password_hash' WHERE user_id='{$this->id}'"))) {
755            throw new Exception(_("Could not change user's password."));
756        }
757        $this->_row['pass'] = $password;
758    }
759
760    function getAccountOrigin() {
761        return $this->_row['account_origin'];
762    }
763
764    /** Return all the users
765     */
766    static function getAllUsers() {
767        $db = AbstractDb::getObject();
768
769        $db->execSql("SELECT * FROM users", $objects, false);
770        if ($objects == null) {
771            throw new Exception(_("No users could not be found in the database"));
772        }
773        return $objects;
774    }
775
776    function sendLostUsername() {
777        $network = $this->getNetwork();
778        require_once ('classes/Mail.php');
779        $mail = new Mail();
780        $mail->setSenderName(_("Registration system"));
781        $mail->setSenderEmail($network->getValidationEmailFromAddress());
782        $mail->setRecipientEmail($this->getEmail());
783        $mail->setMessageSubject($network->getName() . _(" lost username request"));
784        $mail->setMessageBody(_("Hello,\nYou have requested that the authentication server send you your username:\nUsername: ") . $this->getUsername() . _("\n\nHave a nice day,\nThe Team"));
785        $mail->send();
786    }
787
788    function sendValidationEmail() {
789        if ($this->getAccountStatus() != ACCOUNT_STATUS_VALIDATION) {
790            throw new Exception(_("The user is not in validation period."));
791        } else {
792            if ($this->getValidationToken() == "") {
793                throw new Exception(_("The validation token is empty."));
794            } else {
795                $network = $this->getNetwork();
796                require_once ('classes/Mail.php');
797                $mail = new Mail();
798                $mail->setSenderName(_("Registration system"));
799                $mail->setSenderEmail($network->getValidationEmailFromAddress());
800                $mail->setRecipientEmail($this->getEmail());
801                $mail->setMessageSubject($network->getName() . _(" new user validation"));
802                $url = BASE_SSL_PATH . "validate.php?user_id=" . $this->getId() . "&token=" . $this->getValidationToken();
803                $mail->setMessageBody(_("Hello,\nPlease follow the link below to validate your account.\n") . $url . _("\n\nThank you,\nThe Team."));
804                $mail->send();
805            }
806        }
807    }
808
809    function sendLostPasswordEmail() {
810        $network = $this->getNetwork();
811        $new_password = $this->randomPass();
812        $this->setPassword($new_password);
813        require_once ('classes/Mail.php');
814        $mail = new Mail();
815        $mail->setSenderName(_("Registration system"));
816        $mail->setSenderEmail($network->getValidationEmailFromAddress());
817        $mail->setRecipientEmail($this->getEmail());
818        $mail->setMessageSubject($network->getName() . _(" new password request"));
819        $mail->setMessageBody(_("Hello,\nYou have requested that the authentication server send you a new password:\nUsername: ") . $this->getUsername() . _("\nPassword: ") . $new_password . _("\n\nHave a nice day,\nThe Team"));
820        $mail->send();
821    }
822
823    public static function emailExists($id) {
824        $db = AbstractDb::getObject();
825        $id_str = $db->escapeString($id);
826        $sql = "SELECT * FROM users WHERE email='{$id_str}'";
827        $db->execSqlUniqueRes($sql, $row, false);
828        return $row;
829    }
830
831    public static function randomPass() {
832        $rand_pass = ''; // makes sure the $pass var is empty.
833        for ($j = 0; $j < 3; $j++) {
834            $startnend = array (
835            'b',
836            'c',
837            'd',
838            'f',
839            'g',
840            'h',
841            'j',
842            'k',
843            'l',
844            'm',
845            'n',
846            'p',
847            'q',
848            'r',
849            's',
850            't',
851            'v',
852            'w',
853            'x',
854            'y',
855            'z',
856
857            );
858            $id = array (
859            'a',
860            'e',
861            'i',
862            'o',
863            'u',
864            'y',
865
866            );
867            $count1 = count($startnend) - 1;
868            $count2 = count($id) - 1;
869
870            for ($i = 0; $i < 3; $i++) {
871                if ($i != 1) {
872                    $rand_pass .= $startnend[rand(0, $count1)];
873                } else {
874                    $rand_pass .= $id[rand(0, $count2)];
875                }
876            }
877        }
878        return $rand_pass;
879    }
880
881    public static function generateToken() {
882        return md5(uniqid(rand(), 1));
883    }
884
885    /**
886     * Get an interface to add a user to a list
887     *
888     * @param string $user_prefix      A identifier provided by the programmer
889     *                                 to recognise it's generated HTML form
890     * @param string $add_button_name  Name of optional "add" button
891     * @param string $add_button_value Value of optional "add" button
892     *
893     * @return string HTML markup
894
895     */
896    public static function getSelectUserUI($user_prefix, $add_button_name = null, $add_button_value = null) {
897        $db = AbstractDb::getObject();
898        $networkSelector = Network :: getSelectUI($user_prefix);
899        // Check if we need to add an "add" button
900        if ($add_button_name && $add_button_value) {
901            $userSelector = _("Username") . ": " . InterfaceElements :: generateInputText("select_user_" . $user_prefix . "_username", "", "", "input_text", array (
902            "onkeypress" => "if ((event.which ? event.which : event.keyCode) == 13) {form.$add_button_name.click() }"
903            ));
904            $userSelector .= InterfaceElements :: generateInputSubmit($add_button_name, $add_button_value);
905        } else {
906            $userSelector = _("Search for Username or Email Address") . ": " . InterfaceElements :: generateInputText("select_user_" . $user_prefix . "_username");
907        }
908        $html = "<div class='user_select_user_ui_container'>".$networkSelector . "<br>" . $userSelector . "</div>\n";
909        return $html;
910    }
911
912    /** Get the selected user, IF one was selected and is valid
913     * @param $user_prefix A identifier provided by the programmer to recognise it's generated form
914     * @param &$errMsg An error message will be appended to this is the username is not empty, but the user doesn't exist.
915     * @return the User object, or null if the user is invalid or none was selected
916     */
917    static function processSelectUserUI($user_prefix, &$errMsg) {
918        $object = null;
919        try {
920            $network = Network :: processSelectUI($user_prefix);
921            $name = "select_user_{$user_prefix}_username";
922            if (!empty ($_REQUEST[$name])) {
923                $username = $_REQUEST[$name];
924                return self :: getUserByUsernameOrEmailAndOrigin($username, $network, $errMsg);
925            } else
926            return null;
927        } catch (Exception $e) {
928            return null;
929        }
930    }
931
932    public function getAdminUI() {
933        $db = AbstractDb::getObject();
934        $currentUser = self :: getCurrentUser();
935        $userPreferencesItems = array();
936        $finalHtml = '';
937        if(Security::hasPermission(Permission::P('NETWORK_PERM_VIEW_STATISTICS'), $this->getNetwork())) {
938            /* Statistics */
939            $content = "<a href='".BASE_SSL_PATH."admin/stats.php?Statistics=".$this->getNetwork()->getId()."&distinguish_users_by=user_id&stats_selected_users=".$this->getUsername()."&UserReport=on&user_id=".$this->getId()."&action=generate'>"._("Get user statistics")."</a>\n";
940            $administrationItems[] = InterfaceElements::genSectionItem($content);
941
942            /* Account status */
943            $title = _("Account Status");
944            $help = _("Note that Error is for internal use only");
945            $name = "user_" . $this->getId() . "_accountstatus";
946            global $account_status_to_text;
947            $content = FormSelectGenerator::generateFromKeyLabelArray($account_status_to_text, $this->getAccountStatus(), $name, null, false);
948            $administrationItems[] = InterfaceElements::genSectionItem($content, $title, $help);
949
950            $finalHtml .= InterfaceElements::genSection($administrationItems, _("Administrative options"));
951        }
952
953        if (($this == $currentUser && !$this->isSplashOnlyUser() )|| Security::hasPermission(Permission::P('NETWORK_PERM_EDIT_ANY_USER'), $this->getNetwork())) {
954            /* Username */
955            $title = _("Username");
956            $name = "user_" . $this->getId() . "_username";
957            $content = "<input type='text' name='$name' value='" . htmlentities($this->getUsername()) . "' size=30><br/>\n";
958            $content .= _("Be careful when changing this: it's the username you use to log in!");
959            $userPreferencesItems[] = InterfaceElements::genSectionItem($content, $title);
960
961
962            /* Email */
963            $title = _("Email");
964            $name = "email_" . $this->getId() . "_email";
965            $content = "<input type='text' name='$name' disabled='disabled' value='" . htmlentities($this->getEmail()) . "' size=30><br/>\n";
966            $content .= _("If you wish to change this address, please Email Support!");
967            $userPreferencesItems[] = InterfaceElements::genSectionItem($content, $title);
968
969
970
971            /* Change password */
972            $changePasswordItems=array();
973            if($this == $currentUser) {//Don't enter the old password if changing password for another user
974                $title = _("Your current password");
975                $name = "user_" . $this->getId() . "_oldpassword";
976                $content = "<input type='password' name='$name' size='20'>\n";
977                $changePasswordItems[] = InterfaceElements::genSectionItem($content, $title);
978            }
979
980            $title = _("Your new password");
981            $name = "user_" . $this->getId() . "_newpassword";
982            $content = "<input type='password' name='$name' size='20'>\n";
983            $changePasswordItems[] = InterfaceElements::genSectionItem($content, $title);
984
985            $title = _("Your new password (again)");
986            $name = "user_" . $this->getId() . "_newpassword_again";
987            $content = "<input type='password' name='$name' size='20'>\n";
988            $changePasswordItems[] = InterfaceElements::genSectionItem($content, $title);
989
990            $userPreferencesItems[] = InterfaceElements::genSection($changePasswordItems, _("Change my password"));
991
992            $finalHtml .= InterfaceElements::genSection($userPreferencesItems, _("User preferences"), false, false, get_class($this));
993
994            //N.B: For now, let pretend we have only one profile per use...
995            $profiles = $this->getAllProfiles();
996            $current_profile = null;
997            if(!empty($profiles)) {
998                $current_profile = $profiles[0];
999            }
1000
1001            if($current_profile != null) {
1002                $finalHtml .= $current_profile->getAdminUI();
1003                $name = "user_" . $this->getId() . "_delete_profile_".$current_profile->getId();
1004                $value = _("Completely delete my public profile");
1005                $finalHtml .= "<div class='admin_element_tools'>";
1006                $finalHtml .= '<input type="submit" class="submit" name="' . $name . '" value="' . $value . '">';
1007                $finalHtml .= "</div>";
1008            }
1009            else {                    // Get the list of profile templates for the users' network
1010                $profile_templates = ProfileTemplate::getAllProfileTemplates($this->getNetwork());
1011                if(!empty($profile_templates)) {
1012                    $name = "user_" . $this->getId() . "_add_profile";
1013                    $value = _("Create my public profile");
1014                    $finalHtml .= "<div class='admin_element_tools'>";
1015                    $finalHtml .= '<input type="submit" class="submit" name="' . $name . '" value="' . $value . '">';
1016                    $finalHtml .= "</div>";
1017                }
1018            }
1019        }
1020
1021        return $finalHtml;
1022    }
1023
1024    public function processAdminUI() {
1025        $db = AbstractDb::getObject();
1026        $currentUser = self :: getCurrentUser();
1027        if (Security::hasPermission(Permission::P('NETWORK_PERM_EDIT_ANY_USER'), $this->getNetwork())) {
1028            /* Account status */
1029            $name = "user_" . $this->getId() . "_accountstatus";
1030            $status = FormSelectGenerator::getResult($name, null);
1031            $this->setAccountStatus($status);
1032        }
1033
1034        if ($this == $currentUser || Security::requirePermission(Permission::P('NETWORK_PERM_EDIT_ANY_USER'), $this->getNetwork())) {
1035            /* Username */
1036            $name = "user_" . $this->getId() . "_username";
1037            $this->setUsername($_REQUEST[$name]);
1038
1039            /* Change password */
1040            $nameOldpassword = "user_" . $this->getId() . "_oldpassword";
1041            $nameNewpassword = "user_" . $this->getId() . "_newpassword";
1042            $nameNewpasswordAgain = "user_" . $this->getId() . "_newpassword_again";
1043            if($_REQUEST[$nameNewpassword]!=null){
1044                if ($this == $currentUser && $this->getPasswordHash() != User::passwordHash($_REQUEST[$nameOldpassword])) {
1045                    throw new Exception(_("Wrong password."));
1046                }
1047                if ($_REQUEST[$nameNewpassword] != $_REQUEST[$nameNewpasswordAgain]){
1048                    throw new Exception(_("Passwords do not match."));
1049                }
1050                $this->setPassword($_REQUEST[$nameNewpassword]);
1051            }
1052
1053            // Pretend there is only one
1054            $profiles = $this->getAllProfiles();
1055            if(!empty($profiles)) {
1056                $current_profile = $profiles[0];
1057                if($current_profile != null) {
1058                    $current_profile->processAdminUI();
1059                    $name = "user_" . $this->getId() . "_delete_profile_".$current_profile->getId();
1060                    if(!empty($_REQUEST[$name])) {
1061                        $errmsg=null;
1062                        $current_profile->delete($errmsg);
1063                    }
1064                }
1065            }
1066            else {
1067                $name = "user_" . $this->getId() . "_add_profile";
1068                if(!empty($_REQUEST[$name])) {
1069                    // Get the list of profile templates for the users' network
1070                    $profile_templates = ProfileTemplate::getAllProfileTemplates($this->getNetwork());
1071                    if(!empty($profile_templates)) {
1072                        // Create a blank profile and link it to the user
1073                        $current_profile = Profile::createNewObject(null, $profile_templates[0]);
1074                        $this->addProfile($current_profile);
1075                    }
1076                }
1077
1078            }
1079
1080        }
1081    }
1082
1083    public function delete(& $errmsg) {
1084    }
1085
1086    public function getUserUI() {
1087        $html = "";
1088        $html .= $this->getRealName();
1089
1090        return $html;
1091    }
1092
1093    /** Add content to this user ( subscription ) */
1094    public function addContent(Content $content) {
1095        $db = AbstractDb::getObject();
1096        $content_id = $db->escapeString($content->getId());
1097        $sql = "INSERT INTO user_has_content (user_id, content_id) VALUES ('$this->id','$content_id')";
1098        $db->execSqlUpdate($sql, false);
1099        return true;
1100    }
1101
1102    /** Remove content from this node */
1103    public function removeContent(Content $content) {
1104        $db = AbstractDb::getObject();
1105        $content_id = $db->escapeString($content->getId());
1106        $sql = "DELETE FROM user_has_content WHERE user_id='$this->id' AND content_id='$content_id'";
1107        $db->execSqlUpdate($sql, false);
1108        return true;
1109    }
1110
1111    /**Get an array of all Content linked to this node
1112     * @return an array of Content or an empty arrray */
1113    function getAllContent() {
1114        $db = AbstractDb::getObject();
1115        $retval = array ();
1116        $content_rows = null;
1117        $sql = "SELECT * FROM user_has_content WHERE user_id='$this->id' ORDER BY subscribe_timestamp";
1118        $db->execSql($sql, $content_rows, false);
1119        if ($content_rows != null) {
1120            foreach ($content_rows as $content_row) {
1121                $retval[] = Content :: getObject($content_row['content_id']);
1122            }
1123        }
1124        return $retval;
1125    }
1126
1127    /** Reloads the object from the database.  Should normally be called after a set operation */
1128    protected function refresh() {
1129        $this->__construct($this->id);
1130    }
1131    /** Menu hook function */
1132    static public function hookMenu() {
1133        $items = array();
1134        $network = Network::getCurrentNetwork();
1135        $server = Server::getServer();
1136        if(Security::hasAnyPermission(array(array(Permission::P('NETWORK_PERM_VIEW_ONLINE_USERS'), $network))))
1137        {
1138            $items[] = array('path' => 'users/online_users',
1139            'title' => _("Online Users"),
1140            'url' => BASE_URL_PATH."admin/online_users.php");
1141        }
1142        if(Security::hasPermission(Permission::P('SERVER_PERM_EDIT_SERVER_CONFIG'), $server))
1143        {
1144            $items[] = array('path' => 'users/import_nocat',
1145            'title' => _("Import NoCat user database"),
1146            'url' => BASE_URL_PATH."admin/import_user_database.php"
1147            );
1148        }
1149        if(Security::getObjectsWithPermission(Permission::P('NETWORK_PERM_EDIT_ANY_USER')))
1150        {
1151            $items[] = array('path' => 'users/user_manager',
1152            'title' => _("User manager"),
1153            'url' => BASE_URL_PATH."admin/user_log.php"
1154            );
1155        }
1156        if(Security::getObjectsWithPermission(Permission::P('NETWORK_PERM_VIEW_STATISTICS')))
1157        {
1158            $items[] = array('path' => 'users/statistics',
1159            'title' => _("Statistics"),
1160            'url' => BASE_URL_PATH."admin/stats.php"
1161            );
1162        }
1163        $items[] = array('path' => 'users',
1164        'title' => _('User administration'),
1165        'type' => MENU_ITEM_GROUPING);
1166        return $items;
1167    }
1168
1169    /** Set Smarty template values.  Standardization routine. */
1170    public static function assignSmartyValues($smarty, $user = null) {
1171        if (!$user)
1172        $user = User :: getCurrentUser();
1173        $session = Session :: getObject();
1174        $smarty->assign('userOriginallyRequestedURL', $session ? $session->get(SESS_ORIGINAL_URL_VAR) : '');
1175        $smarty->assign('userId', $user ? $user->getId() : '');
1176        $smarty->assign('userName', $user ? $user->getUsername() : '');
1177        /**
1178         * Define user security levels for the template
1179         *
1180         * These values are used in the default template of WiFoDog but could be
1181         * used in a customized template to restrict certain links to specific
1182         * user access levels.  Note however that they will all be deprecateb by the
1183         * new roles system.
1184         */
1185        $smarty->assign('userIsValid', $user && !$user->isSplashOnlyUser() ? true : false);
1186        $smarty->assign('userDEPRECATEDisSuperAdmin', $user && $user->DEPRECATEDisSuperAdmin());
1187
1188        if (isset ($_REQUEST['debug_request']) && ($user && $user->DEPRECATEDisSuperAdmin())) {
1189            // Tell Smarty everything it needs to know
1190            $smarty->assign('debugRequested', true);
1191            $smarty->assign('debugOutput', print_r($_REQUEST, true));
1192        }
1193    }
1194}
1195
1196/*
1197 * Local variables:
1198 * tab-width: 4
1199 * c-basic-offset: 4
1200 * c-hanging-comment-ender-p: nil
1201 * End:
1202 */
Note: See TracBrowser for help on using the browser.