From bff23d0c2e204ab9917359a47d9742bd7f7aba5f Mon Sep 17 00:00:00 2001 From: Pellegrino Durante Date: Thu, 3 Oct 2024 09:29:27 +0200 Subject: [PATCH 1/3] feat: add support to custom guard in controller and resource (#1) --- src/Http/Api/Contracts/HasParser.php | 3 ++- src/Http/Api/Contracts/HasPolicies.php | 12 +++++++----- src/Http/Api/Contracts/HasResponse.php | 1 + src/Http/Api/Controller.php | 8 ++++++++ .../Resources/Contracts/AllowableFields.php | 17 ++++++++++++++++- 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/Http/Api/Contracts/HasParser.php b/src/Http/Api/Contracts/HasParser.php index 01dd64f..ff650ce 100644 --- a/src/Http/Api/Contracts/HasParser.php +++ b/src/Http/Api/Contracts/HasParser.php @@ -86,7 +86,8 @@ protected function filterByParent(): array $parentPolicy = Gate::getPolicyFor($routeRelation); if (! is_null($parentPolicy)) { - $this->authorize('view', $routeRelation); + $user = auth($this->guard)->user(); + $this->authorizeForUser($user, 'view', $routeRelation); } $filter = match (class_basename(get_class($relation))) { diff --git a/src/Http/Api/Contracts/HasPolicies.php b/src/Http/Api/Contracts/HasPolicies.php index df92ca8..779b443 100644 --- a/src/Http/Api/Contracts/HasPolicies.php +++ b/src/Http/Api/Contracts/HasPolicies.php @@ -13,7 +13,7 @@ trait HasPolicies */ protected function qualifyCollectionQuery(): void { - $user = auth()->user(); + $user = auth($this->guard)->user(); $modelPolicy = Gate::getPolicyFor($this->model()); if ($modelPolicy && method_exists($modelPolicy, 'qualifyCollectionQueryWithUser')) { @@ -28,7 +28,7 @@ protected function qualifyCollectionQuery(): void */ protected function qualifyItemQuery(): void { - $user = auth()->user(); + $user = auth($this->guard)->user(); $modelPolicy = Gate::getPolicyFor($this->model()); if ($modelPolicy && method_exists($modelPolicy, 'qualifyItemQueryWithUser')) { @@ -45,7 +45,7 @@ protected function qualifyItemQuery(): void */ protected function qualifyStoreQuery(array $data): array { - $user = auth()->user(); + $user = auth($this->guard)->user(); $modelPolicy = Gate::getPolicyFor($this->model()); if ($modelPolicy && method_exists($modelPolicy, 'qualifyStoreDataWithUser')) { @@ -64,7 +64,7 @@ protected function qualifyStoreQuery(array $data): array */ protected function qualifyUpdateQuery(array $data): array { - $user = auth()->user(); + $user = auth($this->guard)->user(); $modelPolicy = Gate::getPolicyFor($this->model()); if ($modelPolicy && method_exists($modelPolicy, 'qualifyUpdateDataWithUser')) { @@ -124,8 +124,10 @@ protected function testUserPolicyAction(string $ability, $arguments = null, bool return true; } + $user = auth($this->guard)->user(); + /* @scrutinizer ignore-call */ - $this->authorize($ability, $model); + $this->authorizeForUser($user, $ability, $model); return true; } diff --git a/src/Http/Api/Contracts/HasResponse.php b/src/Http/Api/Contracts/HasResponse.php index e95dcec..f0aca4f 100644 --- a/src/Http/Api/Contracts/HasResponse.php +++ b/src/Http/Api/Contracts/HasResponse.php @@ -58,6 +58,7 @@ protected function respondWithMany($items, $code = null, $headers = []) protected function respondWithResource($resource, $data, $code = null, $headers = []) { return $resource::make($data) + ->setGuard($this->guard) ->response() ->setStatusCode($code ?? $this->getStatusCode()) ->withHeaders($headers); diff --git a/src/Http/Api/Controller.php b/src/Http/Api/Controller.php index 6543753..d4b3bec 100644 --- a/src/Http/Api/Controller.php +++ b/src/Http/Api/Controller.php @@ -62,6 +62,14 @@ abstract class Controller extends BaseController */ protected $maximumLimit = 0; + /** + * Guard to use for authentication and authorization. + * null defaults to default guard config (auth.defaults.guard) + * + * @var ?string + */ + protected $guard = null; + /** * Display a listing of the resource. * GET /api/{resource}. diff --git a/src/Http/Resources/Contracts/AllowableFields.php b/src/Http/Resources/Contracts/AllowableFields.php index f07ceec..48d97cc 100644 --- a/src/Http/Resources/Contracts/AllowableFields.php +++ b/src/Http/Resources/Contracts/AllowableFields.php @@ -53,6 +53,14 @@ trait AllowableFields */ protected static ?array $fieldGates = null; + /** + * Guard used to retrieve the user from the request. + * null defaults to default guard config (auth.defaults.guard) + * + * @var ?string + */ + protected ?string $guard = null; + /** * Makes sure we only return allowable fields. * @@ -141,6 +149,13 @@ protected function mapFields($request): array return $this->filterAllowedFields($fields); } + public function setGuard(string $guard): static + { + $this->guard = $guard; + + return $this; + } + public function filterAllowedFields($fields) { if (empty(static::$allowedFields) || static::$allowedFields === ['*']) { @@ -217,7 +232,7 @@ protected function filterUserViewableFields($request): array return collect($this->mapFields($request)) ->when( ! empty(static::$fieldGates), - fn($collection) => $collection->filter(fn($field) => $this->filterUserField($field, $request->user())) + fn($collection) => $collection->filter(fn($field) => $this->filterUserField($field, $request->user($this->guard))) ) ->toArray(); } From 2b9230cd3678331bae0152e5e66f0303bda6fd42 Mon Sep 17 00:00:00 2001 From: Michael Di Prisco Date: Tue, 29 Oct 2024 15:29:51 +0100 Subject: [PATCH 2/3] chore: iterating --- src/Http/Resources/ApiCollection.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Http/Resources/ApiCollection.php b/src/Http/Resources/ApiCollection.php index 9bc36b8..29278ce 100644 --- a/src/Http/Resources/ApiCollection.php +++ b/src/Http/Resources/ApiCollection.php @@ -9,6 +9,21 @@ class ApiCollection extends ResourceCollection { + /** + * Guard used to retrieve the user from the request. + * null defaults to default guard config (auth.defaults.guard) + * + * @var ?string + */ + protected ?string $guard = null; + + public function setGuard(string $guard): static + { + $this->guard = $guard; + + return $this; + } + protected ?string $fieldKey = null; protected function collects() @@ -31,7 +46,7 @@ public function setFieldKey(?string $fieldKey): static public function toArray(Request $request) { return $this->collection->map( - fn($item) => $item->setFieldKey($this->fieldKey)->toArray($request) + fn($item) => $item->setGuard($this->guard)->setFieldKey($this->fieldKey)->toArray($request) )->all(); } } From 1d88000119ea838696060f122d49d0ac3d149e68 Mon Sep 17 00:00:00 2001 From: Pellegrino Durante Date: Wed, 30 Oct 2024 10:39:45 +0100 Subject: [PATCH 3/3] fix: guard nullable on setGuard --- src/Http/Resources/ApiCollection.php | 2 +- src/Http/Resources/Contracts/AllowableFields.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Http/Resources/ApiCollection.php b/src/Http/Resources/ApiCollection.php index 29278ce..656ad20 100644 --- a/src/Http/Resources/ApiCollection.php +++ b/src/Http/Resources/ApiCollection.php @@ -17,7 +17,7 @@ class ApiCollection extends ResourceCollection */ protected ?string $guard = null; - public function setGuard(string $guard): static + public function setGuard(?string $guard): static { $this->guard = $guard; diff --git a/src/Http/Resources/Contracts/AllowableFields.php b/src/Http/Resources/Contracts/AllowableFields.php index 48d97cc..782a1d8 100644 --- a/src/Http/Resources/Contracts/AllowableFields.php +++ b/src/Http/Resources/Contracts/AllowableFields.php @@ -149,7 +149,7 @@ protected function mapFields($request): array return $this->filterAllowedFields($fields); } - public function setGuard(string $guard): static + public function setGuard(?string $guard): static { $this->guard = $guard;