brzez / access-policy-bundle
This package is not auto-updated.
Last update: 2025-02-01 21:09:11 UTC
README
Overview
Access checker, inspired by Laravel.
It allows for checking access via simple can and cannot methods accessible via the brzez_access_policy.access_policy_provider service.
It also extends twig with those two methods as global functions.
can needs minimum 2 arguments:
- intent - what are you checking access for ex. view, edit etc
- object - what object are you checking the access for cannot is just an inverse of can (so !can())
It is also possible to pass additional variables to the can/cannot methods.
The 2nd arg is always used for finding the matching policy.
The rest are just passed to the policy can()* method.
Policy needs to implement AccessPolicyInterface which requires the getPoliciedClass method. Policied objects are checked via
is_a($object, $policy->getPoliciedClass());
Which means that it will work for mocked entities. It's also possible to implement 'global' policies for interfaces / parent classes.
Policies are registered as services.
The policy service needs to be tagged as access_policy so it will be recognized by the access policy provider.
Installation
composer require brzez/access-policy-bundle
Enable the bundle in the kernel
// app/AppKernel.php public function registerBundles() { $bundles = array( //... new Brzez\AccessPolicyBundle\BrzezAccessPolicyBundle(), //... ); return $bundles; }
Registering policies
In services.yml
services: test_policy: class: AppBundle\TestPolicy tags: - {name: access_policy}
Naming intent methods
When using can/cannot methods the intent is written in kebab-case, without the can/cannot word.
Example:
// Will run canChangeStatus($something) on the policy $this->can('change-status', $something); // Will return negated canChangeStatus($something) $this->cannot('change-status', $something);
Usage
PolicyProvider can be accessed via container
$container->get('brzez_access_policy.access_policy_provider')
Controllers can use Brzez\AccessPolicyBundle\Traits\AccessCheckerTrait which will extend the controller by adding:
- can(intent, object)
- cannot(intent, object)
- getPolicyProvider() methods
It also adds twig global functions - can(...) and cannot(...) which can be used like this:
{% if can('view', someObject) %} i can view someObject {% endif %} {% if cannot('view', someObject) %} i cannot view someObject {% endif %}
Example
Let's say we have SomeEntity and we need to check view access via our policy.
We need to create SomeEntityPolicy with canView method.
use Brzez\AccessPolicyBundle\Service\AccessPolicyInterface; class SomeEntityPolicy implements AccessPolicyInterface { public function canView(SomeEntity $entity) { // access logic here return false; } }
Link the policy to the entity
In app/config/services.yml
services: test_policy: class: AppBundle\SomeEntityPolicy tags: - {name: access_policy}
Now you can check access in the controller:
use Brzez\AccessPolicyBundle\Traits\AccessCheckerTrait; class DefaultController extends Controller { use AccessCheckerTrait; /** * @Route("/", name="homepage") */ public function indexAction(Request $request) { // get $someObject from somewhere ... if($this->cannot('view', $someObject)){ throw new AccessDeniedException('...'); } // render view ... } }
You can also check access in twig views:
{% if can('view', someObject) %} i can view someObject {% endif %} {% if cannot('view', someObject) %} i cannot view someObject {% endif %}
Changelog
- 0.9.0 Less strict class checking - is_a (instanceof) instead of strict get_class == classname This way it will work with mocked entities