getRequest('', true)) && array_key_exists('password', Controller::getInstance()->getRequest('', true))) { $this->_auth = Auth::getInstance()->auth( Controller::getInstance()->getRequest('login'), Controller::getInstance()->getRequest('password')); if($this->_auth) { $timeanddateToUser = Db::loadModel('WarehouseLoach\timeanddateToUser')->selectDatasetByFieldWhere(['name' => 'user_id', 'value' => Controller::getInstance()->getSession('auth')['user_id']]); $timeanddate_id = array_shift($timeanddateToUser)['timeanddate_id']; Db::loadModel('WarehouseLoach\timeanddate')->updateRowByFieldWhere('timeanddate_id', $timeanddate_id, 'timeanddate_time', date('Y-m-d H:i:s')); $this->setUserIdToSessionCookie(); } } else { $this->_auth = $this->isAuthorized(); } return $this->_auth; } /** * @desc will return true if the user is authorized otherwise false * @return bool */ public function isAuthorized(): bool { if(array_key_exists('auth', Controller::getInstance()->getSession('', true))) { if(array_key_exists('login', Controller::getInstance()->getSession('auth'))) { return true; } else { return false; } } else { return false; } } /** * @desc will log out the user and destroy the session * @return bool */ public function revokeAuthorized(): bool { setcookie('user_id', '', [ 'expires' => time() - 3600, // set the cookie to expire one hour ago 'path' => '/', 'secure' => false, 'httponly' => true, ]); Memcached::init()->runServer()->delete($_SESSION['auth']['user_id']); unset($_SESSION['auth']); return true; } /** * @desc will update the password of the user, check if the value $user_id is set, if not it will use the current logged in user. * @param int $user_id * @param string $password * @return bool */ public function updatePassword(string $password, int $user_id): bool { if($user_id == 0) { $user_id = $_SESSION['auth']['user_id']; } return Pdo::query('UPDATE user SET user_pass = DES_ENCRYPT("'.$password.'", "'.Config::getInstance()->getConfig()[IView::NIBIRU_SECURITY]["password_hash"].'") WHERE user_id = '.$user_id.';'); } /** * @desc will return true if the standard user is present otherwise false * @return bool * @throws \Exception */ public function checkForStandardUser(): bool { $userTable = Db::loadModel('WarehouseLoach\user')->loadTableAsArray(); if(sizeof($userTable)==0) { return false; } else { $standardUser = array_search(self::getUsersRegistry()->user_login, array_column($userTable, 'user_login')); if($standardUser === false) { return false; } else { return true; } } } /** * @desc will check if the user exists in the database * @param string $user_login * @return bool */ public function checkIfUserExists(string $user_login): bool { $userTable = Db::loadModel('WarehouseLoach\user')->loadTableAsArray(); $user = array_search($user_login, array_column($userTable, 'user_login')); if($user === false) { return false; } else { return true; } } /** * @desc create an object that loads the userdata from the registry, if the user data is not passed by the method * parameter. Also prepares the user data for user updates in the database. * @param array $user_data * @param bool $isUpdate * @return bool */ public function loadUser( array $user_data = [], bool $isUpdate = false ): bool { $this->userRegistry = new \stdClass(); if(sizeof($user_data) == 0) { foreach(self::REGISTRY_USER_KEYS as $key) { $this->userRegistry->$key = self::getUsersRegistry()->$key; } return Message::loadInfo('User loaded', ['info' => json_decode(json_encode($this->userRegistry), true)]); } else { try { if(!$this->checkIfUserExists($user_data['user_login']) || $isUpdate) { foreach(self::REGISTRY_USER_KEYS as $key) { if($user_data[$key] == self::FORM_CHECKBOX_ON || $user_data[$key] == self::FORM_CHECKBOX_OFF) { $user_data[$key] = self::FORM_CHECKBOX_SWITCH[$user_data[$key]]; } $this->userRegistry->$key = $user_data[$key]; } if($isUpdate) { $this->userRegistry->user_id = $user_data['user_id']; } return Message::loadInfo('User loaded', ['info' => json_decode(json_encode($this->userRegistry), true)]); } else { throw new \Exception('User already exists'); } } catch (\Exception $e) { return Message::loadError($e); } } } /** * @desc will create the initial user for the system, if no user is setup. * Can be found in the application/module/users/settings/users.ini * file. * @return int|bool * @throws \Exception */ public function createStandardUser(): int|bool { try { Db::loadModel('WarehouseLoach\user')->insertArrayIntoTable([ 'user_firstname' => $this->userRegistry->user_firstname, 'user_lastname' => $this->userRegistry->user_lastname, 'user_login' => $this->userRegistry->user_login, 'user_account_active' => $this->userRegistry->user_active ]); $lastUserId = Db::loadModel('WarehouseLoach\user')->lastInsertId(); Db::loadModel('WarehouseLoach\timeanddate')->insertArrayIntoTable([ ]); $lastTimeanddateId = Db::loadModel('WarehouseLoach\timeanddate')->lastInsertId(); Db::loadModel('WarehouseLoach\timeanddateToUser')->insertArrayIntoTable([ 'timeanddate_id' => $lastTimeanddateId, 'user_id' => $lastUserId ]); Db::loadModel('WarehouseLoach\userToAcl')->insertArrayIntoTable([ 'user_id' => $lastUserId, 'acl_id' => $this->userRegistry->user_acl_id ]); Db::loadModel('WarehouseLoach\account')->insertArrayIntoTable([ 'account_name' => $this->userRegistry->user_account_name, 'account_email' => $this->userRegistry->user_account_email, 'account_active' => $this->userRegistry->user_account_active ]); $lastAccountId = Db::loadModel('WarehouseLoach\account')->lastInsertId(); Db::loadModel('WarehouseLoach\timeanddate')->insertArrayIntoTable([ ]); $lastTimeanddateId = Db::loadModel('WarehouseLoach\timeanddate')->lastInsertId(); Db::loadModel('WarehouseLoach\timeanddateToAccount')->insertArrayIntoTable([ 'account_id' => $lastAccountId, 'timeanddate_id' => $lastTimeanddateId ]); Db::loadModel('WarehouseLoach\userToAccount')->insertArrayIntoTable([ 'account_id' => $lastAccountId, 'user_id' => $lastUserId ]); $setPassword = Pdo::query('UPDATE user SET user_pass = DES_ENCRYPT("'.$this->userRegistry->user_pass.'", "'.Config::getInstance()->getConfig()[IView::NIBIRU_SECURITY]["password_hash"].'") WHERE user_id = '.$lastUserId.';'); if(empty($setPassword)) { return $lastUserId; } else { throw new \Exception('Could not set password for user '.$lastUserId . ' with exception value: ' . $setPassword . '!'); } } catch (\Exception $e) { return Message::loadError($e); } } /** * @desc will return the role of the logged in user * @return array * @throws \Exception */ public function getRoleByLoggedInUser(): array { $userToAcl = Db::loadModel('WarehouseLoach\userToAcl')->selectRowByFieldWhere([ 'field' => 'user_id', 'value' => $_SESSION['auth']['user_id'] ]); return Db::loadModel('WarehouseLoach\acl')->selectRowByFieldWhere([ 'field' => 'acl_id', 'value' => $userToAcl['acl_id'] ]); } /** * @desc will load all users from the database and return them as an array * @return array */ public function loadUsers(): array { return Pdo::queryString('select u.user_id as uid, u.user_firstname as vorname, u.user_lastname as nachname, u.user_login as login, u.user_account_active as aktiv, a.acl_role as berechtigung, tad.timeanddate_date as datum_benutzer, tad.timeanddate_time as zeit_benutzer, ac.account_name as konto, ac.account_email as konto_email, ac.account_active as konto_aktiv, tadc.timeanddate_date as datum_konto, tadc.timeanddate_time as zeit_konto from warehouse_loach.user as u join warehouse_loach.user_to_acl as uta on u.user_id = uta.user_id join warehouse_loach.acl as a on uta.acl_id = a.acl_id join warehouse_loach.timeanddate_to_user as ttu on u.user_id = ttu.user_id join warehouse_loach.timeanddate as tad on ttu.timeanddate_id = tad.timeanddate_id join user_to_account uta2 on u.user_id = uta2.user_id join account ac on uta2.account_id = ac.account_id join timeanddate_to_account tta on ac.account_id = tta.account_id join timeanddate tadc on tta.timeanddate_id = tadc.timeanddate_id;', true); } /** * @desc will load a user by the given id * @param int $user_id * @return array */ public function loadUserById( int $user_id ): array { $user = Pdo::queryString('select u.user_id as uid, u.user_firstname as user_firstname, u.user_lastname as user_lastname, u.user_login as user_login, DES_DECRYPT(u.user_pass, "'.Config::getInstance()->getConfig()[IView::NIBIRU_SECURITY]["password_hash"].'") as user_pass, u.user_account_active as user_account_active, a.acl_id as user_role_id, ac.account_name as user_account_name, ac.account_active as user_account_active, ac.account_email as user_account_email from warehouse_loach.user as u join warehouse_loach.user_to_acl as uta on u.user_id = uta.user_id join warehouse_loach.acl as a on uta.acl_id = a.acl_id join warehouse_loach.timeanddate_to_user as ttu on u.user_id = ttu.user_id join warehouse_loach.timeanddate as tad on ttu.timeanddate_id = tad.timeanddate_id join user_to_account uta2 on u.user_id = uta2.user_id join account ac on uta2.account_id = ac.account_id join timeanddate_to_account tta on ac.account_id = tta.account_id join timeanddate tadc on tta.timeanddate_id = tadc.timeanddate_id where u.user_id = '.$user_id.';', true); $user = array_shift($user); return $user; } /** * @desc will delete a user by the given id * @param int $user_id * @return bool */ public function deleteUserById( int $user_id ): bool { try { $user = $this->loadUserById($user_id); if($user['user_role_id'] == 1) { unset($user); throw new \Exception('You can not delete the superuser!'); } else { $userToAccount = Pdo::queryString('SELECT account_id FROM user_to_account WHERE user_id = '.$user_id.';', true); $account_id = array_shift($userToAccount)["account_id"]; $timeanddateToUser = Pdo::queryString('SELECT timeanddate_id FROM timeanddate_to_user WHERE user_id = '.$user_id.';', true); $timeanddate_id = array_shift($timeanddateToUser)["timeanddate_id"]; Pdo::query('DELETE FROM user_to_acl WHERE user_id = '.$user_id.';'); Pdo::query('DELETE FROM user_to_account WHERE user_id = '.$user_id.';'); Pdo::query('DELETE FROM timeanddate_to_user WHERE user_id = '.$user_id.';'); Pdo::query('DELETE FROM timeanddate_to_account WHERE account_id = '.$account_id.';'); Pdo::query('DELETE FROM user WHERE user_id = '.$user_id.';'); Pdo::query('DELETE FROM account WHERE account_id = '.$account_id.';'); Pdo::query('DELETE FROM timeanddate WHERE timeanddate_id = '.$timeanddate_id.';'); unset($user['user_pass']); return Message::loadInfo("User deleted successfully", $user); } } catch (\Exception $e) { return Message::loadError($e); } } /** * @desc will set the user active or inactive * @param int $user_id * @param int $active * @return bool */ public function setUserActive( int $user_id, int $active ): bool { try { if($active) { $state = 'Aktiv'; } else { $state = 'Inaktiv'; } $user = $this->loadUserById($user_id); if($user['user_role_id'] == 1) { unset($user); throw new \Exception('You can not deactivate the superuser!'); } else { Db::loadModel('WarehouseLoach\User')->updateRowByFieldWhere('user_id', $user_id, 'user_account_active', $active); unset($user['user_pass']); return Message::loadInfo("User updated active state successfully: $state", $user); } } catch (\Exception $e) { return Message::loadError($e); } } /** * @desc will update the user by the given user array * @return bool * @throws \Exception */ public function updateUser(): bool { try { $user = (array) $this->userRegistry; $userString = ''; foreach(WarehouseLoach\User::TABLE['fields'] as $field) { if(array_key_exists($field, $user)) { if($field == 'user_pass') { $userString .= $field.' = DES_ENCRYPT("'.$user[$field].'", "'.Config::getInstance()->getConfig()[IView::NIBIRU_SECURITY]["password_hash"].'"), '; } else { if($field != 'user_id') { $userString .= $field.' = "'.$user[$field].'", '; } } } } Pdo::query('UPDATE user SET '.substr($userString, 0, -2).' WHERE user_id = '.$user['user_id'].';'); $userToAccount = Db::loadModel('WarehouseLoach\userToAccount')->selectDatasetByFieldWhere(['name' => 'user_id', 'value' => $user['user_id']]); $account_id = array_shift($userToAccount)['account_id']; if(isset($account_id)) { $accountString = ''; foreach(WarehouseLoach\Account::TABLE['fields'] as $field) { foreach($user as $key => $value) { if(strstr($key, $field)) { $accountString .= $field.' = "'.$user[$key].'", '; } } } Pdo::query('UPDATE account SET '.substr($accountString, 0, -2).' WHERE account_id = '.$account_id.';'); } else { throw new \Exception('Did not get valid Account ID, the database could be corrupted for that user! user_id: ' . $user['user_id']); } Db::loadModel('WarehouseLoach\userToAcl')->updateRowByFieldWhere('user_id', $user['user_id'], 'acl_id', $user['user_acl_id']); } catch (\Exception $e) { Message::loadError($e); } } /** * @desc will set the user_id in a cookie, in order to find the memcached session * @return void */ public function setUserIdToSessionCookie(): void { if(!array_key_exists('user_id', $_COOKIE) && array_key_exists('auth', $_SESSION)) { $ivLength = openssl_cipher_iv_length($this->getUsersRegistry()->{self::USER_ID_ENCRYPTION}); $iv = openssl_random_pseudo_bytes($ivLength); $encryptedUserId = openssl_encrypt($_SESSION['auth']['user_id'], $this->getUsersRegistry()->{self::USER_ID_ENCRYPTION}, $this->getUsersRegistry()->{self::USER_ID_ENCRYPTION_KEY}, 0, $iv); $cookieValue = base64_encode($encryptedUserId . '::' . $iv); setcookie('user_id', $cookieValue, [ 'expires' => time() + (86400 * 30), 'path' => '/', 'secure' => false, // only send cookie over https 'httponly' => true, // make the cookie inaccessible to javascript ]); } } /** * @desc will get the user_id from the cookie * @return int */ public function getUserIdFromSessionCookie(): int { if(array_key_exists('user_id', $_COOKIE)) { list($encryptedUserId, $iv) = explode('::', base64_decode($_COOKIE['user_id']), 2); $decryptedUserId = openssl_decrypt($encryptedUserId, $this->getUsersRegistry()->{self::USER_ID_ENCRYPTION}, $this->getUsersRegistry()->{self::USER_ID_ENCRYPTION_KEY}, 0, $iv); return $decryptedUserId; } else { return 0; } } }