sFire PHP Framework

Permissions / Access Control List

Access Control List or ACL is a list of permissions attached to an resource. An ACL specifies which users/roles or system processes are granted access to resources, as well as what operations are allowed on given resources. This way you can create user roles like administrators, moderators and guests and attach resources to them. For example, the administrator role may view, edit and delete a blog post and a guest may only view the blog post.

sFire\Permissions\ACL will give you the option to create user roles and resources.

In this section we will handle:

  • ACL as a service
  • Creating roles and resources
  • Allow access to resources
  • Deny access to resources
  • Check if a role is allowed to a resource
  • Retrieve all roles
  • Retrieve all resources
  • Retrieve all resources from a specific role
  • Role inheritance
  • Use ACL in the View

ACL as a service

To use sFire\Permissions\ACL you can create a ACL service in the app.php:

use sFire\Permissions\ACL;

//Service providers
Application :: add('services', [

    'acl' => function() {
        return new sFire\Permissions\ACL();
    }
]);

Our ACL instance is called "acl" as a key for obtaining this instance in controllers and mappers.

$this -> service('acl');

Creating roles and resources

It is easy to create roles and resources. All the roles and resources will be saved in an Array like:

$roles      = ['administrator', 'moderator'];
$resources  = ['blog.edit', 'blog.delete', 'blog.create', 'blog.view'];

Allow access to resources

To allow access from roles to resources, you may use the allow method:

$roles      = ['administrator', 'moderator'];
$resources  = ['blog.edit', 'blog.delete', 'blog.create', 'blog.view'];

$acl -> allow($roles, $resources);

Deny access to resources

To deny access from roles to resources, you may use the deny method:

$roles      = ['guests'];
$resources  = ['blog.edit', 'blog.delete', 'blog.create'];

$acl -> deny($roles, $resources);

Check if a role is allowed or denied to a resource

To check if a specific role has access to a resource, you may use the isAllowed method. First create the roles and resources:

$roles      = ['administrator', 'moderator'];
$resources  = ['blog.edit', 'blog.delete', 'blog.create', 'blog.view'];

$acl -> allow($roles, $resources);

Then, check if a role is allowed access to a resource:

$role       = 'administrator';
$resource   = 'blog.edit';

if(true === $acl -> isAllowed($role, $resource)) {
    //The administrator role is allowed to edit the blog post
}

You can also use the getRole in combination with the hasResource method:

$role       = 'administrator';
$resource   = 'blog.edit';

if(true === $acl -> getRole($role) -> hasResource($resource)) {
    //The administrator role is allowed to edit the blog post
}

If you want to check if a specific role doesn't have access to a resource, you can use the isDenied method.

$role       = 'guest';
$resource   = 'blog.edit';

if(true === $acl -> isDenied($role, $resource)) {
    //The guest role is not allowed to edit the blog post
}

You can also use the getRole method in combination with the hasResource method for an inverse statement:

$role       = 'guest';
$resource   = 'blog.edit';

if(false === $acl -> getRole($role) -> hasResource($resource)) {
    //The guest role is not allowed to edit the blog post
}

Retrieve all roles

If you want to know all the roles, you may use the getRoles method. This method will return an Array with the role as key and a sFire\Permissions\Resources object as value:

$roles      = ['administrator', 'moderator'];
$resources  = ['blog.edit', 'blog.delete', 'blog.create', 'blog.view'];
$acl -> allow($roles, $resources);

$roles = $this -> service('acl') -> getRoles();

print_r($roles); 

//Output similar to: 
Array
(
    [administrator] => sFire\Permissions\Resources Object
        (
            [resources:sFire\Permissions\Resources:private] => Array
                (
                    [blog.edit] => 1
                    [blog.delete] => 1
                    [blog.create] => 1
                    [blog.view] => 1
                )
        )
    [moderator] => sFire\Permissions\Resources Object
        (
            [resources:sFire\Permissions\Resources:private] => Array
                (
                    [blog.edit] => 1
                    [blog.delete] => 1
                    [blog.create] => 1
                    [blog.view] => 1
                )
        )
)

Retrieve all resources

If you want to know all the resources, you may use the getResources method. This methods will return an Array with all the resources:

$acl -> allow('administrator', ['blog.edit', 'blog.delete', 'blog.create', 'blog.view']);
$acl -> allow('guest', ['blog.view', 'blog.comment']);

$resources = $acl -> getResources();

print_r($resources); 

//Output similar to:
Array
(
    [0] => blog.edit
    [1] => blog.delete
    [2] => blog.create
    [3] => blog.view
    [4] => blog.comment
)

You may use the first parameter to filter the resources you wish to return. This parameter is a Regular Expression:

$resources = $acl -> getResources('create');

print_r($resources); 

//Output similar to:
Array
(
    [0] => blog.create
)

As you can see, only the "blog.create" is returned because only this permission matches the Regular Expression "create" we gave as parameter.

Rerieve all resources from specific role

To retrieve all the resources from a role, you may do this like:

$resources = $acl -> getRole('administrator') -> getResources();

print_r($resources);

//Output similar to:
Array
(
    [0] => blog.edit
    [1] => blog.delete
    [2] => blog.create
    [3] => blog.view
)

You can also use the first parameter to filter the resources you wish to return. This parameter is a Regular Expression:

$resources = $acl -> getRole('administrator') -> getResources('create');

print_r($resources); 

//Output similar to:
Array
(
    [0] => blog.create
)

Role inheritance

The "guest" role may view blog posts, just like the "administrator" role. But the administrator may also edit, delete and create blog post. To prevent duplicate resources, you can inherit roles by using the inherit method:

$acl -> allow('guest', ['blog.view']);
$acl -> allow('administrator', ['blog.edit', 'blog.delete', 'blog.create']);

$acl -> inherit('administrator', 'guest');

This way the administrator role will inherit all the resources of the guest role.

Use ACL in the View

Of course it is possible to use the ACL service in the view. Just create a new Viewmodel and assign the ACL service as a variable to the view:

Controller:

use sFire\MVC\ViewModel;

$view = new ViewModel('home.index');
$view -> assign('acl', $this -> service('acl'));

View:

@if($acl -> isAllowed('administrator', 'blog.delete')
    //administrator is allowed
@endif