Moved more components into lnapp/lnauth sub modules

This commit is contained in:
Deon George 2016-09-01 14:35:14 +10:00
parent 54e4425aa8
commit cd102c6fba
18 changed files with 35 additions and 677 deletions

View File

@ -1,22 +1,23 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class overrides Kohana's Auth
* Enahance Kohanas Auth driver.
*
* @package OSB
* @category Modifications
* @category Classes
* @author Deon George
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Auth_ORM extends Kohana_Auth_ORM {
// Override Kohana Auth requirement to have a hash_key
public function hash($str) {
switch ($this->_config['hash_method']) {
case '' : return $str;
case 'md5': return md5($str);
default: return hash_hmac($this->_config['hash_method'], $str, $this->_config['hash_key']);
}
class Auth_ORM extends lnAuth_Auth_ORM {
/**
* Determine if a user is authorised to view an account
*
* @param Model_Account Account Ojbect to validate if the current user has access
* @return boolean TRUE if authorised, FALSE if not.
*/
public function authorised(Model_Account $ao) {
return (($uo = $this->get_user()) AND $uo->loaded() AND ($uo == $ao OR in_array($ao->id,$uo->RTM->customers($uo->RTM))));
}
}
?>

View File

@ -1,233 +0,0 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* OSB Auth driver.
*
* @package OSB
* @category Classes
* @author Deon George
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Auth_OSB extends Auth_ORM {
/**
* We need to override Kohana's __construct(), for tasks, which attempt to open a session
* and probably dont have access to PHP sessions path.
* Tasks dont need sessions anyway?
*/
public function __construct($config = array()) {
// Save the config in the object
$this->_config = $config;
if (PHP_SAPI !== 'cli')
parent::__construct($config);
}
/**
* 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 Model_Account|NULL The user that the token is valid for.
*/
private function _get_token_user($token) {
// This has been implemented, as we sometimes we seem to come here twice
static $uo = NULL;
if (! is_null($uo))
return $uo;
$mmto = ORM::factory('Module_Method_Token',array('token'=>$token));
// 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 = $mo->module_method
->where_open()
->where('name','=',strtolower(Request::current()->directory() ? sprintf('%s:%s',Request::current()->directory(),Request::current()->action()) : Request::current()->action()))
// @todo No longer required after all method names have been colon delimited
->or_where('name','=',strtolower(Request::current()->directory() ? sprintf('%s_%s',Request::current()->directory(),Request::current()->action()) : Request::current()->action()))
->where_close()
->find();
// 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')));
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')));
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);
$uo = ORM::factory('Account',$mmto->account_id);
$uo->log(sprintf('Token %s used for method %s [%s]',$mmto->token,$mmto->module_method->id,Request::current()->param('id')));
}
}
}
return $uo;
}
/**
* 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 no user loaded, return
if (! $user->loaded())
return FALSE;
}
// Create a hashed password
if (is_string($password))
$password = $this->hash($password);
// If the passwords match, perform a login
if ($user->active AND $user->has_any('group',ORM::factory('Group',array('name'=>'Registered Users'))->list_childgrps(TRUE)) AND $user->password === $password) {
// @todo This is not currently used.
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
$sct = Kohana::$config->load('config')->session_change_trigger;
if (session_id() != $oldsess AND count($sct))
foreach ($sct as $t => $c)
if (Config::module_exist($t))
foreach (ORM::factory(ucwords($t))->where($c,'=',$oldsess)->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 Model_Account Account Ojbect to validate if the current user has access
* @return boolean TRUE if authorised, FALSE if not.
*/
public function authorised(Model_Account $ao) {
return (($uo = $this->get_user()) AND $uo->loaded() AND ($uo == $ao OR in_array($ao->id,$uo->RTM->customers($uo->RTM))));
}
/**
* Gets the currently logged in user from the session.
* Returns NULL if no user is currently logged in.
*
* @param boolean Check token users too
* @return mixed
*/
public function get_user($default=NULL,$tokenuser=TRUE) {
// If we are a CLI, we are not logged in
if (PHP_SAPI === 'cli')
throw new Kohana_Exception('Calling :method from the CLI is not allowed!',array(':method'=>__METHOD__));
// Get the current user
$uo = parent::get_user($default);
// If we are not logged in, see if there is token for the user
if (is_null($uo) AND $tokenuser AND ($token=Session::instance()->get('token')) OR ($token=Arr::get($_REQUEST,'token')))
$uo = $this->_get_token_user($token);
return $uo;
}
public function get_groups() {
return is_null($x=$this->get_user()) ? ORM::factory('Group')->where('id','=',0)->find_all() : $x->groups();
}
/**
* 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;
// If we are a CLI, we are not logged in
if (PHP_SAPI === 'cli')
return $status;
// Get the user from the session
$uo = $this->get_user();
// If we are not a valid user object, then we are not logged in
if (is_object($uo) AND ($uo instanceof Model_Account) AND $uo->loaded())
if (! empty($role)) {
if (($x = Request::current()->mmo()) instanceof Model)
// If the role has the authorisation to run the method
foreach ($x->group->find_all() as $go)
if ($go->id == 0 OR $uo->has_any('group',$go->list_childgrps(TRUE))) {
$status = TRUE;
break;
}
// There is no role, so the method should be allowed to run as anonymous
} else
$status = TRUE;
return $status;
}
}
?>

View File

@ -1,29 +0,0 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides the default template controller for rendering pages.
*
* @package OSB
* @category Controllers
* @author Deon George
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
abstract class Controller_TemplateDefault extends lnAuth_Controller_TemplateDefault {
protected $auth_required = TRUE;
protected function save(Model $o) {
try {
return $o->save();
} catch (ORM_Validation_Exception $e) {
SystemMessage::factory()
->title('Record NOT updated')
->type('error')
->body(join('<br/>',array_values($e->errors('models'))));
return FALSE;
}
}
}
?>

View File

@ -1,23 +0,0 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class extends Kohana's [Database_Query_Builder_Insert] to ensure that we have a site_id included in the values
*
* @package OSB
* @category Helpers
* @author Deon George
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Database_Query_Builder_Insert extends Kohana_Database_Query_Builder_Insert {
public function compile($db = NULL) {
$this->_columns = Arr::Merge($this->_columns,['site_id']);
foreach ($this->_values as $k=>$v)
$this->_values[$k] = Arr::Merge($this->_values[$k],[Site::id()]);
return parent::compile($db);
}
}
?>

View File

@ -1,21 +0,0 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class extends Kohana's [Database_Query_Builder_Join] to ensure that we have a site_id in join statements
*
* @package OSB
* @category Helpers
* @author Deon George
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Database_Query_Builder_Join extends Kohana_Database_Query_Builder_Join {
public function compile($db = NULL) {
$this->_on[] = array($this->_table.'.site_id','=',Site::id());
return parent::compile($db);
}
}
?>

View File

@ -1,25 +0,0 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class overrides Kohana's Minion CLI Module
*
* @package OSB
* @category Helpers
* @author Deon George
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
abstract class Minion_Task extends Kohana_Minion_Task {
protected $_sysoptions = array(
'site'=>NULL,
);
/**
* Override our __construct so that we can specify options in each class file
*/
protected function __construct() {
// Populate $_accepted_options based on keys from $_options
$this->_accepted_options = array_keys(Arr::merge($this->_sysoptions,$this->_options));
}
}
?>

