c
This commit is contained in:
297
inc/Hura8/System/Model/AuthModel.php
Normal file
297
inc/Hura8/System/Model/AuthModel.php
Normal file
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
|
||||
namespace Hura8\System\Model;
|
||||
|
||||
|
||||
use Hura8\Database\iConnectDB;
|
||||
use Hura8\System\IDGenerator;
|
||||
|
||||
class AuthModel
|
||||
{
|
||||
|
||||
/* @var iConnectDB $db */
|
||||
protected $db;
|
||||
|
||||
private $tb_login = '';
|
||||
private $tb_access_code = '';
|
||||
|
||||
private $tb_onetime_key = '';
|
||||
|
||||
public function __construct($tb_login, $tb_access_code)
|
||||
{
|
||||
$this->tb_login = $tb_login;
|
||||
$this->tb_access_code = $tb_access_code;
|
||||
$this->db = get_db('', ENABLE_DB_DEBUG);
|
||||
}
|
||||
|
||||
|
||||
private const ACCESS_CODE_LENGTH = 30;
|
||||
const ONE_TIME_KEY_LENGTH = 15;
|
||||
|
||||
|
||||
public function checkOneTimeKey($auth_key) {
|
||||
$db_response = $this->db->select(
|
||||
$this->tb_onetime_key,
|
||||
['user_id', 'user_name', 'client_id', 'create_time'],
|
||||
[
|
||||
'auth_key' => ["=", $auth_key],
|
||||
],
|
||||
'',
|
||||
1
|
||||
);
|
||||
|
||||
if($db_response->getCode()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$info = $db_response->getData();
|
||||
|
||||
if($info) {
|
||||
|
||||
// used ONCE and delete the key
|
||||
$this->db->runQuery("DELETE FROM `".$this->tb_onetime_key."` WHERE `user_id` = ? ", ['s'], [$info['user_id']]);
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// auth key allows users to export data (i.e. export to excel) for offline use
|
||||
public function createNewOneTimeKey($user_id) {
|
||||
|
||||
// and make a new one
|
||||
$auth_key = IDGenerator::createStringId(self::ONE_TIME_KEY_LENGTH);
|
||||
|
||||
$this->db->insert($this->tb_onetime_key, [
|
||||
'user_id' => $user_id,
|
||||
'auth_key' => $auth_key,
|
||||
'create_time' => CURRENT_TIME,
|
||||
]);
|
||||
|
||||
return $auth_key;
|
||||
}
|
||||
|
||||
|
||||
// for all subsequent requests, API need to provide access-code in the request's header
|
||||
// the server will verify the code
|
||||
public function checkAccessCode($access_code) {
|
||||
return $this->db->select(
|
||||
$this->tb_access_code,
|
||||
['user_id', 'create_time'],
|
||||
[
|
||||
'access_code' => ["=", $access_code],
|
||||
],
|
||||
'',
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function deleteAllAccessCode($user_id) {
|
||||
$this->db->runQuery("DELETE FROM `".$this->tb_access_code."` WHERE `user_id` = ? ", ['s'], [$user_id]);
|
||||
}
|
||||
|
||||
|
||||
protected function createNewAccessCode($user_id) {
|
||||
|
||||
// when use login here, delete all other access code
|
||||
$this->deleteAllAccessCode($user_id);
|
||||
|
||||
// and make a new one
|
||||
$access_code = IDGenerator::createStringId(self::ACCESS_CODE_LENGTH);
|
||||
$user_device = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
|
||||
|
||||
$db_response = $this->db->insert($this->tb_access_code, [
|
||||
'user_id' => $user_id,
|
||||
'access_code' => $access_code,
|
||||
'user_device' => substr($user_device, 0, 150),
|
||||
'create_time' => CURRENT_TIME,
|
||||
]);
|
||||
|
||||
return $access_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* allow to login via mobile
|
||||
* - step 1: sms an OTP code to mobile number
|
||||
* - step 2: verify OTP code (mobile number and otp code sent along in the form)
|
||||
*/
|
||||
|
||||
public function checkLoginViaMobile($mobile, $otp) {
|
||||
// todo
|
||||
}
|
||||
|
||||
/**
|
||||
* @description An OTP code is sent to user's email. This method helps user need not remember the password
|
||||
* @param $email string
|
||||
* @param $otp string
|
||||
*/
|
||||
|
||||
public function checkLoginByOTP($user_id, $otp) {
|
||||
$info = $this->db->select(
|
||||
$this->tb_login,
|
||||
[],
|
||||
[
|
||||
'user_id' => ["=", $user_id],
|
||||
'login_otp' => ["=", $otp],
|
||||
],
|
||||
'',
|
||||
1
|
||||
);
|
||||
|
||||
if($info) {
|
||||
// return to browser
|
||||
return array(
|
||||
'user_id' => $user_id,
|
||||
'access_code' => $this->createNewAccessCode($user_id),
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function createLoginOTP($user_id) {
|
||||
// check email exist
|
||||
$info = $this->db->select(
|
||||
$this->tb_login,
|
||||
[],
|
||||
[
|
||||
'user_id' => ["=", $user_id],
|
||||
],
|
||||
'',
|
||||
1
|
||||
);
|
||||
|
||||
if($info) {
|
||||
$otp = IDGenerator::createStringId(6);
|
||||
$this->db->update(
|
||||
$this->tb_login,
|
||||
[
|
||||
'login_otp' => $otp
|
||||
],
|
||||
[
|
||||
'user_id' => $info['user_id'],
|
||||
]
|
||||
);
|
||||
|
||||
return $otp;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function createOrUpdatePassword($user_id, $new_password) {
|
||||
$query = $this->db->runQuery(
|
||||
"SELECT `user_id` FROM `".$this->tb_login."` WHERE `user_id` = ? LIMIT 1 ",
|
||||
['d'], [ $user_id ]
|
||||
);
|
||||
|
||||
if($this->db->fetchAssoc($query)) {
|
||||
return $this->updatePassword($user_id, $new_password);
|
||||
}
|
||||
|
||||
return $this->createPassword($user_id, $new_password);
|
||||
}
|
||||
|
||||
|
||||
protected function createPassword($user_id, $new_password) {
|
||||
return $this->db->insert(
|
||||
$this->tb_login,
|
||||
[
|
||||
'user_id' => $user_id,
|
||||
'password_hash' => $this->hashPassword($new_password),
|
||||
'create_time' => CURRENT_TIME,
|
||||
'create_by' => '',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
protected function updatePassword($user_id, $new_password) {
|
||||
return $this->db->update(
|
||||
$this->tb_login,
|
||||
[
|
||||
'password_hash' => $this->hashPassword($new_password),
|
||||
'last_update' => CURRENT_TIME,
|
||||
'last_update_by' => ADMIN_NAME,
|
||||
],
|
||||
[
|
||||
'user_id' => $user_id,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $user_id int
|
||||
* @param $password string
|
||||
* @return array|false
|
||||
*/
|
||||
public function checkLogin($user_id, $password) {
|
||||
|
||||
$info = $this->db->select(
|
||||
$this->tb_login,
|
||||
[ 'password_hash'],
|
||||
[
|
||||
'user_id' => ["=", $user_id],
|
||||
],
|
||||
'',
|
||||
1
|
||||
);
|
||||
|
||||
//test password
|
||||
if($info && $this->verifyHash($password, $info['password_hash'])) {
|
||||
|
||||
$this->updateUserLogin($user_id);
|
||||
|
||||
// return to browser
|
||||
return array(
|
||||
'user_id' => $user_id,
|
||||
'access_code' => $this->createNewAccessCode($user_id),
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private function updateUserLogin($user_id){
|
||||
return $this->db->update(
|
||||
$this->tb_login,
|
||||
[
|
||||
'last_login_time' => CURRENT_TIME,
|
||||
'last_login_ip' => USER_IP,
|
||||
'last_login_device' => '',
|
||||
'last_login_session_id' => \Hura8\System\Security\Session::id() ?: '',
|
||||
'last_login_browser' => USER_AGENT,
|
||||
],
|
||||
[
|
||||
'user_id' => $user_id,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $str string
|
||||
* @return string
|
||||
*/
|
||||
private function hashPassword($str) {
|
||||
return password_hash($str, PASSWORD_BCRYPT, array('cost' => 12 ));
|
||||
}
|
||||
|
||||
/**
|
||||
* 15-04-2016 verify string with given hash
|
||||
* @param $str_to_verify string
|
||||
* @param $hash string
|
||||
* @return boolean
|
||||
*/
|
||||
private function verifyHash($str_to_verify, $hash) {
|
||||
return (password_verify($str_to_verify, $hash));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user