/** * If exists, will take our password out of the data array, and * create a new hash for it, which is inserted back into the * data array to be saved to the database. * * @param array $data * * @return array */ protected function hashPassword($data) { if (isset($data['fields'])) { $data = $data['fields']; } if (isset($data['password'])) { $data['password_hash'] = \Myth\Auth\Password::hashPassword($data['password']); unset($data['password'], $data['pass_confirm']); } return $data; }
/** * Validates user login information without logging them in. * * $credentials is an array of key/value pairs needed to log the user in. * This is often email/password, or username/password. * * @param $credentials * @param bool $return_user * @return mixed */ public function validate($credentials, $return_user = false) { // Can't validate without a password. if (empty($credentials['password']) || count($credentials) < 2) { return null; } $password = $credentials['password']; unset($credentials['password']); // We should only be allowed 1 single other credential to // test against. if (count($credentials) > 1) { $this->error = lang('auth.too_many_credentials'); return false; } // Ensure that the fields are allowed validation fields if (!in_array(key($credentials), config_item('auth.valid_fields'))) { $this->error = lang('auth.invalid_credentials'); return false; } // We do not want to force case-sensitivity on things // like username and email for usability sake. if (!empty($credentials['email'])) { $credentials['email'] = strtolower($credentials['email']); } // Can we find a user with those credentials? $user = $this->user_model->as_array()->where($credentials)->first(); // If the user is throttled due to too many invalid logins // or the system is under attack, kick them back. // If throttling time is above zero, we can't allow // logins now. $time = (int) $this->isThrottled($user); if ($time > 0) { $this->error = sprintf(lang('auth.throttled'), $time); return false; } // Get ip address $ip_address = $this->ci->input->ip_address(); if (!$user) { $this->error = lang('auth.invalid_user'); $this->ci->login_model->recordLoginAttempt($ip_address); return false; } // Now, try matching the passwords. $result = password_verify($password, $user['password_hash']); if (!$result) { $this->error = lang('auth.invalid_password'); $this->ci->login_model->recordLoginAttempt($ip_address, $user['id']); return false; } // Check to see if the password needs to be rehashed. // This would be due to the hash algorithm or hash // cost changing since the last time that a user // logged in. if (password_needs_rehash($user['password_hash'], PASSWORD_DEFAULT, ['cost' => config_item('auth.hash_cost')])) { $new_hash = Password::hashPassword($password); $this->user_model->skip_validation()->update($user['id'], ['password_hash' => $new_hash]); unset($new_hash); } // Is the user active? if (!$user['active']) { $this->error = lang('auth.inactive_account'); return false; } return $return_user ? $user : true; }