MyApp_Controller_Plugin_Auth
class MyApp_Controller_Plugin_Auth extends Zend_Controller_Plugin_Abstract
{
protected $_auth;
protected $_authName = 'auth';
protected $_acl;
protected $_aclName = 'acl';
protected $_aclRoute = '%s.%s';
protected $_noauth = array('module' => 'default',
'controller' => 'login',
'action' => 'index');
protected $_noacl = array('module' => 'default',
'controller' => 'error',
'action' => 'privileges');
public function setNoAuth($action, $controller = null, $module = null)
{
if ($module !== null) {
$this->_noauth['module'] = $module;
}
if ($controller !== null) {
$this->_noauth['controller'] = $controller;
}
$this->_noauth['action'] = $action;
}
public function setNoAcl($action, $controller = null, $module = null)
{
if ($module !== null) {
$this->_noacl['module'] = $module;
}
if ($controller !== null) {
$this->_noacl['controller'] = $controller;
}
$this->_noacl['action'] = $action;
}
public function preDispatch($request)
{
$controller = $request->getControllerName();
$action = $request->getActionName();
$module = $request->getModuleName();
$resource = sprintf($this->_aclRoute, $module, $controller);
if (!$this->_getAcl()->has($resource)) {
$resource = null;
}
if (!$this->_getAcl()->isAllowed($resource, $action)) {
if (!$this->_getAuth()->hasIdentity()) {
$module = $this->_noauth['module'];
$controller = $this->_noauth['controller'];
$action = "">
} else {
$module = $this->_noacl['module'];
$controller = $this->_noacl['controller'];
$action = "">
}
}
$request->setModuleName($module);
$request->setControllerName($controller);
$request->setActionName($action);
}
protected function _getAcl()
{
if ($this->_acl === null) {
$this->_acl = Zend_Controller_Front::getInstance()->getParam($this->_aclName);
if (!($this->_acl instanceof Zend_Acl)) {
throw new Zend_Controller_Dispatcher_Exception('no ACL has been passed to the front controller');
}
}
return $this->_acl;
}
protected function _getAuth()
{
if ($this->_auth === null) {
$this->_auth = Zend_Auth::getInstance();
}
return $this->_auth;
}
}
The 'index' and 'view' actions are fairly straight-forward. The 'updateAction' shows the ACL rules in operation...
class BlogController extends PeptoKit_Controller
{
protected $_acl;
public function init()
{
$this->_acl = $this->getInvokeArg('acl');
}
public function indexAction()
{
$blog = new MyApp_Blog();
$this->view->blog = $blog->fetchAll();
}
public function viewAction()
{
$blog = new MyApp_Blog();
$entry = $blog->find($this->getParam()->post)->current();
if (!$entry) {
return $this->_forward('missing', 'error');
}
$this->view->blog = $entry;
}
public function addAction()
{
...form and business logic...
}
public function updateAction()
{
$blog = new MyApp_Blog();
$entry = $blog->find($this->getParam()->post)->current();
if (!$entry) {
return $this->_forward('missing', 'error');
}
if (!$this->_acl->isAllowed($entry, 'update')) {
return $this->_forward('permissions', 'error');
}
...form and business logic...
}
}
Shows the 'isAllowed' helper in action - if a visitor is not authorised or not privileged they won't see the 'Update' widget.
....
So that string of components has allowed me to create a reasonably flexible implementation. If anyone has anything further to add to this I'd be most keen to hear - it's been fun finding my way through this one!