If you override deny() in a policy and then authorize an ability that fails, it does not call the custom deny() method of the policy. This seems similar to #25260
I have created a policy using php artisan make:policy JobPolicy. The policy that was generated uses the HandlesAuthorization trait which defines 2 methods allow() and deny(). I created a custom deny() method in my policy to send a custom error response. I am calling $this->authorize('update', $job) in a controller and I am not seeing the custom response returned from deny(). If you look in Illuminate\Auth\Access\Gate::authorize() it calls allow() or deny() depending on the result but it is the deny() method on the Gate, not the one from the policy. Note: Gate also uses the HandlesAuthorization trait.
<?php
namespace App\Policies;
use App\Models\Employer;
use App\Models\Job;
use Illuminate\Auth\Access\HandlesAuthorization;
class JobPolicy
{
use HandlesAuthorization;
protected function deny($message = 'This action is unauthorized.')
{
//return response()->json([
// 'custom' => 'Custom message',
//]);
throw new \Exception('custom message');
}
public function update(Employer $employer, Job $job)
{
return false;
}
}
In the controller you just need to do something like this:
public function update(Request $request, Job $job)
{
$this->authorize('update', $job);
}
Please post the policy and controller code.
I think you can not send response from here. You need to throw custom exception same as laravel doing here.
I have updated the code to throw an exception with a custom message.
My main point I am trying to make is that the custom deny() in the policy is never called which seems like a bug. Why include the HandlesAuthorization trait in the policy if it is not called?
Have you registered policies rightly?
Closing this since this PR addresses the issue #26208
The trait allows you to use the provided methods in the logic of your policy methods:
public function edit(User $user, Model $model)
{
if (!$user->controls($model)) {
$this->deny("You can't do this!");
}
return true;
}
AFAIK this is the only intended function of the trait.
See #10231. where this was added.
Thank you so much for the example.
Is this documented?
I think no.
No. Ive always used it that way because I saw the pull request come through. Maybe @josephsilber could update the docs. If not, I'll try to make time to do it.
Most helpful comment
The trait allows you to use the provided methods in the logic of your policy methods:
AFAIK this is the only intended function of the trait.
See #10231. where this was added.