402 lines
19 KiB
PHP
402 lines
19 KiB
PHP
<?php
|
|
/**
|
|
* System - PHP Framework
|
|
*
|
|
* PHP Version 5.6
|
|
*
|
|
* @copyright 2016 Ulf Gebhardt (http://www.webcraft-media.de)
|
|
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
|
* @link https://github.com/webcraftmedia/system
|
|
* @package SYSTEM\SECURITY
|
|
*/
|
|
namespace SYSTEM\SECURITY;
|
|
|
|
/**
|
|
* security Class provided by System to manage website user and its attributes
|
|
*/
|
|
class security {
|
|
/**
|
|
* Create a new User. Permanently saved to the Database
|
|
*
|
|
* @param string $username Username of the new User
|
|
* @param string $password_sha1 Hashed Password of the new User
|
|
* @param string $email Email of the new User
|
|
* @param string $locale Language of the new User
|
|
* @param bool $json_result Return data as JSON or Array
|
|
* @return mixed Returns json with status true or Error or Array with userinfo.
|
|
*/
|
|
public static function create($username, $password_sha1, $email, $locale = null,$json_result = false){
|
|
self::startSession();
|
|
if(!self::available($username)){
|
|
throw new \SYSTEM\LOG\ERROR("Username unavailable");}
|
|
$locale = $locale ? $locale : \SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_DEFAULT_LANG);
|
|
$result = \SYSTEM\SQL\SYS_SECURITY_CREATE::QI(array( $username , $password_sha1, $email, $locale));
|
|
$row = true;
|
|
if(!$result || !($row = self::login($username, $password_sha1, $locale))){
|
|
throw new \SYSTEM\LOG\ERROR("Error during Registration process.");}
|
|
return $json_result ? \SYSTEM\LOG\JsonResult::ok() : $row;
|
|
}
|
|
|
|
/**
|
|
* Login a User.
|
|
*
|
|
* @param string $username Username of the User
|
|
* @param string $password_sha1 Hashed Password of the User
|
|
* @param string $locale Language of the User on login.
|
|
* @param bool $json_result Return data as JSON or Array
|
|
* @return mixed Returns json with status true or Error or Array with userinfo.
|
|
*/
|
|
public static function login($username, $password_sha1, $locale=NULL,$json_result = false){
|
|
self::startSession();
|
|
$_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)] = NULL;
|
|
|
|
//Database check
|
|
$row = \SYSTEM\SQL\SYS_SECURITY_LOGIN_USER_SHA1::Q1(array($username, $username, $password_sha1));
|
|
if(!$row){
|
|
throw new \SYSTEM\LOG\WARNING("Login Failed, User was not found in db");}
|
|
|
|
// set session variables
|
|
self::update_session_data(array(
|
|
'id' => $row[\SYSTEM\SQL\system_user::FIELD_ID],
|
|
'username' => $row[\SYSTEM\SQL\system_user::FIELD_USERNAME],
|
|
'email' => $row[\SYSTEM\SQL\system_user::FIELD_EMAIL],
|
|
'joindate' => $row[\SYSTEM\SQL\system_user::FIELD_JOINDATE],
|
|
'last_active' => time(),
|
|
'locale' => $row[\SYSTEM\SQL\system_user::FIELD_LOCALE],
|
|
'email_confirmed' => $row[\SYSTEM\SQL\system_user::FIELD_EMAIL_CONFIRMED]
|
|
));
|
|
|
|
if(isset($locale)){
|
|
\SYSTEM\locale::set($locale);}
|
|
\SYSTEM\SQL\SYS_SECURITY_UPDATE_LASTACTIVE::QI(array(\session_id(),$row[\SYSTEM\SQL\system_user::FIELD_ID]));
|
|
return $json_result ? \SYSTEM\LOG\JsonResult::ok() : $row;
|
|
}
|
|
|
|
/**
|
|
* Determine if username is already in use.
|
|
*
|
|
* @param string $username Username to be checked
|
|
* @param string $email EMail to be checked
|
|
* @param bool $json_result Return data as JSON or Array
|
|
* @return mixed Returns json with status true or Error or Array with userinfo.
|
|
*/
|
|
public static function available($username,$email=null,$json_result=false){
|
|
if($email){
|
|
$res = \SYSTEM\SQL\SYS_SECURITY_AVAILABLE_EMAIL::Q1(array($username,$email));
|
|
} else {
|
|
$res = \SYSTEM\SQL\SYS_SECURITY_AVAILABLE::Q1(array($username));}
|
|
if(!$res){
|
|
if($json_result){
|
|
throw new \SYSTEM\LOG\ERRROR("Cannot determine the availability of username!");
|
|
} else{ return false;}
|
|
}
|
|
if($res['count'] != 0){
|
|
if($json_result){
|
|
throw new \SYSTEM\LOG\ERRROR("Username or Email is not avilable.");
|
|
} else{ return false;}
|
|
}
|
|
return $json_result ? \SYSTEM\LOG\JsonResult::ok() : true;
|
|
}
|
|
|
|
/**
|
|
* Checks for a right for a logged in user
|
|
*
|
|
* @param int $rightid Right ID to be checked
|
|
* @param bool $json_result Return data as JSON or Array
|
|
* @return mixed Returns json with status true or false or true or false.
|
|
*/
|
|
public static function check($rightid,$json_result=false){
|
|
//Not logged in? Go away.
|
|
//If you think you need rights for your guests ur doing smth wrong ;-)
|
|
$user = null;
|
|
if(!($user = self::getUser())){
|
|
return $json_result ? \SYSTEM\LOG\JsonResult::fail() : false;}
|
|
$res = \SYSTEM\SQL\SYS_SECURITY_CHECK::Q1(array($user->id, $rightid));
|
|
if(!$res || $res['count'] == 0){
|
|
return $json_result ? \SYSTEM\LOG\JsonResult::fail() : false;}
|
|
return $json_result ? \SYSTEM\LOG\JsonResult::ok() : true;
|
|
}
|
|
|
|
/**
|
|
* Change logged in users Password
|
|
*
|
|
* @param string $old_password_sha1 Users old hashed Password
|
|
* @param string $new_password_sha1 Users new hashed Password
|
|
* @return json Returns json with status true or false
|
|
*/
|
|
public static function change_password($old_password_sha1,$new_password_sha1){
|
|
if(!\SYSTEM\SECURITY\security::isLoggedIn()){
|
|
throw new \SYSTEM\LOG\ERROR("You need to be logged in to change your Password!");}
|
|
$username = \SYSTEM\SECURITY\security::getUser()->username;
|
|
$row = \SYSTEM\SQL\SYS_SECURITY_LOGIN_USER_SHA1::Q1(array($username, $username, $old_password_sha1));
|
|
if(!$row){
|
|
throw new \SYSTEM\LOG\ERROR("No such User Password combination.");}
|
|
return \SYSTEM\SQL\SYS_SECURITY_UPDATE_PW::QI(array($new_password_sha1, $row['id'])) ? \SYSTEM\LOG\JsonResult::ok() : \SYSTEM\LOG\JsonResult::fail();
|
|
}
|
|
|
|
/**
|
|
* Change logged in users Email.
|
|
*
|
|
* This will facilitate the @see \SYSTEM\TOKEN\token utility to generate
|
|
* a token and send it to the logged in users email using php mailinc function.
|
|
*
|
|
* This function can only be invoked if the user is logged in and uses the
|
|
* function on himself.
|
|
*
|
|
* This function will fail if the Email of the user is unconfirmed. You can
|
|
* only change the email of a confirmed account.
|
|
*
|
|
* @param string $new_email New Email for the logged in User
|
|
* @param string $post_script Function to be executed AFTER clicking the EMail Link, BEFORE updating the EMail
|
|
* @param string $post_script_data Additional Data for the Postscript
|
|
* @return bool Returns true or false
|
|
*/
|
|
public static function change_email($new_email,$post_script=null,$post_script_data=null) {
|
|
if(!\SYSTEM\SECURITY\security::isLoggedIn()){
|
|
throw new \SYSTEM\LOG\ERROR('You need to be logged in to change your EMail!');}
|
|
$res = \SYSTEM\SQL\SYS_SECURITY_AVAILABLE_EMAIL::Q1(array($new_email,$new_email));
|
|
if(!$res || $res['count'] != 0){
|
|
throw new \SYSTEM\LOG\ERROR('The EMail '.$new_email.' is already registered!');}
|
|
//find all userdata
|
|
$username = \SYSTEM\SECURITY\security::getUser()->username;
|
|
$vars = \SYSTEM\SQL\SYS_SECURITY_USER_INFO::Q1(array($username,$username));
|
|
if(!$vars || $vars['email_confirmed'] !== 1){
|
|
throw new \SYSTEM\LOG\ERROR('Username not found or Email unconfirmed.');}
|
|
|
|
$old_email = $vars['email'];
|
|
$data = array('user' => $vars['id'],'email' => $new_email);
|
|
if($post_script){
|
|
$data['post_script_data'] = $post_script_data;}
|
|
|
|
//generate pw & token
|
|
$vars['email'] = $new_email;
|
|
$vars['token'] = \SYSTEM\TOKEN\token::request('\SYSTEM\TOKEN\token_change_email',$data,$post_script);
|
|
$vars['base_url'] = \SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL);
|
|
$vars['newline'] = "\r\n";
|
|
|
|
//mail
|
|
$to = $old_email;
|
|
$subject= \SYSTEM\PAGE\replace::replace(\SYSTEM\PAGE\text::get('mail_change_email_subject'), $vars);
|
|
$message= \SYSTEM\PAGE\replace::replace(\SYSTEM\PAGE\text::get('mail_change_email'), $vars);
|
|
$header = 'From: '. \SYSTEM\PAGE\text::get('mail_change_email_from')."\r\n" .
|
|
'Reply-To: '.\SYSTEM\PAGE\text::get('mail_change_email_replyto');
|
|
|
|
return \mail($to, $subject, $message, $header) ? \SYSTEM\LOG\JsonResult::ok() : \SYSTEM\LOG\JsonResult::fail();
|
|
}
|
|
|
|
/**
|
|
* Reset given users Password.
|
|
*
|
|
* This will facilitate the @see \SYSTEM\TOKEN\token utility to generate
|
|
* a token and send it to the users email using php mailinc function.
|
|
* A new password is generated on invoke and sent with the email.
|
|
* After confirming the token the new password given in the email is valid.
|
|
*
|
|
* @param string Username subject to Password reset
|
|
* @param string $post_script Function to be executed AFTER clicking the EMail Link, BEFORE updating the Password
|
|
* @param string $post_script_data Additional Data for the Postscript
|
|
* @return bool Returns true or false
|
|
*/
|
|
public static function reset_password($username,$post_script=null,$post_script_data=null) {
|
|
//find all userdata
|
|
$vars = \SYSTEM\SQL\SYS_SECURITY_USER_INFO::Q1(array($username,$username));
|
|
if(!$vars){
|
|
throw new \SYSTEM\LOG\ERROR("Username or EMail could not be found.");}
|
|
|
|
//generate pw & token
|
|
$vars['pw'] = substr(sha1(time().rand(0, 4000)), 1,10);
|
|
$data = array('user' => $vars['id'],'pw_sha1' => sha1($vars['pw']));
|
|
if($post_script){
|
|
$data['post_script_data'] = $post_script_data;}
|
|
|
|
$vars['token'] = \SYSTEM\TOKEN\token::request('\SYSTEM\TOKEN\token_reset_password',$data,$post_script);
|
|
$vars['base_url'] = \SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL);
|
|
$vars['newline'] = "\r\n";
|
|
|
|
//mail
|
|
$to = $vars['email'];
|
|
$subject= \SYSTEM\PAGE\replace::replace(\SYSTEM\PAGE\text::get('mail_reset_password_subject'), $vars);
|
|
$message= \SYSTEM\PAGE\replace::replace(\SYSTEM\PAGE\text::get('mail_reset_password'), $vars);
|
|
$header = 'From: '. \SYSTEM\PAGE\text::get('mail_reset_password_from')."\r\n" .
|
|
'Reply-To: '.\SYSTEM\PAGE\text::get('mail_reset_password_replyto');
|
|
|
|
return \mail($to, $subject, $message, $header) ? \SYSTEM\LOG\JsonResult::ok() : \SYSTEM\LOG\JsonResult::fail();
|
|
}
|
|
|
|
/**
|
|
* Request an Confirm-Email for logged in User.
|
|
*
|
|
* This will facilitate the @see \SYSTEM\TOKEN\token utility to generate
|
|
* a token and send it to the users email using php mailinc function.
|
|
*
|
|
* This function can only be invoked if the user is logged in and uses the
|
|
* function on himself.
|
|
*
|
|
* @param string $post_script Function to be executed AFTER clicking the EMail Link, BEFORE updating the Confirmation Status
|
|
* @param string $post_script_data Additional Data for the Postscript
|
|
* @return bool Returns true or false
|
|
*/
|
|
public static function confirm_email($post_script=null,$post_script_data=null) {
|
|
if(!\SYSTEM\SECURITY\security::isLoggedIn()){
|
|
throw new \SYSTEM\SECURITY\ERROR("You need to be logged in to confirm your EMail!");}
|
|
return self::confirm_email_admin(\SYSTEM\SECURITY\security::getUser()->username, $post_script, $post_script_data);
|
|
}
|
|
|
|
/**
|
|
* Request an Confirm-Email for an User.
|
|
*
|
|
* This will facilitate the @see \SYSTEM\TOKEN\token utility to generate
|
|
* a token and send it to the users email using php mailinc function..
|
|
*
|
|
* @param string Username of the Account
|
|
* @param string $post_script Function to be executed AFTER clicking the EMail Link, BEFORE updating the Confirmation Status
|
|
* @param string $post_script_data Additional Data for the Postscript
|
|
* @return bool Returns true or false
|
|
*/
|
|
public static function confirm_email_admin($user, $post_script=null,$post_script_data=null) {
|
|
//find all userdata
|
|
$vars = \SYSTEM\SQL\SYS_SECURITY_USER_INFO::Q1(array($user,$user));
|
|
if(!$vars || $vars['email_confirmed'] == 1){
|
|
throw new \SYSTEM\LOG\ERROR("Username not found or already confirmed.");}
|
|
|
|
$data = array('user' => $vars['id']);
|
|
if($post_script){
|
|
$data['post_script_data'] = $post_script_data;}
|
|
|
|
//generate token
|
|
$vars['token'] = \SYSTEM\TOKEN\token::request('\SYSTEM\TOKEN\token_confirm_email',$data,$post_script);
|
|
$vars['base_url'] = \SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL);
|
|
$vars['newline'] = "\r\n";
|
|
|
|
//mail
|
|
$to = $vars['email'];
|
|
$subject= \SYSTEM\PAGE\replace::replace(\SYSTEM\PAGE\text::get('mail_confirm_email_subject'), $vars);
|
|
$message= \SYSTEM\PAGE\replace::replace(\SYSTEM\PAGE\text::get('mail_confirm_email'), $vars);
|
|
$header = 'From: '. \SYSTEM\PAGE\text::get('mail_confirm_email_from')."\r\n" .
|
|
'Reply-To: '.\SYSTEM\PAGE\text::get('mail_confirm_email_replyto');
|
|
|
|
return \mail($to, $subject, $message, $header) ? \SYSTEM\LOG\JsonResult::ok() : \SYSTEM\LOG\JsonResult::fail();
|
|
}
|
|
|
|
/**
|
|
* Confirm a token sent using @see \SYSTEM\TOKEN\token utility
|
|
* (email confirm, email change, password reset)
|
|
*
|
|
* @param string $token Token given in eg an email.
|
|
* @param bool $json_result Return data as JSON or Array
|
|
* @return bool Returns json with status true or false or a bool
|
|
*/
|
|
public static function confirm($token) {
|
|
return \SYSTEM\LOG\JsonResult::status(\SYSTEM\TOKEN\token::confirm($token));}
|
|
|
|
/**
|
|
* Get Userinfo stored in the current Session.
|
|
*
|
|
* @return User Returns User object or NULL
|
|
*/
|
|
public static function getUser(){
|
|
if(!self::isLoggedIn(false)){
|
|
return NULL;}
|
|
return $_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)];
|
|
}
|
|
|
|
/**
|
|
* End the current Session and logout the User
|
|
*
|
|
* @param bool $json_result Return data as JSON or Array
|
|
* @return mixed Returns Json status true or true
|
|
*/
|
|
public static function logout($json_result = false){
|
|
self::startSession();
|
|
$user = self::getUser();
|
|
if($user && $user->id){
|
|
\SYSTEM\SQL\SYS_SECURITY_UPDATE_LASTACTIVE::QI(array(NULL,$user->id));}
|
|
session_destroy();
|
|
return $json_result ? \SYSTEM\LOG\JsonResult::ok() : true;}
|
|
|
|
/**
|
|
* Save a key=>value into the current session(not preserved)
|
|
*
|
|
* @param string $key key for the given value
|
|
* @param mixed $value Value for the given Key to be saved
|
|
* @return null Returns null.
|
|
*/
|
|
public static function save($key,$value){
|
|
self::startSession();
|
|
$_SESSION['values'][$key] = $value;}
|
|
|
|
/**
|
|
* Save the value of a key from the current session(not preserved)
|
|
*
|
|
* @param string $key key to be queried
|
|
* @return mixed Returns Value or null.
|
|
*/
|
|
public static function load($key){
|
|
self::startSession();
|
|
if(!isset($_SESSION['values'][$key])){
|
|
return NULL;}
|
|
return $_SESSION['values'][$key];}
|
|
|
|
/**
|
|
* Check if the current session is a logged in user
|
|
*
|
|
* @param bool $json_result Return data as JSON or Array
|
|
* @return mixed Returns json with status true or false or a bool.
|
|
*/
|
|
public static function isLoggedIn($json_result = false){
|
|
self::startSession();
|
|
return (isset($_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)]) &&
|
|
$_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)] instanceof User) ?
|
|
($json_result ? \SYSTEM\LOG\JsonResult::ok() : true) : ($json_result ? \SYSTEM\LOG\JsonResult::fail() : false);}
|
|
|
|
/**
|
|
* State the Session for the current request
|
|
*
|
|
* @return null Returns null.
|
|
*/
|
|
protected static function startSession(){
|
|
if(!isset($_SESSION) && !headers_sent()){
|
|
//\session_cache_limiter('private_no_expire');
|
|
\session_start();}
|
|
//respect locale from db if not set(right place here?)
|
|
if( isset($_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)]) &&
|
|
$_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)] instanceof User){
|
|
$_SESSION['values'][\SYSTEM\locale::SESSION_KEY] = $_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)]->locale;}
|
|
}
|
|
|
|
/**
|
|
* Update Sessiondata upon user infos change
|
|
*
|
|
* @param $data Data which has changed
|
|
* @param $session_id Session ID to be changed or null
|
|
* @return null Returns null.
|
|
*/
|
|
public static function update_session_data($data,$session_id = null){
|
|
$old_session_id = \session_id();
|
|
if($session_id){
|
|
\session_write_close();
|
|
\session_id($session_id);
|
|
\session_start();}
|
|
|
|
if( !isset($_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)]) ||
|
|
!$_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)] instanceof \SYSTEM\SECURITY\User){
|
|
$_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)] = new \SYSTEM\SECURITY\User();}
|
|
|
|
foreach(\array_keys($data) as $key){
|
|
switch($key){
|
|
case 'id': $_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)]->id = $data['id']; break;
|
|
case 'username': $_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)]->username = $data['username']; break;
|
|
case 'email': $_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)]->email = $data['email']; break;
|
|
case 'joindate': $_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)]->joindate = $data['joindate']; break;
|
|
case 'last_active': $_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)]->last_active = $data['last_active']; break;
|
|
case 'locale': $_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)]->locale = $data['locale']; break;
|
|
case 'email_confirmed': $_SESSION[\SYSTEM\CONFIG\config::get(\SYSTEM\CONFIG\config_ids::SYS_CONFIG_PATH_BASEURL)]->email_confirmed = $data['email_confirmed']; break;
|
|
}
|
|
}
|
|
|
|
if($old_session_id){
|
|
\session_write_close();
|
|
\session_id($old_session_id);
|
|
\session_start();}
|
|
}
|
|
} |