diff --git a/api/api_login.php b/api/api_login.php index a37a2d5..ff637bc 100644 --- a/api/api_login.php +++ b/api/api_login.php @@ -69,8 +69,8 @@ class api_login { * @param string $username Username * @return JSON Returns JSON result with success/failure status */ - public static function call_account_action_confirm_email($username){ - return \SYSTEM\SECURITY\security::confirm_email($username);} + public static function call_account_action_confirm_email(){ + return \SYSTEM\SECURITY\security::confirm_email();} /** * System Account Confirm Tokens @@ -79,7 +79,7 @@ class api_login { * @return JSON Returns JSON result with success/failure status */ public static function call_account_action_confirm($token){ - return \SYSTEM\SECURITY\security::confirm($token,true);} + return \SYSTEM\SECURITY\security::confirm($token);} /** * System Account Request Reset Password Token @@ -87,8 +87,8 @@ class api_login { * @param string $username Username * @return JSON Returns JSON result with success/failure status */ - public static function call_account_action_reset_password($username){ - return \SYSTEM\SECURITY\security::reset_password($username);} + public static function call_account_action_reset_password(){ + return \SYSTEM\SECURITY\security::reset_password();} /** * System Account Change Password @@ -98,8 +98,8 @@ class api_login { * @param sha1 $new_password_sha1 Users New Password SHA1 String * @return JSON Returns JSON result with success/failure status */ - public static function call_account_action_change_password($username,$old_password_sha1,$new_password_sha1){ - return \SYSTEM\SECURITY\security::change_password($username,$old_password_sha1,$new_password_sha1);} + public static function call_account_action_change_password($old_password_sha1,$new_password_sha1){ + return \SYSTEM\SECURITY\security::change_password($old_password_sha1,$new_password_sha1);} /** * System Account Request Change EMail Token @@ -108,6 +108,6 @@ class api_login { * @param email $new_email Users new EMail Address * @return JSON Returns JSON result with success/failure status */ - public static function call_account_action_change_email($username,$new_email){ - return \SYSTEM\SECURITY\security::change_email($username,$new_email);} + public static function call_account_action_change_email($new_email){ + return \SYSTEM\SECURITY\security::change_email($new_email);} } \ No newline at end of file diff --git a/db/connection/Connection.php b/db/connection/Connection.php index c903115..6457bdf 100644 --- a/db/connection/Connection.php +++ b/db/connection/Connection.php @@ -61,8 +61,8 @@ class Connection extends ConnectionAbstr{ * @param array $values Array of Prepare Values * @return Result Returns Database Query Result. */ - public function prepare($stmtName, $stmt, $values){ - return $this->connection->prepare($stmtName, $stmt, $values);} + public function prepare($stmtName, $stmt, $values, $types = null){ + return $this->connection->prepare($stmtName, $stmt, $values, $types);} /** * Query the Connection using normal Query Statement diff --git a/db/connection/ConnectionAMQP.php b/db/connection/ConnectionAMQP.php index 0593f04..7a650d4 100644 --- a/db/connection/ConnectionAMQP.php +++ b/db/connection/ConnectionAMQP.php @@ -102,7 +102,7 @@ class ConnectionAMQP extends ConnectionAbstr { * @param array $values Array of Prepare Values * @return Result Returns Database Query Result. */ - public function prepare($stmtName, $stmt, $values){ + public function prepare($stmtName, $stmt, $values, $types = null){ throw new \Exception('Could not start Transaction: not implemented');} /** diff --git a/db/connection/ConnectionAbstr.php b/db/connection/ConnectionAbstr.php index 21c1592..5f4afde 100644 --- a/db/connection/ConnectionAbstr.php +++ b/db/connection/ConnectionAbstr.php @@ -42,7 +42,7 @@ abstract class ConnectionAbstr { * @param array $values Array of Prepare Values * @return Result Returns Database Query Result. */ - abstract public function prepare($stmtName, $stmt, $values); + abstract public function prepare($stmtName, $stmt, $values, $types = null); /** * Query the Connection using normal Query Statement diff --git a/db/connection/ConnectionMYS.php b/db/connection/ConnectionMYS.php index bc4584e..62d5550 100644 --- a/db/connection/ConnectionMYS.php +++ b/db/connection/ConnectionMYS.php @@ -59,17 +59,17 @@ class ConnectionMYS extends ConnectionAbstr { * @param array $values Array of Prepare Values * @return Result Returns Database Query Result. */ - public function prepare($stmtName, $stmt, $values){ + public function prepare($stmtName, $stmt, $values, $types = null){ $prepStmt = \mysqli_prepare($this->connection, $stmt); if(!$prepStmt){ throw new \Exception('Prepared Statement prepare fail: '. \mysqli_error($this->connection));} - $types = ''; + $types_ = ''; $binds = array($prepStmt,null); for($i =0; $i < \count($values);$i++){ - $types .= self::getPrepareValueType($values[$i]); + $types_ .= self::getPrepareValueType($values[$i]); $binds[] = &$values[$i];} - $binds[1] = $types; + $binds[1] = $types ? $types : $types_; \call_user_func_array('mysqli_stmt_bind_param', $binds); //you need 2 append the parameters - thats the right way to do that. if(!mysqli_stmt_execute($prepStmt)){ diff --git a/db/connection/ConnectionPG.php b/db/connection/ConnectionPG.php index 4bf5afb..0db36b5 100644 --- a/db/connection/ConnectionPG.php +++ b/db/connection/ConnectionPG.php @@ -51,7 +51,7 @@ class ConnectionPG extends ConnectionAbstr { * @param array $values Array of Prepare Values * @return Result Returns Database Query Result. */ - public function prepare($stmtName, $stmt, $values){ + public function prepare($stmtName, $stmt, $values, $types = null){ $result = pg_query_params($this->connection, 'SELECT name FROM pg_prepared_statements WHERE name = $1', array($stmtName)); //var_dump($stmt); //var_dump($values); diff --git a/db/connection/ConnectionSQLite.php b/db/connection/ConnectionSQLite.php index 0a267ee..02d694e 100644 --- a/db/connection/ConnectionSQLite.php +++ b/db/connection/ConnectionSQLite.php @@ -52,7 +52,7 @@ class ConnectionSQLite extends ConnectionAbstr { * @param array $values Array of Prepare Values * @return Result Returns Database Query Result. */ - public function prepare($stmtName, $stmt, $values){ + public function prepare($stmtName, $stmt, $values, $types = null){ $prepStmt = $this->connection->prepare($stmt); if(!$prepStmt){ throw new \SYSTEM\LOG\ERROR('Prepared Statement prepare fail: '. $error);} diff --git a/db/qq/QP.php b/db/qq/QP.php index 389f07e..448d7aa 100644 --- a/db/qq/QP.php +++ b/db/qq/QP.php @@ -30,19 +30,19 @@ class QP { if($dbinfo instanceof \SYSTEM\DB\DBInfoPG){ if(!\is_callable(static::get_class().'::pgsql')){ throw new \SYSTEM\LOG\ERROR(static::get_class().' failed: no pgsql implementation present.');} - return $con->prepare(static::get_class(),static::pgsql(),$params); + return $con->prepare(static::get_class(),static::pgsql(),$params, \is_callable(static::get_class().'::types') ? static::types() : null); } else if ($dbinfo instanceof \SYSTEM\DB\DBInfoMYS){ if(!\is_callable(static::get_class().'::mysql')){ throw new \SYSTEM\LOG\ERROR(static::get_class().' failed: no mysql implementation present.');} - return $con->prepare(static::get_class(),static::mysql(),$params); + return $con->prepare(static::get_class(),static::mysql(),$params, \is_callable(static::get_class().'::types') ? static::types() : null); } else if ($dbinfo instanceof \SYSTEM\DB\DBInfoAMQP && is_callable(static::amqp())){ if(!\is_callable(static::get_class().'::amqp')){ throw new \SYSTEM\LOG\ERROR(static::get_class().' failed: no amqp implementation present.');} - return $con->prepare(static::get_class(),static::amqp(),$params); + return $con->prepare(static::get_class(),static::amqp(),$params, \is_callable(static::get_class().'::types') ? static::types() : null); } else if ($dbinfo instanceof \SYSTEM\DB\DBInfoSQLite){ if(!\is_callable(static::get_class().'::sqlite')){ throw new \SYSTEM\LOG\ERROR(static::get_class().' failed: no sqlite implementation present.');} - return $con->prepare(static::get_class(),static::sqlite(),$params); + return $con->prepare(static::get_class(),static::sqlite(),$params, \is_callable(static::get_class().'::types') ? static::types() : null); } } catch (\Exception $e){ throw new \Exception(static::get_class().' failed causing: '.$e->getMessage(),$e->getCode(),$e);} diff --git a/lib/system/lib/system.js b/lib/system/lib/system.js index 0c17f79..2a440cf 100644 --- a/lib/system/lib/system.js +++ b/lib/system/lib/system.js @@ -348,7 +348,7 @@ SYSTEM.prototype.account_create = function(username,password,email,success){ } }); }; -SYSTEM.prototype.account_confirm_email = function(username,success){ +SYSTEM.prototype.account_confirm_email = function(success){ $.ajax({ async: true, url: this.endpoint, @@ -356,8 +356,7 @@ SYSTEM.prototype.account_confirm_email = function(username,success){ dataType: 'JSON', data: { call: 'account', - action: 'confirm_email', - username: username, + action: 'confirm_email' }, success: success, error: function(XMLHttpRequest, textStatus, errorThrown){ @@ -405,7 +404,7 @@ SYSTEM.prototype.account_reset_password = function(username,success){ } }); }; -SYSTEM.prototype.account_change_password = function(username,old_password,new_password,success){ +SYSTEM.prototype.account_change_password = function(old_password,new_password,success){ $.ajax({ async: true, url: this.endpoint, @@ -414,7 +413,6 @@ SYSTEM.prototype.account_change_password = function(username,old_password,new_pa data: { call: 'account', action: 'change_password', - username: username, old_password_sha1: $.sha1(old_password), new_password_sha1: $.sha1(new_password) }, @@ -426,7 +424,7 @@ SYSTEM.prototype.account_change_password = function(username,old_password,new_pa } }); }; -SYSTEM.prototype.account_change_email = function(username,new_email,success){ +SYSTEM.prototype.account_change_email = function(new_email,success){ $.ajax({ async: true, url: this.endpoint, @@ -435,7 +433,6 @@ SYSTEM.prototype.account_change_email = function(username,new_email,success){ data: { call: 'account', action: 'change_email', - username: username, new_email: new_email }, success: success, diff --git a/sai/modules/saimod_sys_security/js/saimod_sys_security.js b/sai/modules/saimod_sys_security/js/saimod_sys_security.js index 83045c0..ecf981a 100644 --- a/sai/modules/saimod_sys_security/js/saimod_sys_security.js +++ b/sai/modules/saimod_sys_security/js/saimod_sys_security.js @@ -35,37 +35,34 @@ function init_saimod_sys_security_user() { }); }) $('#adduserright_add').click(function(){ - $.get( './sai.php?sai_mod=.SYSTEM.SAI.saimod_sys_security&action=addrightuser&rightid='+$('#adduserright_rightid').val()+ - '&userid='+$(this).attr('user_id'),function(data){ - if(data==1){ - system.reload(); - } else { - alert('fail'); - } - }); + $.get( './sai.php?sai_mod=.SYSTEM.SAI.saimod_sys_security&action=addrightuser&rightid='+$('#adduserright_rightid').val()+'&userid='+$(this).attr('user_id'),function(data){ + if(data==1){ + system.reload(); + } else { + alert('fail'); + } + }); }); $('#btn_confirm_email').click(function(){ - system.account_confirm_email($(this).attr('user'), - function(data){ - if(data.status){ - alert('Email sent'); - } else { - alert('fail'); - } - }); + $.get( './sai.php?sai_mod=.SYSTEM.SAI.saimod_sys_security&action=confirmemail&user='+$(this).attr('user'),function(data){ + if(data.status){ + alert('Email sent'); + } else { + alert('fail'); + } + }); }); $('#btn_change_password').click(function(){ if($('#input_pw_new1').val() !== $('#input_pw_new2').val()){ alert('Passwords dont match!'); } else { - system.account_change_password($(this).attr('user'),$('#input_pw_old').val(),$('#input_pw_new1').val(), - function(data){ - if(data.status){ + $.get( './sai.php?sai_mod=.SYSTEM.SAI.saimod_sys_security&action=changepassword&user='+$(this).attr('user')+'&new_password_sha1='+$.sha1($('#input_pw_new1').val()),function(data){ + if(data.status){ alert('Password Changed'); } else { alert('fail: '+data.result.message); } - }); + }); } }); $('#btn_reset_password').click(function(){ @@ -79,14 +76,13 @@ function init_saimod_sys_security_user() { }); }); $('#btn_change_email').click(function(){ - system.account_change_email($(this).attr('user'),$('#input_new_email').val(), - function(data){ - if(data.status){ - alert('Email sent'); - } else { - alert('fail'); - } - }); + $.get( './sai.php?sai_mod=.SYSTEM.SAI.saimod_sys_security&action=changeemail&user='+$(this).attr('user')+'&new_email='+$('#input_new_email').val(),function(data){ + if(data.status){ + alert('Email changed'); + } else { + alert('fail'); + } + }); }); $('#btn_rename_account').click(function(){ $.get( './sai.php?sai_mod=.SYSTEM.SAI.saimod_sys_security&action=renameaccount&username='+$(this).attr('user')+'&new_username='+$('#input_new_user').val(), diff --git a/sai/modules/saimod_sys_security/saimod_sys_security.php b/sai/modules/saimod_sys_security/saimod_sys_security.php index 6a17436..234ab95 100644 --- a/sai/modules/saimod_sys_security/saimod_sys_security.php +++ b/sai/modules/saimod_sys_security/saimod_sys_security.php @@ -262,7 +262,7 @@ class saimod_sys_security extends \SYSTEM\SAI\SaiModule { * @return json Returns json with status true or false */ public static function sai_mod__SYSTEM_SAI_saimod_sys_security_action_renameaccount($username,$new_username){ - if(\SYSTEM\SECURITY\security::check(\SYSTEM\SECURITY\RIGHTS::SYS_SAI_SECURITY_RIGHTS_EDIT)){ + if(!\SYSTEM\SECURITY\security::check(\SYSTEM\SECURITY\RIGHTS::SYS_SAI_SECURITY_RIGHTS_EDIT)){ return \SYSTEM\LOG\JsonResult::fail();} if(!\SYSTEM\SECURITY\security::available($new_username)){ throw new \SYSTEM\LOG\ERROR("Username not available");} @@ -275,12 +275,59 @@ class saimod_sys_security extends \SYSTEM\SAI\SaiModule { * @return json Returns json with status true or false */ public static function sai_mod__SYSTEM_SAI_saimod_sys_security_action_deleteaccount($id){ - if(\SYSTEM\SECURITY\security::check(\SYSTEM\SECURITY\RIGHTS::SYS_SAI_SECURITY_RIGHTS_EDIT)){ + if(!\SYSTEM\SECURITY\security::check(\SYSTEM\SECURITY\RIGHTS::SYS_SAI_SECURITY_RIGHTS_EDIT)){ return \SYSTEM\LOG\JsonResult::fail();} \SYSTEM\SQL\SYS_SAIMOD_SECURITY_DELETE_USER_RIGHTS::QI(array($id)); \SYSTEM\SQL\SYS_SAIMOD_SECURITY_DELETE_USER::QI(array($id)); return \SYSTEM\LOG\JsonResult::ok();} + /** + * Request EMail confirmation for the given Account + * + * @param int $user Username of the Account + * @return json Returns json with status true or false + */ + public static function sai_mod__SYSTEM_SAI_saimod_sys_security_action_confirmemail($user){ + if(!\SYSTEM\SECURITY\security::check(\SYSTEM\SECURITY\RIGHTS::SYS_SAI_SECURITY_RIGHTS_EDIT)){ + return \SYSTEM\LOG\JsonResult::fail();} + return \SYSTEM\SECURITY\security::confirm_email_admin($user); + } + + /** + * Change the Password for the given Account + * + * @param int $user Username of the Account + * @param string $new_password_sha1 New Password's SHA1-Hash + * @return json Returns json with status true or false + */ + public static function sai_mod__SYSTEM_SAI_saimod_sys_security_action_changepassword($user,$new_password_sha1){ + if(!\SYSTEM\SECURITY\security::check(\SYSTEM\SECURITY\RIGHTS::SYS_SAI_SECURITY_RIGHTS_EDIT)){ + return \SYSTEM\LOG\JsonResult::fail();} + $row = \SYSTEM\SQL\SYS_SECURITY_USER_INFO::Q1(array($user)); + if(!$row){ + throw new \SYSTEM\LOG\ERROR("No such User.");} + return \SYSTEM\SQL\SYS_SECURITY_UPDATE_PW::QI(array($new_password_sha1, $row['id'])) ? \SYSTEM\LOG\JsonResult::ok() : \SYSTEM\LOG\JsonResult::fail(); + } + + /** + * Change the EMail for the given Account + * + * Does not send an EMail for authorisation! + * Does not send an EMail for confirmation! + * + * @param int $user Username of the Account + * @param string $new_email New EMail + * @return json Returns json with status true or false + */ + public static function sai_mod__SYSTEM_SAI_saimod_sys_security_action_changeemail($user,$new_email){ + if(!\SYSTEM\SECURITY\security::check(\SYSTEM\SECURITY\RIGHTS::SYS_SAI_SECURITY_RIGHTS_EDIT)){ + return \SYSTEM\LOG\JsonResult::fail();} + $row = \SYSTEM\SQL\SYS_SECURITY_USER_INFO::Q1(array($user)); + if(!$row){ + throw new \SYSTEM\LOG\ERROR("No such User.");} + return \SYSTEM\SQL\SYS_SECURITY_CHANGE_EMAIL::QI(array($new_email,$row['id'])) ? \SYSTEM\LOG\JsonResult::ok() : \SYSTEM\LOG\JsonResult::fail(); + } + /** * Internal Function to generate the Tablerow class(color) string according * to last time active diff --git a/sai/modules/saimod_sys_security/tpl/saimod_sys_security_user_view.tpl b/sai/modules/saimod_sys_security/tpl/saimod_sys_security_user_view.tpl index f04a11b..17df451 100644 --- a/sai/modules/saimod_sys_security/tpl/saimod_sys_security_user_view.tpl +++ b/sai/modules/saimod_sys_security/tpl/saimod_sys_security_user_view.tpl @@ -43,7 +43,6 @@ - diff --git a/security/security.php b/security/security.php index a61388e..0e71407 100644 --- a/security/security.php +++ b/security/security.php @@ -117,53 +117,58 @@ class security { } /** - * Change users Password + * Change logged in users Password * - * @param string $username Username whos subject to the passwordchange * @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($username,$old_password_sha1,$new_password_sha1){ - $row = \SYSTEM\SQL\SYS_SECURITY_LOGIN_USER_SHA1::Q1(array($username, $old_password_sha1)); + 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!");} + $row = \SYSTEM\SQL\SYS_SECURITY_LOGIN_USER_SHA1::Q1(array(\SYSTEM\SECURITY\security::getUser()->username, $old_password_sha1)); if(!$row){ - throw new \SYSTEM\LOG\ERROR("No such User Password combination.");} - $result = \SYSTEM\SQL\SYS_SECURITY_UPDATE_PW::QI(array($new_password_sha1, $row['id'])); - return $result ? \SYSTEM\LOG\JsonResult::ok() : \SYSTEM\LOG\JsonResult::fail(); + 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 users Email. + * Change logged in users Email. + * * 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 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 or \SYSTEM\SECURITY\RIGHTS::SYS_SAI_SECURITY_RIGHTS_EDIT - * is present for the invoking user. + * 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 $username Username whos subject to the emailchange - * @param string $new_email New Email for the given Username + * @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($username, $new_email) { - if(!self::isLoggedIn() || (self::getUser()->username !== $username && self::check(\SYSTEM\SECURITY\RIGHTS::SYS_SAI_SECURITY_RIGHTS_EDIT))){ - throw new \SYSTEM\LOG\ERROR("You need to be logged in to trigger this function on your account.");} + 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!");} //find all userdata - $vars = \SYSTEM\SQL\SYS_SECURITY_USER_INFO::Q1(array($username)); + $vars = \SYSTEM\SQL\SYS_SECURITY_USER_INFO::Q1(array(\SYSTEM\SECURITY\security::getUser()->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',array('user' => $vars['id'],'email' => $vars['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 = $vars['email']; + $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" . @@ -173,24 +178,33 @@ class security { } /** - * Reset users Password. + * 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 Username whos subject to the password reset + * @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) { + public static function reset_password($username,$post_script=null,$post_script_data=null) { + if(!\SYSTEM\SECURITY\security::isLoggedIn()){ + throw new \SYSTEM\LOG\ERROR("You need to be logged in to reset your Password!");} //find all userdata $vars = \SYSTEM\SQL\SYS_SECURITY_USER_INFO::Q1(array($username)); if(!$vars){ throw new \SYSTEM\LOG\ERROR("Username not found.");} - + //generate pw & token $vars['pw'] = substr(sha1(time().rand(0, 4000)), 1,10); - $vars['token'] = \SYSTEM\TOKEN\token::request('\SYSTEM\TOKEN\token_reset_password',array('user' => $vars['id'],'pw_sha1' => sha1($vars['pw']))); + $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"; @@ -205,27 +219,47 @@ class security { } /** - * Request an Confirm-Email for given Username. + * 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 or \SYSTEM\SECURITY\RIGHTS::SYS_SAI_SECURITY_RIGHTS_EDIT - * is present for the invoking user. + * function on himself. * - * @param string $username Username whos subject to the email confirm request + * @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($username) { - if(!self::isLoggedIn() || (self::getUser()->username !== $username && self::check(\SYSTEM\SECURITY\RIGHTS::SYS_SAI_SECURITY_RIGHTS_EDIT))){ - throw new \SYSTEM\LOG\ERROR("You need to be logged in to trigger this function on your account.");} + public static function confirm_email($post_script=null,$post_script_data=null) { + if(!\SYSTEM\SECURITY\security::isLoggedIn()){ + throw new 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($username)); + $vars = \SYSTEM\SQL\SYS_SECURITY_USER_INFO::Q1(array($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',array('user' => $vars['id'])); + $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"; @@ -247,10 +281,8 @@ class security { * @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,$json_result = false) { - return \SYSTEM\TOKEN\token::confirm($token) ? - ($json_result ? \SYSTEM\LOG\JsonResult::ok() : true) : - ($json_result ? \SYSTEM\LOG\JsonResult::fail() : false);} + public static function confirm($token) { + return \SYSTEM\TOKEN\token::confirm($token) ? \SYSTEM\TOKEN\token::text_success($token) : \SYSTEM\TOKEN\token::text_fail($token);} /** * Get Userinfo stored in the current Session. diff --git a/sql/qt/mysql/data/system_api.sql b/sql/qt/mysql/data/system_api.sql index 9f44b19..f661157 100644 --- a/sql/qt/mysql/data/system_api.sql +++ b/sql/qt/mysql/data/system_api.sql @@ -1,13 +1,17 @@ REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (10, 0, 0, -1, NULL, 'call', NULL); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (11, 0, 0, 10, NULL, 'action', NULL); -REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (12, 0, 2, 11, 'reset_password', 'username', 'STRING'); -REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (13, 0, 2, 11, 'change_password', 'username', 'STRING'); +-- REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (12, 0, 2, 11, 'reset_password', 'username', 'STRING'); +DELETE FROM `system_api` WHERE `ID` = 12 AND `group` = 0; +-- REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (13, 0, 2, 11, 'change_password', 'username', 'STRING'); +DELETE FROM `system_api` WHERE `ID` = 13 AND `group` = 0; REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (14, 0, 2, 11, 'change_password', 'old_password_sha1', 'STRING'); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (15, 0, 3, 11, 'change_password', 'new_password_sha1', 'STRING'); -REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (16, 0, 2, 11, 'confirm_email', 'username', 'STRING'); +-- REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (16, 0, 2, 11, 'confirm_email', 'username', 'STRING'); +DELETE FROM `system_api` WHERE `ID` = 16 AND `group` = 0; REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (17, 0, 2, 11, 'confirm', 'token', 'STRING'); -REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (18, 0, 2, 11, 'change_email', 'username', 'STRING'); +-- REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (18, 0, 2, 11, 'change_email', 'username', 'STRING'); +DELETE FROM `system_api` WHERE `ID` = 18 AND `group` = 0; REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (19, 0, 2, 11, 'change_email', 'new_email', 'EMAIL'); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (20, 0, 2, 11, 'login', 'username', 'STRING'); @@ -18,7 +22,7 @@ REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `na REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (24, 0, 2, 11, 'create', 'username', 'STRING'); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (25, 0, 2, 11, 'create', 'password_sha1', 'STRING'); -REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (26, 0, 2, 11, 'create', 'email', 'STRING'); +REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (26, 0, 2, 11, 'create', 'email', 'EMAIL'); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (27, 0, 2, 11, 'create', 'locale', 'LANG'); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (30, 0, 2, 10, 'files', 'cat', 'STRING'); diff --git a/sql/qt/mysql/data/system_sai_api.sql b/sql/qt/mysql/data/system_sai_api.sql index 61193e9..0a53d8c 100644 --- a/sql/qt/mysql/data/system_sai_api.sql +++ b/sql/qt/mysql/data/system_sai_api.sql @@ -9,13 +9,17 @@ REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `na -- system_api REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (10, 42, 0, -1, NULL, 'call', NULL); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (11, 42, 0, 10, NULL, 'action', NULL); -REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (12, 42, 2, 11, 'reset_password', 'username', 'STRING'); -REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (13, 42, 2, 11, 'change_password', 'username', 'STRING'); +-- REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (12, 42, 2, 11, 'reset_password', 'username', 'STRING'); +DELETE FROM `system_api` WHERE `ID` = 12 AND `group` = 42; +-- REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (13, 42, 2, 11, 'change_password', 'username', 'STRING'); +DELETE FROM `system_api` WHERE `ID` = 13 AND `group` = 42; REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (14, 42, 2, 11, 'change_password', 'old_password_sha1', 'STRING'); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (15, 42, 3, 11, 'change_password', 'new_password_sha1', 'STRING'); -REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (16, 42, 2, 11, 'confirm_email', 'username', 'STRING'); +-- REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (16, 42, 2, 11, 'confirm_email', 'username', 'STRING'); +DELETE FROM `system_api` WHERE `ID` = 16 AND `group` = 42; REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (17, 42, 2, 11, 'confirm', 'token', 'STRING'); -REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (18, 42, 2, 11, 'change_email', 'username', 'STRING'); +-- REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (18, 42, 2, 11, 'change_email', 'username', 'STRING'); +DELETE FROM `system_api` WHERE `ID` = 18 AND `group` = 42; REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (19, 42, 2, 11, 'change_email', 'new_email', 'EMAIL'); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (20, 42, 2, 11, 'login', 'username', 'STRING'); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (21, 42, 2, 11, 'login', 'password_sha1', 'STRING'); @@ -53,8 +57,8 @@ REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `na -- REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (110, 42, 2, 100, 'register', 'username', 'ALL'); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (111, 42, 2, 100, 'register', 'password', 'ALL'); -REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (112, 42, 2, 100, 'register', 'email', 'ALL'); -REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (113, 42, 3, 100, 'register', 'locale', 'ALL'); +REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (112, 42, 2, 100, 'register', 'email', 'EMAIL'); +REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (113, 42, 3, 100, 'register', 'locale', 'LANG'); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (200, 42, 0, 0, '_SYSTEM_SAI_saimod_sys_log', 'action', NULL); @@ -93,7 +97,11 @@ REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `na REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (350, 42, 2, 300, 'renameaccount', 'username', 'STRING'); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (351, 42, 2, 300, 'renameaccount', 'new_username', 'STRING'); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (355, 42, 2, 300, 'deleteaccount', 'id', 'UINT'); - +REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (360, 42, 2, 300, 'confirmemail', 'user', 'STRING'); +REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (365, 42, 2, 300, 'changepassword', 'user', 'STRING'); +REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (366, 42, 2, 300, 'changepassword', 'new_password_sha1', 'STRING'); +REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (370, 42, 2, 300, 'changeemail', 'user', 'STRING'); +REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (371, 42, 2, 300, 'changeemail', 'new_email', 'EMAIL'); REPLACE INTO `system_api` (`ID`, `group`, `type`, `parentID`, `parentValue`, `name`, `verify`) VALUES (400, 42, 0, 0, '_SYSTEM_SAI_saimod_sys_mod', 'action', NULL); diff --git a/sql/qt/mysql/schema/system_token.sql b/sql/qt/mysql/schema/system_token.sql index 5b9a0b3..5f4684e 100644 --- a/sql/qt/mysql/schema/system_token.sql +++ b/sql/qt/mysql/schema/system_token.sql @@ -7,6 +7,7 @@ CREATE TABLE `system_token` ( `request_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `confirm_user` INT(11) NULL DEFAULT NULL, `confirm_time` TIMESTAMP NULL DEFAULT NULL, + `post_script` VARCHAR(255) NULL DEFAULT NULL, PRIMARY KEY (`token`) ) COLLATE='utf8_general_ci' diff --git a/token/qq/SYS_TOKEN_INSERT.php b/token/qq/SYS_TOKEN_INSERT.php index 350cc48..e8e9427 100644 --- a/token/qq/SYS_TOKEN_INSERT.php +++ b/token/qq/SYS_TOKEN_INSERT.php @@ -22,13 +22,17 @@ class SYS_TOKEN_INSERT extends \SYSTEM\DB\QP { */ public static function get_class(){return \get_class();} + public static function types(){return +'ssssis'; + } + /** * Get QQs MYSQL Query String * * @return string Returns MYSQL Query String */ public static function mysql(){return -'INSERT INTO system_token (token, class, expire, data, request_user)'. -' VALUES (?, ?, FROM_UNIXTIME(?), ?, ?);'; +'INSERT INTO system_token (token, class, expire, data, request_user, post_script)'. +' VALUES (?, ?, FROM_UNIXTIME(?), ?, ?, ?);'; } } \ No newline at end of file diff --git a/token/token.php b/token/token.php index 914284e..c75a619 100644 --- a/token/token.php +++ b/token/token.php @@ -49,7 +49,7 @@ class token{ * @param array $data Data sved to Database for the token_handler on confirm * @return string Returns token string. */ - public static function request($class,$data=array()){ + public static function request($class,$data=array(),$post_script=null){ if(!\in_array($class, self::$type_handlers)){ throw new \SYSTEM\LOG\ERROR("Token_handler class not known to Token class. Please register it first.");} @@ -57,7 +57,8 @@ class token{ $res = \SYSTEM\SQL\SYS_TOKEN_INSERT::QI( array( $token, $class, \call_user_func(array($class, 'expire')), json_encode($data), - \SYSTEM\SECURITY\security::isLoggedIn() ? \SYSTEM\SECURITY\security::getUser()->id : null)); + \SYSTEM\SECURITY\security::isLoggedIn() ? \SYSTEM\SECURITY\security::getUser()->id : null, + $post_script)); return $token; } @@ -69,17 +70,41 @@ class token{ */ public static function confirm($token){ $res = self::get($token); - if(!$res){ + /*if(!$res){ throw new \SYSTEM\LOG\ERROR('Token invalid.');} if(!$res['expire'] || strtotime($res['expire']) < time()){ - throw new \SYSTEM\LOG\ERROR('Token has expired!');} + throw new \SYSTEM\LOG\ERROR('Token has expired!');}*/ + if(!$res || !$res['expire'] || strtotime($res['expire']) < time()){ + return false;} + if(!\in_array($res['class'], self::$type_handlers)){ throw new \SYSTEM\LOG\ERROR('Token_handler class not known to Token class. Please register it first.');} + + if(\array_key_exists('post_script',$res) && $res['post_script']){ + if(!\is_callable($res['post_script'])){ + throw new \SYSTEM\LOG\ERROR('Post Script required, but could not find it!');} + if(!\call_user_func($res['post_script'], $res)){ + throw new \SYSTEM\LOG\ERROR('Post Script did not execute successfully');} + } if(!\call_user_func_array(array($res['class'], 'confirm'),array($res))){ throw new \SYSTEM\LOG\ERROR('Token_handler rejected Token.');} return \SYSTEM\SQL\SYS_TOKEN_CONFIRM::QI(array( \SYSTEM\SECURITY\security::isLoggedIn() ? \SYSTEM\SECURITY\security::getUser()->id : null, $token)); } + public static function text_success($token){ + $res = self::get($token); + if(!\in_array($res['class'], self::$type_handlers)){ + throw new \SYSTEM\LOG\ERROR('Token_handler class not known to Token class. Please register it first.');} + return \call_user_func_array(array($res['class'], 'text_success'),array($res)); + } + + public static function text_fail($token){ + $res = self::get($token); + if(!\in_array($res['class'], self::$type_handlers)){ + throw new \SYSTEM\LOG\ERROR('Token_handler class not known to Token class. Please register it first.');} + return \call_user_func_array(array($res['class'], 'text_fail'),array($res)); + } + /** * Get a existing token from db * diff --git a/token/token_change_email.php b/token/token_change_email.php index 398f824..be70ddd 100644 --- a/token/token_change_email.php +++ b/token/token_change_email.php @@ -41,4 +41,13 @@ class token_change_email implements token_handler{ public static function confirm($token_data){ $data = \json_decode($token_data['data'],true); return \SYSTEM\SQL\SYS_SECURITY_CHANGE_EMAIL::QI(array($data['email'],$data['user'])) ? true : false;} + + public static function text_fail($token_data) { + $data = \json_decode($token_data['data'],true); + return 'Could NOT change your Account\'s EMail-Address to '.$data['email'].'. Token is expired or invalid.';} + + public static function text_success($token_data) { + $data = \json_decode($token_data['data'],true); + return 'Changed your Account\'s EMail-Address to '.$data['email'].'.';} + } \ No newline at end of file diff --git a/token/token_confirm_email.php b/token/token_confirm_email.php index 2151383..aa54f63 100644 --- a/token/token_confirm_email.php +++ b/token/token_confirm_email.php @@ -41,4 +41,10 @@ class token_confirm_email implements token_handler{ public static function confirm($token_data){ $data = \json_decode($token_data['data'],true); return \SYSTEM\SQL\SYS_SECURITY_CONFIRM_EMAIL::QI(array($data['user'])) ? true : false;} + + public static function text_fail($token_data) { + return 'Could NOT confirm your EMail-Address. Token is expired or invalid.';} + + public static function text_success($token_data) { + return 'Confirmed your EMail-Address.';} } \ No newline at end of file diff --git a/token/token_handler.php b/token/token_handler.php index 45fd734..7cbbe5f 100644 --- a/token/token_handler.php +++ b/token/token_handler.php @@ -36,4 +36,8 @@ interface token_handler { * @return bool Returns true or false. */ static function confirm($token_data); + + static function text_success($token_data); + + static function text_fail($token_data); } \ No newline at end of file diff --git a/token/token_reset_password.php b/token/token_reset_password.php index 5e86cb7..d5bb0bc 100644 --- a/token/token_reset_password.php +++ b/token/token_reset_password.php @@ -41,4 +41,10 @@ class token_reset_password implements token_handler{ public static function confirm($token_data){ $data = \json_decode($token_data['data'],true); return \SYSTEM\SQL\SYS_SECURITY_RESET_PASSWORD::QI(array($data['pw_sha1'],$data['user'])) ? true : false;} + + public static function text_fail($token_data) { + return 'Could NOT reset your Password. Token is expired or invalid.';} + + public static function text_success($token_data) { + return 'Changed your Password successfully.';} } \ No newline at end of file