From 8e145e1ecc6d616e8b274cc08d251567ae1f76bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=2E=20Nagy=20Gerg=C5=91?= Date: Mon, 22 Jan 2024 15:17:12 +0100 Subject: [PATCH] authorization wip --- resources/views/resources/form.blade.php | 4 +- resources/views/resources/index.blade.php | 4 +- resources/views/resources/show.blade.php | 4 +- resources/views/table/body.blade.php | 12 ++-- src/Fields/Relation.php | 2 - src/Resources/Resource.php | 82 ++++++++++++++--------- src/Traits/MapsAbilities.php | 16 ----- 7 files changed, 62 insertions(+), 62 deletions(-) delete mode 100644 src/Traits/MapsAbilities.php diff --git a/resources/views/resources/form.blade.php b/resources/views/resources/form.blade.php index dbb0d9be..c454b7d8 100644 --- a/resources/views/resources/form.blade.php +++ b/resources/views/resources/form.blade.php @@ -32,7 +32,7 @@ {{ __('Cancel') }} - @can('delete', $model) + @if($abilities['delete'])
@csrf @@ -40,6 +40,6 @@
- @endcan + @endif @endsection diff --git a/resources/views/resources/index.blade.php b/resources/views/resources/index.blade.php index 69101599..df9fbf70 100644 --- a/resources/views/resources/index.blade.php +++ b/resources/views/resources/index.blade.php @@ -5,12 +5,12 @@ {{-- Actions --}} @section('actions') - @can('create', $model) + @if($abilities['create']) {{ __('Add :resource', ['resource' => $modelName]) }} - @endcan + @endif @endsection {{-- Content --}} diff --git a/resources/views/resources/show.blade.php b/resources/views/resources/show.blade.php index 37d7c033..6dac9237 100644 --- a/resources/views/resources/show.blade.php +++ b/resources/views/resources/show.blade.php @@ -5,12 +5,12 @@ {{-- Actions --}} @section('actions') - @can('update', $model) + @if($abilities['update']) {{ __('Edit') }} - @endcan + @endif @endsection {{-- Content --}} diff --git a/resources/views/table/body.blade.php b/resources/views/table/body.blade.php index 6b14a1f9..8686d738 100644 --- a/resources/views/table/body.blade.php +++ b/resources/views/table/body.blade.php @@ -48,17 +48,17 @@ class="form-check__control" @endforeach
- @can('view', $row['model']) + @if($row['abilities']['view']) - @endcan - @can('update', $row['model']) + @endif + @if($row['abilities']['update']) - @endcan - @can('delete', $row['model']) + @endif + @if($row['abilities']['delete'])
@csrf @method('DELETE') @@ -66,7 +66,7 @@ class="form-check__control" - @endcan + @endif
diff --git a/src/Fields/Relation.php b/src/Fields/Relation.php index 6e789b70..4bb2c81b 100644 --- a/src/Fields/Relation.php +++ b/src/Fields/Relation.php @@ -12,7 +12,6 @@ use Cone\Root\Interfaces\Form; use Cone\Root\Root; use Cone\Root\Traits\AsForm; -use Cone\Root\Traits\MapsAbilities; use Cone\Root\Traits\RegistersRoutes; use Cone\Root\Traits\ResolvesActions; use Cone\Root\Traits\ResolvesFields; @@ -33,7 +32,6 @@ abstract class Relation extends Field implements Form { use AsForm; - use MapsAbilities; use RegistersRoutes { RegistersRoutes::registerRoutes as __registerRoutes; } diff --git a/src/Resources/Resource.php b/src/Resources/Resource.php index 80d3a691..e99739fc 100644 --- a/src/Resources/Resource.php +++ b/src/Resources/Resource.php @@ -15,7 +15,6 @@ use Cone\Root\Root; use Cone\Root\Traits\AsForm; use Cone\Root\Traits\Authorizable; -use Cone\Root\Traits\MapsAbilities; use Cone\Root\Traits\RegistersRoutes; use Cone\Root\Traits\ResolvesActions; use Cone\Root\Traits\ResolvesFilters; @@ -39,7 +38,6 @@ abstract class Resource implements Arrayable, Form { use AsForm; use Authorizable; - use MapsAbilities; use RegistersRoutes { RegistersRoutes::registerRoutes as __registerRoutes; RegistersRoutes::routeMatched as __routeMatched; @@ -172,32 +170,37 @@ public function getPolicy(): mixed } /** - * Map the resource abilities. + * Resolve the ability. */ - public function mapAbilities(): array + public function resolveAbility(string $ability, Request $request, Model $model, ...$arguments): bool + { + $policy = $this->getPolicy(); + + return is_null($policy) || $request->user()->can($ability, $model, ...$arguments); + } + + /** + * Map the resource level abilities. + */ + public function mapResourceAbilities(Request $request): array + { + return [ + 'viewAny' => $this->resolveAbility('viewAny', $request, $this->getModelInstance()), + 'create' => $this->resolveAbility('create', $request, $this->getModelInstance()), + ]; + } + + /** + * Map the model level abilities. + */ + public function mapModelAbilities(Request $request, Model $model): array { return [ - 'viewAny' => function (Request $request): bool { - return is_null($this->getPolicy()) || Gate::allows('viewAny', $this->getModel()); - }, - 'create' => function (Request $request): bool { - return is_null($this->getPolicy()) || Gate::allows('create', $this->getModel()); - }, - 'view' => function (Request $request, Model $model): bool { - return is_null($this->getPolicy()) || Gate::allows('view', $model); - }, - 'update' => function (Request $request, Model $model): bool { - return is_null($this->getPolicy()) || Gate::allows('update', $model); - }, - 'delete' => function (Request $request, Model $model): bool { - return is_null($this->getPolicy()) || Gate::allows('delete', $model); - }, - 'forceDelete' => function (Request $request, Model $model): bool { - return is_null($this->getPolicy()) || Gate::allows('delete', $model); - }, - 'restore' => function (Request $request, Model $model): bool { - return is_null($this->getPolicy()) || Gate::allows('delete', $model); - }, + 'view' => $this->resolveAbility('view', $request, $model), + 'update' => $this->resolveAbility('update', $request, $model), + 'restore' => $this->resolveAbility('restore', $request, $model), + 'delete' => $this->resolveAbility('delete', $request, $model), + 'forceDelete' => $this->resolveAbility('forceDelete', $request, $model), ]; } @@ -386,6 +389,7 @@ public function paginate(Request $request): LengthAwarePaginator 'id' => $model->getKey(), 'url' => $this->modelUrl($model), 'model' => $model, + 'abilities' => $this->mapModelAbilities($request, $model), 'fields' => $this->resolveFields($request) ->subResource(false) ->authorized($request, $model) @@ -447,9 +451,13 @@ public function routeMatched(RouteMatched $event): void { $event->route->defaults('resource', $this->getKey()); - $event->route->getController()->middleware( - $this->getRouteMiddleware() - ); + $controller = $event->route->getController(); + + $controller->middleware($this->getRouteMiddleware()); + + if ($this->getPolicy()) { + $controller->authorizeResource($this->getModel(), 'resourceModel'); + } $this->__routeMatched($event); } @@ -479,9 +487,9 @@ public function toIndex(Request $request): array 'template' => 'root::resources.index', 'title' => $this->getName(), 'actions' => $this->resolveActions($request) - ->authorized($request, $this->getModelInstance()) + ->authorized($request, $model = $this->getModelInstance()) ->visible('index') - ->mapToForms($request, $this->getModelInstance()), + ->mapToForms($request, $model), 'data' => $this->paginate($request), 'widgets' => $this->resolveWidgets($request) ->authorized($request) @@ -493,12 +501,13 @@ public function toIndex(Request $request): array 'filters' => $this->resolveFilters($request) ->authorized($request) ->renderable() - ->map(function (RenderableFilter $filter) use ($request): array { - return $filter->toField()->toInput($request, $this->getModelInstance()); + ->map(function (RenderableFilter $filter) use ($request, $model): array { + return $filter->toField()->toInput($request, $model); }) ->all(), 'activeFilters' => $this->resolveFilters($request)->active($request)->count(), 'url' => $this->getUri(), + 'abilities' => $this->mapResourceAbilities($request), ]); } @@ -518,6 +527,7 @@ public function toCreate(Request $request): array ->authorized($request, $model) ->visible('create') ->mapToInputs($request, $model), + 'abilities' => $this->mapResourceAbilities($request), ]); } @@ -552,6 +562,10 @@ public function toShow(Request $request, Model $model): array 'url' => trim(sprintf('%s?%s', $relation->modelUrl($model), $request->getQueryString()), '?'), ]); }), + 'abilities' => array_merge( + $this->mapResourceAbilities($request), + $this->mapModelAbilities($request, $model) + ), ]); } @@ -571,6 +585,10 @@ public function toEdit(Request $request, Model $model): array ->authorized($request, $model) ->visible('update') ->mapToInputs($request, $model), + 'abilities' => array_merge( + $this->mapResourceAbilities($request), + $this->mapModelAbilities($request, $model) + ), ]); } } diff --git a/src/Traits/MapsAbilities.php b/src/Traits/MapsAbilities.php deleted file mode 100644 index 4b933490..00000000 --- a/src/Traits/MapsAbilities.php +++ /dev/null @@ -1,16 +0,0 @@ -