<?php
/**
* This file is part of php-agenda.
*
* php-agenda is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* php-agenda is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with php-agenda; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Copyright 2006-2007, Thomas Abeel
*
* Project: http://sourceforge.net/projects/php-agenda/
*
*/
?>
<?php
/**
* Session.php
*
* The Session class is meant to simplify the task of keeping
* track of logged in users and also guests.
*
* Written by: Jpmaster77 a.k.a. The Grandmaster of C++ (GMC)
* Last Updated: August 19, 2004
*/
include (dirname(__FILE__) . '/../../config.inc.php');
include (dirname(__FILE__) . '/database.php');
include (dirname(__FILE__) . '/mailer.php');
include (dirname(__FILE__) . '/form.php');
class Session {
var $username; //Username given on sign-up
var $userid; //Random value generated on current login
var $id;
var $userlevel; //The level to which the user pertains
var $time; //Time user was last active (page loaded)
var $logged_in; //True if user is logged in, false otherwise
var $userinfo = array (); //The array holding all user info
var $usersettings = array ();
var $url; //The page url current being viewed
var $referrer; //Last recorded site page viewed
/**
* Note: referrer should really only be considered the actual
* page referrer in process.php, any other time it may be
* inaccurate.
*/
/* Class constructor */
function Session() {
$this->time = time();
$this->startSession();
}
/**
* startSession - Performs all the actions necessary to
* initialize this session object. Tries to determine if the
* the user has logged in already, and sets the variables
* accordingly. Also takes advantage of this page load to
* update the active visitors tables.
*/
function startSession() {
global $database; //The database connection
session_start(); //Tell PHP to start the session
/* Determine if user is logged in */
$this->logged_in = $this->checkLogin();
/**
* Set guest value to users not logged in, and update
* active guests table accordingly.
*/
if (!$this->logged_in) {
$this->username = $_SESSION['username'] = GUEST_NAME;
$this->userlevel = GUEST_LEVEL;
$database->addActiveGuest($_SERVER['REMOTE_ADDR'], $this->time);
}
/* Update users last active timestamp */
else {
$database->addActiveUser($this->username, $this->time);
}
/* Remove inactive visitors from database */
$database->removeInactiveUsers();
$database->removeInactiveGuests();
/* Set referrer page */
if (isset ($_SESSION['url'])) {
$this->referrer = $_SESSION['url'];
} else {
$this->referrer = "/";
}
/* Set current url */
//TODO only update URL when non engine page
$this->url = $_SESSION['url'] = $_SERVER['REQUEST_URI'];
}
/**
* checkLogin - Checks if the user has already previously
* logged in, and a session with the user has already been
* established. Also checks to see if user has been remembered.
* If so, the database is queried to make sure of the user's
* authenticity. Returns true if the user has logged in.
*/
function checkLogin() {
global $database; //The database connection
/* Check if user has been remembered */
if (isset ($_COOKIE['cookname']) && isset ($_COOKIE['cookid']) && isset ($_COOKIE['cookrealid'])) {
$this->username = $_SESSION['username'] = $_COOKIE['cookname'];
$this->userid = $_SESSION['userid'] = $_COOKIE['cookid'];
$this->id = $_SESSION['id'] = $_COOKIE['cookrealid'];
}
/* Username and userid have been set and not guest */
if (isset ($_SESSION['username']) && isset ($_SESSION['userid']) && $_SESSION['username'] != GUEST_NAME) {
/* Confirm that username and userid are valid */
if ($database->confirmUserID($_SESSION['username'], $_SESSION['userid']) != 0) {
/* Variables are incorrect, user not logged in */
unset ($_SESSION['username']);
unset ($_SESSION['userid']);
return false;
}
/* User is logged in, set class variables */
$this->userinfo = $database->getUserInfo($_SESSION['username']);
$this->usersettings = unserialize($this->userinfo['settings']);
$this->username = $this->userinfo['username'];
$this->userid = $this->userinfo['userid'];
$this->userlevel = $this->userinfo['userlevel'];
$this->id = $this->userinfo['id'];
return true;
}
/* User not logged in */
else {
return false;
}
}
/**
* login - The user has submitted his username and password
* through the login form, this function checks the authenticity
* of that information in the database and creates the session.
* Effectively logging in the user if all goes well.
*/
function login($subuser, $subpass, $subremember) {
global $database, $form; //The database and form object
/* Username error checking */
$field = "user"; //Use field name for username
if (!$subuser || strlen($subuser = trim($subuser)) == 0) {
$form->setError($field, "* Username not entered");
} else {
/* Check if username is not alphanumeric */
if (!eregi("^([0-9a-z])*$", $subuser)) {
$form->setError($field, "* Username not alphanumeric");
}
}
/* Password error checking */
$field = "pass"; //Use field name for password
if (!$subpass) {
$form->setError($field, "* Password not entered");
}
/* Return if form errors exist */
if ($form->num_errors > 0) {
return false;
}
/* Checks that username is in database and password is correct */
$subuser = stripslashes($subuser);
$result = $database->confirmUserPass($subuser, md5($subpass));
/* Check error codes */
if ($result == 1) {
$field = "user";
$form->setError($field, "* Username not found");
} else
if ($result == 2) {
$field = "pass";
$form->setError($field, "* Invalid password");
}
/* Return if form errors exist */
if ($form->num_errors > 0) {
return false;
}
/* Username and password correct, register session variables */
$this->userinfo = $database->getUserInfo($subuser);
$this->usersettings = unserialize($this->userinfo['settings']);
$this->username = $_SESSION['username'] = $this->userinfo['username'];
$this->userid = $_SESSION['userid'] = $this->generateRandID();
$this->id = $this->userinfo['id'];
$this->userlevel = $this->userinfo['userlevel'];
/* Insert userid into database and update active users table */
$database->updateUserField($this->username, "userid", $this->userid);
$database->addActiveUser($this->username, $this->time);
$database->removeActiveGuest($_SERVER['REMOTE_ADDR']);
/**
* This is the cool part: the user has requested that we remember that
* he's logged in, so we set two cookies. One to hold his username,
* and one to hold his random value userid. It expires by the time
* specified in constants.php. Now, next time he comes to our site, we will
* log him in automatically, but only if he didn't log out before he left.
*/
// if($subremember){
setcookie("cookname", $this->username, time() + COOKIE_EXPIRE, COOKIE_PATH);
setcookie("cookid", $this->userid, time() + COOKIE_EXPIRE, COOKIE_PATH);
setcookie("cookrealid", $this->id, time() + COOKIE_EXPIRE, COOKIE_PATH);
// } always remember
/* Login completed successfully */
return true;
}
/**
* logout - Gets called when the user wants to be logged out of the
* website. It deletes any cookies that were stored on the users
* computer as a result of him wanting to be remembered, and also
* unsets session variables and demotes his user level to guest.
*/
function logout() {
global $database; //The database connection
/**
* Delete cookies - the time must be in the past,
* so just negate what you added when creating the
* cookie.
*/
//if (isset ($_COOKIE['cookname']) && isset ($_COOKIE['cookid'])) {
setcookie("cookname", "", time() - COOKIE_EXPIRE, COOKIE_PATH);
setcookie("cookid", "", time() - COOKIE_EXPIRE, COOKIE_PATH);
setcookie("cookrealid", "", time() - COOKIE_EXPIRE, COOKIE_PATH);
//}
/* Unset PHP session variables */
unset ($_SESSION['username']);
unset ($_SESSION['userid']);
unset ($_SESSION['userrealid']);
/* Reflect fact that user has logged out */
$this->logged_in = false;
/**
* Remove from active users table and add to
* active guests tables.
*/
$database->removeActiveUser($this->username);
$database->addActiveGuest($_SERVER['REMOTE_ADDR'], $this->time);
/* Set user level to guest */
$this->username = GUEST_NAME;
$this->userlevel = GUEST_LEVEL;
}
/**
* register - Gets called when the user has just submitted the
* registration form. Determines if there were any errors with
* the entry fields, if so, it records the errors and returns
* 1. If no errors were found, it registers the new user and
* returns 0. Returns 2 if registration failed.
*/
function register($subuser, $subpass, $subemail) {
global $database, $form, $mailer; //The database, form and mailer object
/* Username error checking */
$field = "user"; //Use field name for username
if (!$subuser || strlen($subuser = trim($subuser)) == 0) {
$form->setError($field, "* Username not entered");
} else {
/* Spruce up username, check length */
$subuser = stripslashes($subuser);
if (strlen($subuser) < 5) {
$form->setError($field, "* Username below 5 characters");
} else
if (strlen($subuser) > 30) {
$form->setError($field, "* Username above 30 characters");
}
/* Check if username is not alphanumeric */
else
if (!eregi("^([0-9a-z])+$", $subuser)) {
$form->setError($field, "* Username not alphanumeric");
}
/* Check if username is reserved */
else
if (strcasecmp($subuser, GUEST_NAME) == 0) {
$form->setError($field, "* Username reserved word");
}
/* Check if username is already in use */
else
if ($database->usernameTaken($subuser)) {
$form->setError($field, "* Username already in use");
}
/* Check if username is banned */
else
if ($database->usernameBanned($subuser)) {
$form->setError($field, "* Username banned");
}
}
/* Password error checking */
$field = "pass"; //Use field name for password
if (!$subpass) {
$form->setError($field, "* Password not entered");
} else {
/* Spruce up password and check length*/
$subpass = stripslashes($subpass);
if (strlen($subpass) < 4) {
$form->setError($field, "* Password too short");
}
/* Check if password is not alphanumeric */
else
if (!eregi("^([0-9a-z])+$", ($subpass = trim($subpass)))) {
$form->setError($field, "* Password not alphanumeric");
}
/**
* Note: I trimmed the password only after I checked the length
* because if you fill the password field up with spaces
* it looks like a lot more characters than 4, so it looks
* kind of stupid to report "password too short".
*/
}
/* Email error checking */
$field = "email"; //Use field name for email
if (!$subemail || strlen($subemail = trim($subemail)) == 0) {
$form->setError($field, "* Email not entered");
} else {
/* Check if valid email address */
$regex = "^[_+a-z0-9-]+(\.[_+a-z0-9-]+)*" .
"@[a-z0-9-]+(\.[a-z0-9-]{1,})*" .
"\.([a-z]{2,}){1}$";
if (!eregi($regex, $subemail)) {
$form->setError($field, "* Email invalid");
}
$subemail = stripslashes($subemail);
}
/* Errors exist, have user correct them */
if ($form->num_errors > 0) {
return 1; //Errors with form
}
/* No errors, add the new account to the */
else {
if ($database->addNewUser($subuser, md5($subpass), $subemail)) {
$mailer->sendWelcome($subuser, $subemail, $subpass);
return 0; //New user added succesfully
} else {
return 2; //Registration attempt failed
}
}
}
/**
* editAccount - Attempts to edit the user's account information
* including the password, which it first makes sure is correct
* if entered, if so and the new password is in the right
* format, the change is made. All other fields are changed
* automatically.
*/
function editAccount($subcurpass, $subnewpass, $subemail, $dailyreminders, $language, $includetodo, $includedeadlines) {
global $database, $form; //The database and form object
/* New password entered */
if ($subnewpass) {
/* Current Password error checking */
$field = "curpass"; //Use field name for current password
if (!$subcurpass) {
$form->setError($field, "* Current Password not entered");
} else {
/* Check if password too short or is not alphanumeric */
$subcurpass = stripslashes($subcurpass);
if (strlen($subcurpass) < 4 || !eregi("^([0-9a-z])+$", ($subcurpass = trim($subcurpass)))) {
$form->setError($field, "* Current Password incorrect");
}
/* Password entered is incorrect */
if ($database->confirmUserPass($this->username, md5($subcurpass)) != 0) {
$form->setError($field, "* Current Password incorrect");
}
}
/* New Password error checking */
$field = "newpass"; //Use field name for new password
/* Spruce up password and check length*/
$subpass = stripslashes($subnewpass);
if (strlen($subnewpass) < 4) {
$form->setError($field, "* New Password too short");
}
/* Check if password is not alphanumeric */
else
if (!eregi("^([0-9a-z])+$", ($subnewpass = trim($subnewpass)))) {
$form->setError($field, "* New Password not alphanumeric");
}
}
/* Change password attempted */
else
if ($subcurpass) {
/* New Password error reporting */
$field = "newpass"; //Use field name for new password
$form->setError($field, "* New Password not entered");
}
/* Email error checking */
$field = "email"; //Use field name for email
if ($subemail && strlen($subemail = trim($subemail)) > 0) {
/* Check if valid email address */
$regex = "^[_+a-z0-9-]+(\.[_+a-z0-9-]+)*" .
"@[a-z0-9-]+(\.[a-z0-9-]{1,})*" .
"\.([a-z]{2,}){1}$";
if (!eregi($regex, $subemail)) {
$form->setError($field, "* Email invalid");
}
$subemail = stripslashes($subemail);
}
/* Errors exist, have user correct them */
if ($form->num_errors > 0) {
return false; //Errors with form
}
/* Update password since there were no errors */
if ($subcurpass && $subnewpass) {
$database->updateUserField($this->username, "password", md5($subnewpass));
}
/* Change Email */
if ($subemail) {
$database->updateUserField($this->username, "email", $subemail);
}
if (isset ($dailyreminders)) {
$this->usersettings['dailyreminders'] = true;
} else {
$this->usersettings['dailyreminders'] = false;
}
if (isset ($includetodo)) {
$this->usersettings['includetodo'] = true;
} else {
$this->usersettings['includetodo'] = false;
}
if (isset ($includedeadlines)) {
$this->usersettings['includedeadlines'] = true;
} else {
$this->usersettings['includedeadlines'] = false;
}
$this->usersettings['lang'] = $language;
$database->updateSettings($this->username, $this->usersettings);
/* Success! */
return true;
}
/**
* isAdmin - Returns true if currently logged in user is
* an administrator, false otherwise.
*/
function isAdmin() {
return ($this->userlevel == ADMIN_LEVEL);
}
/**
* generateRandID - Generates a string made up of randomized
* letters (lower and upper case) and digits and returns
* the md5 hash of it to be used as a userid.
*/
function generateRandID() {
return md5($this->generateRandStr(16));
}
/**
* generateRandStr - Generates a string made up of randomized
* letters (lower and upper case) and digits, the length
* is a specified parameter.
*/
function generateRandStr($length) {
$randstr = "";
for ($i = 0; $i < $length; $i++) {
$randnum = mt_rand(0, 61);
if ($randnum < 10) {
$randstr .= chr($randnum +48);
} else
if ($randnum < 36) {
$randstr .= chr($randnum +55);
} else {
$randstr .= chr($randnum +61);
}
}
return $randstr;
}
};
/**
* Initialize session object - This must be initialized before
* the form object because the form uses session variables,
* which cannot be accessed unless the session has started.
*/
$session = new Session;
/* Initialize form object */
$form = new Form;
?>