From 566c0fa801bb272c28dc9fc8fb2f07679f2d5445 Mon Sep 17 00:00:00 2001 From: Simon Geoghegan Date: Tue, 3 Dec 2024 11:45:22 +0800 Subject: [PATCH 1/5] Added the ability to allow Protectors to define whether or not static cache is allowed --- config/protect.php | 15 +++++++++++++++ src/Auth/Protect/Protectors/Protector.php | 5 +++++ src/Http/Responses/DataResponse.php | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/config/protect.php b/config/protect.php index 4e78f78a7f..70f064fa06 100644 --- a/config/protect.php +++ b/config/protect.php @@ -15,6 +15,18 @@ 'default' => null, + /* + |-------------------------------------------------------------------------- + | Static caching. + |-------------------------------------------------------------------------- + | + | Default setting for whether or not to allow protected pages in the static + | cache. + | + */ + + 'cacheable' => null, + /* |-------------------------------------------------------------------------- | Protection Schemes @@ -33,6 +45,9 @@ 'ip_address' => [ 'driver' => 'ip_address', 'allowed' => ['127.0.0.1'], + // NOTE: Set `cacheable` to true/false to allow static caching for + // this driver. + // 'cacheable' => null, ], 'logged_in' => [ diff --git a/src/Auth/Protect/Protectors/Protector.php b/src/Auth/Protect/Protectors/Protector.php index cd06d2c6e3..ae57dc355e 100644 --- a/src/Auth/Protect/Protectors/Protector.php +++ b/src/Auth/Protect/Protectors/Protector.php @@ -36,4 +36,9 @@ public function setConfig($config) return $this; } + + public function cacheable() + { + return $this->config['cacheable'] ?? config('statamic.protect.cacheable', false); + } } diff --git a/src/Http/Responses/DataResponse.php b/src/Http/Responses/DataResponse.php index baca6e7896..b04f40f58d 100644 --- a/src/Http/Responses/DataResponse.php +++ b/src/Http/Responses/DataResponse.php @@ -95,7 +95,7 @@ protected function protect() $protection->protect(); - if ($protection->scheme()) { + if ($protection->scheme() && ! $protection->driver()?->cacheable()) { $this->headers['X-Statamic-Protected'] = true; } From c705319ff1f6a62f4dde62356b9fe7cd220c79d9 Mon Sep 17 00:00:00 2001 From: Simon Geoghegan Date: Tue, 3 Dec 2024 12:00:37 +0800 Subject: [PATCH 2/5] Added a 'cacheable' method to the Protection class --- src/Auth/Protect/Protection.php | 6 ++++++ src/Http/Responses/DataResponse.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Auth/Protect/Protection.php b/src/Auth/Protect/Protection.php index ba56c52714..4d5ea4f8f2 100644 --- a/src/Auth/Protect/Protection.php +++ b/src/Auth/Protect/Protection.php @@ -69,6 +69,12 @@ public function protect() ->protect(); } + public function cacheable() + { + $this->driver() + ->cacheable(); + } + protected function url() { return URL::tidy(request()->fullUrl()); diff --git a/src/Http/Responses/DataResponse.php b/src/Http/Responses/DataResponse.php index b04f40f58d..847023d681 100644 --- a/src/Http/Responses/DataResponse.php +++ b/src/Http/Responses/DataResponse.php @@ -95,7 +95,7 @@ protected function protect() $protection->protect(); - if ($protection->scheme() && ! $protection->driver()?->cacheable()) { + if ($protection->scheme() && ! $protection->cacheable()) { $this->headers['X-Statamic-Protected'] = true; } From 06a4cc3081eada1928c4cac0cf1a37eba5ff5631 Mon Sep 17 00:00:00 2001 From: Simon Geoghegan Date: Tue, 3 Dec 2024 12:12:07 +0800 Subject: [PATCH 3/5] Fixed the Protection 'cacheable' method and added some tests --- src/Auth/Protect/Protection.php | 4 +-- tests/Auth/Protect/ProtectionTest.php | 39 +++++++++++++++++++++++++ tests/FrontendTest.php | 42 +++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/src/Auth/Protect/Protection.php b/src/Auth/Protect/Protection.php index 4d5ea4f8f2..37c5f24661 100644 --- a/src/Auth/Protect/Protection.php +++ b/src/Auth/Protect/Protection.php @@ -71,8 +71,8 @@ public function protect() public function cacheable() { - $this->driver() - ->cacheable(); + return $this->driver() + ->cacheable(); } protected function url() diff --git a/tests/Auth/Protect/ProtectionTest.php b/tests/Auth/Protect/ProtectionTest.php index 38005fa7c3..3c2a7d5ba3 100644 --- a/tests/Auth/Protect/ProtectionTest.php +++ b/tests/Auth/Protect/ProtectionTest.php @@ -147,6 +147,45 @@ public function protect() $this->assertTrue($state->protected); } + #[Test] + public function default_configuration_allows_static_caching() + { + config(['statamic.protect.default' => 'logged_in']); + config(['statamic.protect.cacheable' => true]); + + $this->assertTrue($this->protection->cacheable()); + } + + #[Test] + public function driver_allows_static_caching() + { + config(['statamic.protect.default' => 'logged_in']); + config(['statamic.protect.schemes.logged_in' => [ + 'driver' => 'auth', + 'form_url' => '/login', + 'cacheable' => true, + ]]); + + $this->assertTrue($this->protection->cacheable()); + $this->assertTrue($this->protection->driver()->cacheable()); + } + + #[Test] + public function driver_disallows_static_caching() + { + config(['statamic.protect.cacheable' => true]); + config(['statamic.protect.default' => 'logged_in']); + config(['statamic.protect.schemes.logged_in' => [ + 'driver' => 'auth', + 'form_url' => '/login', + 'cacheable' => false, + ]]); + + $this->assertTrue(config('statamic.protect.cacheable')); + $this->assertFalse($this->protection->cacheable()); + $this->assertFalse($this->protection->driver()->cacheable()); + } + private function createEntryWithScheme($scheme) { return EntryFactory::id('test') diff --git a/tests/FrontendTest.php b/tests/FrontendTest.php index 418fa02a94..340415f080 100644 --- a/tests/FrontendTest.php +++ b/tests/FrontendTest.php @@ -373,6 +373,48 @@ public function header_is_added_to_protected_responses() ->assertHeader('X-Statamic-Protected', true); } + #[Test] + public function header_is_not_added_to_cacheable_protected_responses() + { + config()->set('statamic.protect.cacheable', true); + + $page = $this->createPage('about'); + + $this + ->get('/about') + ->assertOk() + ->assertHeaderMissing('X-Statamic-Protected'); + + $page->set('protect', 'logged_in')->save(); + + $this + ->actingAs(User::make()) + ->get('/about') + ->assertOk() + ->assertHeaderMissing('X-Statamic-Protected'); + } + + #[Test] + public function header_is_not_added_to_cacheable_protected_responses_for_driver() + { + config()->set('statamic.protect.schemes.logged_in.cacheable', true); + + $page = $this->createPage('about'); + + $this + ->get('/about') + ->assertOk() + ->assertHeaderMissing('X-Statamic-Protected'); + + $page->set('protect', 'logged_in')->save(); + + $this + ->actingAs(User::make()) + ->get('/about') + ->assertOk() + ->assertHeaderMissing('X-Statamic-Protected'); + } + #[Test] public function key_variables_key_added() { From bee617532589bf430bac4ae91eaea77d60cf4c39 Mon Sep 17 00:00:00 2001 From: Simon Geoghegan Date: Tue, 3 Dec 2024 12:21:05 +0800 Subject: [PATCH 4/5] Fixed code style issues --- src/Auth/Protect/Protection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Auth/Protect/Protection.php b/src/Auth/Protect/Protection.php index 37c5f24661..75031ca3a7 100644 --- a/src/Auth/Protect/Protection.php +++ b/src/Auth/Protect/Protection.php @@ -72,7 +72,7 @@ public function protect() public function cacheable() { return $this->driver() - ->cacheable(); + ->cacheable(); } protected function url() From 0a3d485c48ffc82ef2dec3cfe7b64f112a3e87df Mon Sep 17 00:00:00 2001 From: Simon Geoghegan Date: Fri, 7 Mar 2025 13:33:43 +0800 Subject: [PATCH 5/5] Removed 'cacheable' settings from the protector configuration and made cachability the responsibility of a Protector instance --- config/protect.php | 15 -------- src/Auth/Protect/Protectors/Protector.php | 2 +- tests/Auth/Protect/ProtectionTest.php | 37 +++++++++---------- tests/FrontendTest.php | 43 +++++++++++------------ 4 files changed, 41 insertions(+), 56 deletions(-) diff --git a/config/protect.php b/config/protect.php index 70f064fa06..4e78f78a7f 100644 --- a/config/protect.php +++ b/config/protect.php @@ -15,18 +15,6 @@ 'default' => null, - /* - |-------------------------------------------------------------------------- - | Static caching. - |-------------------------------------------------------------------------- - | - | Default setting for whether or not to allow protected pages in the static - | cache. - | - */ - - 'cacheable' => null, - /* |-------------------------------------------------------------------------- | Protection Schemes @@ -45,9 +33,6 @@ 'ip_address' => [ 'driver' => 'ip_address', 'allowed' => ['127.0.0.1'], - // NOTE: Set `cacheable` to true/false to allow static caching for - // this driver. - // 'cacheable' => null, ], 'logged_in' => [ diff --git a/src/Auth/Protect/Protectors/Protector.php b/src/Auth/Protect/Protectors/Protector.php index ae57dc355e..96cd573228 100644 --- a/src/Auth/Protect/Protectors/Protector.php +++ b/src/Auth/Protect/Protectors/Protector.php @@ -39,6 +39,6 @@ public function setConfig($config) public function cacheable() { - return $this->config['cacheable'] ?? config('statamic.protect.cacheable', false); + return false; } } diff --git a/tests/Auth/Protect/ProtectionTest.php b/tests/Auth/Protect/ProtectionTest.php index 3c2a7d5ba3..febdfa3eb4 100644 --- a/tests/Auth/Protect/ProtectionTest.php +++ b/tests/Auth/Protect/ProtectionTest.php @@ -148,40 +148,41 @@ public function protect() } #[Test] - public function default_configuration_allows_static_caching() + public function protector_driver_allows_static_caching() { - config(['statamic.protect.default' => 'logged_in']); - config(['statamic.protect.cacheable' => true]); + config(['statamic.protect.default' => 'test']); + config(['statamic.protect.schemes.test' => [ + 'driver' => 'test', + ]]); - $this->assertTrue($this->protection->cacheable()); - } + app(ProtectorManager::class)->extend('test', function ($app) { + return new class() extends Protector + { + public function protect() + { + // + } - #[Test] - public function driver_allows_static_caching() - { - config(['statamic.protect.default' => 'logged_in']); - config(['statamic.protect.schemes.logged_in' => [ - 'driver' => 'auth', - 'form_url' => '/login', - 'cacheable' => true, - ]]); + public function cacheable() + { + return true; + } + }; + }); $this->assertTrue($this->protection->cacheable()); $this->assertTrue($this->protection->driver()->cacheable()); } #[Test] - public function driver_disallows_static_caching() + public function protector_driver_disallows_static_caching() { - config(['statamic.protect.cacheable' => true]); config(['statamic.protect.default' => 'logged_in']); config(['statamic.protect.schemes.logged_in' => [ 'driver' => 'auth', 'form_url' => '/login', - 'cacheable' => false, ]]); - $this->assertTrue(config('statamic.protect.cacheable')); $this->assertFalse($this->protection->cacheable()); $this->assertFalse($this->protection->driver()->cacheable()); } diff --git a/tests/FrontendTest.php b/tests/FrontendTest.php index 340415f080..634797cc09 100644 --- a/tests/FrontendTest.php +++ b/tests/FrontendTest.php @@ -11,6 +11,8 @@ use Illuminate\Support\Facades\Event; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; +use Statamic\Auth\Protect\ProtectorManager; +use Statamic\Auth\Protect\Protectors\Protector; use Statamic\Events\ResponseCreated; use Statamic\Facades\Blueprint; use Statamic\Facades\Cascade; @@ -376,28 +378,25 @@ public function header_is_added_to_protected_responses() #[Test] public function header_is_not_added_to_cacheable_protected_responses() { - config()->set('statamic.protect.cacheable', true); - - $page = $this->createPage('about'); - - $this - ->get('/about') - ->assertOk() - ->assertHeaderMissing('X-Statamic-Protected'); - - $page->set('protect', 'logged_in')->save(); - - $this - ->actingAs(User::make()) - ->get('/about') - ->assertOk() - ->assertHeaderMissing('X-Statamic-Protected'); - } + // config(['statamic.protect.default' => 'test']); + config(['statamic.protect.schemes.test' => [ + 'driver' => 'test', + ]]); - #[Test] - public function header_is_not_added_to_cacheable_protected_responses_for_driver() - { - config()->set('statamic.protect.schemes.logged_in.cacheable', true); + app(ProtectorManager::class)->extend('test', function ($app) { + return new class() extends Protector + { + public function protect() + { + // + } + + public function cacheable() + { + return true; + } + }; + }); $page = $this->createPage('about'); @@ -406,7 +405,7 @@ public function header_is_not_added_to_cacheable_protected_responses_for_driver( ->assertOk() ->assertHeaderMissing('X-Statamic-Protected'); - $page->set('protect', 'logged_in')->save(); + $page->set('protect', 'test')->save(); $this ->actingAs(User::make())