I am new to Laravel and am struggling to implement a simple Policy :)
Just for testing I did ->
/app/Policies/ReleasePolicy.php:
<?php
namespace App\Policies;
use App\Models\Release;
use App\Models\User;
use Illuminate\Auth\Access\Response;
class ReleasePolicy
{
public function edit(): bool
{
return false;
}
}
routes/web.php:
<?php
use App\Models\Release;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ReleaseController;
Route::resource('/release', ReleaseController::class);
app/http/controllers/ReleaseController.php:
<?php
namespace App\Http\Controllers;
use App\Models\Release;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Response;
use Illuminate\View\View;
use App\Http\Requests\ReleaseStoreRequest;
use App\Http\Requests\ReleaseUpdateRequest;
class ReleaseController extends Controller
{
/**
* Show the form for editing the specified resource.
*/
public function edit(Release $release): View
{
return view('pages.release.edit', compact('release'));
}
}
When I go to http://localhost:8000/release/56/edit , it still opens, I expected 403. What am I doing wrong?
I assume the policy is not registered/discovered, but why not? The laravel/docs says:
By default, Laravel automatically discover policies as long as the model and policy follow standard Laravel naming conventions. Specifically, the policies must be in a Policies directory at or above the directory that contains your models.
And that's exactly what I did but I think the policy is still not discovered...
I tried to manually register the policy in app/Providers/AppServiceProvider.php
<?php
namespace App\Providers;
use App\Models\Release;
use App\Policies\ReleasePolicy;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Gate;
use App\Models\User;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Gate::policy(Release::class, ReleasePolicy::class);
}
}
Nothing changed. http://localhost:8000/release/56/edit doesnt show 403
Policies do not guard the controller methods but the actions on models. In docs https://laravel.com/docs/11.x/authorization#policy-methods, we can see there are some methods which are auto-discoverable by Laravel:
viewAny, view, create, update, delete, restore, and forceDelete
In your case, you will need to explicitly check for policy in your edit method, as described in docs: https://laravel.com/docs/11.x/authorization#authorizing-or-throwing-exceptions
public function edit(Release $release): View
{
Gate::authorize('edit', $release);
return view('pages.release.edit', compact('release'));
}
Or, I suggest that you use the standard "update" policy method instead of custom "edit":
class ReleasePolicy
{
/**
* Determine if the given release can be updated by the user.
*/
public function update(User $user, Release $release): bool
{
return false;
//or some rule...;
}
}
And use "update" in contoller: Gate::authorize('update', $release);