From cfbf6f968855057a16d98eb71b0752ee3e89a7da Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Thu, 19 Mar 2026 12:03:44 +0000 Subject: [PATCH 1/4] Add authorization to entry revision routes --- .../CP/Collections/EntryRevisionsController.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Http/Controllers/CP/Collections/EntryRevisionsController.php b/src/Http/Controllers/CP/Collections/EntryRevisionsController.php index c1ef85e20f1..f64445f0a5d 100644 --- a/src/Http/Controllers/CP/Collections/EntryRevisionsController.php +++ b/src/Http/Controllers/CP/Collections/EntryRevisionsController.php @@ -12,6 +12,10 @@ class EntryRevisionsController extends CpController { public function index(Request $request, $collection, $entry) { + if (User::current()->cant('view', $entry)) { + abort(403); + } + $revisions = $entry ->revisions() ->reverse() @@ -39,6 +43,10 @@ public function index(Request $request, $collection, $entry) public function store(Request $request, $collection, $entry) { + if (User::current()->cant('edit', $entry)) { + abort(403); + } + $entry->createRevision([ 'message' => $request->message, 'user' => User::fromUser($request->user()), @@ -49,6 +57,10 @@ public function store(Request $request, $collection, $entry) public function show(Request $request, $collection, $entry, $revision) { + if (User::current()->cant('view', $entry)) { + abort(403); + } + $entry = $entry->makeFromRevision($revision); // TODO: Most of this is duplicated with EntriesController@edit. DRY it off. From 8295a3852aa447b755fd3f48d6a9213de16281a1 Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Thu, 19 Mar 2026 13:30:02 +0000 Subject: [PATCH 2/4] tests --- tests/Feature/Entries/EntryRevisionsTest.php | 45 +++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/tests/Feature/Entries/EntryRevisionsTest.php b/tests/Feature/Entries/EntryRevisionsTest.php index d9d032ead25..c7c66735a9e 100644 --- a/tests/Feature/Entries/EntryRevisionsTest.php +++ b/tests/Feature/Entries/EntryRevisionsTest.php @@ -46,7 +46,7 @@ public function it_gets_revisions() $now = Carbon::parse('2017-02-03'); Carbon::setTestNow($now); $this->setTestBlueprint('test', ['foo' => ['type' => 'text']]); - $this->setTestRoles(['test' => ['access cp', 'publish blog entries']]); + $this->setTestRoles(['test' => ['access cp', 'view blog entries', 'publish blog entries']]); $user = User::make()->id('user-1')->assignRole('test')->save(); $entry = EntryFactory::id('1') @@ -97,6 +97,49 @@ public function it_gets_revisions() ->assertJsonPath('1.revisions.1.attributes.item_url', 'http://localhost/cp/collections/blog/entries/1/revisions/'.Carbon::parse('2017-02-03')->timestamp); } + #[Test] + public function it_denies_access_to_revisions_without_permission_to_view_entry() + { + $now = Carbon::parse('2017-02-03'); + Carbon::setTestNow($now); + $this->setTestBlueprint('test', ['foo' => ['type' => 'text']]); + $this->setTestRoles(['test' => ['access cp']]); + $user = User::make()->id('user-1')->assignRole('test')->save(); + + $entry = EntryFactory::id('1') + ->slug('test') + ->collection('blog') + ->published(true) + ->date('2010-12-25') + ->data([ + 'blueprint' => 'test', + 'title' => 'Original title', + 'foo' => 'bar', + ])->create(); + + tap($entry->makeRevision(), function ($copy) { + $copy->message('Revision one'); + $copy->date(Carbon::parse('2017-02-01')); + })->save(); + + tap($entry->makeRevision(), function ($copy) { + $copy->message('Revision two'); + $copy->date(Carbon::parse('2017-02-03')); + })->save(); + + tap($entry->makeWorkingCopy(), function ($copy) { + $attrs = $copy->attributes(); + $attrs['data']['title'] = 'Title modified in working copy'; + $attrs['data']['foo'] = 'baz'; + $copy->attributes($attrs); + })->save(); + + $this + ->actingAs($user) + ->get($entry->revisionsUrl()) + ->assertForbidden(); + } + #[Test] public function it_publishes_an_entry() { From b32126fee0bee1dcc63c3319a9aa7c0fba54fa47 Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Thu, 19 Mar 2026 13:45:53 +0000 Subject: [PATCH 3/4] abort from unused term revision routes --- .../Controllers/CP/Taxonomies/TermRevisionsController.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Http/Controllers/CP/Taxonomies/TermRevisionsController.php b/src/Http/Controllers/CP/Taxonomies/TermRevisionsController.php index dafc0af0488..41543f1ef26 100644 --- a/src/Http/Controllers/CP/Taxonomies/TermRevisionsController.php +++ b/src/Http/Controllers/CP/Taxonomies/TermRevisionsController.php @@ -12,6 +12,8 @@ class TermRevisionsController extends CpController { public function index(Request $request, $taxonomy, $term) { + abort(403); + $revisions = $term ->revisions() ->reverse() @@ -34,6 +36,8 @@ public function index(Request $request, $taxonomy, $term) public function store(Request $request, $taxonomy, $term) { + abort(403); + $term->createRevision([ 'message' => $request->message, 'user' => User::fromUser($request->user()), @@ -44,6 +48,8 @@ public function store(Request $request, $taxonomy, $term) public function show(Request $request, $taxonomy, $term, $site, $revision) { + abort(403); + $term = $term->makeFromRevision($revision); // TODO: Most of this is duplicated with EntriesController@edit. DRY it off. From f0e3611fcdd1f6a1240e73430a1f26e6477c0262 Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Thu, 19 Mar 2026 19:57:36 -0400 Subject: [PATCH 4/4] Remove unused term revision controllers, routes, and commented-out UI Co-Authored-By: Claude Opus 4.6 --- resources/js/components/terms/PublishForm.vue | 39 ------ routes/cp.php | 8 -- .../RestoreTermRevisionController.php | 26 ---- .../CP/Taxonomies/TermRevisionsController.php | 124 ------------------ 4 files changed, 197 deletions(-) delete mode 100644 src/Http/Controllers/CP/Taxonomies/RestoreTermRevisionController.php delete mode 100644 src/Http/Controllers/CP/Taxonomies/TermRevisionsController.php diff --git a/resources/js/components/terms/PublishForm.vue b/resources/js/components/terms/PublishForm.vue index 9adebbd8013..81208100f4b 100644 --- a/resources/js/components/terms/PublishForm.vue +++ b/resources/js/components/terms/PublishForm.vue @@ -131,45 +131,6 @@ - -