[eluser]Oblique[/eluser] @NachoF, i don't like per-method authorization too. That's why i use AOP-like feature (make some coffee, so you don't accidently fall asleep while reading this):
1) we implement our own "template" controller in libraries folder, "MY_Controller", from which our other controllers descend.
2) in MY_Controller's constructor we define $this->current_user (i use tank_auth, but don't like it much, though it's not bad) and analyse uri - basing on what segment(1) is set to, we decide, if this section is accessible by current_user or not.
3) After it, if you have to restrict users from some particular methods, access to which depends on user's behaviour, you could do this in same MY_Controller's contructor.
My implementation of this approach looks like this:
Code:
MY_Controller.php
...
public function __construct()
{
parent::__construct();
// Defining which controller and method are requested:
$this->controller_name = $this->uri->rsegment(1);
$this->current_action = $this->uri->rsegment(2);
// Loading configs and langs if necessary, etc.
...
// Defining dmz-model User. Can be used in descendant controllers for user-depending things
$this->current_user = new User($this->tank_auth->get_user_id());
// If user requested not-restricted controller...
if ( ! (User::is_restriced($this->controller_name)))
return;
// if he's not logged in, or if his role doesn't allowed here, he's kicked out
if ( ! ($this->current_user->exists() AND $this->current_user->authorize($this->controller_name)))
{
redirect('/auth/login/');
}
// if he requested method, he doesn't have permissions for,
// he's either kicked out or recieves some message
elseif ( ! $this->current_user->has_access_to($this->current_action))
{
// naa-na-na-na
// na-na
// na-na
// can't touch this!
}
}
}
...
public static function is_restriced($controller)
{
return array_key_exists($controller, self::$restrictions);
}
function authorize($controller)
{
return $this->role == $controller;
}
function has_access_to($action)
{
// This also could be done with the use of SET sql data type, but since dmz
// doesn't have means to easily do that (not meant as a reproach),
// it's easier to make it yourself
// If this action is restrictable
if (array_key_exists($action, self::$restrictions[$this->role]))
{
// If permissions property of user has parmission flag of this action set to 1
return (self::$restrictions[$this->role][$action] & (int)$this->permissions) !== 0;
}
return TRUE;
}
...
If you have nested directories of controllers, this would look a bit more complicated around that line where current controller and method is defined