redrom
redrom

Reputation: 11632

CakePhp 3.3 - How to allow access Different user roles to different methods in controller?

I'm trying to allow different Controller methods to different user roles, tutorials on the official Dev site expect that user roles are two, but i would like to work with more roles, i did some digging about this, but without the luck.

I tried to following:

AppController

class AppController extends Controller
{

    /**
     * Initialization hook method.
     *
     * Use this method to add common initialization code like loading components.
     *
     * e.g. `$this->loadComponent('Security');`
     *
     * @return void
     */
    public function initialize()
    {
        parent::initialize();

        $this->loadComponent('RequestHandler');
        $this->loadComponent('Flash');
        $this->loadComponent('Auth', [
            'authorize' => 'Controller',
            'authenticate' => [
                'Form' => [
                    'fields' => [
                        'username' => 'email',
                        'password' => 'password'
                    ]
                ]
            ],
            /*'loginRedirect' => [
                'controller' => 'Dashboards',
                'action' => 'index'
            ],*/
            'logoutRedirect' => [
                'controller' => 'Pages',
                'action' => 'logout'
            ],
            'loginAction' => [
                'controller' => 'Users',
                'action' => 'login'
            ],
            //'unauthorizedRedirect' => $this->referer()
        ]);

        // Allow the display action so our pages controller
        // continues to work.
        $this->Auth->allow(['login','register']);
    }

    public function isAuthorized($user)
    {
        return true;
    }

UsersController

class UsersController extends AppController
{
    /**
     * Init method
     *
     * @return \Cake\Network\Response|null
     */
    public function initialize()
    {
        parent::initialize();
        //pr("initialize");
    }

    public function isAuthorized($user)
    {
        if (isset($user['role']) && $user['role'] === 'ADMIN' ||
            isset($user['role']) && $user['role'] === 'MANAGER' ) {
            $this->Auth->allow(['logout', 'index','delete']);
            //return;
        }
        if (isset($user['role']) && $user['role'] === 'PARTNER') {
            $this->Auth->allow(['index']);
            //return;
        }
        if (!isset($user['role'])) {
            $this->Auth->allow(['register','index']);
        //return;
        }
        return parent::isAuthorized($user);
    }

User which have role allowed to called method is able to call method, others are redirected to not allowed method page. After logout is user redirected globally to login page.

I tried a few combinations based on the following tutorials:

http://book.cakephp.org/3.0/en/tutorials-and-examples/blog-auth-example/auth.html

But without the luck

How can i do it in the right way please?

Many thanks for any advice.

Upvotes: 2

Views: 3511

Answers (1)

Greg Schmidt
Greg Schmidt

Reputation: 5099

isAuthorized is the wrong place to be calling allow. Move your allow calls to beforeFilter, and reserve isAuthorized (which should just return a boolean) for anything more fine-grained, like if a particular user has access to edit some items but not others.

Something like this:

public function beforeFilter($event)
{
    parent::beforeFilter($event);
    $user = $this->Auth->user();

    if (isset($user['role']) && $user['role'] === 'ADMIN' ||
        isset($user['role']) && $user['role'] === 'MANAGER' ) {
        $this->Auth->allow(['logout', 'index','delete']);
    }
    if (isset($user['role']) && $user['role'] === 'PARTNER') {
        $this->Auth->allow(['index']);
    }
    if (!isset($user['role'])) {
        $this->Auth->allow(['register','index']);
    }
}

Upvotes: 3

Related Questions