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) { $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) { $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) { 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; } } ?>