2012-11-09 12:18:50 +00:00
|
|
|
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
2010-08-21 04:43:03 +00:00
|
|
|
/**
|
|
|
|
* ORM Auth driver.
|
|
|
|
*
|
|
|
|
* @package Kohana/Auth
|
|
|
|
* @author Kohana Team
|
2012-11-09 12:18:50 +00:00
|
|
|
* @copyright (c) 2007-2012 Kohana Team
|
2011-05-13 06:00:25 +00:00
|
|
|
* @license http://kohanaframework.org/license
|
2010-08-21 04:43:03 +00:00
|
|
|
*/
|
|
|
|
class Kohana_Auth_ORM extends Auth {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if a session is active.
|
|
|
|
*
|
2011-05-13 06:00:25 +00:00
|
|
|
* @param mixed $role Role name string, role ORM object, or array with role names
|
2010-08-21 04:43:03 +00:00
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public function logged_in($role = NULL)
|
|
|
|
{
|
|
|
|
// Get the user from the session
|
|
|
|
$user = $this->get_user();
|
|
|
|
|
2011-05-13 06:00:25 +00:00
|
|
|
if ( ! $user)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if ($user instanceof Model_User AND $user->loaded())
|
2010-08-21 04:43:03 +00:00
|
|
|
{
|
2011-05-13 06:00:25 +00:00
|
|
|
// If we don't have a roll no further checking is needed
|
|
|
|
if ( ! $role)
|
|
|
|
return TRUE;
|
2010-08-21 04:43:03 +00:00
|
|
|
|
2011-05-13 06:00:25 +00:00
|
|
|
if (is_array($role))
|
2010-08-21 04:43:03 +00:00
|
|
|
{
|
2011-05-13 06:00:25 +00:00
|
|
|
// Get all the roles
|
2012-11-09 12:18:50 +00:00
|
|
|
$roles = ORM::factory('Role')
|
2011-05-13 06:00:25 +00:00
|
|
|
->where('name', 'IN', $role)
|
|
|
|
->find_all()
|
|
|
|
->as_array(NULL, 'id');
|
|
|
|
|
|
|
|
// Make sure all the roles are valid ones
|
|
|
|
if (count($roles) !== count($role))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( ! is_object($role))
|
2010-08-21 04:43:03 +00:00
|
|
|
{
|
2011-05-13 06:00:25 +00:00
|
|
|
// Load the role
|
2012-11-09 12:18:50 +00:00
|
|
|
$roles = ORM::factory('Role', array('name' => $role));
|
2011-05-13 06:00:25 +00:00
|
|
|
|
|
|
|
if ( ! $roles->loaded())
|
|
|
|
return FALSE;
|
2010-08-21 04:43:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-13 06:00:25 +00:00
|
|
|
return $user->has('roles', $roles);
|
|
|
|
}
|
2010-08-21 04:43:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Logs a user in.
|
|
|
|
*
|
2012-11-09 12:18:50 +00:00
|
|
|
* @param string $username
|
|
|
|
* @param string $password
|
|
|
|
* @param boolean $remember enable autologin
|
2010-08-21 04:43:03 +00:00
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
protected function _login($user, $password, $remember)
|
|
|
|
{
|
|
|
|
if ( ! is_object($user))
|
|
|
|
{
|
|
|
|
$username = $user;
|
|
|
|
|
|
|
|
// Load the user
|
2012-11-09 12:18:50 +00:00
|
|
|
$user = ORM::factory('User');
|
2010-08-21 04:43:03 +00:00
|
|
|
$user->where($user->unique_key($username), '=', $username)->find();
|
|
|
|
}
|
|
|
|
|
2012-11-09 12:18:50 +00:00
|
|
|
if (is_string($password))
|
|
|
|
{
|
|
|
|
// Create a hashed password
|
|
|
|
$password = $this->hash($password);
|
|
|
|
}
|
|
|
|
|
2010-08-21 04:43:03 +00:00
|
|
|
// If the passwords match, perform a login
|
2012-11-09 12:18:50 +00:00
|
|
|
if ($user->has('roles', ORM::factory('Role', array('name' => 'login'))) AND $user->password === $password)
|
2010-08-21 04:43:03 +00:00
|
|
|
{
|
|
|
|
if ($remember === TRUE)
|
|
|
|
{
|
2011-05-13 06:00:25 +00:00
|
|
|
// Token data
|
|
|
|
$data = array(
|
2012-11-09 12:18:50 +00:00
|
|
|
'user_id' => $user->pk(),
|
2011-05-13 06:00:25 +00:00
|
|
|
'expires' => time() + $this->_config['lifetime'],
|
|
|
|
'user_agent' => sha1(Request::$user_agent),
|
|
|
|
);
|
2010-08-21 04:43:03 +00:00
|
|
|
|
2011-05-13 06:00:25 +00:00
|
|
|
// Create a new autologin token
|
2012-11-09 12:18:50 +00:00
|
|
|
$token = ORM::factory('User_Token')
|
2011-05-13 06:00:25 +00:00
|
|
|
->values($data)
|
|
|
|
->create();
|
2010-08-21 04:43:03 +00:00
|
|
|
|
|
|
|
// Set the autologin cookie
|
|
|
|
Cookie::set('authautologin', $token->token, $this->_config['lifetime']);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finish the login
|
|
|
|
$this->complete_login($user);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Login failed
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Forces a user to be logged in, without specifying a password.
|
|
|
|
*
|
2012-11-09 12:18:50 +00:00
|
|
|
* @param mixed $user username string, or user ORM object
|
|
|
|
* @param boolean $mark_session_as_forced mark the session as forced
|
2010-08-21 04:43:03 +00:00
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public function force_login($user, $mark_session_as_forced = FALSE)
|
|
|
|
{
|
|
|
|
if ( ! is_object($user))
|
|
|
|
{
|
|
|
|
$username = $user;
|
|
|
|
|
|
|
|
// Load the user
|
2012-11-09 12:18:50 +00:00
|
|
|
$user = ORM::factory('User');
|
2010-08-21 04:43:03 +00:00
|
|
|
$user->where($user->unique_key($username), '=', $username)->find();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($mark_session_as_forced === TRUE)
|
|
|
|
{
|
|
|
|
// Mark the session as forced, to prevent users from changing account information
|
|
|
|
$this->_session->set('auth_forced', TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run the standard completion
|
|
|
|
$this->complete_login($user);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Logs a user in, based on the authautologin cookie.
|
|
|
|
*
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
public function auto_login()
|
|
|
|
{
|
|
|
|
if ($token = Cookie::get('authautologin'))
|
|
|
|
{
|
|
|
|
// Load the token and user
|
2012-11-09 12:18:50 +00:00
|
|
|
$token = ORM::factory('User_Token', array('token' => $token));
|
2010-08-21 04:43:03 +00:00
|
|
|
|
|
|
|
if ($token->loaded() AND $token->user->loaded())
|
|
|
|
{
|
|
|
|
if ($token->user_agent === sha1(Request::$user_agent))
|
|
|
|
{
|
|
|
|
// Save the token to create a new unique token
|
|
|
|
$token->save();
|
|
|
|
|
|
|
|
// Set the new token
|
|
|
|
Cookie::set('authautologin', $token->token, $token->expires - time());
|
|
|
|
|
|
|
|
// Complete the login with the found data
|
|
|
|
$this->complete_login($token->user);
|
|
|
|
|
|
|
|
// Automatic login was successful
|
|
|
|
return $token->user;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Token is invalid
|
|
|
|
$token->delete();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the currently logged in user from the session (with auto_login check).
|
2012-11-09 12:18:50 +00:00
|
|
|
* Returns $default if no user is currently logged in.
|
2010-08-21 04:43:03 +00:00
|
|
|
*
|
2012-11-09 12:18:50 +00:00
|
|
|
* @param mixed $default to return in case user isn't logged in
|
2010-08-21 04:43:03 +00:00
|
|
|
* @return mixed
|
|
|
|
*/
|
2011-05-13 06:00:25 +00:00
|
|
|
public function get_user($default = NULL)
|
2010-08-21 04:43:03 +00:00
|
|
|
{
|
2011-05-13 06:00:25 +00:00
|
|
|
$user = parent::get_user($default);
|
2010-08-21 04:43:03 +00:00
|
|
|
|
2012-11-09 12:18:50 +00:00
|
|
|
if ($user === $default)
|
2010-08-21 04:43:03 +00:00
|
|
|
{
|
|
|
|
// check for "remembered" login
|
2012-11-09 12:18:50 +00:00
|
|
|
if (($user = $this->auto_login()) === FALSE)
|
|
|
|
return $default;
|
2010-08-21 04:43:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $user;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Log a user out and remove any autologin cookies.
|
|
|
|
*
|
2012-11-09 12:18:50 +00:00
|
|
|
* @param boolean $destroy completely destroy the session
|
|
|
|
* @param boolean $logout_all remove all tokens for user
|
2010-08-21 04:43:03 +00:00
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public function logout($destroy = FALSE, $logout_all = FALSE)
|
|
|
|
{
|
|
|
|
// Set by force_login()
|
|
|
|
$this->_session->delete('auth_forced');
|
|
|
|
|
|
|
|
if ($token = Cookie::get('authautologin'))
|
|
|
|
{
|
|
|
|
// Delete the autologin cookie to prevent re-login
|
|
|
|
Cookie::delete('authautologin');
|
|
|
|
|
|
|
|
// Clear the autologin token from the database
|
2012-11-09 12:18:50 +00:00
|
|
|
$token = ORM::factory('User_Token', array('token' => $token));
|
2010-08-21 04:43:03 +00:00
|
|
|
|
|
|
|
if ($token->loaded() AND $logout_all)
|
|
|
|
{
|
2012-11-09 12:18:50 +00:00
|
|
|
// Delete all user tokens. This isn't the most elegant solution but does the job
|
|
|
|
$tokens = ORM::factory('User_Token')->where('user_id','=',$token->user_id)->find_all();
|
|
|
|
|
|
|
|
foreach ($tokens as $_token)
|
|
|
|
{
|
|
|
|
$_token->delete();
|
|
|
|
}
|
2010-08-21 04:43:03 +00:00
|
|
|
}
|
|
|
|
elseif ($token->loaded())
|
|
|
|
{
|
|
|
|
$token->delete();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::logout($destroy);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the stored password for a username.
|
|
|
|
*
|
2012-11-09 12:18:50 +00:00
|
|
|
* @param mixed $user username string, or user ORM object
|
2010-08-21 04:43:03 +00:00
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function password($user)
|
|
|
|
{
|
|
|
|
if ( ! is_object($user))
|
|
|
|
{
|
|
|
|
$username = $user;
|
|
|
|
|
|
|
|
// Load the user
|
2012-11-09 12:18:50 +00:00
|
|
|
$user = ORM::factory('User');
|
2010-08-21 04:43:03 +00:00
|
|
|
$user->where($user->unique_key($username), '=', $username)->find();
|
|
|
|
}
|
|
|
|
|
|
|
|
return $user->password;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Complete the login for a user by incrementing the logins and setting
|
|
|
|
* session data: user_id, username, roles.
|
|
|
|
*
|
2012-11-09 12:18:50 +00:00
|
|
|
* @param object $user user ORM object
|
2010-08-21 04:43:03 +00:00
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
protected function complete_login($user)
|
|
|
|
{
|
|
|
|
$user->complete_login();
|
|
|
|
|
|
|
|
return parent::complete_login($user);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Compare password with original (hashed). Works for current (logged in) user
|
|
|
|
*
|
|
|
|
* @param string $password
|
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public function check_password($password)
|
|
|
|
{
|
|
|
|
$user = $this->get_user();
|
|
|
|
|
2011-05-13 06:00:25 +00:00
|
|
|
if ( ! $user)
|
2010-08-21 04:43:03 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2011-05-13 06:00:25 +00:00
|
|
|
return ($this->hash($password) === $user->password);
|
2010-08-21 04:43:03 +00:00
|
|
|
}
|
|
|
|
|
2012-11-09 12:18:50 +00:00
|
|
|
} // End Auth ORM
|