View File

@ -9,7 +9,7 @@
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_Account extends lnApp_Model_Account {
class Model_Account extends lnAuth_Model_Account {
// Relationships
protected $_has_many = array(
'user_tokens'=>array('model'=>'user_token'),
@ -24,32 +24,29 @@ class Model_Account extends lnApp_Model_Account {
'RTM'=>array('far_key'=>'id'),
);
protected $_belongs_to = array(
'country'=>array(),
'currency'=>array(),
'language'=>array(),
);
protected $_display_filters = array(
'active'=>array(
array('StaticList_YesNo::get',array(':value',TRUE)),
),
'date_orig'=>array(
array('Site::Date',array(':value')),
),
'date_last'=>array(
array('Site::Date',array(':value')),
),
);
// Validation rules
public function rules() {
return array(
'username' => array(
array('not_empty'),
array('min_length', array(':value', 4)),
array('max_length', array(':value', 256)),
),
'email' => array(
array('not_empty'),
// @note: cant use unique emails, since multiple accounts may share the same email
// array(array($this, 'unique'), array('email', ':value')),
array('min_length', array(':value', 4)),
array('max_length', array(':value', 127)),
array('email'),
),
);
}
/** REQUIRED ABSTRACT METHODS **/
/** LOCAL METHODS **/
public function activated() {
return $this->has('group');
}
/**
* Get a list of all invoices for this account
*/

View File

@ -1,42 +0,0 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
*
* @package OSB
* @category Models
* @author Deon George
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_Auth_UserDefault extends Model_Auth_User {
// Validation rules
public function rules() {
return array(
'username' => array(
array('not_empty'),
array('min_length', array(':value', 4)),
array('max_length', array(':value', 256)),
),
'email' => array(
array('not_empty'),
array('min_length', array(':value', 4)),
array('max_length', array(':value', 127)),
array('email'),
),
);
}
/**
* Complete our login
*
* For some database logins, we may not want to record the user last login
* details in the repository, so we just override that parent function
* here.
*
* We can also do some other post-login actions here.
*/
public function complete_login() {
return $this->log('Logged In');
}
}
?>

View File

@ -1,31 +0,0 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* OSB Country Model
*
* @package OSB
* @category Models
* @author Deon George
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_Country extends ORM {
protected $_has_one = array(
'currency'=>array('far_key'=>'id'),
);
protected $_has_many = array(
'tax'=>array('far_key'=>'id'),
);
protected $_sorting = array(
'name'=>'ASC',
);
protected $_form = array('id'=>'id','value'=>'name');
public static function icon() {
return HTML::image(sprintf('media/img/country/%s.png',strtolower($this->two_code)),array('alt'=>$this->currency->symbol));
}
}
?>

View File

@ -1,19 +0,0 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* OSB Currency Model
*
* @package OSB
* @category Models
* @author Deon George
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_Currency extends ORM {
protected $_sorting = array(
'name'=>'ASC',
);
protected $_form = array('id'=>'id','value'=>'name');
}
?>

View File

@ -8,66 +8,7 @@
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_Group extends Model_Auth_Role {
// Relationships
protected $_has_many = array(
'account'=>array('through'=>'account_group'),
'module_method'=>array('through'=>'group_method','far_key'=>'method_id'),
);
protected $_sorting = array(
'name'=>'ASC',
);
protected $_display_filters = array(
'active'=>array(
array('StaticList_YesNo::get',array(':value',TRUE)),
),
);
/**
* This function will, given a group, list all of the children that
* are also related to this group, in the group heirarchy.
*/
public function list_childgrps($incParent=FALSE) {
$result = array();
if (! $this->loaded())
return $result;
foreach (ORM::factory('Group')->where_active()->and_where('parent_id','=',$this)->find_all() as $go) {
array_push($result,$go);
$result = array_merge($result,$go->list_childgrps());
}
if ($incParent)
array_push($result,$this);
return $result;
}
/**
* This function will, given a group, list all of the parent that
* are also related to this group, in the group heirarchy.
*/
public function list_parentgrps($incParent=FALSE) {
$result = array();
if (! $this->loaded())
return $result;
foreach (ORM::factory('Group')->where_active()->and_where('id','=',$this->parent_id)->find_all() as $go) {
array_push($result,$go);
$result = array_merge($result,$go->list_parentgrps());
}
if ($incParent)
array_push($result,$this);
return $result;
}
class Model_Group extends lnAuth_Model_Group {
/**
* Get a list of groups that have their own pricing
*/

View File

@ -1,19 +0,0 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* OSB Language Model
*
* @package OSB
* @category Models
* @author Deon George
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_Language extends ORM {
protected $_sorting = array(
'name'=>'ASC',
);
protected $_form = array('id'=>'id','value'=>'name');
}
?>

View File

@ -9,28 +9,7 @@
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_Module_Method extends ORM {
// This module doesnt keep track of column updates automatically
protected $_created_column = FALSE;
protected $_updated_column = FALSE;
// Relationships
protected $_belongs_to = array(
'module'=>array(),
);
protected $_has_one = array(
'record_id'=>array(),
);
protected $_has_many = array(
'group'=>array('through'=>'group_method','foreign_key'=>'method_id')
);
protected $_sorting = array(
'name'=>'ASC',
);
protected $status;
class Model_Module_Method extends lnAuth_Model_Module_Method {
// Temporarily adjust our name
// @todo This is temporary until all our method names are colon delimited.
protected function _load_values(array $values) {
@ -43,48 +22,5 @@ class Model_Module_Method extends ORM {
return $this;
}
public function controller_sub() {
return substr_count($this->name,'_') ? substr($this->name,($x=strpos($this->name,'_')),strpos($this->name,':')-$x) : '';
}
public function controller() {
return Kohana::classname(sprintf('Controller%s_%s',($this->directory() ? '_' : '').$this->directory(),$this->module->name).$this->controller_sub());
}
public function directory() {
return substr($this->name,0,substr_count($this->name,'_') ? strpos($this->name,'_') : strpos($this->name,':'));
}
public function method() {
return substr($this->name,strpos($this->name,':')+1);
}
/**
* Calculate the description for this method on any menu link
*/
public function menu_display() {
// @todo The test for value equal 1 is for legacy, remove when all updated.
if ($this->menu_display AND $this->menu_display != 1)
return $this->menu_display;
else
return sprintf('%s: %s',$this->module->name,$this->name);
}
public function status($status=NULL) {
if ($status)
$this->status = $status;
return $this->status;
}
public function url() {
if (! preg_match('/:/',$this->name))
return NULL;
list($type,$action) = preg_split('/:/',$this->name,2);
return URL::link($this->directory(),$this->module->name.$this->controller_sub().'/'.$action);
}
}
?>

View File

@ -1,47 +0,0 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* Request. Uses the [Route] class to determine what
* [Controller] to send the request to.
*
* @package OSB
* @category Modifications
* @author Deon George
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Request extends lnApp_Request {
/**
* Get our Module_Method object for this request
*/
public function mmo() {
static $result = FALSE;
if (is_null($result) OR $result)
return $result;
$result = NULL;
list($c,$x) = substr_count($this->_controller,'_') ? explode('_',$this->_controller,2) : array($this->_controller,'');
$mo = ORM::factory('Module',array('name'=>$c));
if ($mo->loaded() AND $mo->active) {
$method = strtolower($this->_directory ? sprintf('%s:%s',$this->_directory.($x ? '_'.$x : ''),$this->_action) : $this->_action);
// Get the method number
$mmo = $mo->module_method
->where_open()
->where('name','=',$method)
->or_where('name','=',str_replace(':','_',$method)) // @todo This is temporary until all our method names have a colon delimiter
->where_close()
->find();
if ($mmo->loaded())
$result = $mmo;
}
return $result;
}
}
?>

View File

@ -1,28 +0,0 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This is class renders Person Title responses and forms.
*
* @package OSB
* @category Helpers
* @author Deon George
* @copyright (c) 2009-2013 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class StaticList_Title extends StaticList {
protected function _table() {
return array(
'mr'=>_('Mr'),
'ms'=>_('Ms'),
'mrs'=>_('Mrs'),
'miss'=>_('Miss'),
'dr'=>_('Dr'),
'prof'=>_('Prof')
);
}
public static function get($value) {
return self::factory()->_get($value);
}
}
?>

View File

@ -11,7 +11,7 @@
*/
return array(
'driver' => 'OSB',
'driver' => 'ORM',
'hash_method' => 'md5',
);
?>

@ -1 +1 @@
Subproject commit f5bc5dfa296a1517ebdb29b2dd0f81b09f136b6a
Subproject commit 7e632cf78559fcb0b5e2f9368f65511307d54255

@ -1 +1 @@
Subproject commit 33982a6cecb56069dae94af738541b5b4e4be4ff
Subproject commit 81edc432b4f8e70b389877f234feb610a71672c6