Some enhancements to token logins
This commit is contained in:
parent
718c42be65
commit
c419b50bac
@ -146,31 +146,58 @@ class Auth_OSB extends Auth_ORM {
|
|||||||
* @return mixed The user
|
* @return mixed The user
|
||||||
*/
|
*/
|
||||||
private function _get_token_user($token) {
|
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));
|
$mmto = ORM::factory('module_method_token',array('token'=>$token));
|
||||||
$user = FALSE;
|
$user = FALSE;
|
||||||
|
|
||||||
if ($mmto->loaded()) {
|
if ($mmto->loaded()) {
|
||||||
if ($mmto->date_expire < time()) {
|
if (! is_null($mmto->date_expire) AND $mmto->date_expire < time()) {
|
||||||
SystemMessage::add(array(
|
SystemMessage::add(array(
|
||||||
'title'=>_('Token Not Valid'),
|
'title'=>_('Token Not Valid'),
|
||||||
'type'=>'warning',
|
'type'=>'warning',
|
||||||
'body'=>_('Token expired')));
|
'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');
|
Session::instance()->delete('token');
|
||||||
$mmto->delete();
|
$mmto->delete();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Check that the token is for this URI
|
// Check that the token is for this URI
|
||||||
$mo = ORM::factory('module',array('name'=>Request::current()->controller()));
|
$mo = ORM::factory('module',array('name'=>Request::current()->controller()));
|
||||||
$mmo = ORM::factory('module_method',
|
$mmo = ORM::factory('module_method',array(
|
||||||
array('name'=>Request::current()->directory() ? sprintf('%s_%s',Request::current()->directory(),Request::current()->action()) : Request::current()->action()));
|
'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.
|
// Ignore the token if this is not the right method.
|
||||||
if ($mmo->id == $mmto->method_id) {
|
if ($mmo->id == $mmto->method_id) {
|
||||||
// @todo Implement single use tokens
|
// 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);
|
Session::instance()->set('token',$token);
|
||||||
|
|
||||||
$user = ORM::factory('account',$mmto->account_id);
|
$user = ORM::factory('account',$mmto->account_id);
|
||||||
|
$user->log(sprintf('Token %s used for method %s',$mmto->token,$mmto->method_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,40 +132,24 @@ class Controller_lnApp_Login extends Controller_TemplateDefault {
|
|||||||
if ($_POST) {
|
if ($_POST) {
|
||||||
// If the email address is correct, create a method token
|
// If the email address is correct, create a method token
|
||||||
if (! empty($_POST['email']) AND ($ao=ORM::factory('account',array('email'=>$_POST['email']))) AND $ao->loaded()) {
|
if (! empty($_POST['email']) AND ($ao=ORM::factory('account',array('email'=>$_POST['email']))) AND $ao->loaded()) {
|
||||||
$mt = ORM::factory('module_method_token');
|
$mmto = ORM::factory('module_method_token')
|
||||||
|
->method(array('account','user_resetpassword'))
|
||||||
// Find out our password reset method id
|
->account($ao)
|
||||||
// @todo move this to a more generic method, so that it can be called by other methods
|
->expire(time()+$token_expire*60);
|
||||||
$mo = ORM::factory('module',array('name'=>'account'));
|
|
||||||
$mmo = ORM::factory('module_method',array('name'=>'user_resetpassword','module_id'=>$mo->id));
|
|
||||||
|
|
||||||
// Check to see if there is already a token, if so, do nothing.
|
|
||||||
if ($mt->where('account_id','=',$ao->id)->and_where('method_id','=',$mmo->id)->find()) {
|
|
||||||
if ($mt->loaded() AND ($mt->date_expire < time())) {
|
|
||||||
$mt->delete();
|
|
||||||
$mt->clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $mt->loaded()) {
|
|
||||||
$mt->account_id = $ao->id;
|
|
||||||
$mt->method_id = $mmo->id;
|
|
||||||
$mt->date_expire = time() + $token_expire*60;
|
|
||||||
$mt->token = md5(sprintf('%s:%s:%s',$mt->account_id,$mt->method_id,$mt->date_expire));
|
|
||||||
$mt->save();
|
|
||||||
|
|
||||||
|
if ($mmto->generate()) {
|
||||||
// Send our email with the token
|
// Send our email with the token
|
||||||
// @todo Need to provide an option if Email_Template is not installed/activited.
|
// @todo Need to provide an option if Email_Template is not installed/activited.
|
||||||
// @todo Need to provide an option if account_reset_password template doesnt exist.
|
// @todo Need to provide an option if account_reset_password template doesnt exist.
|
||||||
$et = Email_Template::instance('account_reset_password');
|
$et = Email_Template::instance('account_reset_password');
|
||||||
$et->to = array('account'=>array($mt->account_id));
|
$et->to = array('account'=>array($mmto->account_id));
|
||||||
$et->variables = array(
|
$et->variables = array(
|
||||||
'SITE'=>URL::base(TRUE,TRUE),
|
'SITE'=>URL::base(TRUE,TRUE),
|
||||||
'SITE_ADMIN'=>Config::sitename(),
|
'SITE_ADMIN'=>Config::sitename(),
|
||||||
'SITE_NAME'=>Config::sitename(),
|
'SITE_NAME'=>Config::sitename(),
|
||||||
'TOKEN'=>$mt->token,
|
'TOKEN'=>$mmto->token,
|
||||||
'TOKEN_EXPIRE_MIN'=>$token_expire,
|
'TOKEN_EXPIRE_MIN'=>$token_expire,
|
||||||
'USER_NAME'=>sprintf('%s %s',$mt->account->first_name,$mt->account->last_name),
|
'USER_NAME'=>sprintf('%s %s',$mmto->account->first_name,$mmto->account->last_name),
|
||||||
);
|
);
|
||||||
$et->send();
|
$et->send();
|
||||||
|
|
||||||
|
@ -22,5 +22,87 @@ class Model_Module_Method_Token extends ORMOSB {
|
|||||||
|
|
||||||
// This module doesnt keep track of column updates automatically
|
// This module doesnt keep track of column updates automatically
|
||||||
protected $_update_column = FALSE;
|
protected $_update_column = FALSE;
|
||||||
|
|
||||||
|
public function method(array $modmeth) {
|
||||||
|
list($module,$method) = $modmeth;
|
||||||
|
|
||||||
|
if (! $method instanceof Model_Module_Method) {
|
||||||
|
if (is_numeric($module))
|
||||||
|
$mo = ORM::factory('module',$module);
|
||||||
|
elseif (is_string($module))
|
||||||
|
$mo = ORM::factory('module',array('name'=>$module));
|
||||||
|
elseif (! $module instanceof Model_Module)
|
||||||
|
throw new Kohana_Exception('Unknown module :module',array(':module'=>serialize($module)));
|
||||||
|
else
|
||||||
|
$mo = $module;
|
||||||
|
|
||||||
|
if (! $mo->loaded())
|
||||||
|
throw new Kohana_Exception('Unknown module :module - not loaded?',array(':module'=>$mo->id));
|
||||||
|
|
||||||
|
if (is_numeric($method))
|
||||||
|
$mmo = ORM::factory('module_method',$method);
|
||||||
|
elseif (is_string($method))
|
||||||
|
$mmo = ORM::factory('module_method',array('name'=>$method,'module_id'=>$mo->id));
|
||||||
|
else
|
||||||
|
throw new Kohana_Exception('Unknown method :method',array(':method'=>serialize($method)));
|
||||||
|
} else
|
||||||
|
$mmo = $method;
|
||||||
|
|
||||||
|
if (! $mmo->loaded())
|
||||||
|
throw new Kohana_Exception('Unknown method :method - not loaded?',array(':method'=>$mmo->id));
|
||||||
|
|
||||||
|
$this->method_id = $mmo->id;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function account($account) {
|
||||||
|
if (! $account instanceof Model_Account) {
|
||||||
|
if (is_numeric($account))
|
||||||
|
$ao = ORM::factory('account',$account);
|
||||||
|
else
|
||||||
|
throw new Kohana_Exception('Unknown account :account',array(':account'=>serialize($account)));
|
||||||
|
} else
|
||||||
|
$ao = $account;
|
||||||
|
|
||||||
|
$this->account_id = $ao->id;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function uses($uses) {
|
||||||
|
$this->uses = $uses;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function expire($expire) {
|
||||||
|
$this->date_expire = $expire;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generate() {
|
||||||
|
if (! $this->account_id OR ! $this->method_id OR ! ($this->date_expire OR $this->uses))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Check we dont already have a valid token
|
||||||
|
$mmto = ORM::factory('module_method_token')
|
||||||
|
->where('account_id','=',$this->account_id)
|
||||||
|
->where('method_id','=',$this->method_id)
|
||||||
|
->find();
|
||||||
|
|
||||||
|
if ($mmto->loaded()) {
|
||||||
|
if ((is_null($mmto->date_expire) OR $mmto->date_expire > time()) AND (is_null($mmto->uses) OR $mmto->uses > 0))
|
||||||
|
return $mmto->token;
|
||||||
|
else
|
||||||
|
$mmto->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->token = md5(sprintf('%s:%s:%s',$this->account_id,$this->method_id,time()));
|
||||||
|
$this->save();
|
||||||
|
|
||||||
|
return $this->saved() ? $this->token : NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
Reference in New Issue
Block a user