Home > Zend_Acl > Implementing Access Control using Zend_Acl

Implementing Access Control using Zend_Acl

intro
This article shows an implementation of Access Control using Zend_Acl.
You can check the screens from demonstration site.

1.Create Tables
In this article, the following tables are used.

CREATE TABLE members
(
    id             integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    role_id        integer        NOT NULL,
    nick_name      varchar(100)   NOT NULL,
    email          varchar(200)   NOT NULL
);
 
CREATE TABLE roles
(
    id             integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    role_name      varchar(20)    NOT NULL,
    privileges    varchar(10)    NOT NULL
);
 
CREATE TABLE messages
(
    id             integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    member_id      integer        NOT NULL,
    message        text           NOT NULL
);
2.Create Controller
Create the file application/constorllers/MessageController.php with the following content.

<?php
require_once 'My/Controller/Simple.php';
require_once APP_BASE . '/models/Roles.php';
require_once APP_BASE . '/models/Members.php';
require_once APP_BASE . '/models/Messages.php';
require_once APP_BASE . '/models/forms/MessageForm.php';
require_once APP_BASE . '/models/acls/MessageAcl.php';
 
class MessageController extends My_Controller_Simple
{
    protected $_session_name = "Message";
    protected $_table_class = "Messages";
    protected $_form_class = "MessageForm";
 
    protected $_acl = null;
 
    protected function _getOutputFilter($data = null)
    {
        $messages = new Messages();
        return $messages->getOutputFilter($data);
    }
 
    public function getForm()
    {
        $form = parent::getForm();
        $form->getElement('member_id')->setValue($this->getSession()->member_id);
        return $form;
    }
 
    public function getLoginForm()
    {
        $members = new Members();
        $member_options = $members->getOptions();
 
        $form = new Zend_Form(array(
            'method'   => 'post',
            'action'   => $this->_helper->url->url(array('action'=>'index')),
            'elements' => array(
                'member' => array('select', array(
                    'required' => true,
                    'label' => 'member',
                    'multiOptions' => $member_options,
                    'validators' => array(
                        array('inArray', true, array(array_keys($member_options)))
                    ),
                )),
                'submit' => array('submit', array(
                    'label' => 'Login',
                    'decorators' => array(
                        'ViewHelper',
                        array('HtmlTag', array('tag' => 'dt', 'class' => 'submit'))
                    )
                ))
            ),
        ));
 
        return $form;
    }
 
    public function init()
    {
        parent::init();
        $this->_acl = new MessageAcl();
    }
 
    public function preDispatch()
    {
        parent::preDispatch();
        $action = $this->getRequest()->getActionName();
        $session = $this->getSession();
        if ($action != 'index' && $action != 'deny')
        {
            if (!isset($session->role))
            {
                $this->_helper->redirector('index');
            }
            else if (!$this->_acl->isAllowed($session->role, null, $action))
            {
                $this->_helper->redirector('deny');
            }
        }
        $this->view->name = "message";
        $this->view->of = $this->_getOutputFilter();
    }
 
    public function indexAction()
    {
        // Select member
        $this->view->action = $this->getRequest()->getActionName();
        $form = $this->getLoginForm();
        $session = $this->getSession();
        if ($this->getRequest()->isPost())
        {
            if ($form->isValid($_POST))
            {
                $values = $form->getValues();
                $members = new Members();
                $member = $members->find($values['member'])->current();
                if ($member)
                {
                    $role = $member->findParentRoles();
                    if ($role)
                    {
                        $session->member_id = $values['member'];
                        $session->role = $role->role_name;
                        $this->_helper->redirector('list');
                    }
                }
            }
        }
        $this->view->form = $form;
        return $this->render('form');
    }
 
    public function denyAction()
    {
    }
}
3.Create Models
Create the file application/models/Messages.php with the following content.

<?php
require_once 'Zend/Db/Table/Abstract.php';
require_once APP_BASE . '/models/Members.php';
 
class Messages extends Zend_Db_Table_Abstract
{
    protected $_name = 'messages';
 
    public function getOutputFilter($data = null)
    {
        $members = new Members();
        $member_options = $members->getOptions();
        // add other filters
        $filters = array(
            'member_id' => array(array('ArrayValue', $member_options))
        );
        $of = new Zend_Filter_Input($filters, null, $data);
        $of->addFilterPrefixPath('My_Filter', 'My/Filter/');
        return $of;
    }
}

Create the file application/models/forms/MessageForm.php with the following content.

<?php
require_once 'Zend/Form.php';
require_once APP_BASE . '/models/Members.php';
 
