Написал простую политику безопасности
public function delete(User $user, Product $product): bool
{
return $user->hasRole("admin");
}
Создавалась через артизан. Проблема в том, что политика срабатывает только в случае прямого подключения в контроллере
public function destroy(string $id)
{
$this->authorize('ProductPolicy');//и политика срабатывает
$productToDelete=Product::find($id);
if($productToDelete){
$productToDelete->delete();
return response()->json([
'message'=>"Product ID $id has been deleted"
],200);
}else{
return response()->json([
'message'=>"Product ID $id not found"
],404);
}
}
Хотя в документации сказано что при соблюдении правил наименований политика должна обнаруживаться автоматически. Пробовал явно добавить политику в AuthServiceProvider
protected $policies = [
use App\Models\Product;
use App\Policies\ProductPolicy;
//...code
protected $policies = [
Product::class=>ProductPolicy::class
];
но без результата.
Также подключал в мидлвер посредством
Route::apiResource("products",ProductController::class)->middleware("auth","can:ProductPolicy");
Не работает (впрочем в данном случае не уверен что даже должно работать). Короче, без идей.
UPD: в догонку тест, которым проверяю работу политики
public function test_siteuser_cant_delete_product(): void
{
$this->seed(PermissionsTableSeeder::class);
$this->seed(RolesTableSeeder::class);
$user=User::factory()->create();
$user->assignRole('site_user');
$this->actingAs($user);
$productData=[
'name'=>"testname",
'parent_id'=>null,
"calories"=>500,
"proteins"=>50,
"fats"=>50,
"carbohydrates"=>50,
"description"=>"some test description for product"
];
$newProduct=Product::create($productData);
$response=$this->delete("/api/products/$newProduct->id",$productData);
$response->assertStatus(403);
}