<?php
// ----------------------------------------------------------------------
// LEMP - Lightweight Efficient Modular PHP Application Framework
// @copyright 2002-2003 The CGI Open Source Federation. (http://cosf.sf.net)
// @version $Id: auth.php,v 1.13 2004/05/16 20:59:10 cogs Exp $
// ----------------------------------------------------------------------
// LICENSE
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License (GPL)
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// This program 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 recieved the lincence included with the disribution.
// If not visit http://www.gnu.org/copyleft/gpl.html
// ----------------------------------------------------------------------
/**
* User Manage is a compact suite which can easily be used to any PHP script.
* We modeled it like a puzzle: the "core" handles basic
* authentication, and can be extended with modules which include
* a database handler that help top-level modules like a permissions
* handler. Developers can now build applications with the standard user
* authentication complete, and with drop-in modules, they can handle extra user
* information and functions with compact objects.
*/
class UM extends LEMP {
/**
* UM::UM() User Manage's constructor method.
*
* @access private
* @return void
*/
function UM ()
{
LEMP::LEMP ();
}
/**
* UM::create_user() Add a new user to the database.
*
* @param string $uname Username of the user to be created.
* @param string $CreatePassword Password of the user to be created.
* @param string $ConfirmCreatePassword Used to confirm the password of the user to be created.
* @return boolean Successful | Unsuccessful
*/
function create_user ($uname, $pass, $confirm_pass)
{
$trig_args = compact('uname', 'pass', 'confirm_pass');
trigger_event ('auth:create_user:pre', $trig_args);
$table = get_table_columns('auth_user_info');
// Check if the password fields are set
if ($pass == '' || $confirm_pass == '') {
$errors[] = AUTH_PW_NOT_ENTERED;
}
// Check pass length
if (!empty ($auth_config['min_pass_length']) && strlen($pass) < $auth_config['min_pass_length']) {
$errors[] = AUTH_PW_SHORT;
}
if (!empty ($auth_config['max_pass_length']) && strlen($pass) > $auth_config['max_pass_length']) {
$errors[] = AUTH_PW_LONG;
}
// Check if pass matches confirm pass
if ($pass != $confirm_pass) {
$errors[] = AUTH_PW_MISMATCH;
}
// Check for errors
// If so, return false and add the errors
if (isset($errors)) {
trigger_event ('auth:create_user:unsuccessful', $trig_args);
return error_add ($errors);
}
// Create md5 hash of password. Passwords are always encrypted
$pass = md5 ($pass);
// Check if username is in use
$count = $this->db->query_fetch ("SELECT COUNT(*) FROM {$table['_name']} WHERE {$table['uname']} = '" . addslashes($uname) . '\';', LEMP_SCALAR);
// If count is 0 than uname is free.
if ($count == 0) {
// Increment id
$nextuid = $this->db->query_fetch ("SELECT {$table['uid']} FROM {$table['_name']} ORDER BY {$table['uid']} DESC LIMIT 1;", LEMP_SCALAR);
if ($nextuid == '' || ++$nextuid < 0) {
$nextuid = 0;
}
$result = $this->db->query ("INSERT INTO {$table['_name']} SET {$table['uname']} = '" . addslashes($uname) . "', {$table['pass']} = '" . addslashes ($pass) . "', {$table['uid']} = '$nextuid';");
if ($result == false) {
trigger_event ('auth:create_user:unsuccessful', $trig_args);
return error_add ('Could not add new user', __FILE__, __LINE__, true);
}
$trig_args['uid'] = $nextuid;
trigger_event ('auth:create_user:successful', $trig_args);
return $nextuid;
} else { // If not return FALSE and add error
return error_add (AUTH_DUP_UNAME);
}
}
/**
* UM::modify_user() Modify user information.
*
* @param integer $UID User ID of user to modify.
* @param string $uname Replace username with $uname.
* @param string $pass Replace user's password with $pass.
* @param string $confirm_pass Used to confirm the new password.
* @return boolean
*/
function modify_user ($uid, $uname = '', $pass = '', $confirm_pass = '')
{
$count = 0;
$trig_args = compact('pass', 'confirm_pass', 'uname', 'uid');
trigger_event ('auth:modify_user:pre', $trig_args);
$table = get_config('tables', 'auth_user_info');
// Check if uid is a number
if (!is_numeric($uid)) {
$errors[] = AUTH_INCORRECT_UID;
}
// Check if the password fields are set
if ($pass != '' || $confirm_pass != '') {
// Check pass length
if (!empty ($auth_config['min_pass_length']) && strlen($pass) < $auth_config['min_pass_length']) {
$errors[] = AUTH_PW_SHORT;
}
if (!empty ($auth_config['max_pass_length']) && strlen($pass) > $auth_config['max_pass_length']) {
$errors[] = AUTH_PW_LONG;
}
// Check if pass matches confirm pass
if ($pass != $confirm_pass) {
$errors[] = AUTH_PW_MISMATCH;
}
} else {
// Create md5 hash of password. passs are always encrypted.
$pass = md5 ($pass);
}
// Check if username exists
if ($uname != '') {
$count = $this->db->query_fetch ("SELECT COUNT(*) FROM {$table['_name']} WHERE {$table['uname']} = '" . addslashes($uname) . "' && {$table['uid']} != '" . addslashes($uid) . '\';', LEMP_SCALAR);
if ($count === false) {
return error_add ('Could not get a count of existing users named: ' . $uname, __FILE__, __LINE__, true);
}
}
// Return false and add append to log if any errors are found
if (isset($errors)) {
trigger_event ('auth:modify_user:unsuccessful', $trig_args);
return error_add ($errors);
}
// If count is 1 than uname exists.
if ($uname == '' && $pass != '') {
$result = $this->db->query ("UPDATE {$table['_name']} SET {$table['pass']} = '" . addslashes ($pass) . "' WHERE {$table['uid']} = '" . addslashes ($uid) . '\';');
} elseif ($count == 0 && $uname != '') {
$query = "UPDATE {$table['_name']} SET {$table['uname']} = '" . addslashes ($uname) . "'";
if ($pass != '') {
$query .= ", {$table['pass']} = '" . addslashes ($pass) . '\'';
}
$query .= " WHERE {$table['uid']} = '" . addslashes ($uid) . '\';';
$result = $this->db->query ($query);
} else { // If not return FALSE and add error
return error_add (AUTH_DUP_UNAME);
}
if ($result == false) {
trigger_event ('auth:modify_user:unsuccessful', $trig_args);
return error_add ('Could not add new user', __FILE__, __LINE__, true);
}
trigger_event ('auth:modify_user:successful', $trig_args);
return true;
}
/**
* UM::delete_user() Delete a user from database.
*
* @param string $uid user id of user to delete
* @return result
*/
function delete_user ($uid)
{
$table = get_table_columns('auth_user_info');
$return = $this->dbquery ("DELETE FROM {$table['_name']} WHERE {$table['uid']} = '" . addslashes($uid) . '\' LIMIT 1;');
if (!$return) {
return error_add ('Could not remove uid: ' . $uid);
trigger_event ('auth:delete_user:unsuccessful', array($uid));
}
trigger_event ('auth:delete_user:successful', array($uid));
return true;
}
/**
* UM::is_user() Checks if a user exists.
*
* @param string $user The username of the user.
* @return boolean
*/
function is_user ($user)
{
$table = get_table_columns('auth_user_info');
$result = $this->dbquery ("SELECT count(*) >= 1 FROM {$table['_name']} WHERE {$table['uname']} = '" . addslashes ($user) . '\' LIMIT 1;');
if ($result === false) {
return error_add ("Could not get uid of user: $user", __FILE__, __LINE__, true);
} elseif ($result == '1') {
return true;
} else {
return false;
}
}
/**
* UM::get_uid() Get user id from user name.
*
* @param string $uname
*/
function get_uid ($uname = '')
{
$table = get_table_columns('auth_user_info');
$result = $this->dbquery ("SELECT {$table['uid']} FROM {$table['_name']} WHERE {$table['uname']} = '" . addslashes($uname) . '\' LIMIT 1;');
return ($result === false)? false : $db->fetch ($result, LEMP_SCALAR);
}
/**
* UM::get_uname() Get user name from uid.
*
* @param string $uid The user's userid.
* @return result
*/
function get_uname ($uid)
{
$table = get_table_columns('auth_user_info');
$result = $this->dbquery ("SELECT {$table['uname']} FROM {$table['_name']} WHERE {$table['uid']} = '" . addslashes($uid) . '\' LIMIT 1;');
return ($result === false)? false : $this->dbfetch ($result, LEMP_SCALAR);
}
}
/*
* This authentication object handles the current logged in user.
*/
class auth extends UM {
var $access; // Stores login status of user.
var $uname; // Username
var $uid; // User id
var $pass; // Encrypted user pass
var $sid; // User's current session (stored in database)
var $authok; // Session ID (stored on client)
/**
* auth::auth() Auth's constructor. Invoked when class is initiated. Prepares variables for use.
*
* @param bool|int $uid set to false of you do not want to check for cookies.
* @access private
* @return void
*/
function auth ($uid = '')
{
UM::UM ();
$this->access = 0;
$auth_config = get_config('auth_config');
if (isset($this->in[$auth_config['session_name']])) {
$this->authok = $this->in[$auth_config['session_name']];
}
// echo 'HERE';
// var_dump ($_REQUEST);
// exit ();
if ($this->verify_session() === true) {
if (isset($this->authok)) {
$table = get_table_columns('auth_user_info');
$userdat = $this->dbquery_fetch ("SELECT * FROM {$table['_name']} WHERE {$table['sid']} = '{$this->authok}' LIMIT 1;");
$this->uname = $userdat['uname'];
$this->uid = $userdat['uid'];
$this->pass = $userdat['pass'];
$this->sid = $userdat['sid'];
$this->access = 1;
}
}
}
/**
* auth::verify_session() Check if user is logged in.
*
* @param boolean $must_login Set if user must be logged in
* @return boolean This function returns TRUE, if logged in, or FALSE if not
*/
function verify_session ($must_login = false)
{
$auth_config = get_config('auth_config');
if (empty($auth_config['scheme']) || $auth_config['scheme'] != 'cookie') {
$result = trigger_event ('auth:verify_session:alternative', array('must_login' => $must_login), 1);
if ($result === false) {
return ($must_login)? error_add (AUTH_NOT_LOGED_IN) : false;
} else {
return true;
}
}
$table = get_table_columns('auth_user_info');
if (!isset($this->authok)) { // Is cookie set?
$this->access = 0;
return ($must_login)? error_add (AUTH_NOT_LOGED_IN) : false;
} else {
// Check if sid matches in database
$result = $this->dbquery_fetch ("SELECT count(*) >= 1 FROM {$table['_name']} WHERE {$table['sid']} = '{$this->authok}';", LEMP_SCALAR);
if ($result == '1') { // Check to see if authok matches sid
return true;
} else {
return error_add (AUTH_SESSION_TIMEOUT);
}
}
}
/**
* auth::logout() Log-Out the current user.
*
* @return true
*/
function logout ()
{
trigger_event ('auth:logout:pre');
// Get config vars
$auth_config = get_config('auth_config');
$table = get_table_columns('auth_user_info');
$hostname = get_config('config', 'hostname');
if (empty ($hostname)) {
$hostname = $_SERVER['HTTP_HOST'];
}
$this->dbquery ("UPDATE {$table['_name']} SET {$table['sid']} = '' WHERE {$table['uid']} = '{$this->uid}';");
if (empty($auth_config['scheme']) || $auth_config['scheme'] == 'cookie') {
session_start ();
session_unset ();
session_destroy ();
setcookie ($auth_config['session_name'], '', time() - $auth_config['session_expire'], "/", $hostname, 0);
} else {
trigger_event ('auth:logout:alternate', $args);
}
trigger_event ('auth:logout:successful');
return true;
}
/**
* auth::check_login() Check whether username matches a password in the database
*
* @param string $username
* @param string $password
* @param string $error Pass a reference to collect any errors. ex)
* check_login ($username, $password, &$error);
* if there are any errors, $error will contain the error message either AUTH_UNAME_NOT_FOUND or AUTH_BAD_PW
* @return bool true or false depending on results
*/
function check_login ($username, $password, $error = '')
{
$table = get_table_columns('auth_user_info');
$trig_args = array ($username, $password);
trigger_event ('auth:check_login:pre', $trig_args);
// Check if user exists and get user info
$password = md5($password);
$user_pass = $this->dbquery_fetch ("SELECT {$table['pass']} FROM {$table['_name']} WHERE {$table['uname']} = '" . addslashes ($username) . '\' LIMIT 1;', LEMP_SCALAR);
if (!$user_pass) {
$error = AUTH_UNAME_NOT_FOUND;
} elseif ($password != $user_pass) {
$error = AUTH_BAD_PW;
}
if ($error != '') {
trigger_event ('auth:check_login:unsuccessful', $trig_args);
return false;
} else {
return true;
}
}
/**
* auth::login() Login current user
*
* @param string $UserName Username of the user to be logged in.
* @param string $Password Password of the user to be logged in.
* @param string $mode Accepts 'normal', 'persistent', or 'secure'.
* In normal mode, the cookie will last $auth_config['session_expire'] (set in config.php).
* In persistent mode, the cookie will last $auth_config['session_expire_ext'] (set in config.php).
* In secure mode, the cookie will expire when the browser is closed.
* @return bool Successful | Not Successful
*/
function login ($username, $password, $mode = 'normal')
{
$trig_args = compact('username', 'password', 'mode');
// Get config vars
$table = get_table_columns('auth_user_info');
$hostname = get_config('config', 'hostname'); // Get config vars
if (empty ($hostname)) {
$hostname = $_SERVER['HTTP_HOST'];
}
$auth_config = get_config('auth_config');
trigger_event ('auth:login:pre', $trig_args);
// Check if user exists and get user info
if ($this->check_login ($username, $password, &$error) !== true) {
trigger_event ('auth:login:unsuccessful', $trig_args);
return error_add ($error);
}
if (empty($auth_config['scheme']) || $auth_config['scheme'] == 'cookie') {
session_start();
$sid = session_id();
$this->dbquery ("UPDATE {$table['_name']} SET {$table['sid']} = '$sid' WHERE {$table['uname']} = '" . addslashes ($username) . '\' LIMIT 1;');
$session_expire = ($mode == 'secure')? 0 : ($mode == 'persistent')? time() + $auth_config['session_expire_ext'] : time() + $auth_config['session_expire'];
$return = setcookie ($auth_config['session_name'], $sid, $session_expire, "/", $hostname, 0);
} else {
trigger_event ('auth:login:alternate', $trig_args);
}
trigger_event ('auth:login:successful', $trig_args);
return true;
}
}
?>
|