Из коробки очень даже гибко все получается.
Только от генератора Policy я отказался, и все валидации через контракт Gate в FormRequest в методе authorize.
Как-то так все получается.
// form request
<?php
namespace App\Http\Requests\User;
use App\Models\User;
use Illuminate\Contracts\Auth\Access\Gate;
use Illuminate\Foundation\Http\FormRequest;
class DestroyRequest extends FormRequest
{
public function authorize(Gate $gate)
{
$id = $this->route()->getParameter('user');
return $gate->authorize('destroy', User::query()->findOrFail($id));
}
public function rules()
{
return [
];
}
}
// controller
<?php
namespace App\Http\Controllers\Api;
use App\Contracts\IUsersService;
use App\Http\Controllers\Controller;
use App\Http\Requests\User\DestroyRequest;
use App\Http\Requests\User\IndexRequest;
class UsersController extends Controller
{
public function destroy(DestroyRequest $request, $id)
{
// do stuff
}
}
// policy
<?php
namespace App\Policies;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class UserPolicy
{
use HandlesAuthorization;
public function index()
{
return true;
}
/**
* rbac:user.destroy
*/
public function destroy(User $user, User $entity)
{
if ($entity->hasRole(User::ROLE_ROOT)) {
return false;
}
return $user->isEditor();
}
}