Ugly CakePHP ACL hack

(I appreciate if someone correct my engrish mistakes)

I found difficult to understand CakePHP DB-ACL model, I think the INI-ACL is the simplest and it is enoght for my needs, also I don't have shell access to the server where I'm deploying a simple application, so I can't bake (I guess it is possible to do that without baking too).

The syntax for the INI-ACL is very simple, it is the syntax of a old-school -windows days- ini file. And is something like this, you define users, groups, and objects. you can give or deny access to an object to a entire group or to a user.

You can combine ACL component with the CakePHP Auth component making it, very easy -and powerful- way to administer a website.

Here is a example.

[bofh]
groups = admin, user
allow = wipe_computer

[luser]
;this guy is a bofh enemy
groups = user
deny = play

[admin]
allow = adminstuff

[user]
allow = work, play

The bad thing about INI-ACL is that is not so good integrated to the CakePHP framework like the DB-ACL component. So I decide to workaround a solution.

Look at this lines in my app_controller.php file.

class AppController extends Controller
{
...
  function getACO()
  {
    return(strtolower(implode("/", array($this->name, $this->action))));
  }
  function canAccess()
  {
    return (bool) $this->Acl->check($this->Auth->user('username'), $this->getACO());
  }
...
}

I do not import the ACL nor Auth components into the AppController. They are only imported in the Controllers who need it.

I only need to use the function canAccess in the controller where I want ACL. Like this.

class UsersController extends AppController
{
...
  function beforeFilter()
  {
    parent::beforeFilter();
    $this->Auth->authorize = 'controller';
    $this->Auth->loginError = __('wrongPassword', true);
    $this->Auth->authError = __('notAuthorized', true);
    $this->Auth->allow('register');
  }
  function isAuthorized()
  {
    return $this->canAccess();
  }
...
}

But this does not work without the following modification to the file: CAKE/libs/controller/components/acl.php (I know is ugly, it break the framework -but hey it works for me-)

class IniAcl extends AclBase {
...
  function check($aro, $aco, $aco_action = null) {
    if ($this->config == null) {
      $this->config = $this->readConfigFile(CONFIGS . 'acl.ini.php');
    }
    $aclConfig = $this->config;

    //this is my mod!
    if (!isset($aclConfig[$aro])) {
      $aro = "*";
    }
    //end of my mod!

    if (isset($aclConfig[$aro]['deny'])) {
...
}

This allows the following configuration of my APP/config/acl.ini.php

;Users

[admin1]
groups = admin, user, visitor

[user1]
groups = admin, user
allow = admin/x

[*]
groups = user, visitor

[]
groups = visitor

;Groups

[admin]
allow = pages/admin_edit, pages/admin_index, pages/admin_add, users/admin_index, users/admin_edit, users/admin_add

[user]
allow = users/index, users/logout

[visitor]
allow = users/register, pages/display

As you can see this simple modification allows the use of '*' to reffer to any authenticated (thanks to the Auth component) user, and '´´' to anyone who is not authenticated. Very handy (I insist, for me)


Markup


AndresVia/weblog/2008-11-04 (last edited 2008-11-04 22:58:36 by AndresVia)