This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Deon George 130a87aa9a Major work to domain and hosting
Minor updates for ADSL services
Updates to Sort::MAsort()
Move core OSB items under application/
Moved ACCOUNT functions under application
Minor updates to task
2012-01-12 19:53:55 +11:00

260 lines
8.0 KiB
PHP

<?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
$mo = ORM::factory('module',array('name'=>Request::current()->controller()));
if (! $mo->loaded() OR ! $mo->status) {
SystemMessage::add(array(
'title'=>'Module is not defined or active in the Database',
'type'=>'warning',
'body'=>sprintf('Module not defined: %s',Request::current()->controller()),
));
} else {
if (Request::current()->directory())
$method_name = sprintf('%s_%s',Request::current()->directory(),Request::current()->action());
else
$method_name = Request::current()->action();
// Get the method number
$mmo = ORM::factory('module_method',array('module_id'=>$mo->id,'name'=>$method_name));
if (! $mmo->loaded()) {
SystemMessage::add(array(
'title'=>'Method is not defined or active in the Database',
'type'=>'warning',
'body'=>sprintf('Method not defined: %s for %s',Request::current()->action(),$mo->name),
));
} else {
// If the role has the authorisation to run the method
$gmo = ORM::factory('group_method')
->where('method_id','=',$mmo->id);
$roles = '';
foreach ($gmo->find_all() as $gm) {
$roles .= ($roles ? '|' : '').$gm->group->name;
// $gm->group->id == 0 means all users.
if ($gm->group->id == 0 OR $user->has_any('group',$gm->group->list_childgrps(TRUE))) {
$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,$mo->name,$mmo->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>',
$user->username,Request::current()->controller(),Request::current()->action(),$role,$status,$debug)));
// 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>',
$user->username,Request::current()->controller(),Request::current()->action(),'No Role Default Access',$debug)));
$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));
$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::current()->controller()));
$mmo = ORM::factory('module_method',
array('name'=>Request::current()->directory() ? sprintf('%s_%s',Request::current()->directory(),Request::current()->action()) : Request::current()->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
$user = ORM::factory('account');
$user->where($user->unique_key($username), '=', $username)->find();
}
// If the passwords match, perform a login
if ($user->status AND $user->has_any('group',ORM::factory('group',array('name'=>'Registered Users'))->list_childgrps(TRUE)) 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) {
if (Config::moduleexist($c)) {
$orm = ORM::factory($t)
->where($c,'=',$oldsess);
// @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();
}
}
}
return TRUE;
}
// Login failed
return FALSE;
}
/**
* 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,$afid=NULL) {
return (($ao = $this->get_user()) AND $ao->loaded() AND ($aid == $ao->id OR $ao->isAdmin() OR (! is_null($afid) AND $afid == $ao->affiliate->id))) ? TRUE : FALSE;
}
}
?>