diff --git a/application/config/auth.php b/application/config/auth.php new file mode 100644 index 0000000..c1baa73 --- /dev/null +++ b/application/config/auth.php @@ -0,0 +1,71 @@ + */ class Auth extends CI_Controller { /** - * Shows the index page. + * Constructor. */ - public function index() { - $this->load->view('index'); - } + public function __construct() { + parent::__construct(); + $this->load->library('access'); + $this->load->library('form_validation'); + } + + //redirect if needed, otherwise display the user list + public function index() { + if (!$this->access->loggedIn()) { + redirect('auth/login'); + } else { + //set the flash data error message if there is one + $this->data['message'] = validation_errors() ? validation_errors() : $this->session->flashdata('message'); + + //$this->data['users'] = $this->access->getUsers(); + $this->load->view('index', $this->data); + } + } /** - * Shows the index page. + * Logs the user in. */ - public function login() { - $this->load->view('auth/login'); - } + public function login() { + if ($this->access->loggedIn()) { + redirect('welcome'); + } + + // validate form input + $this->form_validation->set_rules('username', "Benutzername", 'required'); + $this->form_validation->set_rules('password', "Passwort", 'required'); + + if ($this->form_validation->run() == true) { //check to see if the user is logging in + // check for "remember me" + $remember = (boolean) $this->input->post('remember'); + + if ($this->access->login($this->input->post('username'), $this->input->post('password'), $remember)) { //if the login is successful + //redirect them back to the home page + $this->session->set_flashdata('message', $this->access->messages()); + redirect('', 'refresh'); + } else { //if the login was un-successful + //redirect them back to the login page + $this->session->set_flashdata('message', $this->access->errors()); + //redirect('auth/login', 'refresh'); //use redirects instead of loading views for compatibility with MY_Controller libraries + echo "{success: false}"; + } + } else { //the user is not logging in so display the login page + //set the flash data error message if there is one + $this->data['message'] = validation_errors() ? validation_errors() : $this->session->flashdata('message'); + $this->data['username'] = $this->form_validation->set_value('username'); + + $this->load->view('auth/login', $this->data); + } + } /** * Logs the user in - or not ;-) */ - public function do_login() { - echo "{success: true}"; - } + public function do_login() { + $this->form_validation->set_rules('username', "Benutzername", 'required'); + $this->form_validation->set_rules('password', "Passwort", 'required'); + + if ($this->form_validation->run() == true) { + $remember = (boolean) $this->input->post('remember'); + + if ($this->access->login($this->input->post('username'), $this->input->post('password'), $remember)) { + $this->session->set_flashdata('message', $this->access->messages()); + $return['success'] = true; + } else { // if the login was un-successful + $this->session->set_flashdata('message', $this->access->errors()); + $return['success'] = false; + $return['message'] = "Benutzername oder PW falsch"; + } + } + + $this->output->set_content_type('application/json') + ->set_output(json_encode($return)); + } + + /** + * Logs the user out. + */ + public function logout() { + $logout = $this->access->logout(); + redirect('auth'); + } + + /** + * Allows users to register. + */ + public function register() { + if ($this->access->loggedIn()) { + redirect('welcome'); + } + + // validate form input + $this->form_validation->set_rules('username', "Username", 'required'); + $this->form_validation->set_rules('realname', "Realname", 'required'); + $this->form_validation->set_rules('email', "Email address", 'required|valid_email'); + $this->form_validation->set_rules('password', "Password", 'required|min_length[' . $this->config->item('min_password_length', 'access') . ']|max_length[' . $this->config->item('max_password_length', 'access') . ']|matches[password_confirm]'); + $this->form_validation->set_rules('password_confirm', "Password confirmation", 'required'); + + if ($this->form_validation->run() == true) { + $username = $this->input->post('username'); + $email = $this->input->post('email'); + $password = $this->input->post('password'); + + $additional_data = array( + 'realname' => $this->input->post('realname'), + ); + } + + if ($this->form_validation->run() == true && $this->access->register($username, $password, $email, $additional_data)) { + // redirect them to the login page + $this->session->set_flashdata('message', "Registration successful"); + redirect('auth/register_success'); + } else { + // set the flash data error message if there is one + $this->data['message'] = validation_errors() ? validation_errors() : ($this->access->errors() ? $this->access->errors() : $this->session->flashdata('message')); + $this->data['username'] = $this->form_validation->set_value('username'); + $this->data['email'] = $this->form_validation->set_value('email'); + $this->data['realname'] = $this->form_validation->set_value('realname'); + $this->data['password'] = $this->form_validation->set_value('password'); + $this->data['password_confirm'] = $this->form_validation->set_value('password_confirm'); + $this->load->view('auth/register', $this->data); + } + } + + public function register_success() { + $this->load->view('auth/register_success', $this->data); + } + + //change password + public function change_password() { + $this->form_validation->set_rules('old', 'Old password', 'required'); + $this->form_validation->set_rules('new', 'New Password', 'required|min_length[' . $this->config->item('min_password_length', 'access') . ']|max_length[' . $this->config->item('max_password_length', 'access') . ']|matches[new_confirm]'); + $this->form_validation->set_rules('new_confirm', 'Confirm New Password', 'required'); + + if (!$this->access->loggedIn()) { + redirect('auth/login', 'refresh'); + } + $user = $this->access->get_user($this->session->userdata('user_id')); + + if ($this->form_validation->run() == false) { //display the form + //set the flash data error message if there is one + $this->data['message'] = (validation_errors()) ? validation_errors() : $this->session->flashdata('message'); + + $this->data['old_password'] = array('name' => 'old', + 'id' => 'old', + 'type' => 'password' + ); + $this->data['new_password'] = array('name' => 'new', + 'id' => 'new', + 'type' => 'password' + ); + $this->data['new_password_confirm'] = array('name' => 'new_confirm', + 'id' => 'new_confirm', + 'type' => 'password' + ); + $this->data['user_id'] = array('name' => 'user_id', + 'id' => 'user_id', + 'type' => 'hidden', + 'value' => $user->id + ); + + //render + $this->load->view('auth/change_password', $this->data); + } else { + $username = $this->session->userdata('username'); + + $change = $this->access->change_password($username, $this->input->post('old'), $this->input->post('new')); + + if ($change) { //if the password was successfully changed + $this->session->set_flashdata('message', $this->access->messages()); + $this->logout(); + } else { + $this->session->set_flashdata('message', $this->access->errors()); + redirect('auth/change_password', 'refresh'); + } + } + } + + //forgot password + public function forgot_password() { + $this->form_validation->set_rules('email', 'Email Address', 'required'); + if ($this->form_validation->run() == false) { + //setup the input + $this->data['email'] = array('name' => 'email', + 'id' => 'email', + ); + //set any errors and display the form + $this->data['message'] = (validation_errors()) ? validation_errors() : $this->session->flashdata('message'); + $this->load->view('auth/forgot_password', $this->data); + } else { + //run the forgotten password method to email an activation code to the user + $forgotten = $this->access->forgotten_password($this->input->post('email')); + + if ($forgotten) { //if there were no errors + $this->session->set_flashdata('message', $this->access->messages()); + redirect("auth/login", 'refresh'); //we should display a confirmation page here instead of the login page + } else { + $this->session->set_flashdata('message', $this->access->errors()); + redirect("auth/forgot_password", 'refresh'); + } + } + } + + //reset password - final step for forgotten password + public function reset_password($code) { + $reset = $this->access->forgotten_password_complete($code); + + if ($reset) { //if the reset worked then send them to the login page + $this->session->set_flashdata('message', $this->access->messages()); + redirect('auth/login'); + } else { //if the reset didnt work then send them back to the forgot password page + $this->session->set_flashdata('message', $this->access->errors()); + redirect('auth/forgot_password'); + } + } + + private function _get_csrf_nonce() { + $this->load->helper('string'); + $key = random_string('alnum', 8); + $value = random_string('alnum', 20); + $this->session->set_flashdata('csrfkey', $key); + $this->session->set_flashdata('csrfvalue', $value); + + return array($key => $value); + } + + private function _valid_csrf_nonce() { + if ($this->input->post($this->session->flashdata('csrfkey')) !== false && + $this->input->post($this->session->flashdata('csrfkey')) == $this->session->flashdata('csrfvalue')) { + return true; + } else { + return false; + } + } /** * Logs the user out. diff --git a/application/language/english/auth_lang.php b/application/language/english/auth_lang.php new file mode 100644 index 0000000..5566e5a --- /dev/null +++ b/application/language/english/auth_lang.php @@ -0,0 +1,20 @@ + + */ +class Access { + + /** + * CodeIgniter global + * + * @var string + **/ + protected $ci; + + protected $message_start_delimiter = '

'; + protected $message_end_delimiter = '

'; + protected $error_start_delimiter = '

'; + protected $error_end_delimiter = '

'; + + /** + * message (uses lang file) + * + * @var string + **/ + protected $messages = array(); + + /** + * error message (uses lang file) + * + * @var string + **/ + protected $errors = array(); + + /** + * Constructor. + */ + public function __construct() { + $this->ci =& get_instance(); + $this->ci->load->config('auth', true); + $this->ci->load->library('email'); + $this->ci->lang->load('auth'); + $this->ci->load->model('user'); + $this->ci->load->model('group'); + $this->ci->load->helper('cookie'); + + $this->messages = array(); + $this->errors = array(); + + // auto-login the user if they are remembered + if (!$this->loggedIn() && get_cookie('username') && get_cookie('remember_code')) { + $this->ci->access = $this; + $this->ci->user->loginRememberedUser(); + } + } + + /** + * Changes a users password. + * + * @return boolean + */ + public function changePassword($username, $old, $new) { + if ($this->ci->user->changePassword($username, $old, $new)) { + $this->setMessage('password_change_successful'); + return true; + } + + $this->setError('password_change_unsuccessful'); + return false; + } + + /** + * forgotten password feature + * + * @return void + */ + public function forgottenPassword($username) { + if ($this->ci->user->forgottenPassword($username)) { + // get user information + $user = $this->getUserByUsername($username); + + $data = array( + 'username' => $user['username'], + 'forgotten_password_code' => $user['forgotten_password_code'] + ); + + $message = $this->ci->load->view($this->ci->config->item('email_templates', 'auth') . $this->ci->config->item('email_forgot_password', 'auth'), $data, true); + $this->ci->email->clear(); + $config['mailtype'] = $this->ci->config->item('email_type', 'auth'); + $this->ci->email->initialize($config); + $this->ci->email->set_newline("\r\n"); + $this->ci->email->from($this->ci->config->item('admin_email', 'auth'), 'Scattport'); + $this->ci->email->to($user['email']); + $this->ci->email->subject('Scattport - Forgotten Password Verification'); + $this->ci->email->message($message); + + if ($this->ci->email->send()) { + $this->setMessage('forgot_password_successful'); + return true; + } else { + $this->setError('forgot_password_unsuccessful'); + return false; + } + } else { + $this->setError('forgot_password_unsuccessful'); + return false; + } + } + + /** + * forgotten_password_complete + * + * @return void + */ + public function forgottenPasswordComplete($code) { + $profile = $this->ci->user->profile($code, true); // pass the code to profile + + if (!is_object($profile)) { + $this->setError('password_change_unsuccessful'); + return false; + } + + $new_password = $this->ci->user->forgottenPasswordComplete($code, $profile->salt); + + if ($new_password) { + $data = array( + 'username' => $profile->username, + 'new_password' => $new_password + ); + + $message = $this->ci->load->view($this->ci->config->item('email_templates', 'ion_auth').$this->ci->config->item('email_forgot_password_complete', 'ion_auth'), $data, true); + + $this->ci->email->clear(); + $config['mailtype'] = $this->ci->config->item('email_type', 'ion_auth'); + $this->ci->email->initialize($config); + $this->ci->email->set_newline("\r\n"); + $this->ci->email->from($this->ci->config->item('admin_email', 'ion_auth'), $this->ci->config->item('site_title', 'ion_auth')); + $this->ci->email->to($profile->email); + $this->ci->email->subject($this->ci->config->item('site_title', 'ion_auth') . ' - New Password'); + $this->ci->email->message($message); + + if ($this->ci->email->send()) { + $this->setMessage('password_change_successful'); + return true; + } else { + $this->setError('password_change_unsuccessful'); + return false; + } + } + + $this->setError('password_change_unsuccessful'); + return false; + } + + /** + * Registers a new user. + * + * @return integer|boolean + */ + public function register($username, $password, $email, $additionalData, $groupName = false) { + $id = $this->ci->user->register($username, $password, $email, $additionalData, $groupName); + + if ($id !== false) { + $this->setMessage('account_creation_successful'); + return $id; + } else { + $this->setError('account_creation_unsuccessful'); + return false; + } + } + + /** + * Logs the user in. + * + * @return boolean + */ + public function login($username, $password, $remember = false) { + if ($this->ci->user->login($username, $password, $remember)) { + $this->setMessage('login_successful'); + return true; + } + + $this->setError('login_unsuccessful'); + return false; + } + + /** + * Logs the user out. + * + * @return boolean + */ + public function logout() { + $this->ci->session->unset_userdata('username'); + $this->ci->session->unset_userdata('group'); + $this->ci->session->unset_userdata('user_id'); + + // delete the remember cookies if they exist + if (get_cookie('username')) { + delete_cookie('username'); + } if (get_cookie('remember_code')) { + delete_cookie('remember_code'); + } + + $this->ci->session->sess_destroy(); + + $this->setMessage('logout_successful'); + return true; + } + + /** + * Checks if the user is logged in. + * + * @return boolean + */ + public function loggedIn() { + return (boolean) $this->ci->session->userdata('username'); + } + + /** + * Checks if the user is an admin. + * + * @return boolean + */ + public function isAdmin() { + $adminGroup = 'admins'; + $userGroup = $this->ci->session->userdata('group'); + return $userGroup == $adminGroup; + } + + /** + * Checks if the current user is assigned to the specified group. + * + * @return boolean + */ + public function isGroup($checkGroup) { + $userGroup = $this->ci->session->userdata('group'); + + if (is_array($checkGroup)) { + return in_array($userGroup, $checkGroup); + } + return $userGroup == $checkGroup; + } + + /** + * Gets the profile of the current user. + * + * @return array + */ + public function profile() { + return $this->ci->user->profile($this->ci->session->userdata('username')); + } + + /** + * Updates a specified user. + * + * @return boolean + */ + public function updateUser($id, $data) { + if ($this->ci->user->update($id, $data)) { + $this->setMessage('update_successful'); + return true; + } + + $this->setError('update_unsuccessful'); + return false; + } + + /** + * Deletes a specified user. + * + * @return boolean + */ + public function deleteUser($id) { + if ($this->ci->user->delete($id)) { + $this->setMessage('delete_successful'); + return true; + } + + $this->setError('delete_unsuccessful'); + return false; + } + + /** + * Sets a message. + * + * @return string + */ + public function setMessage($message) { + $this->messages[] = $message; + return $message; + } + + /** + * Gets all messages. + * + * @return void + */ + public function messages() { + $_output = ''; + foreach ($this->messages as $message) { + $_output .= $this->message_start_delimiter . $this->ci->lang->line($message) . $this->message_end_delimiter; + } + + return $_output; + } + + /** + * Sets an error message. + * + * @return void + */ + public function setError($error) { + $this->errors[] = $error; + return $error; + } + + /** + * Gets all error messages. + * + * @return void + */ + public function errors() { + $_output = ''; + foreach ($this->errors as $error) { + $_output .= $this->error_start_delimiter . $this->ci->lang->line($error) . $this->error_end_delimiter; + } + + return $_output; + } + +} + +/* End of file access.php */ +/* Location: ./application/libraries/access.php */ diff --git a/application/models/group.php b/application/models/group.php new file mode 100644 index 0000000..ba0d4e5 --- /dev/null +++ b/application/models/group.php @@ -0,0 +1,49 @@ + + */ +class Group extends CI_Model { + + /** + * Constructor. + */ + public function __construct() { + parent::__construct(); + } + + /** + * get + * + * @return object + */ + public function get() { + return $this->db->get('groups')->result_array(); + } + + /** + * getGroupByID + * + * @return object + */ + public function getGroupByID($id) { + $this->db->where('id', $id); + return $this->db->get('groups')->row_array(); + } + + /** + * getGroupByName + * + * @return object + */ + public function getGroupByName($name) { + $this->db->where('name', $name); + return $this->db->get('groups')->row_array(); + } + +} + +/* End of file group.php */ +/* Location: ./application/controllers/group.php */ diff --git a/application/models/user.php b/application/models/user.php new file mode 100644 index 0000000..1d73ed3 --- /dev/null +++ b/application/models/user.php @@ -0,0 +1,533 @@ + + */ +class User extends CI_Model { + + /** + * Contains the forgotten password key. + * + * @var string + */ + public $forgottenPasswordCode; + + public function __construct() { + parent::__construct(); + $this->load->config('auth', true); + $this->load->helper('cookie'); + $this->load->helper('date'); + + $this->storeSalt = $this->config->item('store_salt', 'auth'); + $this->saltLength = $this->config->item('salt_length', 'auth'); + } + + /** + * Hashes the password to be stored in the database. + * + * @param string $password + * @param boolean $salt + * @return boolean|string + */ + public function hashPassword($password, $salt = false) { + if (empty($password)) { + return false; + } + + if ($this->storeSalt && $salt) { + return sha1($password . $salt); + } else { + $salt = $this->salt(); + return $salt . substr(sha1($salt . $password), 0, -$this->saltLength); + } + } + + /** + * Takes a password and validates it against an entry in the users table. + * + * @param string $username + * @param string $password + * @return boolean|string + */ + public function hashPasswordForDB($username, $password) { + if (empty($username) || empty($password)) { + return false; + } + + $query = $this->db->select('password, salt') + ->where('username', $username)->limit(1)->get('users'); + + $result = $query->row(); + + if ($query->num_rows() !== 1) { + return false; + } + + if ($this->storeSalt) { + return sha1($password . $result->salt); + } else { + $salt = substr($result->password, 0, $this->saltLength); + return $salt . substr(sha1($salt . $password), 0, -$this->saltLength); + } + } + + /** + * Generates a random salt value. + * + * @return string + */ + private function salt() { + return substr(md5(uniqid(rand(), true)), 0, $this->saltLength); + } + + /** + * Changes the password of the given user. + * + * @param string $username + * @param string $old + * @param string $new + * @return boolean + */ + public function changePassword($username, $old, $new) { + $query = $this->db->select('password, salt') + ->where('username', $username)->limit(1)->get('users'); + + $result = $query->row(); + + $dbPassword = $result->password; + $old = $this->hashPasswordForDB($username, $old); + $new = $this->hashPassword($new, $result->salt); + + if ($dbPassword === $old) { + // store the new password and reset the remember code so all remembered instances have to re-login + $data = array('password' => $new, 'remember_code' => ''); + + $this->db->update('users', $data, array('username' => $username)); + + return $this->db->affected_rows() == 1; + } + return false; + } + + /** + * Checks entered usernames. + * + * @return boolean + */ + public function checkUsername($username = '') { + if (empty($username)) { + return false; + } + return $this->db->where('username', $username)->count_all_results('users') > 0; + } + + /** + * Checks entered emails. + * + * @return boolean + */ + public function checkEmail($email = '') { + if (empty($email)) { + return false; + } + return $this->db->where('email', $email)->count_all_results('users') > 0; + } + + /** + * Inserts a forgotten password key. + * + * @return boolean + */ + public function forgottenPassword($email = '') { + if (empty($email)) { + return false; + } + + $key = $this->hashPassword(microtime() . $email); + + $this->forgottenPasswordCode = $key; + + $this->db->update('users', array('forgotten_password_code' => $key), array('email' => $email)); + + return $this->db->affected_rows() == 1; + } + + /** + * Forgotten Password Complete + * + * @return string + */ + public function forgottenPasswordComplete($code, $salt = false) { + if (empty($code)) { + return false; + } + + $this->db->where('forgotten_password_code', $code); + + if ($this->db->count_all_results('users') > 0) { + $password = $this->salt(); + + $data = array( + 'password' => $this->hashPassword($password, $salt), + 'forgotten_password_code' => null + ); + + $this->db->update('users', $data, array('forgotten_password_code' => $code)); + + return $password; + } + return false; + } + + /** + * profile + * + * @return boolean|object + */ + public function profile($username = '', $isCode = false) { + if (empty($username)) { + return false; + } + + $this->db->select('users.*, groups.name AS `group`, groups.description AS `group_description`'); + $this->db->join('groups', 'users.group_id = groups.id', 'left'); + + if ($isCode) { + $this->db->where('users.forgotten_password_code', $username); + } else { + $this->db->where('users.username', $username); + } + + $query = $this->db->limit(1)->get('users'); + + return $query->num_rows > 0 ? $query->row() : false; + } + + /** + * register + * + * @return boolean + */ + public function register($username, $password, $email, $additionalData = false, $groupName = false) { + if ($this->username_check($username)) { + $this->access->setError('account_creation_duplicate_username'); + return false; + } + + // if a groupID was passed, use it + if (isset($additional_data['group_id'])) { + $groupID = $additional_data['group_id']; + unset($additional_data['group_id']); + } else { // otherwise get default groupID + $groupName = !$groupName ? 'users' : $groupName; + $groupID = $this->db->select('id')->where('name', $groupName)->get('groups')->row()->id; + } + + // IP Address + $ipAddress = $this->input->ip_address(); + $salt = $this->storeSalt ? $this->salt() : false; + $password = $this->hashPassword($password, $salt); + + // Users table. + $data = array( + 'username' => $username, + 'password' => $password, + 'email' => $email, + 'group_id' => $groupID, + 'last_login' => now(), + ); + + if ($this->storeSalt) { + $data['salt'] = $salt; + } + + $this->db->insert('users', $data); + $id = $this->db->insert_id(); + + return $this->db->affected_rows() > 0 ? $id : false; + } + + /** + * login + * + * @return boolean + */ + public function login($username, $password, $remember = false) { + if (empty($username) || empty($password) || !$this->checkUsername($username)) { + return false; + } + + $query = $this->db->select('id, username, password, group_id') + ->where('username', $username)->limit(1)->get('users'); + + $result = $query->row(); + + if ($query->num_rows() == 1) { + $password = $this->hashPasswordForDB($username, $password); + + if ($result->password === $password) { + $this->updateLastLogin($result->id); + + $group = $this->db->select('name')->where('id', $result->group_id)->get('groups')->row(); + + $session_data = array( + 'username' => $result->username, + 'id' => $result->id, // kept for backwards compatibility + 'user_id' => $result->id, + 'group_id' => $result->group_id, + 'group' => $group->name + ); + + $this->session->set_userdata($session_data); + + if ($remember && $this->config->item('remember_users', 'auth')) { + $this->rememberUser($result->id); + } + return true; + } + } + return false; + } + + /** + * get + * + * @return object + */ + public function get($group = false, $limit = null, $offset = null) { + $this->db->select('users.*, groups.name AS `group`, groups.description AS `group_description`'); + $this->db->join('groups', 'users.group_id = groups.id', 'left'); + + if (is_string($group)) { + $this->db->where('groups.name', $group); + } else if (is_array($group)) { + $this->db->where_in('groups.name', $group); + } + + if (isset($limit) && isset($offset)) { + $this->db->limit($limit, $offset); + } + return $this->db->get('users'); + } + + /** + * Returns the number of users. + * + * @return integer The number of users + */ + public function count($group = false) { + if (is_string($group)) { + $this->db->where('groups.name', $group); + } else if (is_array($group)) { + $this->db->where_in('groups.name', $group); + } + return $this->db->from('users')->count_all_results(); + } + + /** + * getUserByID + * + * @return object + */ + public function getUserByID($id = false) { + // if no ID was passed use the current users ID + if (empty($id)) { + $id = $this->session->userdata('user_id'); + } + + $this->db->where('users.id', $id); + $this->db->limit(1); + + return $this->get(); + } + + /** + * getUserByEmail + * + * @return object + */ + public function getUserByEmail($email) { + $this->db->where('users.email', $email); + $this->db->limit(1); + return $this->get(); + } + + /** + * getUserByUsername + * + * @return object + */ + public function getUserByUsername($username) { + $this->db->where('users.username', $username); + $this->db->limit(1); + return $this->get(); + } + + /** + * getNewestUsers + * + * @return object + */ + public function getNewestUsers($limit = 10) { + $this->db->order_by('users.created_on DESC'); + $this->db->limit($limit); + return $this->get(); + } + + /** + * getUsersGroup + * + * @return object + */ + public function getUsersGroup($id = false) { + // if no ID was passed use the current users ID + $id || $id = $this->session->userdata('user_id'); + + $user = $this->db->select('group_id')->where('id', $id)->get('users') + ->row(); + + return $this->db->select('name, description') + ->where('id', $user->group_id)->get('groups')->row(); + } + + /** + * update + * + * @return boolean + */ + public function update($id, $data) { + $user = $this->get_user($id)->row(); + + $this->db->trans_begin(); + + if (array_key_exists('username', $data) && $this->username_check($data['username']) && $user->username !== $data['username']) { + $this->db->trans_rollback(); + $this->access->setError('account_creation_duplicate_username'); + return false; + } + + if (array_key_exists('username', $data) || array_key_exists('password', $data) || array_key_exists('email', $data)) { + if (array_key_exists('password', $data)) { + $data['password'] = $this->hashPassword($data['password'], $user->salt); + } + + $this->db->update('users', $data, array('id' => $id)); + } + + if ($this->db->trans_status() === false) { + $this->db->trans_rollback(); + return false; + } + + $this->db->trans_commit(); + return true; + } + + /** + * delete + * + * @return boolean + */ + public function delete($id) { + $this->db->trans_begin(); + + $this->db->delete('users', array('id' => $id)); + + if ($this->db->trans_status() === false) { + $this->db->trans_rollback(); + return false; + } + + $this->db->trans_commit(); + return true; + } + + /** + * updateLastLogin + * + * @return boolean + */ + public function updateLastLogin($id) { + $this->db->update('users', array('last_login' => now()), array('id' => $id)); + return $this->db->affected_rows() == 1; + } + + /** + * loginRemembedUser + * + * @return boolean + */ + public function loginRememberedUser() { + if (!get_cookie('username') || !get_cookie('remember_code') || !$this->username_check(get_cookie('username'))) { + return false; + } + + $query = $this->db->select('id, username, group_id') + ->where('username', get_cookie('username')) + ->where('remember_code', get_cookie('remember_code'))->limit(1) + ->get('users'); + + if ($query->num_rows() == 1) { + $user = $query->row(); + + $this->updateLastLogin($user->id); + + $group = $this->db->select('name')->where('id', $user->group_id) + ->get('groups')->row(); + + $session_data = array( + 'username' => $user->username, + 'user_id' => $user->id, + 'group_id' => $user->group_id, + 'group' => $group->name + ); + + $this->session->set_userdata($session_data); + + // extend the users cookies if the option is enabled + if ($this->config->item('user_extend_on_login', 'auth')) { + $this->rememberUser($user->id); + } + return true; + } + return false; + } + + /** + * rememberUser + * + * @return boolean + */ + private function rememberUser($id) { + if (!$id) { + return false; + } + + $user = $this->getUserByID($id)->row(); + + $salt = sha1($user->password); + + $this->db->update('users', array('remember_code' => $salt), array('id' => $id)); + + if ($this->db->affected_rows() > -1) { + set_cookie(array( + 'name' => 'username', + 'value' => $user->username, + 'expire' => $this->config->item('user_expire', 'auth'), + )); + set_cookie(array( + 'name' => 'remember_code', + 'value' => $salt, + 'expire' => $this->config->item('user_expire', 'auth'), + )); + return true; + } + return false; + } + +} + +/* End of file user.php */ +/* Location: ./application/models/user.php */ diff --git a/application/views/auth/login.php b/application/views/auth/login.php index d60b6fc..4575be2 100755 --- a/application/views/auth/login.php +++ b/application/views/auth/login.php @@ -1,48 +1,64 @@ -load->view('header'); ?> + + + + Scattport + + + + + + + + + + + + + -load->view('footer'); ?> + + diff --git a/application/views/header.php b/application/views/header.php index eb12c08..3565854 100644 --- a/application/views/header.php +++ b/application/views/header.php @@ -10,17 +10,11 @@ - + diff --git a/assets/js/common.js b/assets/js/common.js new file mode 100644 index 0000000..481e9a0 --- /dev/null +++ b/assets/js/common.js @@ -0,0 +1,23 @@ +/** + * Shows a message box with given the title and message. + * + * @param {} title + * @param {} message + */ +var message = function(title, message, icon) { + Ext.Msg.show({ + title: title, + msg: message, + minWidth: 200, + modal: true, + icon: Ext.Msg.ERROR, + buttons: Ext.Msg.OK + }); +} + +/** + * Initialize tooltips. + */ +$(document).ready(function() { + Ext.QuickTips.init(); +});