Karim Taha
Karim Taha

Reputation: 1241

How to access model data in SecurityPlugin (Acl) in Phalcon PHP?

I am working on a small project where I have to implement an Acl, so i tried to implement it like in the sample invo project and it worked well. However, I want to add to the functionality that it gets its roles from the existing model called Role. Whenever I add the line $roles = Role::find(); there is an error in the application. Is it not possible to access this data from a plugin? Or if possible how to access it? Here is my SecurityPlugin file

<?php

use Phalcon\Acl;
use Phalcon\Acl\Role;
use Phalcon\Acl\Resource;
use Phalcon\Events\Event;
use Phalcon\Mvc\User\Plugin;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Acl\Adapter\Memory as AclList;

/**
 * SecurityPlugin
 *
 * This is the security plugin which controls that users only have access to the modules they're assigned to
 */
class SecurityPlugin extends Plugin
{

    /**
     * Returns an existing or new access control list
     *
     * @returns AclList
     */
    public function getAcl()
    {


        if (!isset($this->persistent->acl)) {

            $acl = new AclList();

            $acl->setDefaultAction(Acl::DENY);

            //Register roles **this is the line that causes the problem**

            $roles = Role::find();

            $acl->addRole(new Role('Guest'));
            $acl->addRole(new Role('User'));


            //Public area resources
            $publicResources = array(
                'index'      => array('index'),
                'User'       => array('new'),
                'Errors'     => array('show401'),
                'Session'    => array('index', 'register', 'start', 'end')
                );
            foreach ($publicResources as $resource => $actions) {
                $acl->addResource(new Resource($resource), $actions);
            }

            foreach ($publicResources as $resource => $actions) {
                foreach ($actions as $action) {
                    $acl->allow('Guest', $resource, $action);
                    $acl->allow('User', $resource, $action);
                }
            }

            //Grant access to public areas to both users and guests

            //The acl is stored in session, APC would be useful here too
            $this->persistent->acl = $acl;
        }

        return $this->persistent->acl;
    }

    /**
     * This action is executed before execute any action in the application
     *
     * @param Event $event
     * @param Dispatcher $dispatcher
     */
    public function beforeDispatch(Event $event, Dispatcher $dispatcher)
    {

        $auth = $this->session->get('auth');
        if (!$auth){
            $role = 'Guest';
        } else {
            $role = 'User';
        }

        $controller = $dispatcher->getControllerName();
        $action = $dispatcher->getActionName();

        if ($auth['username'] == 'Admin') {
            return;
        }

        $acl = $this->getAcl();

        $allowed = $acl->isAllowed($role, $controller, $action);
        if ($allowed != Acl::ALLOW) {
            $dispatcher->forward(array(
                'controller' => 'Errors',
                'action'     => 'show401'
                ));
            $this->session->destroy();
            return false;
        }
    }
}

and here is the related code in services.php

$di->set('dispatcher', function() use ($di) {

    $eventsManager = new EventsManager;

    /**
     * Check if the user is allowed to access certain action using the SecurityPlugin
     */
    $eventsManager->attach('dispatch:beforeDispatch', new SecurityPlugin);

    $dispatcher = new Dispatcher;
    $dispatcher->setEventsManager($eventsManager);

    return $dispatcher;
});

Upvotes: 2

Views: 919

Answers (1)

James Fenwick
James Fenwick

Reputation: 2211

It looks like your Role model and the Phalcon\Acl\Role are colliding.

I would alias your Role model to something like RoleModel.

<?php
use Phalcon\Acl\Role;
use \Role as RoleModel;
...
class SecurityPlugin extends Plugin {
  public function getAcl() {
    ...
    $roles = RoleModel::find();
    ...

Upvotes: 4

Related Questions