/fuel/packages/auth/classes/auth/login/simpleauth.php
PHP | 542 lines | 343 code | 65 blank | 134 comment | 38 complexity | aa5653372736aec6ca93c0ee77b25332 MD5 | raw file
Possible License(s): MIT
- <?php
- /**
- * Fuel is a fast, lightweight, community driven PHP5 framework.
- *
- * @package Fuel
- * @version 1.0
- * @author Fuel Development Team
- * @license MIT License
- * @copyright 2010 - 2011 Fuel Development Team
- * @link http://fuelphp.com
- */
- namespace Auth;
- class SimpleUserUpdateException extends \FuelException {}
- class SimpleUserWrongPassword extends \FuelException {}
- /**
- * SimpleAuth basic login driver
- *
- * @package Fuel
- * @subpackage Auth
- */
- class Auth_Login_SimpleAuth extends \Auth_Login_Driver
- {
- public static function _init()
- {
- \Config::load('simpleauth', true, true, true);
- }
- /**
- * @var Database_Result when login succeeded
- */
- protected $user = null;
- /**
- * @var array value for guest login
- */
- protected static $guest_login = array(
- 'id' => 0,
- 'username' => 'guest',
- 'group' => '0',
- 'login_hash' => false,
- 'email' => false
- );
- /**
- * @var array SimpleAuth class config
- */
- protected $config = array(
- 'drivers' => array('group' => array('SimpleGroup')),
- 'additional_fields' => array('profile_fields'),
- );
- /**
- * Check for login
- *
- * @return bool
- */
- protected function perform_check()
- {
- $username = \Session::get('username');
- $login_hash = \Session::get('login_hash');
- // only worth checking if there's both a username and login-hash
- if ( ! empty($username) and ! empty($login_hash))
- {
- if (is_null($this->user) or ($this->user['username'] != $username and $this->user != static::$guest_login))
- {
- $this->user = \DB::select_array(\Config::get('simpleauth.table_columns', array('*')))
- ->where('username', '=', $username)
- ->from(\Config::get('simpleauth.table_name'))
- ->execute(\Config::get('simpleauth.db_connection'))->current();
- }
- // return true when login was verified
- if ($this->user and $this->user['login_hash'] === $login_hash)
- {
- return true;
- }
- }
- // no valid login when still here, ensure empty session and optionally set guest_login
- $this->user = \Config::get('simpleauth.guest_login', true) ? static::$guest_login : false;
- \Session::delete('username');
- \Session::delete('login_hash');
- return false;
- }
- /**
- * Check the user exists before logging in
- *
- * @return bool
- */
- public function validate_user($username_or_email = '', $password = '')
- {
- $username_or_email = trim($username_or_email) ?: trim(\Input::post(\Config::get('simpleauth.username_post_key', 'username')));
- $password = trim($password) ?: trim(\Input::post(\Config::get('simpleauth.password_post_key', 'password')));
- if (empty($username_or_email) or empty($password))
- {
- return false;
- }
- $password = $this->hash_password($password);
- $this->user = \DB::select_array(\Config::get('simpleauth.table_columns', array('*')))
- ->where_open()
- ->where('username', '=', $username_or_email)
- ->or_where('email', '=', $username_or_email)
- ->where_close()
- ->where('password', '=', $password)
- ->from(\Config::get('simpleauth.table_name'))
- ->execute(\Config::get('simpleauth.db_connection'))->current();
- return $this->user ?: false;
- }
- /**
- * Login user
- *
- * @param string
- * @param string
- * @return bool
- */
- public function login($username_or_email = '', $password = '')
- {
- if ( ! ($this->user = $this->validate_user($username_or_email, $password)))
- {
- $this->user = \Config::get('simpleauth.guest_login', true) ? static::$guest_login : false;
- \Session::delete('username');
- \Session::delete('login_hash');
- return false;
- }
- \Session::set('username', $this->user['username']);
- \Session::set('login_hash', $this->create_login_hash());
- \Session::instance()->rotate();
- return true;
- }
- /**
- * Force login user
- *
- * @param string
- * @return bool
- */
- public function force_login($user_id = '')
- {
- if (empty($user_id))
- {
- return false;
- }
- $this->user = \DB::select_array(\Config::get('simpleauth.table_columns', array('*')))
- ->where_open()
- ->where('id', '=', $user_id)
- ->where_close()
- ->from(\Config::get('simpleauth.table_name'))
- ->execute(\Config::get('simpleauth.db_connection'))
- ->current();
- if ($this->user == false)
- {
- $this->user = \Config::get('simpleauth.guest_login', true) ? static::$guest_login : false;
- \Session::delete('username');
- \Session::delete('login_hash');
- return false;
- }
- \Session::set('username', $this->user['username']);
- \Session::set('login_hash', $this->create_login_hash());
- return true;
- }
- /**
- * Logout user
- *
- * @return bool
- */
- public function logout()
- {
- $this->user = \Config::get('simpleauth.guest_login', true) ? static::$guest_login : false;
- \Session::delete('username');
- \Session::delete('login_hash');
- return true;
- }
- /**
- * Create new user
- *
- * @param string
- * @param string
- * @param string must contain valid email address
- * @param int group id
- * @param Array
- * @return bool
- */
- public function create_user($username, $password, $email, $group = 1, Array $profile_fields = array())
- {
- $password = trim($password);
- $email = filter_var(trim($email), FILTER_VALIDATE_EMAIL);
- if (empty($username) or empty($password) or empty($email))
- {
- throw new \SimpleUserUpdateException('Username, password or email address is not given, or email address is invalid', 1);
- }
- $same_users = \DB::select_array(\Config::get('simpleauth.table_columns', array('*')))
- ->where('username', '=', $username)
- ->or_where('email', '=', $email)
- ->from(\Config::get('simpleauth.table_name'))
- ->execute(\Config::get('simpleauth.db_connection'));
- if ($same_users->count() > 0)
- {
- if (in_array(strtolower($email), array_map('strtolower', $same_users->current())))
- {
- throw new \SimpleUserUpdateException('Email address already exists', 2);
- }
- else
- {
- throw new \SimpleUserUpdateException('Username already exists', 3);
- }
- }
- $user = array(
- 'username' => (string) $username,
- 'password' => $this->hash_password((string) $password),
- 'email' => $email,
- 'group' => (int) $group,
- 'profile_fields' => serialize($profile_fields),
- 'last_login' => 0,
- 'login_hash' => '',
- 'created_at' => \Date::forge()->get_timestamp()
- );
- $result = \DB::insert(\Config::get('simpleauth.table_name'))
- ->set($user)
- ->execute(\Config::get('simpleauth.db_connection'));
- return ($result[1] > 0) ? $result[0] : false;
- }
- /**
- * Update a user's properties
- * Note: Username cannot be updated, to update password the old password must be passed as old_password
- *
- * @param Array properties to be updated including profile fields
- * @param string
- * @return bool
- */
- public function update_user($values, $username = null)
- {
- $username = $username ?: $this->user['username'];
- $current_values = \DB::select_array(\Config::get('simpleauth.table_columns', array('*')))
- ->where('username', '=', $username)
- ->from(\Config::get('simpleauth.table_name'))
- ->execute(\Config::get('simpleauth.db_connection'));
- if (empty($current_values))
- {
- throw new \SimpleUserUpdateException('Username not found', 4);
- }
- $update = array();
- if (array_key_exists('username', $values))
- {
- throw new \SimpleUserUpdateException('Username cannot be changed.', 5);
- }
- if (array_key_exists('password', $values))
- {
- if (empty($values['old_password'])
- or $current_values->get('password') != $this->hash_password(trim($values['old_password'])))
- {
- throw new \SimpleUserWrongPassword('Old password is invalid');
- }
- $password = trim(strval($values['password']));
- if ($password === '')
- {
- throw new \SimpleUserUpdateException('Password can\'t be empty.', 6);
- }
- $update['password'] = $this->hash_password($password);
- unset($values['password']);
- }
- if (array_key_exists('old_password', $values))
- {
- unset($values['old_password']);
- }
- if (array_key_exists('email', $values))
- {
- $email = filter_var(trim($values['email']), FILTER_VALIDATE_EMAIL);
- if ( ! $email)
- {
- throw new \SimpleUserUpdateException('Email address is not valid', 7);
- }
- $update['email'] = $email;
- unset($values['email']);
- }
- if (array_key_exists('group', $values))
- {
- if (is_numeric($values['group']))
- {
- $update['group'] = (int) $values['group'];
- }
- unset($values['group']);
- }
- if ( ! empty($values))
- {
- $profile_fields = @unserialize($current_values->get('profile_fields')) ?: array();
- foreach ($values as $key => $val)
- {
- if ($val === null)
- {
- unset($profile_fields[$key]);
- }
- else
- {
- $profile_fields[$key] = $val;
- }
- }
- $update['profile_fields'] = serialize($profile_fields);
- }
- $affected_rows = \DB::update(\Config::get('simpleauth.table_name'))
- ->set($update)
- ->where('username', '=', $username)
- ->execute(\Config::get('simpleauth.db_connection'));
- // Refresh user
- if ($this->user['username'] == $username)
- {
- $this->user = \DB::select_array(\Config::get('simpleauth.table_columns', array('*')))
- ->where('username', '=', $username)
- ->from(\Config::get('simpleauth.table_name'))
- ->execute(\Config::get('simpleauth.db_connection'))->current();
- }
- return $affected_rows > 0;
- }
- /**
- * Change a user's password
- *
- * @param string
- * @param string
- * @param string username or null for current user
- * @return bool
- */
- public function change_password($old_password, $new_password, $username = null)
- {
- try
- {
- return (bool) $this->update_user(array('old_password' => $old_password, 'password' => $new_password), $username);
- }
- // Only catch the wrong password exception
- catch (SimpleUserWrongPassword $e)
- {
- return false;
- }
- }
- /**
- * Generates new random password, sets it for the given username and returns the new password.
- * To be used for resetting a user's forgotten password, should be emailed afterwards.
- *
- * @param string $username
- * @return string
- */
- public function reset_password($username)
- {
- $new_password = \Str::random('alnum', 8);
- $password_hash = $this->hash_password($new_password);
- $affected_rows = \DB::update(\Config::get('simpleauth.table_name'))
- ->set(array('password' => $password_hash))
- ->where('username', '=', $username)
- ->execute(\Config::get('simpleauth.db_connection'));
- if ( ! $affected_rows)
- {
- throw new \SimpleUserUpdateException('Failed to reset password, user was invalid.', 8);
- }
- return $new_password;
- }
- /**
- * Deletes a given user
- *
- * @param string
- * @return bool
- */
- public function delete_user($username)
- {
- if (empty($username))
- {
- throw new \SimpleUserUpdateException('Cannot delete user with empty username', 9);
- }
- $affected_rows = \DB::delete(\Config::get('simpleauth.table_name'))
- ->where('username', '=', $username)
- ->execute(\Config::get('simpleauth.db_connection'));
- return $affected_rows > 0;
- }
- /**
- * Creates a temporary hash that will validate the current login
- *
- * @return string
- */
- public function create_login_hash()
- {
- if (empty($this->user))
- {
- throw new \SimpleUserUpdateException('User not logged in, can\'t create login hash.', 10);
- }
- $last_login = \Date::forge()->get_timestamp();
- $login_hash = sha1(\Config::get('simpleauth.login_hash_salt').$this->user['username'].$last_login);
- \DB::update(\Config::get('simpleauth.table_name'))
- ->set(array('last_login' => $last_login, 'login_hash' => $login_hash))
- ->where('username', '=', $this->user['username'])
- ->execute(\Config::get('simpleauth.db_connection'));
- $this->user['login_hash'] = $login_hash;
- return $login_hash;
- }
- /**
- * Get the user's ID
- *
- * @return Array containing this driver's ID & the user's ID
- */
- public function get_user_id()
- {
- if (empty($this->user))
- {
- return false;
- }
- return array($this->id, (int) $this->user['id']);
- }
- /**
- * Get the user's groups
- *
- * @return Array containing the group driver ID & the user's group ID
- */
- public function get_groups()
- {
- if (empty($this->user))
- {
- return false;
- }
- return array(array('SimpleGroup', $this->user['group']));
- }
- /**
- * Get the user's emailaddress
- *
- * @return string
- */
- public function get_email()
- {
- if (empty($this->user))
- {
- return false;
- }
- return $this->user['email'];
- }
- /**
- * Get the user's screen name
- *
- * @return string
- */
- public function get_screen_name()
- {
- if (empty($this->user))
- {
- return false;
- }
- return $this->user['username'];
- }
- /**
- * Get the user's profile fields
- *
- * @return Array
- */
- public function get_profile_fields($field = null, $default = null)
- {
- if (empty($this->user))
- {
- return false;
- }
- if (isset($this->user['profile_fields']))
- {
- is_array($this->user['profile_fields']) or $this->user['profile_fields'] = @unserialize($this->user['profile_fields']);
- }
- else
- {
- $this->user['profile_fields'] = array();
- }
- return is_null($field) ? $this->user['profile_fields'] : \Arr::get($this->user['profile_fields'], $field, $default);
- }
- /**
- * Extension of base driver method to default to user group instead of user id
- */
- public function has_access($condition, $driver = null, $user = null)
- {
- if (is_null($user))
- {
- $groups = $this->get_groups();
- $user = reset($groups);
- }
- return parent::has_access($condition, $driver, $user);
- }
- /**
- * Extension of base driver because this supports a guest login when switched on
- */
- public function guest_login()
- {
- return \Config::get('simpleauth.guest_login', true);
- }
- }
- // end of file simpleauth.php