intro
This article shows code of access control using Zend_Acl especially with DB.
You can see the screens from the demonstration site.
You can see the screens from the demonstration site.
1.Create Tables
In this article, the following tables are used.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
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
This controller checks the access privileges including the resource in the function
application/constorllers/MessageController.php
with the following content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
<?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 { $id = isset($session->current_id) ? $session->current_id : null; $id = isset($_GET['id']) ? $_GET['id'] : $id; $resource = $this->_acl->getResource($id, $session->member_id); if (!$this->_acl->isAllowed($session->role, $resource, $action)) { $this->_helper->redirector('deny'); } } } $this->view->name = "message"; $this->view->of = $this->_getOutputFilter(); } public function indexAction() { // Select project and 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() { } } |
This controller checks the access privileges including the resource in the function
preDispatch
.
1 2 3 4 |
$id = isset($session->current_id) ? $session->current_id : null; $id = isset($_GET['id']) ? $_GET['id'] : $id; $resource = $this->_acl->getResource($id, $session->member_id); if (!$this->_acl->isAllowed($session->role, $resource, $action)) |
3.Create Models
Create the file
This class sets the acl including resources in the constructor.
The other models are same as the previous article.
application/models/acls/MessageAcl.php
with the following content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
<?php require_once 'Zend/Acl.php'; require_once 'Zend/Acl/Role.php'; require_once 'Zend/Acl/Resource.php'; require_once APP_BASE . '/models/Messages.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')); $messages = new Messages(); $rowset = $messages->fetchAll(); foreach($rowset as $row) { $resource = $this->getResource($row->id, $row->member_id, false); $this->add($resource); $this->allow($user, $resource, array('update', 'delete')); } } public function getResource($message_id, $member_id, $check = true) { if ($message_id == null || $member_id == null) { return null; } $resource_name = 'message_' . $message_id . '_' . $member_id; $resource = new Zend_Acl_Resource($resource_name); if (!$check || $this->has($resource)) { return $resource; } return null; } } |
This class sets the acl including resources in the constructor.
The other models are same as the previous article.
4.Create Views
The views are same as the previous article.
5.Check
Access the web server and check that some members can’t edit messages.
History
Date | Content |
---|---|
2008/5/10 | Published |
Wow. This is the first time I’ve seen someone not blabber on for years and produce 10 lines of code I could figure out myself. I haven’t even begun to read through you’re articles, but I’m very excited. You’re personality fits me well.