ok
Direktori : /home2/selectio/www/mm-tailor-billing/app/models/ |
Current File : //home2/selectio/www/mm-tailor-billing/app/models/Auth_model.php |
<?php defined('BASEPATH') or exit('No direct script access allowed'); class Auth_model extends CI_Model { public $_cache_user_in_group = []; public $_ion_like = []; public $_ion_limit = null; public $_ion_offset = null; public $_ion_order = null; public $_ion_order_by = null; public $_ion_select = []; public $_ion_where = []; public $activation_code; public $forgotten_password_code; public $identity; public $new_password; public $tables = []; protected $_cache_groups = []; protected $_ion_hooks; protected $error_end_delimiter; protected $error_start_delimiter; protected $errors; protected $messages; protected $response = null; public function __construct() { parent::__construct(); $this->load->config('ion_auth', true); //initialize db tables data $this->tables = $this->config->item('tables', 'ion_auth'); //initialize data $this->identity_column = $this->config->item('identity', 'ion_auth'); $this->store_salt = $this->config->item('store_salt', 'ion_auth'); $this->salt_length = $this->config->item('salt_length', 'ion_auth'); $this->join = $this->config->item('join', 'ion_auth'); //initialize hash method options (Bcrypt) $this->hash_method = $this->config->item('hash_method', 'ion_auth'); $this->default_rounds = $this->config->item('default_rounds', 'ion_auth'); $this->random_rounds = $this->config->item('random_rounds', 'ion_auth'); $this->min_rounds = $this->config->item('min_rounds', 'ion_auth'); $this->max_rounds = $this->config->item('max_rounds', 'ion_auth'); //initialize messages and error $this->messages = []; $this->errors = []; $delimiters_source = $this->config->item('delimiters_source', 'ion_auth'); //load the error delimeters either from the config file or use what's been supplied to form validation if ($delimiters_source === 'form_validation') { //load in delimiters from form_validation //to keep this simple we'll load the value using reflection since these properties are protected $this->load->library('form_validation'); $form_validation_class = new ReflectionClass('CI_Form_validation'); $error_prefix = $form_validation_class->getProperty('_error_prefix'); $error_prefix->setAccessible(true); $this->error_start_delimiter = $error_prefix->getValue($this->form_validation); $this->message_start_delimiter = $this->error_start_delimiter; $error_suffix = $form_validation_class->getProperty('_error_suffix'); $error_suffix->setAccessible(true); $this->error_end_delimiter = $error_suffix->getValue($this->form_validation); $this->message_end_delimiter = $this->error_end_delimiter; } else { //use delimiters from config $this->message_start_delimiter = $this->config->item('message_start_delimiter', 'ion_auth'); $this->message_end_delimiter = $this->config->item('message_end_delimiter', 'ion_auth'); $this->error_start_delimiter = $this->config->item('error_start_delimiter', 'ion_auth'); $this->error_end_delimiter = $this->config->item('error_end_delimiter', 'ion_auth'); } //initialize our hooks object $this->_ion_hooks = new stdClass; //load the bcrypt class if needed if ($this->hash_method == 'bcrypt') { if ($this->random_rounds) { $rand = rand($this->min_rounds, $this->max_rounds); $rounds = ['rounds' => $rand]; } else { $rounds = ['rounds' => $this->default_rounds]; } $this->load->library('bcrypt', $rounds); } $this->trigger_events('model_constructor'); } protected function _call_hook($event, $name) { if (isset($this->_ion_hooks->{$event}[$name]) && method_exists($this->_ion_hooks->{$event}[$name]->class, $this->_ion_hooks->{$event}[$name]->method)) { $hook = $this->_ion_hooks->{$event}[$name]; return call_user_func_array([$hook->class, $hook->method], $hook->arguments); } return false; } protected function _filter_data($table, $data) { $filtered_data = []; $columns = $this->db->list_fields($table); if (is_array($data)) { foreach ($columns as $column) { if (array_key_exists($column, $data)) { $filtered_data[$column] = $data[$column]; } } } return $filtered_data; } protected function _prepare_ip($ip_address) { if ($this->db->platform() === 'postgre' || $this->db->platform() === 'sqlsrv' || $this->db->platform() === 'mssql' || $this->db->platform() === 'mysqli' || $this->db->platform() === 'mysql') { return $ip_address; } return inet_pton($ip_address); } public function activate($id, $code = false) { $this->trigger_events('pre_activate'); if ($code !== false) { $query = $this->db->select($this->identity_column) ->where('activation_code', $code) ->limit(1) ->get($this->tables['users']); $result = $query->row(); if ($query->num_rows() !== 1) { $this->trigger_events(['post_activate', 'post_activate_unsuccessful']); $this->set_error('activate_unsuccessful'); return false; } $identity = $result->{$this->identity_column}; $data = [ 'activation_code' => null, 'active' => '-1', ]; $this->trigger_events('extra_where'); $this->db->update($this->tables['users'], $data, [$this->identity_column => $identity]); } else { $user = $this->user($id)->row(); $data = [ 'activation_code' => null, 'active' => '1', ]; $this->trigger_events('extra_where'); $this->db->update($this->tables['users'], $data, ['id' => $id]); } $return = $this->db->affected_rows() == 1; if ($return) { $this->trigger_events(['post_activate', 'post_activate_successful']); $this->set_message('activate_successful'); } else { $this->trigger_events(['post_activate', 'post_activate_unsuccessful']); $this->set_error('activate_unsuccessful'); } return $return; } public function change_password($identity, $old, $new) { $this->trigger_events('pre_change_password'); $this->trigger_events('extra_where'); $query = $this->db->select('id, password, salt') ->where($this->identity_column, $identity) ->limit(1) ->get($this->tables['users']); if ($query->num_rows() !== 1) { $this->trigger_events(['post_change_password', 'post_change_password_unsuccessful']); $this->set_error('password_change_unsuccessful'); return false; } $user = $query->row(); $old_password_matches = $this->hash_password_db($user->id, $old); if ($old_password_matches === true) { //store the new password and reset the remember code so all remembered instances have to re-login $hashed_new_password = $this->hash_password($new, $user->salt); $data = [ 'password' => $hashed_new_password, 'remember_code' => null, ]; $this->trigger_events('extra_where'); $successfully_changed_password_in_db = $this->db->update($this->tables['users'], $data, [$this->identity_column => $identity]); if ($successfully_changed_password_in_db) { $this->trigger_events(['post_change_password', 'post_change_password_successful']); $this->set_message('password_change_successful'); } else { $this->trigger_events(['post_change_password', 'post_change_password_unsuccessful']); $this->set_error('password_change_unsuccessful'); } return $successfully_changed_password_in_db; } $this->set_error('old_password_wrong'); $this->set_error('password_change_unsuccessful'); return false; } public function clear_forgotten_password_code($code) { if (empty($code)) { return false; } $this->db->where('forgotten_password_code', $code); if ($this->db->count_all_results($this->tables['users']) > 0) { $data = [ 'forgotten_password_code' => null, 'forgotten_password_time' => null, ]; $this->db->update($this->tables['users'], $data, ['forgotten_password_code' => $code]); return true; } return false; } public function clear_login_attempts($identity, $expire_period = 86400) { if ($this->config->item('track_login_attempts', 'ion_auth')) { $ip_address = $this->_prepare_ip($this->input->ip_address()); $this->db->where(['ip_address' => $ip_address, 'login' => $identity]); // Purge obsolete login attempts $this->db->or_where('time <', time() - $expire_period, false); return $this->db->delete($this->tables['login_attempts']); } return false; } public function create_group($group_name = false, $group_description = '', $additional_data = []) { // bail if the group name was not passed if (!$group_name) { $this->set_error('group_name_required'); return false; } // bail if the group name already exists $existing_group = $this->db->get_where($this->tables['groups'], ['name' => $group_name])->num_rows(); if ($existing_group !== 0) { $this->set_error('group_already_exists'); return false; } $data = ['name' => $group_name, 'description' => $group_description]; //filter out any data passed that doesnt have a matching column in the groups table //and merge the set group data and the additional data if (!empty($additional_data)) { $data = array_merge($this->_filter_data($this->tables['groups'], $additional_data), $data); } $this->trigger_events('extra_group_set'); // insert the new group $this->db->insert($this->tables['groups'], $data); $group_id = $this->db->insert_id(); // report success $this->set_message('group_creation_successful'); // return the brand new group id return $group_id; } public function deactivate($id = null) { $this->trigger_events('deactivate'); if (!isset($id)) { $this->set_error('deactivate_unsuccessful'); return false; } $activation_code = sha1(md5(microtime())); $this->activation_code = $activation_code; $data = [ 'activation_code' => $activation_code, 'active' => 0, ]; $this->trigger_events('extra_where'); $this->db->update($this->tables['users'], $data, ['id' => $id]); $return = $this->db->affected_rows() == 1; if ($return) { $this->set_message('deactivate_successful'); } else { $this->set_error('deactivate_unsuccessful'); } return $return; } public function delete_group($group_id = false) { // bail if mandatory param not set if (!$group_id || empty($group_id)) { return false; } $this->trigger_events('pre_delete_group'); $this->db->trans_begin(); // remove all users from this group //$this->db->delete($this->tables['users_groups'], array($this->join['groups'] => $group_id)); // remove the group itself $this->db->delete($this->tables['groups'], ['id' => $group_id]); if ($this->db->trans_status() === false) { $this->db->trans_rollback(); $this->trigger_events(['post_delete_group', 'post_delete_group_unsuccessful']); $this->set_error('group_delete_unsuccessful'); return false; } $this->db->trans_commit(); $this->trigger_events(['post_delete_group', 'post_delete_group_successful']); $this->set_message('group_delete_successful'); return true; } public function delete_user($id) { $this->trigger_events('pre_delete_user'); $this->db->trans_begin(); // remove user from groups //$this->remove_from_group(NULL, $id); // delete user from users table should be placed after remove from group $this->db->delete($this->tables['users'], ['id' => $id]); // if user does not exist in database then it returns FALSE else removes the user from groups if ($this->db->affected_rows() == 0) { return false; } if ($this->db->trans_status() === false) { $this->db->trans_rollback(); $this->trigger_events(['post_delete_user', 'post_delete_user_unsuccessful']); $this->set_error('delete_unsuccessful'); return false; } $this->db->trans_commit(); $this->trigger_events(['post_delete_user', 'post_delete_user_successful']); $this->set_message('delete_successful'); return true; } public function email_check($email = '') { $this->trigger_events('email_check'); if (empty($email)) { return false; } $this->trigger_events('extra_where'); return $this->db->where('email', $email) ->count_all_results($this->tables['users']) > 0; } public function errors() { $_output = ''; foreach ($this->errors as $error) { $errorLang = $this->lang->line($error) ? $this->lang->line($error) : '##' . $error . '##'; $_output .= $this->error_start_delimiter . $errorLang . $this->error_end_delimiter; } return $_output; } public function errors_array($langify = true) { if ($langify) { $_output = []; foreach ($this->errors as $error) { $errorLang = $this->lang->line($error) ? $this->lang->line($error) : '##' . $error . '##'; $_output[] = $this->error_start_delimiter . $errorLang . $this->error_end_delimiter; } return $_output; } return $this->errors; } public function forgotten_password($identity) { if (empty($identity)) { $this->trigger_events(['post_forgotten_password', 'post_forgotten_password_unsuccessful']); return false; } //All some more randomness $activation_code_part = ''; if (function_exists('openssl_random_pseudo_bytes')) { $activation_code_part = openssl_random_pseudo_bytes(128); } for ($i = 0; $i < 1024; $i++) { $activation_code_part = sha1($activation_code_part . mt_rand() . microtime()); } $key = $this->hash_code($activation_code_part . $identity); $this->forgotten_password_code = $key; $this->trigger_events('extra_where'); $update = [ 'forgotten_password_code' => $key, 'forgotten_password_time' => time(), ]; $this->db->update($this->tables['users'], $update, [$this->identity_column => $identity]); $return = $this->db->affected_rows() == 1; if ($return) { $this->trigger_events(['post_forgotten_password', 'post_forgotten_password_successful']); } else { $this->trigger_events(['post_forgotten_password', 'post_forgotten_password_unsuccessful']); } return $return; } public function forgotten_password_complete($code, $salt = false) { $this->trigger_events('pre_forgotten_password_complete'); if (empty($code)) { $this->trigger_events(['post_forgotten_password_complete', 'post_forgotten_password_complete_unsuccessful']); return false; } $profile = $this->where('forgotten_password_code', $code)->users()->row(); //pass the code to profile if ($profile) { if ($this->config->item('forgot_password_expiration', 'ion_auth') > 0) { //Make sure it isn't expired $expiration = $this->config->item('forgot_password_expiration', 'ion_auth'); if (time() - $profile->forgotten_password_time > $expiration) { //it has expired $this->set_error('forgot_password_expired'); $this->trigger_events(['post_forgotten_password_complete', 'post_forgotten_password_complete_unsuccessful']); return false; } } $password = $this->salt(); $data = [ 'password' => $this->hash_password($password, $salt), 'forgotten_password_code' => null, 'active' => 1, ]; $this->db->update($this->tables['users'], $data, ['forgotten_password_code' => $code]); $this->trigger_events(['post_forgotten_password_complete', 'post_forgotten_password_complete_successful']); return $password; } $this->trigger_events(['post_forgotten_password_complete', 'post_forgotten_password_complete_unsuccessful']); return false; } public function get_attempts_num($identity) { if ($this->config->item('track_login_attempts', 'ion_auth')) { $ip_address = $this->_prepare_ip($this->input->ip_address()); $this->db->select('1', false); if ($this->config->item('track_login_ip_address', 'ion_auth')) { $this->db->where('ip_address', $ip_address); } elseif (strlen($identity) > 0) { $this->db->or_where('login', $identity); } $qres = $this->db->get($this->tables['login_attempts']); return $qres->num_rows(); } return 0; } public function get_last_attempt_time($identity) { if ($this->config->item('track_login_attempts', 'ion_auth')) { $ip_address = $this->_prepare_ip($this->input->ip_address()); $this->db->select_max('time'); if ($this->config->item('track_login_ip_address', 'ion_auth')) { $this->db->where('ip_address', $ip_address); } elseif (strlen($identity) > 0) { $this->db->or_where('login', $identity); } $qres = $this->db->get($this->tables['login_attempts'], 1); if ($qres->num_rows() > 0) { return $qres->row()->time; } } return 0; } public function group($id = null) { $this->trigger_events('group'); if (isset($id)) { $this->db->where($this->tables['groups'] . '.id', $id); } $this->limit(1); return $this->groups(); } /** * get_users_groups * * @return array * @author Ben Edmunds * */ /*public function get_users_groups($id = FALSE) { $this->trigger_events('get_users_group'); //if no id was passed use the current users id $id || $id = $this->session->userdata('user_id'); return $this->db->select($this->tables['users_groups'] . '.' . $this->join['groups'] . ' as id, ' . $this->tables['groups'] . '.name, ' . $this->tables['groups'] . '.description') ->where($this->tables['users_groups'] . '.' . $this->join['users'], $id) ->join($this->tables['groups'], $this->tables['users_groups'] . '.' . $this->join['groups'] . '=' . $this->tables['groups'] . '.id') ->get($this->tables['users_groups']); }*/ /** * add_to_group * * @return bool * @author Ben Edmunds * */ /*public function add_to_group($group_id, $user_id = false) { $this->trigger_events('add_to_group'); //if no id was passed use the current users id $user_id || $user_id = $this->session->userdata('user_id'); //check if unique - num_rows() > 0 means row found if ($this->db->where(array($this->join['groups'] => (int) $group_id, $this->join['users'] => (int) $user_id))->get($this->tables['users_groups'])->num_rows()) return false; if ($return = $this->db->insert($this->tables['users_groups'], array($this->join['groups'] => (int) $group_id, $this->join['users'] => (int) $user_id))) { if (isset($this->_cache_groups[$group_id])) { $group_name = $this->_cache_groups[$group_id]; } else { $group = $this->group($group_id)->result(); $group_name = $group[0]->name; $this->_cache_groups[$group_id] = $group_name; } $this->_cache_user_in_group[$user_id][$group_id] = $group_name; } return $return; }*/ /** * remove_from_group * * @return bool * @author Ben Edmunds * */ /*public function remove_from_group($group_ids = false, $user_id = false) { $this->trigger_events('remove_from_group'); // user id is required if (empty($user_id)) { return FALSE; } // if group id(s) are passed remove user from the group(s) if (!empty($group_ids)) { if (!is_array($group_ids)) { $group_ids = array($group_ids); } foreach ($group_ids as $group_id) { $this->db->delete($this->tables['users_groups'], array($this->join['groups'] => (int) $group_id, $this->join['users'] => (int) $user_id)); if (isset($this->_cache_user_in_group[$user_id]) && isset($this->_cache_user_in_group[$user_id][$group_id])) { unset($this->_cache_user_in_group[$user_id][$group_id]); } } $return = TRUE; } // otherwise remove user from all groups else { if ($return = $this->db->delete($this->tables['users_groups'], array($this->join['users'] => (int) $user_id))) { $this->_cache_user_in_group[$user_id] = array(); } } return $return; }*/ /** * groups * * @return object * @author Ben Edmunds * */ public function groups() { $this->trigger_events('groups'); //run each where that was passed if (isset($this->_ion_where) && !empty($this->_ion_where)) { foreach ($this->_ion_where as $where) { $this->db->where($where); } $this->_ion_where = []; } if (isset($this->_ion_limit) && isset($this->_ion_offset)) { $this->db->limit($this->_ion_limit, $this->_ion_offset); $this->_ion_limit = null; $this->_ion_offset = null; } elseif (isset($this->_ion_limit)) { $this->db->limit($this->_ion_limit); $this->_ion_limit = null; } //set the order if (isset($this->_ion_order_by) && isset($this->_ion_order)) { $this->db->order_by($this->_ion_order_by, $this->_ion_order); } $this->response = $this->db->get($this->tables['groups']); return $this; } public function hash_code($password) { return $this->hash_password($password, false, true); } public function hash_password($password, $salt = false, $use_sha1_override = false) { if (empty($password)) { return false; } //bcrypt if ($use_sha1_override === false && $this->hash_method == 'bcrypt') { return $this->bcrypt->hash($password); } if ($this->store_salt && $salt) { return sha1($password . $salt); } $salt = $this->salt(); return $salt . substr(sha1($salt . $password), 0, -$this->salt_length); } public function hash_password_db($id, $password, $use_sha1_override = false) { if (empty($id) || empty($password)) { return false; } $this->trigger_events('extra_where'); $query = $this->db->select('password, salt') ->where('id', $id) ->limit(1) ->get($this->tables['users']); $hash_password_db = $query->row(); if ($query->num_rows() !== 1) { return false; } // bcrypt if ($use_sha1_override === false && $this->hash_method == 'bcrypt') { if ($this->bcrypt->verify($password, $hash_password_db->password)) { return true; } return false; } // sha1 if ($this->store_salt) { $db_password = sha1($password . $hash_password_db->salt); } else { $salt = substr($hash_password_db->password, 0, $this->salt_length); $db_password = $salt . substr(sha1($salt . $password), 0, -$this->salt_length); } if ($db_password == $hash_password_db->password) { return true; } return false; } public function identity_check($identity = '') { $this->trigger_events('identity_check'); if (empty($identity)) { return false; } return $this->db->where($this->identity_column, $identity) ->count_all_results($this->tables['users']) > 0; } public function increase_login_attempts($identity) { if ($this->config->item('track_login_attempts', 'ion_auth')) { $ip_address = $this->_prepare_ip($this->input->ip_address()); return $this->db->insert($this->tables['login_attempts'], ['ip_address' => $ip_address, 'login' => $identity, 'time' => time()]); } return false; } public function is_max_login_attempts_exceeded($identity) { if ($this->config->item('track_login_attempts', 'ion_auth')) { $max_attempts = $this->config->item('maximum_login_attempts', 'ion_auth'); if ($max_attempts > 0) { $attempts = $this->get_attempts_num($identity); return $attempts >= $max_attempts; } } return false; } public function is_time_locked_out($identity) { return $this->is_max_login_attempts_exceeded($identity) && $this->get_last_attempt_time($identity) > time() - $this->config->item('lockout_time', 'ion_auth'); } public function like($like, $value = null, $position = 'both') { $this->trigger_events('like'); if (!is_array($like)) { $like = [$like => [ 'value' => $value, 'position' => $position, ]]; } array_push($this->_ion_like, $like); return $this; } public function limit($limit) { $this->trigger_events('limit'); $this->_ion_limit = $limit; return $this; } public function login($identity, $password, $remember = false) { $this->trigger_events('pre_login'); if (empty($identity) || empty($password)) { $this->set_error('login_unsuccessful'); return false; } $this->trigger_events('extra_where'); $this->load->helper('email'); $this->identity_column = valid_email($identity) ? 'email' : 'username'; $query = $this->db->select($this->identity_column . ', username, email, id, password, active, first_name, last_name, created_on, last_login, last_ip_address, avatar, gender, group_id, store_id') ->where($this->identity_column, $this->db->escape_str($identity)) ->limit(1) ->get($this->tables['users']); if ($this->is_time_locked_out($identity)) { //Hash something anyway, just to take up time $this->hash_password($password); $this->trigger_events('post_login_unsuccessful'); $this->set_error('login_timeout'); return false; } if ($query->num_rows() === 1) { $user = $query->row(); $password = $this->hash_password_db($user->id, $password); if ($password === true) { if (!isset($this->Settings->single_login)) { $this->Settings->single_login = 0; } if ($user->active != 1) { $this->trigger_events('post_login_unsuccessful'); $this->set_error('login_unsuccessful_not_active'); return false; } $this->set_session($user); $this->update_last_login($user->id); $this->update_last_login_ip($user->id); $ldata = ['user_id' => $user->id, 'ip_address' => $this->input->ip_address(), 'login' => $identity]; $this->db->insert('user_logins', $ldata); $this->clear_login_attempts($identity); if ($remember && $this->config->item('remember_users', 'ion_auth')) { $this->remember_user($user->id); } $this->trigger_events(['post_login', 'post_login_successful']); $this->set_message('login_successful'); return true; } } //Hash something anyway, just to take up time $this->hash_password($password); $this->increase_login_attempts($identity); $this->trigger_events('post_login_unsuccessful'); $this->set_error('login_unsuccessful'); return false; } public function login_remembered_user() { $this->trigger_events('pre_login_remembered_user'); //check for valid data if (!get_cookie('identity') || !get_cookie('remember_code') || !$this->identity_check(get_cookie('identity'))) { $this->trigger_events(['post_login_remembered_user', 'post_login_remembered_user_unsuccessful']); return false; } //get the user $this->trigger_events('extra_where'); $query = $this->db->select($this->identity_column . ', id, username, email, last_login, last_ip_address, avatar, first_name, last_name, created_on, gender, group_id, store_id') ->where($this->identity_column, get_cookie('identity')) ->where('remember_code', get_cookie('remember_code')) ->limit(1) ->get($this->tables['users']); //if the user was found, sign them in if ($query->num_rows() == 1) { $user = $query->row(); $this->update_last_login($user->id); $this->update_last_login_ip($user->id); $this->set_session($user); //extend the users cookies if the option is enabled if ($this->config->item('user_extend_on_login', 'ion_auth')) { $this->remember_user($user->id); } $this->trigger_events(['post_login_remembered_user', 'post_login_remembered_user_successful']); return true; } $this->trigger_events(['post_login_remembered_user', 'post_login_remembered_user_unsuccessful']); return false; } public function messages() { $_output = ''; foreach ($this->messages as $message) { $messageLang = $this->lang->line($message) ? $this->lang->line($message) : '##' . $message . '##'; $_output .= $this->message_start_delimiter . $messageLang . $this->message_end_delimiter; } return $_output; } public function messages_array($langify = true) { if ($langify) { $_output = []; foreach ($this->messages as $message) { $messageLang = $this->lang->line($message) ? $this->lang->line($message) : '##' . $message . '##'; $_output[] = $this->message_start_delimiter . $messageLang . $this->message_end_delimiter; } return $_output; } return $this->messages; } public function num_rows() { $this->trigger_events(['num_rows']); $result = $this->response->num_rows(); $this->response->free_result(); return $result; } public function offset($offset) { $this->trigger_events('offset'); $this->_ion_offset = $offset; return $this; } public function order_by($by, $order = 'desc') { $this->trigger_events('order_by'); $this->_ion_order_by = $by; $this->_ion_order = $order; return $this; } public function register($username, $password, $email, $additional_data = [], $active = false) { $this->trigger_events('pre_register'); $manual_activation = $this->config->item('manual_activation', 'ion_auth'); if ($this->identity_column == 'email' && $this->email_check($email)) { $this->set_error('account_creation_duplicate_email'); return false; } elseif ($this->identity_column == 'username' && $this->username_check($username)) { $this->set_error('account_creation_duplicate_username'); return false; } // If username is taken, use username1 or username2, etc. if ($this->identity_column != 'username') { $original_username = $username; for ($i = 0; $this->username_check($username); $i++) { if ($i > 0) { $username = $original_username . $i; } } } // IP Address $ip_address = $this->_prepare_ip($this->input->ip_address()); $salt = $this->store_salt ? $this->salt() : false; $password = $this->hash_password($password, $salt); // Users table. $data = [ 'username' => $username, 'password' => $password, 'email' => $email, 'ip_address' => $ip_address, 'created_on' => time(), 'last_login' => time(), 'active' => ($active ? 1 : (($manual_activation === false) ? 1 : 0)), ]; if ($this->store_salt) { $data['salt'] = $salt; } if (!isset($additional_data['group_id'])) { $additional_data['group_id'] = 3; } //filter out any data passed that doesnt have a matching column in the users table //and merge the set user data and the additional data $user_data = array_merge($this->_filter_data($this->tables['users'], $additional_data), $data); $this->trigger_events('extra_set'); $this->db->insert($this->tables['users'], $user_data); $id = $this->db->insert_id(); $this->trigger_events('post_register'); return (isset($id)) ? $id : false; } public function remember_user($id) { $this->trigger_events('pre_remember_user'); if (!$id) { return false; } $user = $this->user($id)->row(); $salt = sha1($user->password); $this->db->update($this->tables['users'], ['remember_code' => $salt], ['id' => $id]); if ($this->db->affected_rows() > -1) { // if the user_expire is set to zero we'll set the expiration two years from now. if ($this->config->item('user_expire', 'ion_auth') === 0) { $expire = (60 * 60 * 24 * 365 * 2); } // otherwise use what is set else { $expire = $this->config->item('user_expire', 'ion_auth'); } set_cookie([ 'name' => 'identity', 'value' => $user->{$this->identity_column}, 'expire' => $expire, ]); set_cookie([ 'name' => 'remember_code', 'value' => $salt, 'expire' => $expire, ]); $this->trigger_events(['post_remember_user', 'remember_user_successful']); return true; } $this->trigger_events(['post_remember_user', 'remember_user_unsuccessful']); return false; } public function remove_hook($event, $name) { if (isset($this->_ion_hooks->{$event}[$name])) { unset($this->_ion_hooks->{$event}[$name]); } } public function remove_hooks($event) { if (isset($this->_ion_hooks->$event)) { unset($this->_ion_hooks->$event); } } public function reset_password($identity, $new) { $this->trigger_events('pre_change_password'); if (!$this->identity_check($identity)) { $this->trigger_events(['post_change_password', 'post_change_password_unsuccessful']); return false; } $this->trigger_events('extra_where'); $query = $this->db->select('id, password, salt') ->where($this->identity_column, $identity) ->limit(1) ->get($this->tables['users']); if ($query->num_rows() !== 1) { $this->trigger_events(['post_change_password', 'post_change_password_unsuccessful']); $this->set_error('password_change_unsuccessful'); return false; } $result = $query->row(); $new = $this->hash_password($new, $result->salt); //store the new password and reset the remember code so all remembered instances have to re-login //also clear the forgotten password code $data = [ 'password' => $new, 'remember_code' => null, 'forgotten_password_code' => null, 'forgotten_password_time' => null, ]; $this->trigger_events('extra_where'); $this->db->update($this->tables['users'], $data, [$this->identity_column => $identity]); $return = $this->db->affected_rows() == 1; if ($return) { $this->trigger_events(['post_change_password', 'post_change_password_successful']); $this->set_message('password_change_successful'); } else { $this->trigger_events(['post_change_password', 'post_change_password_unsuccessful']); $this->set_error('password_change_unsuccessful'); } return $return; } public function result() { $this->trigger_events('result'); $result = $this->response->result(); $this->response->free_result(); return $result; } public function result_array() { $this->trigger_events(['result', 'result_array']); $result = $this->response->result_array(); $this->response->free_result(); return $result; } public function row() { $this->trigger_events('row'); $row = $this->response->row(); $this->response->free_result(); return $row; } public function row_array() { $this->trigger_events(['row', 'row_array']); $row = $this->response->row_array(); $this->response->free_result(); return $row; } public function salt() { return substr(md5(uniqid(rand(), true)), 0, $this->salt_length); } public function select($select) { $this->trigger_events('select'); $this->_ion_select[] = $select; return $this; } public function set_error($error) { $this->errors[] = $error; return $error; } public function set_error_delimiters($start_delimiter, $end_delimiter) { $this->error_start_delimiter = $start_delimiter; $this->error_end_delimiter = $end_delimiter; return true; } public function set_hook($event, $name, $class, $method, $arguments) { $this->_ion_hooks->{$event}[$name] = new stdClass; $this->_ion_hooks->{$event}[$name]->class = $class; $this->_ion_hooks->{$event}[$name]->method = $method; $this->_ion_hooks->{$event}[$name]->arguments = $arguments; } public function set_lang($lang = 'en') { $this->trigger_events('set_lang'); // if the user_expire is set to zero we'll set the expiration two years from now. if ($this->config->item('user_expire', 'ion_auth') === 0) { $expire = (60 * 60 * 24 * 365 * 2); } // otherwise use what is set else { $expire = $this->config->item('user_expire', 'ion_auth'); } set_cookie([ 'name' => 'lang_code', 'value' => $lang, 'expire' => $expire, ]); return true; } public function set_message($message) { $this->messages[] = $message; return $message; } public function set_message_delimiters($start_delimiter, $end_delimiter) { $this->message_start_delimiter = $start_delimiter; $this->message_end_delimiter = $end_delimiter; return true; } public function set_session($user) { $this->trigger_events('pre_set_session'); $session_data = [ 'identity' => $user->{$this->identity_column}, 'username' => $user->username, 'email' => $user->email, 'user_id' => $user->id, 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'created_on' => $this->tec->hrld(date('Y-m-d H:i:s', $user->created_on)), 'old_last_login' => $user->last_login, 'last_ip' => $user->last_ip_address, 'avatar' => $user->avatar, 'gender' => $user->gender, 'group_id' => $user->group_id, 'store_id' => $user->store_id, 'has_store_id' => $user->store_id, ]; $this->session->set_userdata($session_data); $this->trigger_events('post_set_session'); return true; } public function trigger_events($events) { if (is_array($events) && !empty($events)) { foreach ($events as $event) { $this->trigger_events($event); } } else { if (isset($this->_ion_hooks->$events) && !empty($this->_ion_hooks->$events)) { foreach ($this->_ion_hooks->$events as $name => $hook) { $this->_call_hook($events, $name); } } } } public function update($id, array $data, $upgs = []) { $this->trigger_events('pre_update_user'); $user = $this->user($id)->row(); $this->db->trans_begin(); if (array_key_exists($this->identity_column, $data) && $this->identity_check($data[$this->identity_column]) && $user->{$this->identity_column} !== $data[$this->identity_column]) { $this->db->trans_rollback(); $this->set_error('account_creation_duplicate_' . $this->identity_column); $this->trigger_events(['post_update_user', 'post_update_user_unsuccessful']); $this->set_error('update_unsuccessful'); return false; } // Filter the data passed $data = $this->_filter_data($this->tables['users'], $data); if (array_key_exists('username', $data) || array_key_exists('password', $data) || array_key_exists('email', $data)) { if (array_key_exists('password', $data)) { if (!empty($data['password'])) { $data['password'] = $this->hash_password($data['password'], $user->salt); } else { // unset password so it doesn't effect database entry if no password passed unset($data['password']); } } } $this->trigger_events('extra_where'); $this->db->update($this->tables['users'], $data, ['id' => $user->id]); //foreach($upgs as $upg){ // $this->usersProductGroups($upg); //} if ($this->db->trans_status() === false) { $this->db->trans_rollback(); $this->trigger_events(['post_update_user', 'post_update_user_unsuccessful']); $this->set_error('update_unsuccessful'); return false; } $this->db->trans_commit(); $this->trigger_events(['post_update_user', 'post_update_user_successful']); $this->set_message('update_successful'); return true; } public function update_group($group_id = false, $group_name = false, $additional_data = []) { if (empty($group_id)) { return false; } $data = []; if (!empty($group_name)) { // we are changing the name, so do some checks // bail if the group name already exists $existing_group = $this->db->get_where($this->tables['groups'], ['name' => $group_name])->row(); if (isset($existing_group->id) && $existing_group->id != $group_id) { $this->set_error('group_already_exists'); return false; } $data['name'] = $group_name; } // IMPORTANT!! Third parameter was string type $description; this following code is to maintain backward compatibility // New projects should work with 3rd param as array if (is_string($additional_data)) { $additional_data = ['description' => $additional_data]; } //filter out any data passed that doesnt have a matching column in the groups table //and merge the set group data and the additional data if (!empty($additional_data)) { $data = array_merge($this->_filter_data($this->tables['groups'], $additional_data), $data); } $this->db->update($this->tables['groups'], $data, ['id' => $group_id]); $this->set_message('group_update_successful'); return true; } public function update_last_login($id) { $this->trigger_events('update_last_login'); $this->load->helper('date'); $this->trigger_events('extra_where'); $this->db->update($this->tables['users'], ['last_login' => time()], ['id' => $id]); return $this->db->affected_rows() == 1; } public function update_last_login_ip($id) { $this->trigger_events('update_last_login_ip'); $this->trigger_events('extra_where'); $this->db->update($this->tables['users'], ['last_ip_address' => $this->input->ip_address()], ['id' => $id]); return $this->db->affected_rows() == 1; } public function updateAvatar($id, $avatar) { if ($this->db->update($this->tables['users'], ['avatar' => $avatar], ['id' => $id])) { $this->set_message('avatar_updated'); return true; } return false; } public function user($id = null) { $this->trigger_events('user'); //if no id was passed use the current users id $id || $id = $this->session->userdata('user_id'); $this->limit(1); $this->where($this->tables['users'] . '.id', $id); $this->users(); return $this; } public function username_check($username = '') { $this->trigger_events('username_check'); if (empty($username)) { return false; } $this->trigger_events('extra_where'); return $this->db->where('username', $username) ->count_all_results($this->tables['users']) > 0; } public function users($groups = null) { $this->trigger_events('users'); if (isset($this->_ion_select) && !empty($this->_ion_select)) { foreach ($this->_ion_select as $select) { $this->db->select($select); } $this->_ion_select = []; } else { //default selects $this->db->select([ $this->tables['users'] . '.*', $this->tables['users'] . '.id as id', $this->tables['users'] . '.id as user_id', ]); } $this->trigger_events('extra_where'); //run each where that was passed if (isset($this->_ion_where) && !empty($this->_ion_where)) { foreach ($this->_ion_where as $where) { $this->db->where($where); } $this->_ion_where = []; } if (isset($this->_ion_like) && !empty($this->_ion_like)) { foreach ($this->_ion_like as $like) { $this->db->or_like($like); } $this->_ion_like = []; } if (isset($this->_ion_limit) && isset($this->_ion_offset)) { $this->db->limit($this->_ion_limit, $this->_ion_offset); $this->_ion_limit = null; $this->_ion_offset = null; } elseif (isset($this->_ion_limit)) { $this->db->limit($this->_ion_limit); $this->_ion_limit = null; } //set the order if (isset($this->_ion_order_by) && isset($this->_ion_order)) { $this->db->order_by($this->_ion_order_by, $this->_ion_order); $this->_ion_order = null; $this->_ion_order_by = null; } $this->response = $this->db->get($this->tables['users']); return $this; } public function where($where, $value = null) { $this->trigger_events('where'); if (!is_array($where)) { $where = [$where => $value]; } array_push($this->_ion_where, $where); return $this; } }