From de4c232488e7cb503f4988e9f9ee0dadba28a85e Mon Sep 17 00:00:00 2001 From: Alex Tselegidis Date: Wed, 27 Oct 2021 10:05:26 +0200 Subject: [PATCH] Migrated the user model logic into the accounts library --- application/libraries/Accounts.php | 170 +++++++++++++++++++++++ application/models/User_model.php | 211 ----------------------------- 2 files changed, 170 insertions(+), 211 deletions(-) create mode 100644 application/libraries/Accounts.php delete mode 100644 application/models/User_model.php diff --git a/application/libraries/Accounts.php b/application/libraries/Accounts.php new file mode 100644 index 00000000..da9c1cb0 --- /dev/null +++ b/application/libraries/Accounts.php @@ -0,0 +1,170 @@ + + * @copyright Copyright (c) 2013 - 2020, Alex Tselegidis + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @link http://easyappointments.org + * @since v1.4.0 + * ---------------------------------------------------------------------------- */ + + +/** + * Accounts + * + * Handles any account related functionality. + */ +class Accounts { + /** + * @var EA_Controller + */ + protected $CI; + + /** + * Availability constructor. + */ + public function __construct() + { + $this->CI =& get_instance(); + + $this->CI->load->model('users'); + + $this->CI->load->library('timezones'); + + $this->CI->load->helper('password'); + $this->CI->load->helper('string'); + } + + /** + * Get the user data from the database. + * + * @param int $user_id User ID. + * + * @return array Returns an array with user data. + */ + public function get_user(int $user_id): array + { + return $this->CI->users_model->find($user_id); + } + + /** + * Update a user. + * + * @param array $user Associative array with the user data. + */ + public function save_user(array $user): void + { + $this->CI->users_model->save($user); + } + + /** + * Authenticate the provided credentials. + * + * @param string $username Username. + * @param string $password Password (non-hashed). + * + * @return array|null Returns an associative array with the PHP session data or NULL on failure. + */ + public function check_login(string $username, string $password): ?array + { + $salt = $this->get_salt_by_username($username); + + $password = hash_password($salt, $password); + + $user_settings = $this->CI->db->get_where('user_settings', [ + 'username' => $username, + 'password' => $password + ])->row_array(); + + if (empty($user_settings)) + { + return NULL; + } + + $user = $this->CI->users_model->find($user_settings['id_users']); + + $role = $this->CI->roles_model->find($user['id_roles']); + + $default_timezone = $this->CI->timezones->get_default_timezone(); + + return [ + 'user_id' => $user['id'], + 'user_email' => $user['email'], + 'username' => $username, + 'timezone' => ! empty($user['timezone']) ? $user['timezone'] : $default_timezone, + 'role_slug' => $role['slug'], + ]; + } + + /** + * Get the user's salt value. + * + * @param string $username Username. + * + * @return string Returns the salt value. + */ + public function get_salt_by_username(string $username): string + { + $user_settings = $this->CI->db->get_where('user_settings', ['username' => $username])->row_array(); + + return $user_settings['salt'] ?? ''; + } + + /** + * Get the user full name. + * + * @param int $user_id User ID. + * + * @return string Returns the user full name. + */ + public function get_user_display_name(int $user_id): string + { + $user = $this->CI->users_model->find($user_id); + + return $user['first_name'] . ' ' . $user['last_name']; + } + + /** + * Regenerate the password of the user that matches the provided username and email. + * + * @param string $username Username. + * @param string $email Email. + * + * @return string|bool Returns the new password on success or FALSE on failure. + * + * @throws RuntimeException + */ + public function regenerate_password(string $username, string $email): string + { + $query = $this + ->CI + ->db + ->select('users.id') + ->from('users') + ->join('user_settings', 'user_settings.id_users = users.id', 'inner') + ->where('users.email', $email) + ->where('user_settings.username', $username) + ->get(); + + if ( ! $query->num_rows()) + { + throw new RuntimeException('The username was not found in the database: ' . $username); + } + + $user = $query->row_array(); + + // Generate a new password for the user. + $new_password = random_string('alnum', 12); + + $salt = $this->get_salt_by_username($username); + + $hash_password = hash_password($salt, $new_password); + + $this->CI->users_model->set_setting($user['id'], 'password', $hash_password); + + return $new_password; + } +} diff --git a/application/models/User_model.php b/application/models/User_model.php deleted file mode 100644 index f5344349..00000000 --- a/application/models/User_model.php +++ /dev/null @@ -1,211 +0,0 @@ - - * @copyright Copyright (c) 2013 - 2020, Alex Tselegidis - * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 - * @link http://easyappointments.org - * @since v1.0.0 - * ---------------------------------------------------------------------------- */ - -/** - * User Model - * - * Contains current user's methods. - * - * @package Models - */ -class User_model extends EA_Model { - /** - * User_Model constructor. - */ - public function __construct() - { - parent::__construct(); - $this->load->library('timezones'); - $this->load->helper('general'); - $this->load->helper('string'); - } - - /** - * Returns the user from the database for the "settings" page. - * - * @param int $user_id User record id. - * - * @return array Returns an array with user data. - */ - public function get_user($user_id) - { - $user = $this->db->get_where('users', ['id' => $user_id])->row_array(); - $user['settings'] = $this->db->get_where('user_settings', ['id_users' => $user_id])->row_array(); - unset($user['settings']['id_users']); - return $user; - } - - /** - * This method saves the user record into the database (used in backend settings page). - * - * @param array $user Contains the current users data. - * - * @return bool Returns the operation result. - */ - public function save_user($user) - { - $user_settings = $user['settings']; - $user_settings['id_users'] = $user['id']; - unset($user['settings']); - - // Prepare user password (hash). - if (isset($user_settings['password'])) - { - $salt = $this->db->get_where('user_settings', ['id_users' => $user['id']])->row()->salt; - $user_settings['password'] = hash_password($salt, $user_settings['password']); - } - - if ( ! $this->db->update('users', $user, ['id' => $user['id']])) - { - return FALSE; - } - - if ( ! $this->db->update('user_settings', $user_settings, ['id_users' => $user['id']])) - { - return FALSE; - } - - return TRUE; - } - - /** - * Performs the check of the given user credentials. - * - * @param string $username Given user's name. - * @param string $password Given user's password (not hashed yet). - * - * @return array|null Returns the session data of the logged in user or null on failure. - */ - public function check_login($username, $password) - { - $salt = $this->get_salt($username); - $password = hash_password($salt, $password); - - $user_settings = $this->db->get_where('user_settings', [ - 'username' => $username, - 'password' => $password - ])->row_array(); - - if (empty($user_settings)) - { - return NULL; - } - - $user = $this->db->get_where('users', ['id' => $user_settings['id_users']])->row_array(); - - if (empty($user)) - { - return NULL; - } - - $role = $this->db->get_where('roles', ['id' => $user['id_roles']])->row_array(); - - if (empty($role)) - { - return NULL; - } - - $default_timezone = $this->timezones->get_default_timezone(); - - return [ - 'user_id' => $user['id'], - 'user_email' => $user['email'], - 'username' => $username, - 'timezone' => isset($user['timezone']) ? $user['timezone'] : $default_timezone, - 'role_slug' => $role['slug'], - ]; - } - - /** - * Retrieve user's salt from database. - * - * @param string $username This will be used to find the user record. - * - * @return string Returns the salt db value. - */ - public function get_salt($username) - { - $user = $this->db->get_where('user_settings', ['username' => $username])->row_array(); - return ($user) ? $user['salt'] : ''; - } - - /** - * Get the given user's display name (first + last name). - * - * @param int $user_id The given user record id. - * - * @return string Returns the user display name. - * - * @throws Exception If $user_id argument is invalid. - */ - public function get_user_display_name($user_id) - { - if ( ! is_numeric($user_id)) - { - throw new Exception ('Invalid argument given: ' . $user_id); - } - - $user = $this->db->get_where('users', ['id' => $user_id])->row_array(); - - return $user['first_name'] . ' ' . $user['last_name']; - } - - /** - * If the given arguments correspond to an existing user record, generate a new - * password and send it with an email. - * - * @param string $username User's username. - * @param string $email User's email. - * - * @return string|bool Returns the new password on success or FALSE on failure. - */ - public function regenerate_password($username, $email) - { - $result = $this->db - ->select('users.id') - ->from('users') - ->join('user_settings', 'user_settings.id_users = users.id', 'inner') - ->where('users.email', $email) - ->where('user_settings.username', $username) - ->get(); - - if ($result->num_rows() == 0) - { - return FALSE; - } - - $user_id = $result->row()->id; - - // Create a new password and send it with an email to the given email address. - $new_password = random_string('alnum', 12); - $salt = $this->db->get_where('user_settings', ['id_users' => $user_id])->row()->salt; - $hash_password = hash_password($salt, $new_password); - $this->db->update('user_settings', ['password' => $hash_password], ['id_users' => $user_id]); - - return $new_password; - } - - /** - * Get the timezone of a user. - * - * @param int $id Database ID of the user. - * - * @return string|null - */ - public function get_user_timezone($id) - { - $row = $this->db->get_where('users', ['id' => $id])->row_array(); - - return $row ? $row['timezone'] : NULL; - } -}