class MessageForm extends Zend_Form
{
    public function __construct()
    {
        $members = new Members();
        $member_options = $members->getOptions();
 
        parent::__construct();
        $member_id = $this->createElement('hidden', 'member_id');
        $member_id->setRequired(true)
                  ->addFilter('stringTrim')
                  ->addValidator('inArray', false, array(array_keys($member_options)));
        $message = $this->createElement('textarea', 'message');
        $message->setLabel('message')
                ->setAttribs(array('cols'=>'40', 'rows'=>'10'))
                ->setRequired(true)
                ->addFilter('stringTrim')
                ->addValidator('stringLength', false, array(1,1000));
 
        $this->addElements(array(
            $member_id, $message
        ));
    }
}

Create the file application/models/acls/MessageAcl.php with the following content.

<?php
require_once 'Zend/Acl.php';
require_once 'Zend/Acl/Role.php';
 
class MessageAcl extends Zend_Acl
{
    public function __construct()
    {
        $admin = new Zend_Acl_Role('admin');
        $user = new Zend_Acl_Role('user');
        $guest = new Zend_Acl_Role('guest');
 
        $this->addRole($admin);
        $this->addRole($guest);
        $this->addRole($user, $guest);
 
        $this->allow($admin);
 
        $this->allow($guest, null, array('list', 'detail'));
 
        // user is allowed list and view also
        $this->allow($user, null, array('add'));
    }
}
4.Create Views
Create the file application/views/scripts/message/list.phtml with the following content.

 
<h1><?= $this->translate($this->name . '.title.list') ?></h1>
 
<?php if (!$this->list) : ?>
<span><?= $this->translate($this->name . 'label.no_data') ?></span>
<?php else : ?>
<a href="<?=$this->url(array('action'=>'add'))?>">
<?= $this->translate($this->name . '.label.new') ?></a>
<table>
<?php   $this->header = true; ?>
<?php   foreach($this->list as $row) :
          $values = $row->toArray();
          $this->of->setData($values);
          if ($this->header) : ?>
<tr>
<?php       foreach($values as $key => $value) : ?>
<th><?= $this->translate($key) ?></th>
 
<?php       endforeach; ?>
<th><?= $this->translate('detail') ?></th>
<th><?= $this->translate('edit') ?></th>
<th><?= $this->translate('delete') ?></th>
 
<?php       $this->header = false; ?>
</tr>
 
<?php     endif; ?>
<tr>
<?php       foreach($values as $key => $value) : ?>
<td><?= $this->of->$key ?></td>
 
<?php       endforeach; ?>
<td><a href="<?=$this->url(array('action'=>'detail'))?>?id=<?=$values['id']?>">
  <?= $this->translate('detail') ?></a></td>
<td><a href="<?=$this->url(array('action'=>'update'))?>?id=<?=$values['id']?>">
  <?= $this->translate('edit') ?></a></td>
<td><a href="<?=$this->url(array('action'=>'delete'))?>?id=<?=$values['id']?>">
  <?= $this->translate('delete') ?></a></td>
</tr>
 
<?php   endforeach; ?>
</table>
 
<span><?= $this->translate($this->name . '.label.max') ?></span>
<?php endif; ?>

Create the file application/views/scripts/message/form.phtml with the following content.

 
<h1><?= $this->translate($this->name . '.title.' . $this->action) ?></h1>
 
<?= $this->form ?>

Create the file application/views/scripts/message/detail.phtml with the following content.

 
<h1><?= $this->translate($this->name . '.title.detail') ?></h1>
 
<?php if ($this->values) : ?>
<?php   $this->of->setData($this->values); ?>
<dl>
<?php foreach($this->values as $key => $value) : ?>
<dt><?= $this->translate($key) ?></dt>
<dd><?= $this->of->$key ?></dd>
 
<?php endforeach; ?>
</dl>
 
<?php endif; ?>
<?php if ($this->form) : ?>
<?= $this->form ?>
<?php endif; ?>

Create the file application/views/scripts/message/finish.phtml with the following content.

 
<h1><?= $this->translate($this->name . '.title.finish.' . $this->action) ?></h1>
 
<a href="<?=$this->url(array('action'=>'list'))?>">
<?= $this->translate('back') ?></a>

Create the file application/views/scripts/message/deny.phtml with the following content.

 
<h1><?= $this->translate($this->name . '.title.deny') ?></h1>
<div><?= $this->translate($this->name . '.label.deny') ?></div>
 
<a href="<?=$this->url(array('action'=>'index'))?>">
<?= $this->translate('login') ?></a>
 
<a href="<?=$this->url(array('action'=>'list'))?>">
<?= $this->translate('back') ?></a>

5.Check
Access the web server and check that some members can't edit messages.
History
Date Content
2008/5/9 Published
2008/5/9 MessageAcl was fixed.(changed from 'view' to 'detail')

Comments:0

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://www.oplabo.com/article/44/trackback
Listed below are links to weblogs that reference
Implementing Access Control using Zend_Acl from Open Programming Laboratory

Home > Zend_Acl > Implementing Access Control using Zend_Acl

Japanese
Search
Feeds

Return to page top