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
User: %s
Module: %s
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: %s, Module: %s, Method: %s, Role: %s, Status: %s, Data: %s', $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: %s, Module: %s, Method: %s, Status: %s, Data: %s', $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) { // This has been implemented, as we sometimes we seem to come here twice static $user = NULL; if (! is_null($user)) return $user; $mmto = ORM::factory('module_method_token',array('token'=>$token)); $user = FALSE; // Ignore the token if it doesnt exist. if ($mmto->loaded()) { // Check that the token is for this URI $mo = ORM::factory('module',array('name'=>Request::current()->controller())); $mmo = ORM::factory('module_method',array( 'module_id'=>$mo->id, '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) { if (! is_null($mmto->date_expire) AND $mmto->date_expire < time()) { SystemMessage::add(array( 'title'=>_('Token Not Valid'), 'type'=>'warning', 'body'=>_('Token expired'))); // @todo Log the token deletion Session::instance()->delete('token'); $mmto->delete(); } elseif (! is_null($mmto->uses) AND $mmto->uses < 1) { SystemMessage::add(array( 'title'=>_('Token Not Valid'), 'type'=>'warning', 'body'=>_('Token expired'))); // @todo Log the token deletion Session::instance()->delete('token'); $mmto->delete(); } else { // If this is a usage count token, reduce the count. if (! is_null($mmto->uses)) $mmto->uses -= 1; // Record the date this token was used $mmto->date_last = time(); $mmto->save(); Session::instance()->set('token',$token); $user = ORM::factory('account',$mmto->account_id); $user->log(sprintf('Token %s used for method %s [%s]',$mmto->token,$mmto->module_method->name(),Request::current()->param('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('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; } } ?>