From 8286d7504d9d368de81b4e8d095398764278bb95 Mon Sep 17 00:00:00 2001 From: nala Date: Thu, 22 Oct 2026 21:03:11 +0200 Subject: [PATCH] fix: preserve approved editorial access independently of technical reservation --- app/Services/DocumentManagementAccess.php | 5 +++-- tests/Feature/ContentManagementEntryTest.php | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/Services/DocumentManagementAccess.php b/app/Services/DocumentManagementAccess.php index f3712661..b7fd285a 100644 --- a/app/Services/DocumentManagementAccess.php +++ b/app/Services/DocumentManagementAccess.php @@ -26,8 +26,9 @@ class DocumentManagementAccess /** Restore the approved editorial operation without a global management grant. */ public function editorial(User $actor): bool { - return config('portal.homologation_only', false) - && in_array(strtolower(trim($actor->email)), config('homologation_editorial.accounts', []), true) + // Tempo's named editorial designation does not depend on whether the + // site's technical reviewer reservation is enabled. + return in_array(strtolower(trim($actor->email)), config('homologation_editorial.accounts', []), true) && app(PortalProfileAccess::class)->superuser($actor) && ! app(PortalProfileAccess::class)->has($actor, 'auditor') && app(PortalProfileAccess::class)->mfa($actor); diff --git a/tests/Feature/ContentManagementEntryTest.php b/tests/Feature/ContentManagementEntryTest.php index 1fa12a31..57a7bed7 100644 --- a/tests/Feature/ContentManagementEntryTest.php +++ b/tests/Feature/ContentManagementEntryTest.php @@ -102,4 +102,23 @@ class ContentManagementEntryTest extends TestCase $this->assertDatabaseHas('documents', ['id' => $document->id, 'sha256' => $document->sha256]); $this->assertSame(4, DB::table('portal_resource_revisions')->where('resource_id', $resource->id)->count()); } + + public function test_existing_named_editorial_designation_survives_removal_of_technical_reservation(): void + { + $actor = User::factory()->create(); + $other = User::factory()->create(); + $actor->forceFill(['two_factor_secret' => Crypt::encryptString('JBSWY3DPEHPK3PXP'), 'two_factor_confirmed_at' => now()])->save(); + config(['portal.homologation_only' => false, 'portal.profile_access_enabled' => true, + 'portal.managers' => [], 'homologation_editorial.accounts' => [$actor->email]]); + DB::table('portal_superuser_pair')->updateOrInsert(['id' => 1], ['first_user_id' => $actor->id, 'second_user_id' => $other->id, 'approved_by' => $other->id]); + $this->actingAs($actor)->withSession(['portal.mfa_actor' => $actor->id, 'portal.mfa_at' => time(), 'portal.access_revision' => (int) $actor->portal_access_revision]); + $this->get('/gestao-conteudos')->assertOk()->assertInertia(fn (Assert $page) => $page->where('access.documents.edit', true)); + $this->get('/management/portal-services?intent=legislation')->assertOk()->assertInertia(fn (Assert $page) => $page + ->where('editorialScopeOnly', true)->where('documentAccessOnly', false)); + config(['homologation_editorial.accounts' => []]); + $this->get('/management/portal-services')->assertForbidden(); + config(['homologation_editorial.accounts' => [$actor->email]]); + $this->withSession(['portal.mfa_at' => time() - 901]); + $this->assertFalse(app(\App\Services\DocumentManagementAccess::class)->editorial($actor)); + } }