<?
//
// Copyright (c) 2002, Cameron McKay
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
// Informium -- Advanced News Script
//
// User Class (user-class.php)
//
// Author: Cameron McKay
// Note: This contains all the functions Informium needs retrieve and
// set use: detail.
//
class user
{
//
// Function: add ( $username, $password, $cipher, $email, $access )
//
// Purpose: Adds an user to the Informium database.
//
// Arguments:
// $username -> The user's username (automatically stripped of illegal characters).
// $password -> The user's password.
// $cipher -> The user's password cipher (Currently either MD5 or DES).
// $email -> The user's e-mail address (automatically checked for correct format).
// $access -> The user's access level (Currently 0-4).
//
// Returns: The user's new user_id, or -1 for empty field.
//
function add ($username, $password, $cipher, $email, $access)
{
// Call the insert() function to insert the article.
return $this->insert(0, $username, $password, $cipher, $email, $access);
}
//
// Function: edit ( $user_id, $username, $password, $cipher, $email, $access )
//
// Purpose: Edits an user in the Informium database.
//
// Arguments:
// $user_id -> The user's user_id.
// $username -> The user's username (automatically stripped of illegal characters).
// $password -> The user's password.
// $cipher -> The user's password cipher (Currently either MD5 or DES).
// $email -> The user's e-mail address (automatically checked for correct format).
// $access -> The user's access level (Currently 0-4).
//
// Returns: The user_id, or -1 for empty field.
//
function edit ($user_id, $username, $password, $cipher, $email, $access)
{
// Call the insert() function to update the article.
return $this->insert($user_id, $username, $password, $cipher, $email, $access);
}
//
// Function: delete ( $user_id )
//
// Purpose: Deletes an user in the Informium database.
//
// Arguments:
// $user_id -> The user's user_id.
//
// Returns: Nothing.
//
function delete ($user_id)
{
// Import CONF.
global $CONF;
// Import the MYSQL class, if needed.
require_once("$CONF[local_path]/class/mysql-class.php");
// Create a new MYSQL object.
$db = new mysql();
// Connect to the DB.
$db->pconnect();
// Check if the user has any posts or comments.
$query1 = "SELECT * FROM news WHERE user_id='$user_id'";
$query2 = "SELECT * FROM comments WHERE user_id='$user_id'";
$result1 = $db->query($query1);
$result2 = $db->query($query2);
// If they do, then we only 'fake' delete them.
if ($db->num_rows($result1) || $db->num_rows($result2)) {
// Free the results.
$db->free($result1);
$db->free($result2);
// Prepare and execute the query.
$query = "SELECT * FROM user WHERE user_id='$user_id'";
$result = $db->query($query);
// Read the data into an array.
$list = $db->fetch_array($result);
// Use the edit command to change the access level to -1 (deleted).
$this->edit($list[user_id], $list[username], $list[password], $list[cipher], $list[email], -$list[access]);
// Otherwise we really delete them.
} else {
// Prepare and execute the query.
$query = "DELETE FROM user WHERE user_id='$user_id'";
$db->query($query);
}
}
//
// Function: restore ( $user_id )
//
// Purpose: Restores a deleted user in the Informium database.
//
// Arguments:
// $user_id -> The user's user_id.
//
// Returns: Nothing.
//
function restore ($user_id)
{
// Merely running the delete method on a deleted user restores him... cool eh? :)
$this->delete($user_id);
}
//
// Function: insert ( $user_id, $username, $password, $cipher, $email, $access);
//
// Purpose: Adds or edits an user in the database.
//
// Arguments:
// $user_id -> The user's user_id. If '0', then the user is new.
// $username -> The user's username.
// $password -> The user's encrypted password.
// $cipher -> The user's password cipher.
// $email -> The user's e-mail address.
// $access -> The user's access level.
//
// Returns: The new user_id, or error number.
//
function insert ($user_id, $username, $password, $cipher, $email, $access)
{
// Import CONF and COOKIE.
global $CONF, $COOKIE_ADMIN;
// Import COOKIE, MYSQL and SYSTEM classes, if needed.
require_once("$CONF[local_path]/class/cookie-class.php");
require_once("$CONF[local_path]/class/mysql-class.php");
require_once("$CONF[local_path]/class/system-class.php");
// Make new COOKIE, MYSQL and SYSTEM objects.
$cookie = new cookie();
$db = new mysql();
$system = new system();
// Connect to the DB.
$db->pconnect();
// Check the username for illegal characters.
if (preg_match("/[^A-Za-z-_ ]/i", $username)) {
return -1;
}
// Make sure there are no empty fields.
if (!strcmp($username, '') || !strcmp($password, '') || !strcmp($email, '')) {
return -2;
}
// Check if we have a user_id that's greater than 0. If we do, then
// we're merely updating a user.
if ($user_id > 0) {
// Get the original create_date (since UPDATE automatically changes the timestamp...
$create_date = $this->info($user_id, 'create_date');
// Prepare the update.
$query = "UPDATE user SET
username='$username',
password='$password',
cipher='$cipher',
email='$email',
access='$access',
create_date='$create_date'
WHERE user_id=$user_id";
// Otherwise we're adding a new one.
} else {
// Make sure there are no user's with that name already.
$query = "SELECT * FROM user WHERE username='$username'";
$result = $db->query($query);
if ($db->num_rows($result)) {
// Free the result.
$db->free($result);
// Return -3 (duplicate user).
return -3;
}
// Prepare the addition.
$query = "INSERT user VALUES('', '$username', '$password', '$cipher', '$email', '$access', now())";
}
// Execute the query.
$db->query($query);
// Fetch the post_id for return, if needed.
if ($user_id < 1)
$user_id = $db->insert_id();
// Return the values that were added.
return $user_id;
}
//
// Function: form ( [$user_id] )
//
// Purpose: Creates a form used for adding and editing
// users.
//
// Arguments:
// $user_id -> If user_id is provided, then use those values.
//
// Returns: Nothing.
//
function form()
{
// Import CONF and INF.
global $CONF, $INF;
// Import SYSTEM and XHTML classes, if needed.
require_once("$CONF[local_path]/class/system-class.php");
require_once("$CONF[local_path]/class/xhtml-class.php");
// Make new SYSTEM and XHTML objects.
$system = new system();
$xhtml = new xhtml();
// Determine access level.
$access = $this->info(0, 'access');
// Disabled certain fields if access is below 4.
if ($access > 3) {
$att_disabled = "";
} else {
$att_disabled = "disabled='disabled'";
}
// Check if we're editing.
if (func_num_args() > 0) {
// If we're editing, define the type.
$type = 'edit';
// Get the user_id.
$user_id = func_get_arg(0);
// Fetch details about that user.
$list = $this->info($user_id);
// Make the creation date look nice.
$list[create_date] = $system->date_format($user_id, 'create_date', 'user');
// Otherwise we're adding.
} else {
// If we're adding, define the type.
$type = 'add';
// Fill in the values we can.
$list[create_date] = $system->date_format(0, 'now', 'user');
}
// Start a new table.
$xhtml->table_start('normal', $CONF[table_size]);
// Escape PHP.
?>
<br />
<form action='user.php?exec=<? echo $type; ?>&user_id=<? echo $user_id; ?>' method='post'>
<table class='normal' width='100%' cellpadding='5' cellspacing='0' border='0' align='center'>
<tr>
<td>Username:</td>
<td>
<input type='text' name='username' value='<? echo $list[username]; ?>' size='40' <? echo $att_disabled; ?>' />
</td>
</tr>
<tr>
<td>E-Mail:</td>
<td><input type='text' name='email' value='<? echo $list[email]; ?>' size='40' /></td>
</tr>
<tr><td><br /></td><td><br /></td></tr>
<tr>
<td>Password:</td>
<td><input type='password' name='password' size='40' /></td>
</tr>
<tr>
<td>Re-type Password:</td>
<td><input type='password' name='password_check' size='40' /></td>
</tr>
<?
// If we're editing, then give the option to use the old password.
if (!strcmp($type, 'edit')) {
echo "<tr>\n";
echo "<td>Use Old Password:</td>\n";
echo "<td>\n";
echo "<select name='password_old'>\n";
echo "<option value='1'>Yes</option>\n";
echo "<option value='0'>No</option>\n";
echo "</select>\n";
echo "</td>\n";
echo "</tr>\n";
}
?>
<tr>
<td>Password Cipher:</td>
<td>
<?
// If we're editing, then the cipher cannot be changed.
if (!strcmp($type, 'edit')) {
echo "<input type='hidden' name='cipher' value='$list[cipher]' />\n";
echo "<select name='cipher' disabled='disabled'>\n";
echo "<option value='$list[cipher]' selected='selected'>$list[cipher]</option>\n";
// Otherwise, it's business as usual.
} else {
echo "<select name='cipher'>\n";
for ($i = 0; $i < count($CONF[cipher_list]); ++$i)
echo "<option value='{$CONF[cipher_list][$i]}'>{$CONF[cipher_list][$i]}</option>\n";
}
// End the list.
echo "</select>\n";
?>
</td>
</tr>
<tr><td><br /></td><td><br /></td></tr>
<tr>
<td>Access Level:</td>
<td>
<?
// If we're editing, and the user's access level < 4, then the
// access level cannot be changed.
if (!strcmp($type, 'edit') && ($this->info(0, 'access') < 4))
echo "<select name='access' disabled='disabled'>\n";
// Otherwise, ti's business as usual.
else
echo "<select name='access'>\n";
// List the possible access levels.
for ($i = 1; $i <= ($CONF[access_count]); ++$i) {
// If we're editing, set it to the current users access level.
if (!strcmp($type, 'edit')) {
// Determine access level.
$access = $this->info($user_id, 'access');
// If they match, then we make the match the default selected.
if ($access == $i) {
echo "<option value='$i' selected='selected'>$i - {$CONF[access_list][$i]}</option>\n";
continue;
}
}
echo "<option value='$i'>$i - {$CONF[access_list][$i]}</option>\n";
}
// End the list.
echo "</select>\n";
?>
</td>
</tr>
<tr><td><br /></td><td><br /></td></tr>
<tr>
<td>Creation Date:</td>
<td><? echo $list[create_date]; ?></td>
</tr>
<tr>
<td>Current Date:</td>
<td><? echo $system->date_format(0, 'now', 'user'); ?></td>
</tr>
<tr><td><br /></td><td><br /></td></tr>
<tr>
<td><input type='submit' value='<? echo ucfirst($type); ?> User'> <input type='reset' value='Reset' /></td>
<td> </td>
</tr>
</table>
</form>
<?
// Re-enter PHP.
// End the table.
$xhtml->table_end();
}
//
// Function: dropdown ( $type, $limit )
//
// Purpose: Displays a dropdown menu of users so the user may choose one.
//
// Arguments:
// $type -> Type of dropdown (i.e. edit or delete).
// $limit -> Number of items in the dropdown.
//
// Returns: Nothing.
//
function dropdown ($type, $limit, $real_user = TRUE)
{
// Import CONF and COOKIE.
global $CONF, $COOKIE_ADMIN;
// Import COOKIE, MYSQL, USER and XHTML classes, if needed.
require_once("$CONF[local_path]/class/cookie-class.php");
require_once("$CONF[local_path]/class/mysql-class.php");
require_once("$CONF[local_path]/class/xhtml-class.php");
// Make COOKIE, MYSQL and USER objects.
$cookie = new cookie();
$db = new mysql();
$xhtml = new xhtml();
// Make a new MYSQL object.
$db = new mysql();
// Connect to the database to check the access.
$db->pconnect();
// If real_user is TRUE then we user any number > 0,
// If real_user is FALSE then we user any numer < 0.
if ($real_user == TRUE) {
$compare = '>';
} else {
$compare = '<';
}
// Prepare the query.
// If the limit is greater than 0, than we have a limit.
if ($limit > 0)
$query = "SELECT * FROM user WHERE access $compare 0 ORDER BY access DESC, username ASC LIMIT $limit";
// If the limit is lees than 0, than we have no limit.
else if ($limit < 0)
$query = "SELECT * FROM user WHERE access $compare 0 ORDER BY access DESC, username ASC";
// Execute the query.
$result = $db->query($query);
// Make the argument string for the form.
if (!strcmp($type, 'edit')) {
$argument = 'form=edit';
// If we're restoring, restore the user.
} else if (!strcmp($type, 'restore')) {
$argument = 'exec=restore';
// Otherwise we're deleting.
} else if (!strcmp($type, 'delete')) {
$argument = 'exec=delete';
}
// Start the table.
$xhtml->table_start('normal', $CONF[table_size]);
// Start the form.
echo "<br />\n";
echo "<form action='user.php?$argument' method='post'>\n";
echo "<select name='user_id'>\n";
// Display the user list.
while ($list = $db->fetch_array($result))
{
// Determine the username.
$list[username] = $this->to_name($list[user_id]);
// Print the information.
echo "<option value='$list[user_id]'>$list[username] - Level $list[access] ({$CONF[access_list][$list[access]]})</option>\n";
}
// End the form and list.
echo "</select><br />\n";
echo "<br />\n";
echo "<input type='submit' value='" . ucfirst($type) . " User'>\n";
echo "</form>\n";
// End the table.
$xhtml->table_end();
// Free the result.
$db->free($result);
}
//
// Function: i_list ( $field )
//
// Purpose: Retrieves a list array of any given field name.
//
// Arguments:
// $field -> Can be any of the values written below.
//
// Returns: An array with one of the following list of values.
// user_id -> The uesr's id number.
// username -> The user's username.
// password -> The user's password.
// email -> The user's email address.
// access -> The user's access level.
// create_date -> The user's creation date.
//
function i_list ($field)
{
// Import CONF.
global $CONF;
// Import MYSQL class, if needed.
require_once("$CONF[local_path]/class/mysql-class.php");
// Make a new MYSQL object.
$db = new mysql();
// Connect to the database to check the access.
$db->pconnect();
// Prepare the query.
$query = "SELECT ($field) FROM user WHERE access > 0";
$result = $db->query($query);
// Cycle through the results, making them into a list.
while ($list = $db->fetch_array($result))
$return[] = $list[$field];
// Free the result.
$db->free($result);
// Return the answer.
return $return;
}
//
// Function: info ( $user_id, $type )
//
// Purpose: Retrieves important user values by decoding the cookie and looking
// their name up in the database (depending on what needs to be found).
//
// Arguments:
// $type -> Can be any of the values written below or blank.
//
// Returns: An associative array with all of the following values (if argument is blank).
// user_id -> The uesr's id number.
// username -> The user's username.
// password -> The user's password.
// email -> The user's email address.
// access -> The user's access level.
// create_date -> The user's creation date.
//
// Otherwise it returns the requested value.
//
function info()
{
// Load the INF array and cookie.
global $CONF, $INF, $COOKIE_ADMIN;
// Import COOKIE class, if needed.
require_once("$CONF[local_path]/class/cookie-class.php");
// Make a new COOKIE object.
$cookie = new cookie();
// If the user_id is '0', then we get the information from the cookie.
if (($user_id = func_get_arg(0)) == 0) {
// Decode and check the cookie.
if(!(list($user_id, $username, $password, $ip) = $cookie->decode($COOKIE_ADMIN)))
die("INFORMIUM: Cookie values illegally changed.<br />\n");
}
// Import MYSQL class, if needed.
require_once("$CONF[local_path]/class/mysql-class.php");
// Make a new MYSQL object.
$db = new mysql();
// Connect to the database to check the access.
$db->pconnect();
// If we have no arguments, then get them all.
if (func_num_args() < 2) {
$query = "SELECT * FROM user WHERE user_id='$user_id'";
$result = $db->query($query);
$return = $db->fetch_array($result);
} else {
$field = func_get_arg(1);
$query = "SELECT ($field) FROM user WHERE user_id='$user_id'";
$result = $db->query($query);
$return = $db->result($result);
}
// Free the result.
$db->free($result);
// Return what they want.
return $return;
}
//
// Function: check ( $username | $user_id )
//
// Purpose: Checks if the username or user_id exists.
//
// Arguments:
// $username -> The user's username.
// $user_id -> The user's user_id.
//
// Returns: 1 if the user exists, 0 if they do not exist, -1 if it contains illegal characters.
//
function check ($data)
{
// Import CONF.
global $CONF;
// Import MYSQL class, if needed.
require_once("$CONF[local_path]/class/mysql-class.php");
// Make a new MYSQL object.
$db = new mysql();
// Check username illegal characters.
if (preg_match("/[^A-Za-z-_ ]/i", $username)) {
return -1;
}
// If it's numerical, then it's a user_id.
if (is_int($data)) {
$data_type = 'user_id';
// Otherwise, it's a username.
} else {
$data_type = 'username';
}
// Connect to the DB.
$db->pconnect();
// Prepare and execute the query.
$query = "SELECT * FROM user WHERE $data_type='$data'";
$result = $db->query($query);
// Check if we got a result.
$return = $db->num_rows($result);
// Free the result.
$db->free($result);
// Return the answer.
return $return;
}
//
// Function: to_name ( $user_id )
//
// Purpose: Translates a user_id to a username.
//
// Returns: Username for given user_id.
//
function to_name($user_id)
{
// Import CONF.
global $CONF;
// Import MYSQL class, if needed.
require_once("$CONF[local_path]/class/mysql-class.php");
// Make a new MYSQL object.
$db = new mysql();
// Connect to the database.
$db->pconnect();
// Execute query.
$query = "SELECT username FROM user WHERE user_id='$user_id'";
$result = $db->query($query);
$return = $db->result($result);
// Free result.
$db->free($result);
// Return username.
return $return;
}
//
// Function: to_id ($username OR $user_id)
//
// Purpose: Translates a username (or user_id) to a user_id.
//
// Return: The user_id for given username.
//
function to_id ( $userdata )
{
// Import CONF.
global $CONF;
// If it's an integer than we assume it's already a user_id.
if (is_numeric($userdata)) {
// So we return the value untouched.
return $userdata;
} else {
// Rename it for aesthetics.
$username = $userdata;
}
// Import MYSQL class, if needed.
require_once("$CONF[local_path]/class/mysql-class.php");
// Make a new MYSQL object.
$db = new mysql();
// Connect to the database.
$db->pconnect();
// Execute query.
$query = "SELECT user_id FROM user WHERE username='$username'";
$result = $db->query($query);
$return = $db->result($result);
// Free result.
$db->free($result);
// Return user_id.
return $return;
}
//
// Function: encrypt_password ( $username OR user_id, $password )
//
// Purpose: Encrypts the user's password with the proper cipher.
//
// Arguments:
// $userdata -> The user's username or user_id.
// $password -> The user's plaintext password.
//
// Returns: The user's properly encrypted password.
//
function encrypt_password ( $userdata, $password )
{
// Import CONF & INF.
global $CONF, $INF;
// Import SYSTEM class, if needed.
require_once("$CONF[local_path]/class/system-class.php");
// Make a new SYSTEM object.
$system = new system();
// Make sure it's a user_id.
$user_id = $this->to_id($userdata);
// Find out the user's cipher.
$cipher = $this->info($user_id, 'cipher');
// Return the encrypted password.
return $system->do_encrypt($password, $cipher);
}
//
// Function: authenticate ( $username OR $user_id , $password )
//
// Purpose: Determines whether or not a user is allowed access onto the system.
//
// Arguments:
// $userdata -> The user's username or user_id.
// $password -> The plaintext version of the password to check against.
//
// Returns: 1 if the password is valid, 0 if it is not.
//
function authenticate ( $userdata, $password )
{
// Import CONF.
global $CONF;
// Make sure it's a user_id.
$user_id = $this->to_id($userdata);
// Deny user if their access is less than 1.
if ($this->info($user_id, 'access') < 1) {
return 0;
// Otherwise check the passwords.
} else if (!strcmp($this->encrypt_password($user_id, $password), $this->info($user_id, 'password'))) {
// The user is authenticated.
return 1;
// Otherwise .... the user is not authenticated.
} else {
return 0;
}
}
}
?>