Skip to content

Action Policies

Steps to add a policy to an action

  1. Create a new Policy in the right directory. e.g App\Policies\Actions\Order\CreateOrderPolicy

  2. Override the $codes variable to create the permissions you want. The format you want to follow is project:model:name so it would look like storefront:order:create. Each permission is an array because it has options on a per permission basis. A finalized permission would look like. Default means that every role will get this permission so it’s by default ON. The alias isn’t currently used anywhere, but it will be used to give a better name for permissions on the admin panel.

    php
    'storefront:order:create' => [
        'alias' => 'Create Order',
        'default' => true,
    ]
  3. Now in order for the policy to be accessible in the project you have to run php artisan framework:build-bindings and then run php artisan framework:seed-roles-and-permissions

  4. At this point you should have the policy in your binding file and the permission should exist in your database. The next step is to go to the action you want to use this permission and extend AuthorizableAction which is an interface that includes

    php
    public function getRequiredPermissions(): array;
    
    public function validateAuthorization($context = null): void;
  5. A finalized action would look like this.

    php
    class CreateOrder implements AuthorizableAction
    {
        use AsAction;
    
        public function handle($fields = [])
        {
            $this->validateAuthorization();
        }
    
        public function validateAuthorization($context = null): void
        {
            \CBOX::can(policyCollection: $this->getRequiredPermissions());
        }
    
        public function getRequiredPermissions(): array
        {
            return [\CBOX::policy('Actions/Order/CreateOrderPolicy')];
        }
    }

Specific features:

  • In a blade component you can use the @CBOXcan directive to add the equivalent of an normal if check, but for policies it would look like this in practice:

    php
    @CBOXcan('Order/UpdateOrderPolicy')
    <div class="px-6 py-4">
        <livewire:admin::order.items.add-item :orderId="$order->id"></livewire:admin::order.items.add-item>
    </div>
    @endCBOXcan
  • If you need a specific implementation of how you want to validate the permission / the authorization of the policy you should override the authorize function in your policy and write your custom logic there. In practice it looks like this:

    php
    protected static function authorize($context): bool
    {
        $user = \CBOX::getCurrentUser();
    
        if ($user->can('admin:comment:update') && $context->author_id == $user->id) {
            return true;
        }
    
        return false;
    }
  • If your policy is for an action that is storefront facing and it is allowed in a storefront that doesn’t required auth, there is a bool variable in your policy that you can override to allow that. This means that if you set this variable to false it will skip all the validation in the preAuthorize and authorize function if the user is not logged in.

    php
    protected static bool $authRequired = true;