1
votes

I have been trying to get the CakePHP ACL's working with my new application, it is causing me a world of pain. For some reason the ACL doesnt seem to be working however the tutorials are rubbish and don't explain each component very well. e.g. how a ACO links to a controller / function / views

I have got the ACL working correctly up until getting the pages to know if the user is allowed to view it, also same issue with menu items that they can / cant see.

I have noticed that if i add this code to my page the array shows the group as blank:

$user = $this->Auth->user(); 
pr($user);

The array returned:

Array
(
    [id] => 80
    [first_name] => Bob
    [last_name] => Test
    [email] => [email protected]
    [username] => TestAdmin
    [tokenhash] => cleared
    [is_active] => 1
    [created] => 2014-10-03 16:32:45
    [modified] => 2014-10-03 16:32:45
    [token_expires_at] => 
    [group_id] => 3
    [Group] => Array
        (
            [id] => 
            [name] => 
            [enabled] => 
            [created] => 
            [modified] => 
        )

)

The site is basically a portal, visitors should only have access to login / register. and the users groups all have access to the dashboard however it ends up in a continuous loop unless i allow everyone access to the dashboard (due to the group not being recognised i guess)

any help would be appreciated, I realise that you may need me to post the code im using so please let me know what you would require.

Thanks in advance

EDIT:

I have updated my AppController as below and it has started showing the group in the array as it should!!! weird thanks for the push in the right direction.

AppController.php

<?php

App::uses('Controller', 'Controller');

class AppController extends Controller {
    public function beforeRender() {
        if((($this->params['controller']==='Users') || ($this->params['controller']==='users'))&&(($this->params['action']=='login') || ($this->params['action']=='register') || ($this->params['action']=='success') || ($this->params['action']=='forgot_password') || ($this->params['action']=='reset_password')) ){
            $this->theme = 'DataHouseLogin';
        }else{
            $this->theme = 'DataHouse';
        }
        parent::beforeRender();
    }

    public $components = array(
        'Acl',
        'RequestHandler',
        'DebugKit.Toolbar' => array('panels' => array('history' => false)),
        'Session',
        'Auth' => array(
            'authorize' => array(
                'Actions' => array(
                    'actionPath' => 'controllers'
                    )
            ), 
            'loginAction' => array(
                'controller' => 'Users', 
                'action' => 'login'
            ),
            'loginRedirect' => array(
                'controller' => 'Dashboard',
                'action' => 'index'
            ),
            'logoutRedirect' => array(
                'controller' => 'Users',
                'action' => 'login'
            ),
            'authError' => 'Did you really think you are allowed to see that?',
            'authenticate' => array(
                'Form' => array(
                    'passwordHasher' => 'Blowfish'
                )
            )
        )
    );

    public function beforeFilter() {
        //$this->Auth->allowedActions = array('display','index','register');
        $this->set('user', $this->Auth->user());    
        $this->set('acl', $this->Acl);
        $this->Auth->authorize = array(
            'Controller',
            'Actions' => array('actionPath' => 'controllers')
        ); 


        parent::beforeFilter();
    }
    public function isAuthorized($user) {
        // Default deny
        return false;
    } 
}
1
Have you configured ACL and Auth components ? Show me your AppController->beforeFilter() function please. - Grzegorz Motyl
Hi Grzegorz, i have added the beforeFilter. - Steven Marks

1 Answers

1
votes

I think you should try to configure Auth component correctly. Try to put this code in your AppController:

class AppController extends Controller {
 public $components = array('RequestHandler', 'Session',
    'Acl',
    'Auth' => array(
        'authorize' => array(
            'Actions' => array('actionPath' => 'controllers')
        )
    ),
  );  

 public function beforeFilter() {
   $this->Auth->authorize = array(
        'Controller',
        'Actions' => array('actionPath' => 'controllers')
  );    
   $this->Auth->authenticate = array('Form' => array('fields' => array('username' => 'name', 'password' => 'password')));
   $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login', 'admin' => false, 'plugin' => false);
   $this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login', 'admin' => false, 'plugin' => false);
 }

 public function isAuthorized($user) {
    // Default deny
    return false;
 } 
}

EDIT: in UserModel and GroupModel add act as property:

public $actsAs = array('Acl' => array('type' => 'requester'));

in UserModel setup parentNode function:

public function parentNode() {
  if (!$this->id && empty($this->data)) {
      return null;
  }
  if (isset($this->data['User']['group_id'])) {
      $groupId = $this->data['User']['group_id'];
  } else {
      $groupId = $this->field('group_id');
  }
  if (!$groupId) {
      return null;
  } else {
      return array('Group' => array('id' => $groupId));
  }
}