// This class contains an interface to the VerifiedUsers table as well as
// various helper-functions.
require_once("common.php");
require_once("loggedinuser.php");
class Users {
// Deletes a user (by UID). All ACLs belonging to that user are removed,
// and all changes made to any content become attributed to the Anonymous
// account before the appropriate row is deleted.
// Note that this is an irreversible process! Once the history trail is
// attributed to Anonymous, it isn't possible to tell which used to belong
// to a deleted user.
public static function deleteUser($uid) {
$db = getDBConnection();
$result = mysql_query("DELETE FROM ACLs WHERE UID=" . $uid, $db);
if (!$result) {
die("Error while deleting ACLs!");
}
$result = mysql_query("UPDATE PendingQueue SET UID=-1 WHERE UID=" . $uid, $db);
if (!$result) {
die("Error while updating pending queue!");
}
$result = mysql_query("UPDATE History SET createdbyUID=-1 WHERE createdbyUID=" . $uid, $db);
if (!$result) {
die("Error while updating history (1)!");
}
$result = mysql_query("UPDATE History SET approvedbyUID=-1 WHERE approvedbyUID=" . $uid, $db);
if (!$result) {
die("Error while updating history (2)!");
}
$result = mysql_query("DELETE FROM VerifiedUsers WHERE UID=" . $uid, $db);
if (!$result) {
die("Error while updating users!");
}
}
// Returns true if the plaintext $password matches the stored $salt and $hash.
public static function checkPassword($password, $salt, $hash) {
// echo "password is $password. salt is $salt. hash is $hash. sha1 is " . sha1($salt . $password) . "
";
settype($salt, "string");
if ($hash == sha1($salt . $password))
return true;
else
return false;
}
// Obtains an unused UID for use in VerifiedUsers. This implementation can
// be greatly improved...
private static function getUnusedUID($db) {
$result = mysql_query("SELECT MAX(UID) FROM VerifiedUsers", $db);
if (!$result) {
die('Error getting unused UID: ' . mysql_error());
}
$retVal = mysql_result($result, 0);
if ($retVal == NULL)
$retVal = 0;
else
$retVal++;
mysql_free_result($result);
return $retVal;
}
// Returns true if a username is unique (ie: no VerifiedUser or PendingUser
// has the same username).
private static function isUsernameUnique($db, $username) {
$retVal = false;
$result = mysql_query("SELECT username FROM VerifiedUsers WHERE username='" . $username . "'", $db);
if ($result && mysql_affected_rows($db) == 0) {
// There is a way to do these two queries at once, but I forgot how...
// $result = mysql_query("SELECT username FROM PendingUsers WHERE username='" . $username . "'", $db);
// if ($result && mysql_affected_rows($db) == 0)
$retVal = true;
}
return $retVal;
}
// Creates a new PendingUser entry.
public static function newPendingUser($username, $pw, $name, $email) {
$retVal = false;
$db = getDBConnection();
$randomInt = mt_rand();
if (Users::isUsernameUnique($db, $username)) {
$pwsalt = mt_rand();
settype($pwsalt, "string");
$pwhash = sha1($pwsalt . $pw);
$q = "INSERT INTO PendingUsers VALUES('" . $username . "','" . $pwsalt .
"','" . $pwhash . "','" . $name . "','" . $email . "'," .
$randomInt . ",NOW())";
$result = mysql_query($q, $db);
if ($result)
$retVal = true;
//mysql_free_result($result);
mysql_close($db);
if ($retVal == true) {
global $CMS_BASE_PATH;
global $WELCOME_EMAIL_BODY;
global $WELCOME_EMAIL_SUBJECT;
global $ADMIN_EMAIL;
$reg_url = $CMS_BASE_PATH . 'register.php?code=' . $randomInt;
//echo "REGISTER URL IS " . $reg_url;
$body = str_replace("%REG_URL%", $reg_url, $WELCOME_EMAIL_BODY);
if (!mail($email, $WELCOME_EMAIL_SUBJECT, $body)) {
die("Error: could not send confirmation e-mail. Please contact $ADMIN_EMAIL.");
}
}
} else {
die("The specified username already exists!");
}
return $retVal;
}
// Adds a user to the VerifiedUsers table.
public static function addVerifiedUser($username, $pwsalt, $pwhash,
$realname, $email, $enabled, $ip,
$db) {
$retVal = -1;
if (Users::isUsernameUnique($db, $username)) {
if ($pwsalt == null) {
$pwsalt = mt_rand();
settype($pwsalt, "string");
$pwhash = sha1($pwsalt . $pwhash);
}
if ($enabled == true)
$enabled = "Y";
else
$enabled = "N";
$uid = Users::getUnusedUID($db);
$result = mysql_query("INSERT INTO VerifiedUsers VALUES(" . $uid . ",'" . $username . "'," . $pwsalt . ",'" . $pwhash . "','" . $realname . "','" . $email . "','" . $enabled . "',0,'" . $ip . "')", $db);
if ($result)
$retVal = $uid;
} else {
die("The specified username already exists!");
}
return $retVal;
}
// Moves the specified username from the PendingUsers table into the
// VerifiedUsers table because his/her e-mail address has been verified.
public static function accountVerified($username, $ip) {
$db = getDBConnection();
//$uid = Users::getUnusedUID($db);
mysql_query("BEGIN", $db);
$result = mysql_query("SELECT * FROM PendingUsers WHERE username='" . $username . "'", $db);
if (!$result) {
mysql_query("ROLLBACK", $db);
die("Error while updating user tables.");
}
$row = mysql_fetch_row($result);
$username = $row[ 0 ];
$pwsalt = $row[ 1 ];
$pwhash = $row[ 2 ];
$realname = $row[ 3 ];
$email = $row[ 4 ];
settype($pwsalt, "integer");
$uid = Users::addVerifiedUser($username, $pwsalt,
$pwhash, $realname, $email, true, $ip, $db);
if ($uid == -1) {
mysql_query("ROLLBACK", $db);
die("Error while updating user tables.");
}
$result = mysql_query("DELETE FROM PendingUsers WHERE username='" . $username . "'", $db);
if (!$result) {
mysql_query("ROLLBACK", $db);
die("Error while updating user tables.");
}
mysql_query("COMMIT", $db);
mysql_close($db);
}
// Enables or disables a user's login. A disabled user cannot log into the
// CMS, but their history trail remains intact (versus a deleted user whose
// trail is destroyed).
public static function enableUser($UID, $which) {
$db = getDBConnection();
if ($which == true)
$q = "UPDATE Users SET enabled='Y' WHERE UID=" . $UID;
else
$q = "UPDATE Users SET enabled='N' WHERE UID=" . $UID;
$result = mysql_query($q, $db);
if (!$result) {
die("Error in enableUser().");
}
//mysql_free_result($result);
mysql_close($db);
}
// Attempts to log a user into the CMS. Returns a LoggedInUser object on
// success, or null on failure (the number of failed login attempts is
// bumped in this case too).
public static function attemptLogin($username, $password, $ip) {
$retVal = null;
$db = getDBConnection();
$result1 = mysql_query("SELECT UID,pwsalt,pwhash,enabled,failedlogins,lastip FROM VerifiedUsers WHERE username='" . $username . "'", $db);
if (!$result1) {
//return $retVal;
die("Could not retrieve user row in attemptLogin().");
}
$row = mysql_fetch_assoc($result1);
if (!$row) {
//return $retVal;
die("Username not found.");
}
$uid = $row["UID"];
if (Users::checkPassword($password, $row['pwsalt'], $row['pwhash']) &&
($row["enabled"] === 'Y')) {
echo 'Login successful!';
$failedlogins = $row["failedlogins"];
$lastip = $row["lastip"];
$result2 = mysql_query("SELECT Languages.LID,access FROM Languages,ACLs WHERE ACLs.UID=" . $uid . " AND Languages.LID = ACLs.LID", $db);
if (!$result2) {
die("Could not retrieve acl row in attemptLogin().");
}
$aclArray = array();
while($row = mysql_fetch_assoc($result2)) {
$aclArray[$row["LID"]] = $row["access"];
}
mysql_free_result($result2);
$retVal = new LoggedInUser($uid, $username, $aclArray,
$failedlogins, $lastip, $ip);
$result3 = mysql_query("UPDATE VerifiedUsers SET failedlogins=0, lastip='" .
$ip . "' WHERE UID='" . $uid . "'", $db);
} else {
$result3 = mysql_query("UPDATE VerifiedUsers SET failedlogins=failedlogins+1 WHERE UID='" . $uid . "'", $db);
}
mysql_free_result($result1);
mysql_close($db);
return $retVal;
}
// Removes a user from the PendingUsers table.
public static function deletePendingUser($username) {
$retVal = false;
$db = getDBConnection();
$result = mysql_query("DELETE FROM PendingUsers WHERE username='" . $username . "'", $db);
if (mysql_affected_rows($db) == 1)
$retVal = true;
mysql_close($db);
return $retVal;
}
}
?>