TalkPHP

TalkPHP (http://www.talkphp.com/forums.php)
-   Script Giveaway (http://www.talkphp.com/script-giveaway/)
-   -   Simple ACL (http://www.talkphp.com/script-giveaway/5203-simple-acl.html)

Enfernikus 01-02-2010 12:51 AM

Simple ACL
 
I was in need of a really simple ACL so I just made my own ( I would've liked to use Zend's but the need for it was so small I couldn't justify including even a portion of that beast )

It's simple, it works off Resources & Roles just like Zends ( Albeit simplified ) and allows for role inheritance and binding ( Binding a particular role to a or set of resources )

Having made use of the __sleep magic method, this object can be serialized so the role(s) and resource(s) are store able.

You can see an example below

php Code:
<?php


$acl->addResource('forum', array('edit', 'view', 'delete', 'add'));

$acl->addRole('guest', null, array('view'), 'forum')
    ->addRole('user', 'guest', array('add'))
    ->addRole('moderator', 'user', array('edit', 'delete'))
    ->addRole('administrator');
   
if( $acl->isAllowed('moderator', 'edit', 'forum') )
    echo 'FOOO';

$acl->addResource('gallery', array('view'))
    ->addRole('guest', null, array('view'), 'gallery')
    ->addRole('user', 'guest', null, 'gallery')
    ->addRole('moderator', 'user', array('delete'), 'gallery');


if( $acl->isAllowed('user', 'view', 'gallery') )
    echo "FOOO";

$serializedObject = serialize($acl);
$acl2 = new System_Acl(unserialize($serializedObject));


The actual object is below:

php Code:
<?php

class System_Acl
{
    private $roles     = array();
    private $resources = array();
    private $bindings  = array();
   
        public function __construct( $unserializedACL = null )
        {
            // Restore object
            if( is_array($unserializedACL) && count($unserializedACL) == 3 )
            {
                $this->roles     = $unserializedACL['roles'];
                $this->resources = $unserializedACL['resources'];
                $this->bindings  = $unserializedACL['bindings'];
            }
        }
       
        public function __sleep()
        {
            // When we serialize the object for keeping
            return array(
                            'bindings'  => $this->bindings,
                            'roles'     => $this->roles,
                            'resources' => $this->resources
                        );
        }
       
        public function addResource( $resourceName, $actions = array() )
        {
            // Add a resource to be considered
            $this->resources[$resourceName] = $actions;
            return $this;
        }
       
        public function addRole( $roleName, $inherit = null, $allowedActions = array(), $addRoleTo = null )
        {
            $allowedActions = ( is_null($allowedActions) ) ? array() : $allowedActions;
           
            // Construct allowed actions array, if there's an inheritence add it
            $allowedActions = (!is_null($inherit) && array_key_exists($inherit, $this->roles)) ?
                                    array_merge($this->roles[$inherit], $allowedActions) : $allowedActions;
           
            // Add the role
            $this->roles[$roleName] = $allowedActions;   
           
            // If these rules are bound to a particular object
            // Add the bind
            if( (!is_null($addRoleTo) || array_key_exists($inherit, $this->bindings))  )
            {
                $resourceBind = ( is_null($addRoleTo) ) ? $this->bindings[$inherit] : $addRoleTo;
                if( !is_array($resourceBind) )
                {
                    if( array_key_exists($resourceBind, $this->resources) )
                        $this->bindings[$roleName][] = $resourceBind;   
                }else{
                    foreach( $resourceBind as $bindingResource )
                    {
                        if( array_key_exists($bindingResource, $this->resources) )
                            $this->bindings[$roleName] = $resourceBind
                    }
                }
            }
           
            return $this;
        }
       
        public function allow( $roleName, $actions = array() )
        {
            // Allow this role new powers
            if( array_key_exists($roleName, $this->roles) )
                $this->roles[$roleName] = array_merge($this->roles[$roleName], $actions);
            return $this;
        }
       
        public function deny( $roleName, $deniedActions )
        {
            // Deny him powers
            if( !is_array($deniedActions) )
                $deniedActions = array($deniedActions);
               
            if( array_key_exists($roleName, $this->roles) )
            {
                $roleActions = $this->roles[$roleName];
                $newRoleActions = array();
                foreach( $roleActions as $roleAction )
                {
                    if( !in_array($roleAction, $deniedActions) )
                        $newRoleActions[] = $roleAction;
                }
               
                $this->roles[$roleName] = $newRoleActions;
            }
           
            return $this;
        }
       
        public function isAllowed( $roleName, $action, $resoure = null )
        {
            if( array_key_exists($roleName, $this->roles) )
            {
                if( count($this->roles[$roleName]) == 0 )
                    return true;
               
                if( !is_null($resoure) )
                {
                    if( array_key_exists($resoure, $this->resources) && !in_array($action, $this->resources[$resoure]) )
                        return false;
                   
                    if( array_key_exists($roleName, $this->bindings) )
                    {
                        if( is_array($this->bindings[$roleName]) )
                        {
                            if( in_array($action, $this->roles[$roleName]) )
                                return true;
                        }elseif( is_string($this->bindings[$roleName]) && $resoure == $this->bindings[$roleName] )
                        {
                            if( in_array($action, $this->roles[$roleName]) )
                                return true;
                        }else{
                            if( in_array($action, $this->roles[$roleName]) )
                                return true;
                        }
                    }else{
                        return false;
                    }   
                }else{
                    if( in_array($action, $this->roles[$roleName]) )
                        return true;
                }
            }
           
            return false;
        }
}

captainCrest 06-26-2011 05:49 PM

Hehe. nice class. I was digging through interwebZ trying to solve exactly the same issue: find a smaller 80/20 replacement for Zend_Acl. Well - it seems like the one.
Thank you!


---------
there seem to be an error in this class in isAllowed() method:

When you compare
if( count($this->roles[$roleName]) == 0 )

IMHO - it should return FALSE, it's however returns TRUE in that method.


All times are GMT. The time now is 06:37 AM.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0