Chapter 2. Xyster_Acl

Table of Contents

2.1. Introduction
2.1.1. Authorizers
2.2. The ACL Role Provider

2.1. Introduction

Xyster_Acl is an extension of Zend_Acl. It is an access control list used to define rules where roles are granted or denied access to resources. If any of this sounds unfamiliar to you, check out the documentation for Zend_Acl.

To put it simply, we found that the Zend_Acl object was lacking something important. As is, each rule in the ACL must be defined explicitly. While this is fine for broad permissions setups, anything fine-grained will quickly result in an obscene amount of rules loaded unnecessarily, especially when access to a resource is dependent on things about the role accessing it. Ultimately, the access control list needs the ability to determine its rules on the fly.

What about Zend_Acl_Assert classes, you say? These are objects that determine if a rule is valid when queried. This idea would be perfect if these objects were passed the role, resource, and privilege currently being queried—not the ones with which the rule was defined.

Seeing no readily available solution to this problem, we came up with the idea of authorizers.

2.1.1. Authorizers

An ACL Authorizer is just a class that implements Xyster_Acl_Authorizer_Interface. It has two methods:

  1. applies – Does the authorizer apply to the supplied resource?

  2. isAllowed – Passed the role, resource, and privilege currently being queried and returns a boolean if the role should be given access to the resource with the given privilege.

A Xyster_Acl object can be loaded with one or more authorizer. Each authorizer can apply to a different type of resource. As an example, let's say you have two objects that implement Zend_Acl_Resource_Interface: Document and Article. You can have a Document_Authorizer and an Article_Authorizer to determine if users can perform certain actions on Documents and Articles.

<?php
class Document_Authorizer implements Xyster_Acl_Authorizer_Interface
{
	public function applies( Zend_Acl_Resource_Interface $resource )
	{
		return $resource instanceof Document;
	}
	public function isAllowed( Zend_Acl_Role_Interface $role = null, Zend_Acl_Resource_Interface $resource = null, $privilege = null )
	{
		if ( $resource !== null && $role !== null ) {
			return $role->getRoleId() == $resource->userId;
		}
		return false;
	}	
}
$acl = new Xyster_Acl;
$acl->addAuthorizer(new Document_Authorizer);

So according to this object, if a role's id is the same as the userId property of the Document, the role should be allowed access. Once the Xyster_Acl receives a response, it creates the rule and never has to re-query the authorizer.

If the Xyster_Acl goes through all of its authorizers and can't find one that applies to the resource, it assumes the default rule in the ACL, which is usually to deny access.