From 095f868ca21b747037c06c475dc5e9df3e8e4522 Mon Sep 17 00:00:00 2001 From: Eduard Lupacescu Date: Sun, 24 May 2020 18:42:35 +0300 Subject: [PATCH 1/2] Custom middleware --- config/config.php | 1 + .../Controllers/ProfileAvatarController.php | 2 +- src/Http/Controllers/ProfileController.php | 2 +- .../Controllers/RepositoryIndexController.php | 2 - .../Requests/InteractWithRepositories.php | 13 +++- src/Http/Requests/RestifyRequest.php | 1 - src/Repositories/Repository.php | 12 +++ .../GlobalSearchControllerTest.php | 3 +- .../Controllers/RepositoryMiddlewaresTest.php | 77 +++++++++++++++++++ tests/Fixtures/Post/PostAbortMiddleware.php | 15 ++++ .../PostWithCustomMiddlewareRepository.php | 26 +++++++ tests/IntegrationTest.php | 3 + 12 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 tests/Controllers/RepositoryMiddlewaresTest.php create mode 100644 tests/Fixtures/Post/PostAbortMiddleware.php create mode 100644 tests/Fixtures/Post/PostWithCustomMiddlewareRepository.php diff --git a/config/config.php b/config/config.php index 8c10001d1..598f7bde0 100644 --- a/config/config.php +++ b/config/config.php @@ -2,6 +2,7 @@ use Binaryk\LaravelRestify\Http\Middleware\AuthorizeRestify; use Binaryk\LaravelRestify\Http\Middleware\DispatchRestifyStartingEvent; +use Binaryk\LaravelRestify\Tests\Fixtures\Post\PostMiddleware; return [ 'auth' => [ diff --git a/src/Http/Controllers/ProfileAvatarController.php b/src/Http/Controllers/ProfileAvatarController.php index 3e5f93417..63c7bc7c2 100644 --- a/src/Http/Controllers/ProfileAvatarController.php +++ b/src/Http/Controllers/ProfileAvatarController.php @@ -26,6 +26,6 @@ public function __invoke(ProfileAvatarRequest $request) $user->{ProfileAvatarRequest::$userAvatarAttribute} = url($user->{ProfileAvatarRequest::$userAvatarAttribute}); - return $this->response()->data($user); + return $this->response()->model($user); } } diff --git a/src/Http/Controllers/ProfileController.php b/src/Http/Controllers/ProfileController.php index 67a9906de..f6b54a169 100644 --- a/src/Http/Controllers/ProfileController.php +++ b/src/Http/Controllers/ProfileController.php @@ -15,6 +15,6 @@ public function __invoke(RestifyRequest $request) $user->{ProfileAvatarRequest::$userAvatarAttribute} = url($user->{ProfileAvatarRequest::$userAvatarAttribute}); } - return $this->response()->data($user); + return $this->response()->model($user); } } diff --git a/src/Http/Controllers/RepositoryIndexController.php b/src/Http/Controllers/RepositoryIndexController.php index f8127fe55..99aee7d0f 100644 --- a/src/Http/Controllers/RepositoryIndexController.php +++ b/src/Http/Controllers/RepositoryIndexController.php @@ -18,8 +18,6 @@ public function __invoke(RepositoryIndexRequest $request) ->dump($e, $request->isDev()); } catch (UnauthorizedException $e) { return $this->response()->forbidden()->addError($e->getMessage())->dump($e, $request->isDev()); - } catch (\Throwable $e) { - return $this->response()->error()->dump($e, $request->isDev()); } } } diff --git a/src/Http/Requests/InteractWithRepositories.php b/src/Http/Requests/InteractWithRepositories.php index 16d1b3759..599829b02 100644 --- a/src/Http/Requests/InteractWithRepositories.php +++ b/src/Http/Requests/InteractWithRepositories.php @@ -7,6 +7,8 @@ use Binaryk\LaravelRestify\Repositories\Repository; use Binaryk\LaravelRestify\Restify; use Illuminate\Database\Eloquent\Model; +use Illuminate\Pipeline\Pipeline; +use Throwable; /** * @author Eduard Lupacescu @@ -44,11 +46,16 @@ public function repository($key = null): ?Repository ]), 404); } - if (! $repository::authorizedToUseRepository($this)) { + if (!$repository::authorizedToUseRepository($this)) { throw new UnauthorizedException(__('Unauthorized to view repository :name. See "allowRestify" policy.', [ 'name' => $repository, ]), 403); } + + app(Pipeline::class) + ->send($this) + ->through($repository::collectMiddlewares()->toArray()) + ->thenReturn(); }); return $repository::resolveWith($repository::newModel()); @@ -114,7 +121,7 @@ public function newRepositoryWith($model, $uriKey = null) */ public function newQueryWithoutScopes($uriKey = null) { - if (! $this->isViaRepository()) { + if (!$this->isViaRepository()) { return $this->model($uriKey)->newQueryWithoutScopes(); } @@ -181,7 +188,7 @@ public function viaParentModel() { $parent = $this->repository($this->viaRepository); - return once(fn () => $parent::newModel()->newQueryWithoutScopes()->whereKey($this->viaRepositoryId)->firstOrFail()); + return once(fn() => $parent::newModel()->newQueryWithoutScopes()->whereKey($this->viaRepositoryId)->firstOrFail()); } public function viaQuery() diff --git a/src/Http/Requests/RestifyRequest.php b/src/Http/Requests/RestifyRequest.php index 446dbec95..3b6c8c531 100644 --- a/src/Http/Requests/RestifyRequest.php +++ b/src/Http/Requests/RestifyRequest.php @@ -2,7 +2,6 @@ namespace Binaryk\LaravelRestify\Http\Requests; -use Binaryk\LaravelRestify\Restify; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Support\Facades\App; diff --git a/src/Repositories/Repository.php b/src/Repositories/Repository.php index 9b0b2f83e..462ca9dcb 100644 --- a/src/Repositories/Repository.php +++ b/src/Repositories/Repository.php @@ -97,6 +97,13 @@ abstract class Repository implements RestifySearchable, JsonSerializable */ public static $globalSearchResults = 5; + /** + * The list of middlewares for the current repository. + * + * @var array + */ + public static $middlewares = []; + /** * Get the underlying model instance for the resource. * @@ -731,4 +738,9 @@ public function availableFilters(RestifyRequest $request) return collect($this->filter($this->filters($request)))->each(fn (Filter $filter) => $filter->authorizedToSee($request)) ->values(); } + + public static function collectMiddlewares(): Collection + { + return collect(static::$middlewares); + } } diff --git a/tests/Controllers/GlobalSearchControllerTest.php b/tests/Controllers/GlobalSearchControllerTest.php index a64be8eb3..39c41bd9f 100644 --- a/tests/Controllers/GlobalSearchControllerTest.php +++ b/tests/Controllers/GlobalSearchControllerTest.php @@ -58,7 +58,8 @@ public function test_global_search_filter_will_filter_with_index_query() $response = $this ->withoutExceptionHandling() - ->getJson('/restify-api/search?search=1'); + ->getJson('/restify-api/search?search=1') + ->dump(); $this->assertCount(1, $response->json('data')); diff --git a/tests/Controllers/RepositoryMiddlewaresTest.php b/tests/Controllers/RepositoryMiddlewaresTest.php new file mode 100644 index 000000000..5246a33c7 --- /dev/null +++ b/tests/Controllers/RepositoryMiddlewaresTest.php @@ -0,0 +1,77 @@ +expects('handle') + ->once(); + + PostWithCustomMiddlewareRepository::$middlewares = [ + $middleware, + ]; + + Restify::repositories([ + PostWithCustomMiddlewareRepository::class, + ]); + + $this->getJson('restify-api/post-with-middleware') + ->assertStatus(200); + } + + public function test_request_fails_if_middleware_abort() + { + PostWithCustomMiddlewareRepository::$middlewares = [ + PostAbortMiddleware::class + ]; + + Restify::repositories([ + PostWithCustomMiddlewareRepository::class, + ]); + + $this->getJson('restify-api/post-with-middleware') + ->assertStatus(404); + } + + public function test_foreign_repository_middleware_should_not_be_invoked() + { + + $middleware = m::mock(PostAbortMiddleware::class); + + $nextParam = null; + + $middleware + ->expects('handle') + ->never(); + + PostWithCustomMiddlewareRepository::$middlewares = [ + $middleware, + ]; + + Restify::repositories([ + PostWithCustomMiddlewareRepository::class, + ]); + + $this->getJson('restify-api/posts') + ->assertStatus(200); + } +} diff --git a/tests/Fixtures/Post/PostAbortMiddleware.php b/tests/Fixtures/Post/PostAbortMiddleware.php new file mode 100644 index 000000000..fa74a7b5a --- /dev/null +++ b/tests/Fixtures/Post/PostAbortMiddleware.php @@ -0,0 +1,15 @@ +setRounds(4); + $this->repositoryMock(); $this->loadMigrations(); $this->loadRoutes(); From ad6021896c37fd2212705fc489ed6ff44c689b51 Mon Sep 17 00:00:00 2001 From: Lupacescu Eduard Date: Sun, 24 May 2020 18:42:57 +0300 Subject: [PATCH 2/2] Apply fixes from StyleCI (#193) --- config/config.php | 1 - src/Http/Controllers/ProfileAvatarController.php | 1 - src/Http/Requests/InteractWithRepositories.php | 7 +++---- tests/Controllers/RepositoryMiddlewaresTest.php | 4 +--- tests/Fixtures/Post/PostWithCustomMiddlewareRepository.php | 1 - tests/IntegrationTest.php | 1 - 6 files changed, 4 insertions(+), 11 deletions(-) diff --git a/config/config.php b/config/config.php index 598f7bde0..8c10001d1 100644 --- a/config/config.php +++ b/config/config.php @@ -2,7 +2,6 @@ use Binaryk\LaravelRestify\Http\Middleware\AuthorizeRestify; use Binaryk\LaravelRestify\Http\Middleware\DispatchRestifyStartingEvent; -use Binaryk\LaravelRestify\Tests\Fixtures\Post\PostMiddleware; return [ 'auth' => [ diff --git a/src/Http/Controllers/ProfileAvatarController.php b/src/Http/Controllers/ProfileAvatarController.php index 63c7bc7c2..8463a5a78 100644 --- a/src/Http/Controllers/ProfileAvatarController.php +++ b/src/Http/Controllers/ProfileAvatarController.php @@ -23,7 +23,6 @@ public function __invoke(ProfileAvatarRequest $request) $user->{$request::$userAvatarAttribute} = $path; $user->save(); - $user->{ProfileAvatarRequest::$userAvatarAttribute} = url($user->{ProfileAvatarRequest::$userAvatarAttribute}); return $this->response()->model($user); diff --git a/src/Http/Requests/InteractWithRepositories.php b/src/Http/Requests/InteractWithRepositories.php index 599829b02..5d3e95ddd 100644 --- a/src/Http/Requests/InteractWithRepositories.php +++ b/src/Http/Requests/InteractWithRepositories.php @@ -8,7 +8,6 @@ use Binaryk\LaravelRestify\Restify; use Illuminate\Database\Eloquent\Model; use Illuminate\Pipeline\Pipeline; -use Throwable; /** * @author Eduard Lupacescu @@ -46,7 +45,7 @@ public function repository($key = null): ?Repository ]), 404); } - if (!$repository::authorizedToUseRepository($this)) { + if (! $repository::authorizedToUseRepository($this)) { throw new UnauthorizedException(__('Unauthorized to view repository :name. See "allowRestify" policy.', [ 'name' => $repository, ]), 403); @@ -121,7 +120,7 @@ public function newRepositoryWith($model, $uriKey = null) */ public function newQueryWithoutScopes($uriKey = null) { - if (!$this->isViaRepository()) { + if (! $this->isViaRepository()) { return $this->model($uriKey)->newQueryWithoutScopes(); } @@ -188,7 +187,7 @@ public function viaParentModel() { $parent = $this->repository($this->viaRepository); - return once(fn() => $parent::newModel()->newQueryWithoutScopes()->whereKey($this->viaRepositoryId)->firstOrFail()); + return once(fn () => $parent::newModel()->newQueryWithoutScopes()->whereKey($this->viaRepositoryId)->firstOrFail()); } public function viaQuery() diff --git a/tests/Controllers/RepositoryMiddlewaresTest.php b/tests/Controllers/RepositoryMiddlewaresTest.php index 5246a33c7..ce52bd2a5 100644 --- a/tests/Controllers/RepositoryMiddlewaresTest.php +++ b/tests/Controllers/RepositoryMiddlewaresTest.php @@ -7,7 +7,6 @@ use Binaryk\LaravelRestify\Tests\Fixtures\Post\PostWithCustomMiddlewareRepository; use Binaryk\LaravelRestify\Tests\IntegrationTest; use Mockery as m; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class RepositoryMiddlewaresTest extends IntegrationTest { @@ -41,7 +40,7 @@ public function test_repository_can_have_custom_middleware() public function test_request_fails_if_middleware_abort() { PostWithCustomMiddlewareRepository::$middlewares = [ - PostAbortMiddleware::class + PostAbortMiddleware::class, ]; Restify::repositories([ @@ -54,7 +53,6 @@ public function test_request_fails_if_middleware_abort() public function test_foreign_repository_middleware_should_not_be_invoked() { - $middleware = m::mock(PostAbortMiddleware::class); $nextParam = null; diff --git a/tests/Fixtures/Post/PostWithCustomMiddlewareRepository.php b/tests/Fixtures/Post/PostWithCustomMiddlewareRepository.php index 537533d7c..4b886f9fb 100644 --- a/tests/Fixtures/Post/PostWithCustomMiddlewareRepository.php +++ b/tests/Fixtures/Post/PostWithCustomMiddlewareRepository.php @@ -16,7 +16,6 @@ class PostWithCustomMiddlewareRepository extends Repository public static $uriKey = 'post-with-middleware'; - public function fields(RestifyRequest $request) { return [ diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index 65b639a97..4f69f6677 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -11,7 +11,6 @@ use Binaryk\LaravelRestify\Tests\Fixtures\Post\PostMergeableRepository; use Binaryk\LaravelRestify\Tests\Fixtures\Post\PostRepository; use Binaryk\LaravelRestify\Tests\Fixtures\Post\PostUnauthorizedFieldRepository; -use Binaryk\LaravelRestify\Tests\Fixtures\Post\PostWithCustomMiddlewareRepository; use Binaryk\LaravelRestify\Tests\Fixtures\Post\PostWithHiddenFieldRepository; use Binaryk\LaravelRestify\Tests\Fixtures\Post\PostWithUnauthorizedFieldsRepository; use Binaryk\LaravelRestify\Tests\Fixtures\User\User;