View Source

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{composition-setup}{composition-setup}]]></ac:plain-text-body></ac:macro>
<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{zone-template-instance:ZFPROP:Proposal Zone Template}
{note:title=Under Construction}
This proposal is under construction and is not ready for review.
{note}

{zone-data:component-name}
Zend_Acl & Zend_Acl_Adapter
{zone-data}

{zone-data:proposer-list}
[Niek Slatius]
{zone-data}

{zone-data:liaison}
TBD
{zone-data}

{zone-data:revision}
0.1 - 17 December 2008: Initial Draft.
{zone-data}

{zone-data:overview}
Zend_Acl is a component that manages ACL rules. Zend_Acl currently has no (flexible) support for retreiving ACL rules from persistent sources and no support for storing ACL rules to persistent sources. This improvement wil provide support for aforementioned functionality by adding support for adapters to the Zend_Acl component.
{zone-data}

{zone-data:references}
* [Access control list Wikipedia Entry|http://en.wikipedia.org/wiki/Access_control_list]
{zone-data}

{zone-data:requirements}
* Zend_Acl *will* add have support for accepting an adapter from which this component can read ACL rules
* Zend_Acl *will* add have support for accepting an adapter to which this component can write ACL rules
* Zend_Acl *will* add have support for accepting a default adapter for each new instance of Zend_Acl
* Zend_Acl *will* add have support for accepting a default readonly value for each new instance of Zend_Acl
{zone-data}

{zone-data:dependencies}
* Zend_Acl_Exception
{zone-data}

{zone-data:operation}
The component will provide an interface to which an instance of a Zend_Acl_Adapter_Interface can be provided.

This Zend_Acl_Adapter_Interface will provide support for reading:
* roles
* recources
* privileges

This Zend_Acl_Adapter_Interface will provide support for writing:
* save (roles, recources and privileges in one go, because of possible integrity constraint handling )

The Zend_Acl_Adapter_Interface will also provide support for being set as readonly.
{zone-data}

{zone-data:milestones}
* Milestone 1: Requirement specifications
* Milestone 2: Receive comments from the community about draft / suggestions from community for further improvements
* Milestone 3: Create working prototype
{zone-data}

{zone-data:class-list}
* Zend_Acl
* Zend_Acl_Exception
* Zend_Acl_Adapter_Exception
* Zend_Acl_Adapter_Interface
* Zend_Acl_Adapter_Abstract
{zone-data}

{zone-data:use-cases}

config.ini:
{code:ini}
database.adapter = pdo_mysql
database.params.host = localhost
database.params.dbname = zendtest
database.params.username = ****
database.params.password = ****

acl.resourcetable.name = aclresource
acl.resourcetable.resourceColumn = id
acl.resourcetable.resourceParentColumn = aclresourceId
acl.privilegetable.name = aclprivilege
acl.privilegetable.roleColumn = aclroleId
acl.privilegetable.resourceColumn = aclresourceId
acl.privilegetable.nameColumn = name
acl.privilegetable.allowColumn = allow
acl.roletable.name = aclrole
acl.roletable.primary = id
acl.role2roletable.name = aclrole_aclrole
acl.role2roletable.roleColumn = aclroleId
acl.role2roletable.roleParentColumn = aclroleParentId
acl.readonly = 1
{code}

{deck:id=Use Cases}
{card:label=Use Case 1}

This example shows the usage with a fictional Zend_Acl_Adapter_Db

Set adapter through constructor and autoload rules
{code:php}

$configuration = new Zend_Config_Ini( 'config.ini' );

$db = Zend_Db::factory( $configuration->database->adapter, $configuration->database->params->toArray() );

$aclAdapterDb = new Zend_Acl_Adapter_Db( $db, $configuration->acl->toArray() );

$acl = new Zend_Acl( $aclAdapterDb, true );

if( !$acl->isAllowed( 'guest', 'guestbook', 'read' ) )
{
echo 'Sorry buddy, out of luck';
}
{code}
{card}
{card:label=Use Case 2}

This example uses same fictional Zend_Acl_Adapter_Db

Set adapter and load from adapter (fluent)
{code:php}

$configuration = new Zend_Config_Ini( 'config.ini' );

$db = Zend_Db::factory( $configuration->database->adapter, $configuration->database->params->toArray() );

$aclAdapterDb = new Zend_Acl_Adapter_Db( $db, $configuration->acl->toArray() );

$acl = new Zend_Acl();
$acl->setAdapter( $aclAdapterDb )->load();

if( !$acl->isAllowed( 'guest', 'guestbook', 'read' ) )
{
echo 'Sorry buddy, out of luck';
}
{code}
{card}
{card}
{card:label=Use Case 3}

This example uses same fictional Zend_Acl_Adapter_Db

Set adapter, (un)set some rule, and try to save
{code:php}

$configuration = new Zend_Config_Ini( 'config.ini' );

$db = Zend_Db::factory( $configuration->database->adapter, $configuration->database->params->toArray() );

$aclAdapterDb = new Zend_Acl_Adapter_Db( $db, $configuration->acl->toArray() );

$acl = new Zend_Acl();

// set adapter (but don't override readonly setting) and fluently load rules
$acl->setAdapter( $aclAdapterDb )->load();

$acl->removeDeny( 'guest', 'guestbook', 'read' );

try
{
// throws Zend_Acl_Exception, because default readonly = true and because config setting for Zend_Acl_Adapter_Db was also set to true
$acl->save();
}
catch( Zend_Acl_Exception $e )
{
$acl->setReadonly( false );
// will work now
$acl->save();
}
{code}
{card}
{card:label=Use Case 4}

This example uses same fictional Zend_Acl_Adapter_Db

Set adapter, (un)set some rule, and save
{code:php}

$configuration = new Zend_Config_Ini( 'config.ini' );

$db = Zend_Db::factory( $configuration->database->adapter, $configuration->database->params->toArray() );

$aclAdapterDb = new Zend_Acl_Adapter_Db( $db, $configuration->acl->toArray() );

$acl = new Zend_Acl();

// set adapter and set readonly to false and fluently load rules
$acl->setAdapter( $aclAdapterDb, false )->load();

// remove deny rule
$acl->removeDeny( 'guest', 'guestbook', 'read' );

// save all changes to persistent storage
$acl->save();
{code}
{deck}
{zone-data}

{zone-data:skeletons}
{deck:id=Skeletons}
{card:label=Zend_Acl}
{code:php}

// for Zend_Acl: only improved / new methods are shown
class Zend_Acl
{
protected static $_defaultAdapter;
protected static $_defaultReadOnly = true;
protected static $_defaultAutoload = false;

protected $_adapter;

public function __construct( Zend_Acl_Adapter_Interface $adapter = null, $autoload = self::$_defaultAutoload )
{
}

public static function setDefaultAdapter( Zend_Acl_Adapter_Interface $adapter, $readOnly = null )
{
}

public function setAdapter( Zend_Acl_Adapter_Interface $adapter, $readOnly = null )
{
}

public function hasAdapter()
{
}

public static function setDefaultReadOnly( $readOnly = true )
{
}

public function setReadOnly( $readOnly = true )
{
}

public function isReadOnly()
{
}

public static function setDefaultAutoload( $readOnly = true )
{
}

public function load()
{
}

public function loadRoles()
{
}

public function loadResources()
{
}

public function loadPrivileges()
{
}

public function save()
{
}

protected function _addRoleRecursive( $role, $ascendantIds = array() )
{
}

protected function _addRecursive( $resource, $ascendantIds = array() )
{
}
}
{code}
{card}
{card:label=Zend_Acl_Exception}
{code:php}

class Zend_Acl_Exception extends Zend_Exception
{
}
{code}
{card}
{card:label=Zend_Acl_Adapter_Exception}
{code:php}

class Zend_Acl_Adapter_Exception extends Zend_Acl_Exception
{
}
{code}
{card}
{card:label=Zend_Acl_Adapter_Interface}
{code:php}

interface Zend_Acl_Adapter_Interface
{

public function getRoles();

public function getResources();

public function getPrivileges();

public function setReadOnly( $readOnly = true );

public function isReadOnly();

public function save( array $roles, array $resources, array $privileges );

}
{code}
{card}
{card:label=Zend_Acl_Adapter_Abstract}
{code:php}

abstract class Zend_Acl_Adapter_Abstract implements Zend_Acl_Adapter_Interface
{

protected $_readOnly = true;

public function setReadOnly( $readOnly = true )
{}

public function isReadOnly()
{}

}
{code}
{card}
{deck}
{zone-data}

{zone-template-instance}]]></ac:plain-text-body></ac:macro>