|
|
|
@ -110,149 +110,441 @@ class Aauth
|
|
|
|
|
$this->session = $session; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------- |
|
|
|
|
// User Functions |
|
|
|
|
//-------------------------------------------------------------------- |
|
|
|
|
//-------------------------------------------------------------------------- |
|
|
|
|
// Login Functions |
|
|
|
|
//-------------------------------------------------------------------------- |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Create user |
|
|
|
|
* Login user |
|
|
|
|
* |
|
|
|
|
* Creates a new user |
|
|
|
|
* Check provided details against the database. Add items to error array on fail |
|
|
|
|
* |
|
|
|
|
* @param string $email User's email address |
|
|
|
|
* @param string $password User's password |
|
|
|
|
* @param string|boolean $username User's username |
|
|
|
|
* @param string $identifier Identifier |
|
|
|
|
* @param string $password Password |
|
|
|
|
* @param boolean $remember Whether to remember login |
|
|
|
|
* @param string $totpCode TOTP Code |
|
|
|
|
* |
|
|
|
|
* @return integer|boolean |
|
|
|
|
* @return boolean |
|
|
|
|
*/ |
|
|
|
|
public function createUser(string $email, string $password, string $username = null) |
|
|
|
|
public function login(string $identifier, string $password, bool $remember = null, string $totpCode = null) |
|
|
|
|
{ |
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
|
|
|
|
|
$data['email'] = $email; |
|
|
|
|
$data['password'] = $password; |
|
|
|
|
helper('cookie'); |
|
|
|
|
delete_cookie('remember'); |
|
|
|
|
|
|
|
|
|
if (! is_null($username)) |
|
|
|
|
{ |
|
|
|
|
$data['username'] = $username; |
|
|
|
|
} |
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
$loginAttemptModel = new LoginAttemptModel(); |
|
|
|
|
$userVariableModel = new UserVariableModel(); |
|
|
|
|
|
|
|
|
|
if (! $userId = $userModel->insert($data)) |
|
|
|
|
if ($this->config->loginProtection && ! $loginAttemptModel->save()) |
|
|
|
|
{ |
|
|
|
|
$this->error(array_values($userModel->errors())); |
|
|
|
|
$this->error(lang('Aauth.loginAttemptsExceeded')); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($this->config->userVerification) |
|
|
|
|
// if ($this->config->ddos_protection && $this->config->recaptcha_active && $loginAttempts->get() > $this->config->recaptcha_login_attempts){ |
|
|
|
|
// $this->CI->load->helper('recaptchalib'); |
|
|
|
|
// $reCaptcha = new ReCaptcha( $this->config->recaptcha_secret); |
|
|
|
|
// $resp = $reCaptcha->verifyResponse( $this->CI->input->server("REMOTE_ADDR"), $this->CI->input->post("g-recaptcha-response") ); |
|
|
|
|
// if( ! $resp->success){ |
|
|
|
|
// $this->error(lang('Aauth.aauth_error_recaptcha_not_correct')); |
|
|
|
|
// return false; |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
if ($this->config->loginUseUsername) |
|
|
|
|
{ |
|
|
|
|
$this->sendVerification($userId, $email); |
|
|
|
|
$this->info(lang('Aauth.infoCreateVerification')); |
|
|
|
|
if (! $identifier || strlen($password) < $this->config->passwordMin || strlen($password) > $this->config->passwordMax) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.loginFailedUsername')); |
|
|
|
|
|
|
|
|
|
return $userId; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (! $user = $userModel->where('username', $identifier)->first()) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.notFoundUser')); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
$validation = \Config\Services::validation(); |
|
|
|
|
|
|
|
|
|
$this->info(lang('Aauth.infoCreateSuccess')); |
|
|
|
|
if (! $validation->check($identifier, 'valid_email') || strlen($password) < $this->config->passwordMin || strlen($password) > $this->config->passwordMax) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.loginFailedEmail')); |
|
|
|
|
|
|
|
|
|
return $userId; |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Update user |
|
|
|
|
* |
|
|
|
|
* Updates existing user details |
|
|
|
|
* |
|
|
|
|
* @param integer $userId User id to update |
|
|
|
|
* @param string|boolean $email User's email address, or FALSE if not to be updated |
|
|
|
|
* @param string|boolean $password User's password, or FALSE if not to be updated |
|
|
|
|
* @param string|boolean $username User's name, or FALSE if not to be updated |
|
|
|
|
* |
|
|
|
|
* @return boolean |
|
|
|
|
*/ |
|
|
|
|
public function updateUser(int $userId, $email = null, string $password = null, string $username = null) |
|
|
|
|
{ |
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
if (! $user = $userModel->where('email', $identifier)->first()) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.notFoundUser')); |
|
|
|
|
|
|
|
|
|
if (! $userModel->existsById($userId)) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.notFoundUser')); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (! empty($userVariableModel->find($user['id'], 'verification_code', true))) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.notVerified')); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
else if (is_null($email) && is_null($password) && is_null($username)) |
|
|
|
|
else if ($user['banned']) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.invalidUserBanned')); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$data['id'] = $userId; |
|
|
|
|
// if ($this->config->totpEnabled && ! $this->config->totpOnIpChange && $this->config->totpLogin) |
|
|
|
|
// { |
|
|
|
|
// if ($this->config->totpLogin == true) |
|
|
|
|
// { |
|
|
|
|
// $this->session->set('totp_required', true); |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
if (! is_null($email)) |
|
|
|
|
{ |
|
|
|
|
$data['email'] = $email; |
|
|
|
|
} |
|
|
|
|
// $totp_secret = $userVariableModel->find($user['id'], 'totp_secret', true); |
|
|
|
|
// if ( ! empty($totp_secret) && ! $totp_code) { |
|
|
|
|
// $this->error(lang('Aauth.requiredTOTPCode')); |
|
|
|
|
// return false; |
|
|
|
|
// } else { |
|
|
|
|
// if( ! empty($totp_secret)){ |
|
|
|
|
// $this->CI->load->helper('googleauthenticator'); |
|
|
|
|
// $ga = new PHPGangsta_GoogleAuthenticator(); |
|
|
|
|
// $checkResult = $ga->verifyCode($totp_secret, $totp_code, 0); |
|
|
|
|
// if ( ! $checkResult) { |
|
|
|
|
// $this->error(lang('Aauth.invalidTOTPCode')); |
|
|
|
|
// return false; |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// else if ($this->config->totpEnabled && $this->config->totpOnIpChange) |
|
|
|
|
// { |
|
|
|
|
// $query = null; |
|
|
|
|
// $query = $this->aauth_db->where($db_identifier, $identifier); |
|
|
|
|
// $query = $this->aauth_db->get($this->config->users); |
|
|
|
|
// $totp_secret = $query->row()->totp_secret; |
|
|
|
|
// $ip_address = $query->row()->ip_address; |
|
|
|
|
// $current_ip_address = $this->CI->input->ip_address(); |
|
|
|
|
// if ($query->num_rows() > 0 AND !$totp_code) { |
|
|
|
|
// if($ip_address != $current_ip_address ){ |
|
|
|
|
// if($this->config->totpLogin == false){ |
|
|
|
|
// $this->error(lang('Aauth.aauth_error_totp_code_required')); |
|
|
|
|
// return false; |
|
|
|
|
// } else if($this->config->totpLogin == true){ |
|
|
|
|
// $this->session->set('totp_required', true); |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// }else { |
|
|
|
|
// if(!empty($totp_secret)){ |
|
|
|
|
// if($ip_address != $current_ip_address ){ |
|
|
|
|
// $this->CI->load->helper('googleauthenticator'); |
|
|
|
|
// $ga = new PHPGangsta_GoogleAuthenticator(); |
|
|
|
|
// $checkResult = $ga->verifyCode($totp_secret, $totp_code, 0); |
|
|
|
|
// if (!$checkResult) { |
|
|
|
|
// $this->error(lang('Aauth.aauth_error_totp_code_invalid')); |
|
|
|
|
// return false; |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
if (! is_null($password)) |
|
|
|
|
if (password_verify($password, $user['password'])) |
|
|
|
|
{ |
|
|
|
|
$data['password'] = $password; |
|
|
|
|
} |
|
|
|
|
$data['id'] = $user['id']; |
|
|
|
|
$data['username'] = $user['username']; |
|
|
|
|
$data['email'] = $user['email']; |
|
|
|
|
$data['loggedIn'] = true; |
|
|
|
|
$this->session->set('user', $data); |
|
|
|
|
|
|
|
|
|
if (! is_null($username)) |
|
|
|
|
{ |
|
|
|
|
$data['username'] = $username; |
|
|
|
|
} |
|
|
|
|
if ($remember) |
|
|
|
|
{ |
|
|
|
|
helper('text'); |
|
|
|
|
$loginTokenModel = new LoginTokenModel(); |
|
|
|
|
$expire = $this->config->loginRemember; |
|
|
|
|
$userId = base64_encode($user['id']); |
|
|
|
|
$randomString = random_string('alnum', 32); |
|
|
|
|
$selectorString = random_string('alnum', 16); |
|
|
|
|
|
|
|
|
|
if ($userModel->update($userId, $data)) |
|
|
|
|
{ |
|
|
|
|
$this->info(lang('Aauth.infoUpdateSuccess')); |
|
|
|
|
$cookieData['name'] = 'remember'; |
|
|
|
|
$cookieData['value'] = $userId . ';' . $randomString . ';' . $selectorString; |
|
|
|
|
$cookieData['expire'] = YEAR; |
|
|
|
|
|
|
|
|
|
$tokenData['user_id'] = $user['id']; |
|
|
|
|
$tokenData['random_hash'] = password_hash($randomString, PASSWORD_DEFAULT); |
|
|
|
|
$tokenData['selector_hash'] = password_hash($selectorString, PASSWORD_DEFAULT); |
|
|
|
|
$tokenData['expires_at'] = date('Y-m-d H:i:s', strtotime($expire)); |
|
|
|
|
|
|
|
|
|
set_cookie($cookieData); |
|
|
|
|
$loginTokenModel->insert($tokenData); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$userModel->updateLastLogin($user['id']); |
|
|
|
|
|
|
|
|
|
if ($this->config->loginAttemptRemoveSuccessful) |
|
|
|
|
{ |
|
|
|
|
$loginAttemptModel->delete(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.loginFailedAll')); |
|
|
|
|
|
|
|
|
|
$this->error(array_values($userModel->errors())); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Delete user |
|
|
|
|
* Logout |
|
|
|
|
* |
|
|
|
|
* @param integer $userId User id to delete |
|
|
|
|
* Deletes session and cookie |
|
|
|
|
* |
|
|
|
|
* @return boolen |
|
|
|
|
* @return void |
|
|
|
|
*/ |
|
|
|
|
public function deleteUser(int $userId) |
|
|
|
|
public function logout() |
|
|
|
|
{ |
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
|
|
|
|
|
if (! $userModel->existsById($userId)) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.notFoundUser')); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return $userModel->delete($userId); |
|
|
|
|
helper('cookie'); |
|
|
|
|
set_cookie('remember', '', -3600); |
|
|
|
|
$this->session->remove('user'); |
|
|
|
|
@$this->session->destroy(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* List users |
|
|
|
|
* Fast login |
|
|
|
|
* |
|
|
|
|
* Return users as an object array |
|
|
|
|
* Login with just a user id |
|
|
|
|
* |
|
|
|
|
* @param integer $limit Limit of users to be returned |
|
|
|
|
* @param integer $offset Offset for limited number of users |
|
|
|
|
* @param boolean $includeBanneds Include banned users |
|
|
|
|
* @param string $orderBy Order by MYSQL string (e.g. 'name ASC', 'email DESC') |
|
|
|
|
* @param integer $userId User id |
|
|
|
|
* |
|
|
|
|
* @return array Array of users |
|
|
|
|
* @return boolean |
|
|
|
|
*/ |
|
|
|
|
public function listUsers(int $limit = 0, int $offset = 0, bool $includeBanneds = null, string $orderBy = null) |
|
|
|
|
protected function loginFast(int $userId) |
|
|
|
|
{ |
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
$user = $userModel->limit($limit, $offset); |
|
|
|
|
$userModel->select('id, email, username'); |
|
|
|
|
$userModel->where('id', $userId); |
|
|
|
|
$userModel->where('banned', 0); |
|
|
|
|
|
|
|
|
|
$userModel->select('id, email, username, banned, created_at, updated_at, last_activity, last_ip_address, last_login'); |
|
|
|
|
// eanbool $group_par = null, |
|
|
|
|
if ($user = $userModel->get()->getFirstRow()) |
|
|
|
|
{ |
|
|
|
|
$this->session->set('user', [ |
|
|
|
|
'id' => $user->id, |
|
|
|
|
'username' => $user->username, |
|
|
|
|
'email' => $user->email, |
|
|
|
|
'loggedIn' => true, |
|
|
|
|
]); |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------- |
|
|
|
|
// Access Functions |
|
|
|
|
//-------------------------------------------------------------------------- |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Check user login |
|
|
|
|
* |
|
|
|
|
* Checks if user logged in, also checks remember. |
|
|
|
|
* |
|
|
|
|
* @return boolean |
|
|
|
|
*/ |
|
|
|
|
public function isLoggedIn() |
|
|
|
|
{ |
|
|
|
|
helper('cookie'); |
|
|
|
|
|
|
|
|
|
if (isset($this->session->get('user')['loggedIn'])) |
|
|
|
|
{ |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
else if ($cookie = get_cookie('remember')) |
|
|
|
|
{ |
|
|
|
|
$cookie = explode(';', $cookie); |
|
|
|
|
$cookie[0] = base64_decode($cookie[0]); |
|
|
|
|
|
|
|
|
|
if (! is_numeric($cookie[0]) || strlen($cookie[1]) !== 32 || strlen($cookie[2]) !== 16) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
$loginTokenModel = new LoginTokenModel(); |
|
|
|
|
$loginTokens = $loginTokenModel->findAllByUserId($cookie[0]); |
|
|
|
|
|
|
|
|
|
foreach ($loginTokens as $loginToken) |
|
|
|
|
{ |
|
|
|
|
if (password_verify($cookie[1], $loginToken['random_hash']) && password_verify($cookie[2], $loginToken['selector_hash'])) |
|
|
|
|
{ |
|
|
|
|
if (strtotime($loginToken['expires_at']) > strtotime('now')) |
|
|
|
|
{ |
|
|
|
|
$loginTokenModel->update($loginToken['id']); |
|
|
|
|
|
|
|
|
|
return $this->loginFast($loginToken['user_id']); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
$loginTokenModel->deleteExpired($cookie[0]); |
|
|
|
|
delete_cookie('remember'); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------- |
|
|
|
|
// User Functions |
|
|
|
|
//-------------------------------------------------------------------- |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Create user |
|
|
|
|
* |
|
|
|
|
* Creates a new user |
|
|
|
|
* |
|
|
|
|
* @param string $email User's email address |
|
|
|
|
* @param string $password User's password |
|
|
|
|
* @param string|boolean $username User's username |
|
|
|
|
* |
|
|
|
|
* @return integer|boolean |
|
|
|
|
*/ |
|
|
|
|
public function createUser(string $email, string $password, string $username = null) |
|
|
|
|
{ |
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
|
|
|
|
|
$data['email'] = $email; |
|
|
|
|
$data['password'] = $password; |
|
|
|
|
|
|
|
|
|
if (! is_null($username)) |
|
|
|
|
{ |
|
|
|
|
$data['username'] = $username; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (! $userId = $userModel->insert($data)) |
|
|
|
|
{ |
|
|
|
|
$this->error(array_values($userModel->errors())); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($this->config->userVerification) |
|
|
|
|
{ |
|
|
|
|
$this->sendVerification($userId, $email); |
|
|
|
|
$this->info(lang('Aauth.infoCreateVerification')); |
|
|
|
|
|
|
|
|
|
return $userId; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$this->info(lang('Aauth.infoCreateSuccess')); |
|
|
|
|
|
|
|
|
|
return $userId; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Update user |
|
|
|
|
* |
|
|
|
|
* Updates existing user details |
|
|
|
|
* |
|
|
|
|
* @param integer $userId User id to update |
|
|
|
|
* @param string|boolean $email User's email address, or FALSE if not to be updated |
|
|
|
|
* @param string|boolean $password User's password, or FALSE if not to be updated |
|
|
|
|
* @param string|boolean $username User's name, or FALSE if not to be updated |
|
|
|
|
* |
|
|
|
|
* @return boolean |
|
|
|
|
*/ |
|
|
|
|
public function updateUser(int $userId, $email = null, string $password = null, string $username = null) |
|
|
|
|
{ |
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
|
|
|
|
|
if (! $userModel->existsById($userId)) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.notFoundUser')); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
else if (is_null($email) && is_null($password) && is_null($username)) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$data['id'] = $userId; |
|
|
|
|
|
|
|
|
|
if (! is_null($email)) |
|
|
|
|
{ |
|
|
|
|
$data['email'] = $email; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (! is_null($password)) |
|
|
|
|
{ |
|
|
|
|
$data['password'] = $password; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (! is_null($username)) |
|
|
|
|
{ |
|
|
|
|
$data['username'] = $username; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($userModel->update($userId, $data)) |
|
|
|
|
{ |
|
|
|
|
$this->info(lang('Aauth.infoUpdateSuccess')); |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$this->error(array_values($userModel->errors())); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Delete user |
|
|
|
|
* |
|
|
|
|
* @param integer $userId User id to delete |
|
|
|
|
* |
|
|
|
|
* @return boolen |
|
|
|
|
*/ |
|
|
|
|
public function deleteUser(int $userId) |
|
|
|
|
{ |
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
|
|
|
|
|
if (! $userModel->existsById($userId)) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.notFoundUser')); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return $userModel->delete($userId); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* List users |
|
|
|
|
* |
|
|
|
|
* Return users as an object array |
|
|
|
|
* |
|
|
|
|
* @param integer $limit Limit of users to be returned |
|
|
|
|
* @param integer $offset Offset for limited number of users |
|
|
|
|
* @param boolean $includeBanneds Include banned users |
|
|
|
|
* @param string $orderBy Order by MYSQL string (e.g. 'name ASC', 'email DESC') |
|
|
|
|
* |
|
|
|
|
* @return array Array of users |
|
|
|
|
*/ |
|
|
|
|
public function listUsers(int $limit = 0, int $offset = 0, bool $includeBanneds = null, string $orderBy = null) |
|
|
|
|
{ |
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
$user = $userModel->limit($limit, $offset); |
|
|
|
|
|
|
|
|
|
$userModel->select('id, email, username, banned, created_at, updated_at, last_activity, last_ip_address, last_login'); |
|
|
|
|
// eanbool $group_par = null, |
|
|
|
|
|
|
|
|
|
if (is_null($includeBanneds)) |
|
|
|
|
{ |
|
|
|
@ -297,9 +589,9 @@ class Aauth
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return [ |
|
|
|
|
'users' => $userModel->paginate($limit), |
|
|
|
|
'pager' => $userModel->pager, |
|
|
|
|
]; |
|
|
|
|
'users' => $userModel->paginate($limit), |
|
|
|
|
'pager' => $userModel->pager, |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -410,7 +702,7 @@ class Aauth
|
|
|
|
|
* |
|
|
|
|
* Get user id from email address, if par. not given, return current user's id |
|
|
|
|
* |
|
|
|
|
* @param string|boolean $email Email address for user |
|
|
|
|
* @param string|boolean $email Email address for user, |
|
|
|
|
* |
|
|
|
|
* @return object|boolean User information or false if user not found |
|
|
|
|
*/ |
|
|
|
@ -438,7 +730,7 @@ class Aauth
|
|
|
|
|
/** |
|
|
|
|
* Is banned |
|
|
|
|
* |
|
|
|
|
* @param integer $userId User id |
|
|
|
|
* @param integer $userId User id, can be null to use session user |
|
|
|
|
* |
|
|
|
|
* @return boolean |
|
|
|
|
*/ |
|
|
|
@ -462,7 +754,7 @@ class Aauth
|
|
|
|
|
/** |
|
|
|
|
* Ban User |
|
|
|
|
* |
|
|
|
|
* @param integer $userId User id |
|
|
|
|
* @param integer $userId User id, can be null to use session user |
|
|
|
|
* |
|
|
|
|
* @return boolean |
|
|
|
|
*/ |
|
|
|
@ -488,7 +780,7 @@ class Aauth
|
|
|
|
|
/** |
|
|
|
|
* Unban User |
|
|
|
|
* |
|
|
|
|
* @param integer $userId User id |
|
|
|
|
* @param integer $userId User id, can be null to use session user |
|
|
|
|
* |
|
|
|
|
* @return boolean |
|
|
|
|
*/ |
|
|
|
@ -557,6 +849,7 @@ class Aauth
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Reset password |
|
|
|
|
* |
|
|
|
@ -624,298 +917,147 @@ class Aauth
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------- |
|
|
|
|
// Login Functions |
|
|
|
|
//-------------------------------------------------------------------------- |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Login user |
|
|
|
|
* Set User Variable as key value |
|
|
|
|
* if variable not set before, it will ve set |
|
|
|
|
* if set, overwrites the value |
|
|
|
|
* |
|
|
|
|
* Check provided details against the database. Add items to error array on fail |
|
|
|
|
* |
|
|
|
|
* @param string $identifier Identifier |
|
|
|
|
* @param string $password Password |
|
|
|
|
* @param boolean $remember Whether to remember login |
|
|
|
|
* @param string $totpCode TOTP Code |
|
|
|
|
* @param string $key |
|
|
|
|
* @param string $value |
|
|
|
|
* @param integer $userId User id, can be null to use session user |
|
|
|
|
* |
|
|
|
|
* @return boolean |
|
|
|
|
*/ |
|
|
|
|
public function login(string $identifier, string $password, bool $remember = null, string $totpCode = null) |
|
|
|
|
public function setUserVar(string $key, string $value, int $userId = null) |
|
|
|
|
{ |
|
|
|
|
helper('cookie'); |
|
|
|
|
delete_cookie('remember'); |
|
|
|
|
|
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
$loginAttemptModel = new LoginAttemptModel(); |
|
|
|
|
$userVariableModel = new UserVariableModel(); |
|
|
|
|
|
|
|
|
|
if ($this->config->loginProtection && ! $loginAttemptModel->save()) |
|
|
|
|
if (! $userId) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.loginAttemptsExceeded')); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
$userId = $this->session->user['id']; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// if ($this->config->ddos_protection && $this->config->recaptcha_active && $loginAttempts->get() > $this->config->recaptcha_login_attempts){ |
|
|
|
|
// $this->CI->load->helper('recaptchalib'); |
|
|
|
|
// $reCaptcha = new ReCaptcha( $this->config->recaptcha_secret); |
|
|
|
|
// $resp = $reCaptcha->verifyResponse( $this->CI->input->server("REMOTE_ADDR"), $this->CI->input->post("g-recaptcha-response") ); |
|
|
|
|
// if( ! $resp->success){ |
|
|
|
|
// $this->error(lang('Aauth.aauth_error_recaptcha_not_correct')); |
|
|
|
|
// return false; |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
|
|
|
|
|
if ($this->config->loginUseUsername) |
|
|
|
|
if (! $userModel->existsById($userId)) |
|
|
|
|
{ |
|
|
|
|
if (! $identifier || strlen($password) < $this->config->passwordMin || strlen($password) > $this->config->passwordMax) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.loginFailedUsername')); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (! $user = $userModel->where('username', $identifier)->first()) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.notFoundUser')); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
$validation = \Config\Services::validation(); |
|
|
|
|
|
|
|
|
|
if (! $validation->check($identifier, 'valid_email') || strlen($password) < $this->config->passwordMin || strlen($password) > $this->config->passwordMax) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.loginFailedEmail')); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (! $user = $userModel->where('email', $identifier)->first()) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.notFoundUser')); |
|
|
|
|
$userVariableModel = new UserVariableModel(); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return $userVariableModel->save($userId, $key, $value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (! empty($userVariableModel->find($user['id'], 'verification_code', true))) |
|
|
|
|
/** |
|
|
|
|
* Unset User Variable as key value |
|
|
|
|
* |
|
|
|
|
* @param string $key |
|
|
|
|
* @param integer $userId User id, can be null to use session user |
|
|
|
|
* |
|
|
|
|
* @return boolean |
|
|
|
|
*/ |
|
|
|
|
public function unsetUserVar(string $key, int $userId = null) |
|
|
|
|
{ |
|
|
|
|
if (! $userId) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.notVerified')); |
|
|
|
|
return false; |
|
|
|
|
$userId = $this->session->user['id']; |
|
|
|
|
} |
|
|
|
|
else if ($user['banned']) |
|
|
|
|
|
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
|
|
|
|
|
if (! $userModel->existsById($userId)) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.invalidUserBanned')); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// if ($this->config->totpEnabled && ! $this->config->totpOnIpChange && $this->config->totpLogin) |
|
|
|
|
// { |
|
|
|
|
// if ($this->config->totpLogin == true) |
|
|
|
|
// { |
|
|
|
|
// $this->session->set('totp_required', true); |
|
|
|
|
// } |
|
|
|
|
$userVariableModel = new UserVariableModel(); |
|
|
|
|
|
|
|
|
|
// $totp_secret = $userVariableModel->find($user['id'], 'totp_secret', true); |
|
|
|
|
// if ( ! empty($totp_secret) && ! $totp_code) { |
|
|
|
|
// $this->error(lang('Aauth.requiredTOTPCode')); |
|
|
|
|
// return false; |
|
|
|
|
// } else { |
|
|
|
|
// if( ! empty($totp_secret)){ |
|
|
|
|
// $this->CI->load->helper('googleauthenticator'); |
|
|
|
|
// $ga = new PHPGangsta_GoogleAuthenticator(); |
|
|
|
|
// $checkResult = $ga->verifyCode($totp_secret, $totp_code, 0); |
|
|
|
|
// if ( ! $checkResult) { |
|
|
|
|
// $this->error(lang('Aauth.invalidTOTPCode')); |
|
|
|
|
// return false; |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// else if ($this->config->totpEnabled && $this->config->totpOnIpChange) |
|
|
|
|
// { |
|
|
|
|
// $query = null; |
|
|
|
|
// $query = $this->aauth_db->where($db_identifier, $identifier); |
|
|
|
|
// $query = $this->aauth_db->get($this->config->users); |
|
|
|
|
// $totp_secret = $query->row()->totp_secret; |
|
|
|
|
// $ip_address = $query->row()->ip_address; |
|
|
|
|
// $current_ip_address = $this->CI->input->ip_address(); |
|
|
|
|
// if ($query->num_rows() > 0 AND !$totp_code) { |
|
|
|
|
// if($ip_address != $current_ip_address ){ |
|
|
|
|
// if($this->config->totpLogin == false){ |
|
|
|
|
// $this->error(lang('Aauth.aauth_error_totp_code_required')); |
|
|
|
|
// return false; |
|
|
|
|
// } else if($this->config->totpLogin == true){ |
|
|
|
|
// $this->session->set('totp_required', true); |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// }else { |
|
|
|
|
// if(!empty($totp_secret)){ |
|
|
|
|
// if($ip_address != $current_ip_address ){ |
|
|
|
|
// $this->CI->load->helper('googleauthenticator'); |
|
|
|
|
// $ga = new PHPGangsta_GoogleAuthenticator(); |
|
|
|
|
// $checkResult = $ga->verifyCode($totp_secret, $totp_code, 0); |
|
|
|
|
// if (!$checkResult) { |
|
|
|
|
// $this->error(lang('Aauth.aauth_error_totp_code_invalid')); |
|
|
|
|
// return false; |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
return $userVariableModel->delete($userId, $key); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (password_verify($password, $user['password'])) |
|
|
|
|
/** |
|
|
|
|
* Get User Variable by key |
|
|
|
|
* |
|
|
|
|
* @param string $key Variable Key |
|
|
|
|
* @param integer $userId User id, can be null to use session user |
|
|
|
|
* |
|
|
|
|
* @return boolean|string FALSE if var is not set, the value of var if set |
|
|
|
|
*/ |
|
|
|
|
public function getUserVar(string $key, int $userId = null) |
|
|
|
|
{ |
|
|
|
|
if (! $userId) |
|
|
|
|
{ |
|
|
|
|
$data['id'] = $user['id']; |
|
|
|
|
$data['username'] = $user['username']; |
|
|
|
|
$data['email'] = $user['email']; |
|
|
|
|
$data['loggedIn'] = true; |
|
|
|
|
$this->session->set('user', $data); |
|
|
|
|
|
|
|
|
|
if ($remember) |
|
|
|
|
{ |
|
|
|
|
helper('text'); |
|
|
|
|
$loginTokenModel = new LoginTokenModel(); |
|
|
|
|
$expire = $this->config->loginRemember; |
|
|
|
|
$userId = base64_encode($user['id']); |
|
|
|
|
$randomString = random_string('alnum', 32); |
|
|
|
|
$selectorString = random_string('alnum', 16); |
|
|
|
|
|
|
|
|
|
$cookieData['name'] = 'remember'; |
|
|
|
|
$cookieData['value'] = $userId . ';' . $randomString . ';' . $selectorString; |
|
|
|
|
$cookieData['expire'] = YEAR; |
|
|
|
|
|
|
|
|
|
$tokenData['user_id'] = $user['id']; |
|
|
|
|
$tokenData['random_hash'] = password_hash($randomString, PASSWORD_DEFAULT); |
|
|
|
|
$tokenData['selector_hash'] = password_hash($selectorString, PASSWORD_DEFAULT); |
|
|
|
|
$tokenData['expires_at'] = date('Y-m-d H:i:s', strtotime($expire)); |
|
|
|
|
$userId = $this->session->user['id']; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
set_cookie($cookieData); |
|
|
|
|
$loginTokenModel->insert($tokenData); |
|
|
|
|
} |
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
|
|
|
|
|
$userModel->updateLastLogin($user['id']); |
|
|
|
|
if (! $userModel->existsById($userId)) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($this->config->loginAttemptRemoveSuccessful) |
|
|
|
|
{ |
|
|
|
|
$loginAttemptModel->delete(); |
|
|
|
|
} |
|
|
|
|
$userVariableModel = new UserVariableModel(); |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
if ($variable = $userVariableModel->find($user['id'], 'verification_code', true)) |
|
|
|
|
{ |
|
|
|
|
$this->error(lang('Aauth.loginFailedAll')); |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
return $variable; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Logout |
|
|
|
|
* |
|
|
|
|
* Deletes session and cookie |
|
|
|
|
* |
|
|
|
|
* @return void |
|
|
|
|
*/ |
|
|
|
|
public function logout() |
|
|
|
|
{ |
|
|
|
|
helper('cookie'); |
|
|
|
|
set_cookie('remember', '', -3600); |
|
|
|
|
$this->session->remove('user'); |
|
|
|
|
@$this->session->destroy(); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Fast login |
|
|
|
|
* |
|
|
|
|
* Login with just a user id |
|
|
|
|
* Get User Variables by user id |
|
|
|
|
* Return array with all user keys & variables |
|
|
|
|
* |
|
|
|
|
* @param integer $userId User id |
|
|
|
|
* |
|
|
|
|
* @return boolean |
|
|
|
|
* @param integer $user_id ; if not given current user |
|
|
|
|
* @return boolean|array , FALSE if var is not set, the value of var if set |
|
|
|
|
*/ |
|
|
|
|
protected function loginFast(int $userId) |
|
|
|
|
public function getUserVars(int $userId = null) |
|
|
|
|
{ |
|
|
|
|
if (! $userId) |
|
|
|
|
{ |
|
|
|
|
$userId = $this->session->user['id']; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
$userModel->select('id, email, username'); |
|
|
|
|
$userModel->where('id', $userId); |
|
|
|
|
$userModel->where('banned', 0); |
|
|
|
|
|
|
|
|
|
if ($user = $userModel->get()->getFirstRow()) |
|
|
|
|
if (! $userModel->existsById($userId)) |
|
|
|
|
{ |
|
|
|
|
$this->session->set('user', [ |
|
|
|
|
'id' => $user->id, |
|
|
|
|
'username' => $user->username, |
|
|
|
|
'email' => $user->email, |
|
|
|
|
'loggedIn' => true, |
|
|
|
|
]); |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
$userVariableModel = new UserVariableModel(); |
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------- |
|
|
|
|
// Access Functions |
|
|
|
|
//-------------------------------------------------------------------------- |
|
|
|
|
return $userVariableModel->findAll(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Check user login |
|
|
|
|
* |
|
|
|
|
* Checks if user logged in, also checks remember. |
|
|
|
|
* List User Variable Keys by UserID |
|
|
|
|
* Return array of variable keys or FALSE |
|
|
|
|
* |
|
|
|
|
* @return boolean |
|
|
|
|
* @param integer $user_id ; if not given current user |
|
|
|
|
* @return boolean|array |
|
|
|
|
*/ |
|
|
|
|
public function isLoggedIn() |
|
|
|
|
public function list_user_var_keys($user_id = false) |
|
|
|
|
{ |
|
|
|
|
helper('cookie'); |
|
|
|
|
|
|
|
|
|
if (isset($this->session->get('user')['loggedIn'])) |
|
|
|
|
if (! $userId) |
|
|
|
|
{ |
|
|
|
|
return true; |
|
|
|
|
$userId = $this->session->user['id']; |
|
|
|
|
} |
|
|
|
|
else if ($cookie = get_cookie('remember')) |
|
|
|
|
{ |
|
|
|
|
$cookie = explode(';', $cookie); |
|
|
|
|
$cookie[0] = base64_decode($cookie[0]); |
|
|
|
|
|
|
|
|
|
if (! is_numeric($cookie[0]) || strlen($cookie[1]) !== 32 || strlen($cookie[2]) !== 16) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
$loginTokenModel = new LoginTokenModel(); |
|
|
|
|
$loginTokens = $loginTokenModel->findAllByUserId($cookie[0]); |
|
|
|
|
|
|
|
|
|
foreach ($loginTokens as $loginToken) |
|
|
|
|
{ |
|
|
|
|
if (password_verify($cookie[1], $loginToken['random_hash']) && password_verify($cookie[2], $loginToken['selector_hash'])) |
|
|
|
|
{ |
|
|
|
|
if (strtotime($loginToken['expires_at']) > strtotime('now')) |
|
|
|
|
{ |
|
|
|
|
$loginTokenModel->update($loginToken['id']); |
|
|
|
|
$userModel = new UserModel(); |
|
|
|
|
|
|
|
|
|
return $this->loginFast($loginToken['user_id']); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
$loginTokenModel->deleteExpired($cookie[0]); |
|
|
|
|
delete_cookie('remember'); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (! $userModel->existsById($userId)) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
$userVariableModel = new UserVariableModel(); |
|
|
|
|
$userVariableModel->select('data_key as key'); |
|
|
|
|
|
|
|
|
|
return $userVariableModel->findAll(); |
|
|
|
|
} |
|
|
|
|
//-------------------------------------------------------------------------- |
|
|
|
|
// Error Functions |
|
|
|
|
//-------------------------------------------------------------------------- |
|
|
|
|