2018-07-13 18:39:55 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) Codiad & Kent Safranski (codiad.com), distributed
|
|
|
|
* as-is and without warranty under the MIT License. See
|
|
|
|
* [root]/license.txt for more. This information must remain intact.
|
|
|
|
*/
|
|
|
|
|
2018-11-19 19:30:49 +01:00
|
|
|
require_once( "../settings/class.settings.php" );
|
|
|
|
|
2018-10-11 16:17:41 +02:00
|
|
|
class User {
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// PROPERTIES
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
2018-11-10 06:41:28 +01:00
|
|
|
public $access = 'user';
|
2018-10-11 16:17:41 +02:00
|
|
|
public $username = '';
|
|
|
|
public $password = '';
|
|
|
|
public $project = '';
|
|
|
|
public $projects = '';
|
|
|
|
public $users = '';
|
|
|
|
public $actives = '';
|
|
|
|
public $lang = '';
|
|
|
|
public $theme = '';
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// METHODS
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// -----------------------------||----------------------------- //
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// Construct
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
public function __construct() {
|
|
|
|
|
|
|
|
$this->actives = getJSON( 'active.php' );
|
|
|
|
}
|
|
|
|
|
2018-11-10 06:41:28 +01:00
|
|
|
public function add_user() {
|
|
|
|
|
|
|
|
$sql = "INSERT INTO `users`( `username`, `password`, `access`, `project` ) VALUES ( ?, PASSWORD( ? ), ?, ? );";
|
|
|
|
$bind = "ssss";
|
|
|
|
$bind_variables = array( $this->username, $this->password, $this->access, null );
|
|
|
|
$return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error that username is already taken." ) );
|
|
|
|
|
|
|
|
if( sql::check_sql_error( $return ) ) {
|
|
|
|
|
2018-11-19 19:30:49 +01:00
|
|
|
$this->set_default_options();
|
2018-11-10 06:41:28 +01:00
|
|
|
echo formatJSEND( "success", array( "username" => $this->username ) );
|
|
|
|
} else {
|
|
|
|
|
|
|
|
echo formatJSEND( "error", "The Username is Already Taken" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-19 19:30:49 +01:00
|
|
|
public function delete_user() {
|
|
|
|
|
|
|
|
$sql = "DELETE FROM `user_options` WHERE `username`=?;";
|
|
|
|
$bind = "s";
|
|
|
|
$bind_variables = array( $this->username );
|
|
|
|
$return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error deleting user information." ) );
|
|
|
|
|
|
|
|
if( sql::check_sql_error( $return ) ) {
|
|
|
|
|
|
|
|
$sql = "DELETE FROM `users` WHERE `username`=?;";
|
|
|
|
$bind = "s";
|
|
|
|
$bind_variables = array( $this->username );
|
|
|
|
$return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error deleting user information." ) );
|
|
|
|
|
|
|
|
if( sql::check_sql_error( $return ) ) {
|
|
|
|
|
|
|
|
echo formatJSEND( "success", null );
|
|
|
|
} else {
|
|
|
|
|
|
|
|
echo $return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
echo $return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-10 06:41:28 +01:00
|
|
|
public function get_user( $username ) {
|
|
|
|
|
|
|
|
$sql = "SELECT * FROM `users` WHERE `username`=?";
|
|
|
|
$bind = "s";
|
|
|
|
$bind_variables = array( $username );
|
|
|
|
$return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error can not select user." ) );
|
|
|
|
|
|
|
|
if( sql::check_sql_error( $return ) ) {
|
|
|
|
|
|
|
|
echo formatJSEND( "success", $return );
|
|
|
|
} else {
|
|
|
|
|
|
|
|
echo $return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function list_users() {
|
|
|
|
|
|
|
|
$sql = "SELECT * FROM `users`";
|
|
|
|
$bind = "";
|
|
|
|
$bind_variables = array( $this->username, $this->password, $this->access, null );
|
|
|
|
$return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error can not select users." ) );
|
|
|
|
|
|
|
|
return( $return );
|
|
|
|
}
|
2018-11-19 19:30:49 +01:00
|
|
|
|
|
|
|
public function set_default_options() {
|
|
|
|
|
|
|
|
$Settings = new Settings();
|
|
|
|
$Settings->username = $this->username;
|
|
|
|
foreach( Settings::DEFAULT_OPTIONS as $id => $option ) {
|
|
|
|
|
|
|
|
$Settings->update_option( $option["name"], $option["value"], true );
|
|
|
|
}
|
|
|
|
}
|
2018-11-10 06:41:28 +01:00
|
|
|
|
2018-10-11 16:17:41 +02:00
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// Authenticate
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
public function Authenticate() {
|
2018-07-27 19:59:08 +02:00
|
|
|
|
2018-10-11 16:17:41 +02:00
|
|
|
if( ! is_dir( SESSIONS_PATH ) ) {
|
2018-07-27 19:59:08 +02:00
|
|
|
|
|
|
|
mkdir( SESSIONS_PATH, 00755 );
|
|
|
|
}
|
|
|
|
|
|
|
|
$permissions = array(
|
|
|
|
"755",
|
|
|
|
"0755"
|
|
|
|
);
|
|
|
|
|
|
|
|
$server_user = posix_getpwuid( posix_geteuid() );
|
|
|
|
$sessions_permissions = substr( sprintf( '%o', fileperms( SESSIONS_PATH ) ), -4 );
|
|
|
|
$sessions_owner = posix_getpwuid( fileowner( SESSIONS_PATH ) );
|
|
|
|
|
2018-10-11 16:17:41 +02:00
|
|
|
if( ! ( $sessions_owner === $server_user ) ) {
|
2018-07-27 19:59:08 +02:00
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
chown( SESSIONS_PATH, $server_user );
|
|
|
|
} catch( Exception $e ) {
|
|
|
|
|
|
|
|
echo( formatJSEND("error", "Error, incorrect owner of sessions folder. Expecting: $server_user, Recieved: " . $sessions_owner ) );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-11 16:17:41 +02:00
|
|
|
if( ! in_array( $sessions_permissions, $permissions ) ) {
|
2018-07-27 19:59:08 +02:00
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
chmod( SESSIONS_PATH, 00755 );
|
|
|
|
} catch( Exception $e ) {
|
|
|
|
|
|
|
|
echo( formatJSEND("error", "Error, incorrect permissions on sessions folder. Expecting: 0755, Recieved: " . $sessions_permissions ) );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-11 16:17:41 +02:00
|
|
|
$pass = false;
|
|
|
|
$this->EncryptPassword();
|
2018-11-10 06:41:28 +01:00
|
|
|
$sql = "SELECT * FROM `users` WHERE `username`=? AND `password`=PASSWORD( ? );";
|
|
|
|
$bind = "ss";
|
|
|
|
$bind_variables = array( $this->username, $this->password );
|
|
|
|
$return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error fetching user information." ) );
|
|
|
|
|
|
|
|
if( mysqli_num_rows( $return ) > 0 ) {
|
2018-10-11 16:17:41 +02:00
|
|
|
|
2018-11-10 06:41:28 +01:00
|
|
|
$pass = true;
|
|
|
|
$token = mb_strtoupper( strval( bin2hex( openssl_random_pseudo_bytes( 16 ) ) ) );
|
|
|
|
$_SESSION['id'] = SESSION_ID;
|
|
|
|
$_SESSION['user'] = $this->username;
|
|
|
|
$_SESSION['token'] = $token;
|
|
|
|
$_SESSION['lang'] = $this->lang;
|
|
|
|
$_SESSION['theme'] = $this->theme;
|
|
|
|
$_SESSION["login_session"] = true;
|
|
|
|
$user = mysqli_fetch_assoc( $return );
|
|
|
|
|
|
|
|
$sql = "UPDATE `users` SET `token`=PASSWORD( ? ) WHERE `username`=?;";
|
|
|
|
$bind = "ss";
|
|
|
|
$bind_variables = array( $token, $this->username );
|
|
|
|
sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error updating user information." ) );
|
|
|
|
|
|
|
|
if( $user['project'] != '' ) {
|
2018-10-11 16:17:41 +02:00
|
|
|
|
2018-11-10 06:41:28 +01:00
|
|
|
$_SESSION['project'] = $user['project'];
|
2018-10-11 16:17:41 +02:00
|
|
|
}
|
2018-11-10 06:41:28 +01:00
|
|
|
|
|
|
|
$this->checkDuplicateSessions( $this->username );
|
2018-10-11 16:17:41 +02:00
|
|
|
}
|
2018-07-24 20:27:53 +02:00
|
|
|
|
2018-10-11 16:17:41 +02:00
|
|
|
if( $pass ) {
|
|
|
|
|
|
|
|
echo formatJSEND( "success", array( "username" => $this->username ) );
|
|
|
|
} else {
|
|
|
|
|
|
|
|
echo formatJSEND( "error", "Incorrect Username or Password" );
|
|
|
|
}
|
|
|
|
}
|
2018-07-27 19:59:08 +02:00
|
|
|
|
2018-10-11 16:17:41 +02:00
|
|
|
/**
|
|
|
|
* Check duplicate sessions
|
|
|
|
*
|
|
|
|
* This function checks to see if the user is currently logged in
|
|
|
|
* on any other machine and if they are then log them off. This
|
|
|
|
* will fix the issue with the new auto save attempting to save both
|
|
|
|
* users at the same time.
|
|
|
|
*/
|
|
|
|
|
|
|
|
public static function checkDuplicateSessions( $username ) {
|
|
|
|
|
|
|
|
session_write_close();
|
|
|
|
$all_sessions = array();
|
|
|
|
$sessions = glob( SESSIONS_PATH . "/*" );
|
|
|
|
session_id( SESSION_ID );
|
|
|
|
|
|
|
|
foreach( $sessions as $session ) {
|
|
|
|
|
|
|
|
if( strpos( $session, "sess_") == false ) {
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$session = str_replace( "sess_", "", $session );
|
|
|
|
$session = str_replace( SESSIONS_PATH . "/", "", $session );
|
|
|
|
//This skips temp files that aren't sessions
|
|
|
|
if( strpos( $session, "." ) == false ) {
|
|
|
|
|
|
|
|
session_id( $session );
|
|
|
|
session_start();
|
|
|
|
$_SESSION["id"] = $session;
|
|
|
|
array_push( $all_sessions, $_SESSION );
|
|
|
|
|
|
|
|
if( isset( $_SESSION["user"] ) && $_SESSION["user"] === $username && isset( $_SESSION["login_session"] ) && $_SESSION["login_session"] === true && SESSION_ID !== session_id() ) {
|
|
|
|
|
|
|
|
session_destroy();
|
|
|
|
} else {
|
|
|
|
|
|
|
|
session_abort();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
session_id( SESSION_ID );
|
|
|
|
session_start();
|
|
|
|
}
|
|
|
|
|
2018-11-10 06:41:28 +01:00
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// Check Duplicate
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
public function CheckDuplicate() {
|
|
|
|
|
|
|
|
$pass = true;
|
|
|
|
foreach( $this->users as $user => $data ) {
|
|
|
|
|
|
|
|
if( $data['username'] == $this->username ) {
|
|
|
|
|
|
|
|
$pass = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $pass;
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// Clean username
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
public static function CleanUsername( $username ) {
|
|
|
|
|
|
|
|
return preg_replace( '#[^A-Za-z0-9' . preg_quote( '-_@. ').']#', '', $username );
|
|
|
|
}
|
|
|
|
|
2018-10-11 16:17:41 +02:00
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// Create Account
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
public function Create() {
|
|
|
|
|
|
|
|
$this->EncryptPassword();
|
2018-11-10 06:41:28 +01:00
|
|
|
$this->add_user();
|
2018-10-11 16:17:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// Delete Account
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
public function Delete() {
|
|
|
|
|
2018-11-19 19:30:49 +01:00
|
|
|
$this->delete_user();
|
2018-10-11 16:17:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
2018-11-10 06:41:28 +01:00
|
|
|
// Encrypt Password
|
2018-10-11 16:17:41 +02:00
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
2018-11-10 06:41:28 +01:00
|
|
|
private function EncryptPassword() {
|
2018-10-11 16:17:41 +02:00
|
|
|
|
2018-11-10 06:41:28 +01:00
|
|
|
$this->password = sha1( md5( $this->password ) );
|
2018-10-11 16:17:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
2018-11-10 06:41:28 +01:00
|
|
|
// Change Password
|
2018-10-11 16:17:41 +02:00
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
2018-11-10 06:41:28 +01:00
|
|
|
public function Password() {
|
|
|
|
|
|
|
|
$this->EncryptPassword();
|
|
|
|
$sql = "UPDATE `users` SET `password`=PASSWORD( ? ) WHERE `username`=?;";
|
|
|
|
$bind = "ss";
|
|
|
|
$bind_variables = array( $this->password, $this->username );
|
|
|
|
$return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error updating user information." ) );
|
2018-10-11 16:17:41 +02:00
|
|
|
|
2018-11-10 06:41:28 +01:00
|
|
|
if( sql::check_sql_error( $return ) ) {
|
2018-10-11 16:17:41 +02:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2018-11-10 06:41:28 +01:00
|
|
|
echo formatJSEND( "success", null );
|
2018-10-11 16:17:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// Set Current Project
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
public function Project() {
|
|
|
|
|
2018-11-10 06:41:28 +01:00
|
|
|
$sql = "UPDATE `users` SET `project`=? WHERE `username`=?;";
|
|
|
|
$bind = "ss";
|
|
|
|
$bind_variables = array( $this->project, $this->username );
|
|
|
|
$return = sql::sql( $sql, $bind, $bind_variables, formatJSEND( "error", "Error updating user information." ) );
|
|
|
|
|
|
|
|
if( sql::check_sql_error( $return ) ) {
|
2018-10-11 16:17:41 +02:00
|
|
|
|
2018-11-10 06:41:28 +01:00
|
|
|
echo formatJSEND( "success", null );
|
|
|
|
} else {
|
|
|
|
|
|
|
|
echo( $return );
|
2018-10-11 16:17:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// Verify Account Exists
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
public function Verify() {
|
|
|
|
|
|
|
|
$pass = 'false';
|
|
|
|
foreach( $this->users as $user => $data ) {
|
|
|
|
|
|
|
|
if( $this->username == $data['username'] ) {
|
|
|
|
|
|
|
|
$pass = 'true';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
echo( $pass );
|
|
|
|
}
|
2018-07-26 21:39:40 +02:00
|
|
|
}
|