From 6e1c680f46e8e06ab8dc7cece0334f60dd11eed1 Mon Sep 17 00:00:00 2001 From: Lukas Bestle Date: Thu, 19 Dec 2024 21:31:48 +0100 Subject: [PATCH] Check permissions in API and Fiber Co-authored-by: Ahmet Bora --- config/api/routes/languages.php | 10 +++++----- src/Cms/Api.php | 20 +++++++++++++++++--- src/Cms/Find.php | 18 +++++++++++++++--- tests/Cms/Api/ApiTest.php | 30 ++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/config/api/routes/languages.php b/config/api/routes/languages.php index e2d4f6b839..acfb7f9ba9 100644 --- a/config/api/routes/languages.php +++ b/config/api/routes/languages.php @@ -8,35 +8,35 @@ 'pattern' => 'languages', 'method' => 'GET', 'action' => function () { - return $this->kirby()->languages(); + return $this->languages(); } ], [ 'pattern' => 'languages', 'method' => 'POST', 'action' => function () { - return $this->kirby()->languages()->create($this->requestBody()); + return $this->languages()->create($this->requestBody()); } ], [ 'pattern' => 'languages/(:any)', 'method' => 'GET', 'action' => function (string $code) { - return $this->kirby()->languages()->find($code); + return $this->languages()->find($code); } ], [ 'pattern' => 'languages/(:any)', 'method' => 'PATCH', 'action' => function (string $code) { - return $this->kirby()->languages()->find($code)?->update($this->requestBody()); + return $this->languages()->find($code)?->update($this->requestBody()); } ], [ 'pattern' => 'languages/(:any)', 'method' => 'DELETE', 'action' => function (string $code) { - return $this->kirby()->languages()->find($code)?->delete(); + return $this->languages()->find($code)?->delete(); } ] ]; diff --git a/src/Cms/Api.php b/src/Cms/Api.php index d7945b4ac2..8060f45c4f 100644 --- a/src/Cms/Api.php +++ b/src/Cms/Api.php @@ -138,6 +138,14 @@ public function language(): string|null $this->requestHeaders('x-language'); } + /** + * Returns the languages collection + */ + public function languages(): Languages + { + return $this->kirby()->languages()->filter('isAccessible', true); + } + /** * Returns the page object for the given id * @@ -225,9 +233,15 @@ public function session(array $options = []): Session /** * Returns the site object */ - public function site(): Site + public function site(): Site|null { - return $this->kirby->site(); + $site = $this->kirby->site(); + + if ($site->isAccessible() === true) { + return $site; + } + + return null; } /** @@ -255,6 +269,6 @@ public function user(string|null $id = null): User|null */ public function users(): Users { - return $this->kirby->users(); + return $this->kirby->users()->filter('isAccessible', true); } } diff --git a/src/Cms/Find.php b/src/Cms/Find.php index 046a749d4f..6f69a59adc 100644 --- a/src/Cms/Find.php +++ b/src/Cms/Find.php @@ -52,7 +52,9 @@ public static function file( */ public static function language(string $code): Language|null { - if ($language = App::instance()->language($code)) { + $language = App::instance()->language($code); + + if ($language?->isAccessible() === true) { return $language; } @@ -158,13 +160,23 @@ public static function user(string|null $id = null): User|null $kirby->option('api.allowImpersonation', false) ); - return $user ?? throw new NotFoundException( + if ($user?->isAccessible() === true) { + return $user; + } + + throw new NotFoundException( key: 'user.undefined' ); } // get a specific user by id - return $kirby->user($id) ?? throw new NotFoundException( + $user = $kirby->user($id); + + if ($user?->isAccessible() === true) { + return $user; + } + + throw new NotFoundException( key: 'user.notFound', data: ['name' => $id] ); diff --git a/tests/Cms/Api/ApiTest.php b/tests/Cms/Api/ApiTest.php index d1bc3e83fa..f3a2dc0b02 100644 --- a/tests/Cms/Api/ApiTest.php +++ b/tests/Cms/Api/ApiTest.php @@ -436,6 +436,36 @@ public function testUsers() $this->assertSame($this->app->users(), $this->api->users()); } + public function testUsersWithoutPermissions() + { + $app = $this->app->clone([ + 'users' => [ + ['email' => 'test@getkirby.com'] + ] + ]); + $app->impersonate('test@getkirby.com'); + + $this->assertNotSame($app->users(), $app->api()->users()); + } + + public function testUsersWithoutPermissionsDebugEnabled() + { + $app = $this->app->clone([ + 'options' => [ + 'debug' => true + ], + 'users' => [ + ['email' => 'test@getkirby.com'] + ] + ]); + $app->impersonate('test@getkirby.com'); + + $this->expectException(AuthException::class); + $this->expectExceptionMessage('You are not allowed to access the users'); + + $app->api()->users(); + } + public function testFileGetRoute() { // regular