2010-11-29 22:41:08 +00:00
|
|
|
<?php defined('SYSPATH') or die('No direct access allowed.');
|
|
|
|
|
|
|
|
/**
|
|
|
|
* OSB Auth driver.
|
|
|
|
*
|
|
|
|
* @package OSB
|
|
|
|
* @subpackage Account
|
|
|
|
* @category Auth
|
|
|
|
* @author Deon George
|
|
|
|
* @copyright (c) 2010 Deon George
|
|
|
|
* @license http://dev.leenooks.net/license.html
|
|
|
|
*/
|
|
|
|
class Auth_OSB extends Auth_ORM {
|
|
|
|
/**
|
|
|
|
* OSB authentication is controlled via database queries.
|
|
|
|
*
|
|
|
|
* This method can be used to test two situations:
|
|
|
|
* 1) Is the user logged in? ($role == FALSE)
|
|
|
|
* 2) Can the user run the current controller->action ($role == TRUE)
|
|
|
|
*
|
|
|
|
* @param boolean If authentication should be done for this module:method (ie: controller:action).
|
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public function logged_in($role = NULL, $debug = NULL) {
|
|
|
|
$status = FALSE;
|
|
|
|
|
|
|
|
// Get the user from the session
|
|
|
|
$user = $this->get_user(FALSE);
|
|
|
|
|
|
|
|
// If we are not a valid user object, then we are not logged in
|
|
|
|
if (is_object($user) AND $user instanceof Model_Account AND $user->loaded()) {
|
|
|
|
|
|
|
|
if (Config::sitemode() == Kohana::DEVELOPMENT && Kohana::config('config.site_debug'))
|
|
|
|
SystemMessage::add(array('title'=>'Debug','type'=>'debug','body'=>Kohana::debug(array('user'=>$user->username,'r'=>$role))));
|
|
|
|
|
|
|
|
if (! empty($role)) {
|
|
|
|
// Get the module details
|
2011-05-14 07:35:33 +00:00
|
|
|
$module = ORM::factory('module',array('name'=>Request::current()->controller()));
|
2010-11-29 22:41:08 +00:00
|
|
|
if (! $module->loaded() OR ! $module->status) {
|
|
|
|
SystemMessage::add(array(
|
|
|
|
'title'=>'Module is not defined or active in the Database',
|
|
|
|
'type'=>'warning',
|
2011-05-14 07:35:33 +00:00
|
|
|
'body'=>sprintf('Module not defined: %s',Request::current()->controller()),
|
2010-11-29 22:41:08 +00:00
|
|
|
));
|
|
|
|
|
|
|
|
} else {
|
2011-05-14 07:35:33 +00:00
|
|
|
if (Request::current()->directory())
|
|
|
|
$method_name = sprintf('%s_%s',Request::current()->directory(),Request::current()->action());
|
2010-11-29 22:41:08 +00:00
|
|
|
else
|
2011-05-14 07:35:33 +00:00
|
|
|
$method_name = Request::current()->action();
|
2010-11-29 22:41:08 +00:00
|
|
|
|
|
|
|
// Get the method number
|
|
|
|
$method = ORM::factory('module_method',array('module_id'=>$module->id,'name'=>$method_name));
|
|
|
|
if (! $method->loaded()) {
|
|
|
|
SystemMessage::add(array(
|
|
|
|
'title'=>'Method is not defined or active in the Database',
|
|
|
|
'type'=>'warning',
|
2011-05-14 07:35:33 +00:00
|
|
|
'body'=>sprintf('Method not defined: %s for %s',Request::current()->action(),$module->name),
|
2010-11-29 22:41:08 +00:00
|
|
|
));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// If the role has the authorisation to run the method
|
|
|
|
$group_method = ORM::factory('group_method')
|
|
|
|
->where('method_id','=',$method->id);
|
|
|
|
|
|
|
|
$roles = '';
|
|
|
|
foreach ($group_method->find_all() as $gm) {
|
|
|
|
$roles .= ($roles ? '|' : '').$gm->group->name;
|
|
|
|
|
|
|
|
$ro = ORM::factory('group', array('name' => $gm->group->name));
|
|
|
|
|
|
|
|
// $ro->id == 0 means all users.
|
|
|
|
if ($ro->id == 0 OR $user->has('group', $ro)) {
|
|
|
|
$status = TRUE;
|
|
|
|
$roles = '';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! $status) {
|
|
|
|
if (Config::sitemode() == Kohana::DEVELOPMENT)
|
|
|
|
SystemMessage::add(array(
|
|
|
|
'title'=>'User is not authorised in Database',
|
|
|
|
'type'=>'debug',
|
|
|
|
'body'=>sprintf('Role(s) checked: %s<br/>User: %s</br>Module: %s<br/>Method: %s',$roles,$user->username,$module->name,$method->name),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Config::sitemode() == Kohana::DEVELOPMENT)
|
|
|
|
SystemMessage::add(array(
|
|
|
|
'title'=>'Debug',
|
|
|
|
'type'=>'debug',
|
|
|
|
'body'=>sprintf('A-User: <b>%s</b>, Module: <b>%s</b>, Method: <b>%s</b>, Role: <b>%s</b>, Status: <b>%s</b>, Data: <b>%s</b>',
|
2011-05-14 07:35:33 +00:00
|
|
|
$user->username,Request::current()->controller(),Request::current()->action(),$role,$status,$debug)));
|
2010-11-29 22:41:08 +00:00
|
|
|
|
|
|
|
// There is no role, so the method should be allowed to run as anonymous
|
|
|
|
} else {
|
|
|
|
if (Config::sitemode() == Kohana::DEVELOPMENT)
|
|
|
|
SystemMessage::add(array(
|
|
|
|
'title'=>'Debug',
|
|
|
|
'type'=>'debug',
|
|
|
|
'body'=>sprintf('B-User: <b>%s</b>, Module: <b>%s</b>, Method: <b>%s</b>, Status: <b>%s</b>, Data: <b>%s</b>',
|
2011-05-14 07:35:33 +00:00
|
|
|
$user->username,Request::current()->controller(),Request::current()->action(),'No Role Default Access',$debug)));
|
2010-11-29 22:41:08 +00:00
|
|
|
|
|
|
|
$status = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check and see if we have a token to login and run the method
|
|
|
|
} elseif ((! empty($_REQUEST['token']) AND $token = $_REQUEST['token']) OR $token=Session::instance()->get('token')) {
|
|
|
|
|
|
|
|
if ($user=$this->_get_token_user($token) AND $user !== FALSE)
|
|
|
|
$status = TRUE;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if (Config::sitemode() == Kohana::DEVELOPMENT)
|
|
|
|
SystemMessage::add(array('title'=>'Debug','type'=>'debug','body'=>'No user logged in'));
|
|
|
|
}
|
|
|
|
|
|
|
|
return $status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the currently logged in user from the session.
|
|
|
|
* Returns FALSE if no user is currently logged in.
|
|
|
|
*
|
|
|
|
* @param boolean Check token users too
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
public function get_user($tokenuser=TRUE) {
|
|
|
|
$user = parent::get_user();
|
|
|
|
|
|
|
|
// If we are not logged in, see if there is token for the usre
|
|
|
|
if ($tokenuser AND $user === FALSE AND $token=Session::instance()->get('token')) {
|
|
|
|
$user = $this->_get_token_user($token);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $user;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the user that a token applies to
|
|
|
|
*
|
|
|
|
* This will check that the token is valid (not expired and for the request)
|
|
|
|
*
|
|
|
|
* @param $token The token
|
|
|
|
* @return mixed The user
|
|
|
|
*/
|
|
|
|
private function _get_token_user($token) {
|
|
|
|
$mmto = ORM::factory('module_method_token',array('token'=>$token));
|
2011-05-14 07:35:33 +00:00
|
|
|
$request = Request::current();
|
2010-11-29 22:41:08 +00:00
|
|
|
$user = FALSE;
|
|
|
|
|
|
|
|
if ($mmto->loaded()) {
|
|
|
|
if ($mmto->date_expire < time()) {
|
|
|
|
SystemMessage::add(array(
|
|
|
|
'title'=>_('Token Not Valid'),
|
|
|
|
'type'=>'warning',
|
|
|
|
'body'=>_('Token expired')));
|
|
|
|
|
|
|
|
Session::instance()->delete('token');
|
|
|
|
$mmto->delete();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// Check that the token is for this URI
|
|
|
|
$mo = ORM::factory('module',array('name'=>$request->controller));
|
|
|
|
$mmo = ORM::factory('module_method',
|
|
|
|
array('name'=>$request->directory ? sprintf('%s_%s',$request->directory,$request->action) : $request->action));
|
|
|
|
|
|
|
|
// Ignore the token if this is not the right method.
|
|
|
|
if ($mmo->id == $mmto->method_id) {
|
|
|
|
// @todo Implement single use tokens
|
|
|
|
Session::instance()->set('token',$token);
|
|
|
|
|
|
|
|
$user = ORM::factory('account',$mmto->account_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $user;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Logs a user in.
|
|
|
|
*
|
|
|
|
* @param string username
|
|
|
|
* @param string password
|
|
|
|
* @param boolean enable autologin
|
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
protected function _login($user, $password, $remember)
|
|
|
|
{
|
|
|
|
if ( ! is_object($user))
|
|
|
|
{
|
|
|
|
$username = $user;
|
|
|
|
|
|
|
|
// Load the user
|
2011-05-14 07:35:33 +00:00
|
|
|
$user = ORM::factory('account');
|
2010-11-29 22:41:08 +00:00
|
|
|
$user->where($user->unique_key($username), '=', $username)->find();
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the passwords match, perform a login
|
|
|
|
if ($user->has('group', ORM::factory('group', array('name' => 'Registered Users'))) AND $user->password === $password)
|
|
|
|
{
|
|
|
|
if ($remember === TRUE)
|
|
|
|
{
|
|
|
|
// Create a new autologin token
|
|
|
|
$token = ORM::factory('user_token');
|
|
|
|
|
|
|
|
// Set token data
|
|
|
|
$token->user_id = $user->id;
|
|
|
|
$token->expires = time() + $this->_config['lifetime'];
|
|
|
|
$token->save();
|
|
|
|
|
|
|
|
// Set the autologin cookie
|
|
|
|
Cookie::set('authautologin', $token->token, $this->_config['lifetime']);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Record our session ID, we may need to update our DB when we get a new ID
|
|
|
|
$oldsess = session_id();
|
|
|
|
|
|
|
|
// Finish the login
|
|
|
|
$this->complete_login($user);
|
|
|
|
|
|
|
|
// Do we need to update databases with our new sesion ID
|
|
|
|
// @todo figure out where this is best to go
|
|
|
|
$session_change_trigger = array('cart'=>'session_id');
|
|
|
|
|
|
|
|
if (count($session_change_trigger) AND (session_id() != $oldsess)) {
|
|
|
|
foreach ($session_change_trigger as $t => $c) {
|
|
|
|
$orm = ORM::factory($t)
|
|
|
|
->where($c,'=',$oldsess);
|
|
|
|
|
2011-05-14 07:35:33 +00:00
|
|
|
// @todo There must be a way that ORM can update multiple records with 1 SQL
|
|
|
|
foreach ($orm->find_all() as $o)
|
|
|
|
$o->set('session_id',session_id())
|
|
|
|
->update();
|
2010-11-29 22:41:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Login failed
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Override the supplied find_salt() to enable disabling salt keys
|
|
|
|
*/
|
|
|
|
public function find_salt($password) {
|
|
|
|
$salt = '';
|
|
|
|
|
|
|
|
foreach ($this->_config['salt_pattern'] as $i => $offset) {
|
|
|
|
// Find salt characters, take a good long look...
|
|
|
|
if (is_numeric($offset))
|
|
|
|
$salt .= substr($password, $offset + $i, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $salt;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determine if a user is authorised to view an account
|
|
|
|
*
|
|
|
|
* @param integer Account ID
|
|
|
|
*
|
|
|
|
* @return boolean TRUE if authorised, FALSE if not.
|
|
|
|
*/
|
|
|
|
public function authorised($aid) {
|
|
|
|
if (! $this->get_user())
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
// @todo Consider caching this.
|
|
|
|
$ao = ORM::factory('account',$this->get_user()->id);
|
|
|
|
|
|
|
|
if (! $ao->loaded() OR ($aid != $ao->id AND ! $ao->admin()))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Disable KO3 hash_password function
|
|
|
|
*/
|
|
|
|
public function hash_password($password,$salt = FALSE) {
|
|
|
|
return md5($password);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
?>
|