pulse14/cakephp-resolveauth

This package is abandoned and no longer maintained. No replacement package was suggested.
There is no license information available for the latest version (1.0.1) of this package.

Authorization plugin for CakePHP

Installs: 209

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 1

Forks: 0

Open Issues: 6

Type:cakephp-plugin

1.0.1 2017-10-03 09:21 UTC

This package is not auto-updated.

Last update: 2018-06-07 14:29:35 UTC


README

Build Status

CakePHP ResolveAuth - Authorization plugin

Authorization component/behavior for CakePHP ~3.0 ~3.1 NOTE : This is an experimental plugin.

Install with composer

    composer require pulse14/cakephp-resolveauth
    Plugin::load('ResolveAuth');

Why ?

  • Authorizations based on Group, Context and you can create your own.
  • You can check authorizations when you have the data required to do it. For example to check if a post belongs to an user.
  • Authorizations can hide fields in entities automatically, they can also change accessible fields.

Introduction

Load the the component.

You need two additionnal functions to handle unauthorized attempts and to get the current user informations (id and group name).

Even if you don't need the current user, it's used to generate the current AuthorizationContext.

    public function initialize()
    {
      $this->loadComponent('ResolveAuth.Authorization');
    }

    public function getUser(){
      return [
        'id' => 1,
        'group' => 'user' // Group must be present to use GroupAuthorization
      ];
    }

    // Redirect, throw exception,...
    public function unauthorized($rule){
      throw new Exception();
    }

Every controller (where authorizations are checked) needs to have buildAuthorization method :

public class PostsController extends AppController{
    public function buildAuthorization(AuthorizationComponent $authorization){
      //Build authorizations here
    }
    public function add(){
      //...
    }
    public function update(){
      //...
    }
}

You should use buildAuthorization to create new rules.

Examples

Different types of authorization are included in the plugin:

  • Group : checks user group name
  • Context : uses a callback function

Group Authorization with Group

    public function buildAuthorization($authorization){
        $authorization
            ->actions(['add', 'update'])
            ->group(['admin', 'moderator']);
    }

If add or update action is called, and the user isn't in admin or moderator group, unauthorized callback will be called.

Authorizations are checked after buildAuthorization. Other examples :

      $authorization
        ->actions('*')
        ->group(['admin','moderator']);
      $authorization
        ->actions('add')
        ->group('admin');

Context Authorization with Context

With context authorization you can specify callback.

    public function buildAuthorization($authorization){
        $authorization
            ->actions(['add', 'update'])
            ->context([$this, 'callback']);
    }

    public function callback($context){
        return $context->user['id'] == 1;
    }

$context is the current authorization context. $context contains the:

  • Controller
  • Action
  • Request
  • Current user
  • And the authorization manager which create the context, usually AuthorizationComponent

If you want to check if a post belongs to an user before update it : you can't do it this way because you don't know to which user the post belongs at this point.

Late resolution

It's possible to register an authorization to resolve it later.

In ResolveAuth all authorization types are resolvables. They are automatically resolved when authorization are checked but, if the authorization is registered, you need to resolve it manually when you can.

Note: Not all authorization types are registrable.

Here is an example with the ContextAuthorization


  public class PostsController extends AppController{

    public function buildAuthorization($authorization){
      //Register the callback
      $authorization->register('ownPost', $authorization->context([$this, 'ownPost']));

      //Define the registered rule authorizations
      $authorization
        ->actions(['update'])
        ->registered('ownPost');

      //Note the update method will start his excecution even if ownPost isn't resolved yet
    }

    public function ownPost($context, $params){
      return $context->user['id'] == $params->user_id;
    }

    public function update($id){
      $post = $this->Posts->get($id);

      $this->Authorization->resolve('ownPost', $post);
      //If authorization fails, `unauthorized` will be called. You need to throw an exception or redirect to avoid
      //the update exceution


      //update the post here
    }
  }

Model authorization

Accessibility/Visibility authorization

Used to restrict visibility and accessibility based on authorization result. You need a buildAuthorization method in your table :

    public function buildAuthorization($authorization){
        $authorization
            ->accessibility(['title','content'])
            ->group('admin');

        $authorization
            ->visibility(['adminField']
            ->group('admin');
    }

The fields are added to hidden fields when you use visibility.

Finders

Finders are applied when rules pass.

    public function buildAuthorization($authorization){
        $authorization
            ->finders('published')
            ->group("user");
    }

    public function findPublished(){
        //
    }

Logic

Available operators :

  • Or
  • Not

Example

    $authorization->actions("index")
        ->not($authorization->group("admin"));

    // Pass if one rule return true
    // Note that if it contains unresolved authorizations,it returns true while it is not resolved
    $authorization->actions("index")
        ->or([
            $authorization->group("admin"),
            $authorization->context(function(){})
        ]);

Notes

  • The rule is ignored if the specified authorization is not resolved.
  • It's possible to use component registered authorization inside model, but it's a bad practice.

Todo