Wallogit.com
2017 © Pedro Peláez
Access checker, inspired by Laravel., (*1)
It allows for checking access via simple can and cannot methods accessible via the brzez_access_policy.access_policy_provider service., (*2)
It also extends twig with those two methods as global functions., (*3)
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()), (*4)
It is also possible to pass additional variables to the can/cannot methods., (*5)
The 2nd arg is always used for finding the matching policy., (*6)
The rest are just passed to the policy can*() method., (*7)
Policy needs to implement AccessPolicyInterface which requires the getPoliciedClass method. Policied objects are checked via, (*8)
``` php is_a($object, $policy->getPoliciedClass());, (*9)
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 ``` bash composer require brzez/access-policy-bundle
Enable the bundle in the kernel, (*10)
``` php // app/AppKernel.php, (*11)
public function registerBundles() { $bundles = array( //... new Brzez\AccessPolicyBundle\BrzezAccessPolicyBundle(), //... ); return $bundles; }, (*12)
## Registering policies In **services.yml** ```yml services: test_policy: class: AppBundle\TestPolicy tags: - {name: access_policy}
When using can/cannot methods the intent is written in kebab-case, without the can/cannot word., (*13)
Example:, (*14)
// Will run canChangeStatus($something) on the policy
$this->can('change-status', $something);
// Will return negated canChangeStatus($something)
$this->cannot('change-status', $something);
PolicyProvider can be accessed via container, (*15)
$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, (*16)
It also adds twig global functions - can(...) and cannot(...) which can be used like this:, (*17)
{% if can('view', someObject) %}
i can view someObject
{% endif %}
{% if cannot('view', someObject) %}
i cannot view someObject
{% endif %}
Let's say we have SomeEntity and we need to check view access via our policy., (*18)
We need to create SomeEntityPolicy with canView method., (*19)
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, (*20)
In app/config/services.yml, (*21)
services:
test_policy:
class: AppBundle\SomeEntityPolicy
tags:
- {name: access_policy}
Now you can check access in the controller:, (*22)
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:, (*23)
{% if can('view', someObject) %}
i can view someObject
{% endif %}
{% if cannot('view', someObject) %}
i cannot view someObject
{% endif %}