From ae1d6111cfe74306bdb5da2bda1f6be6fe6f5aef Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Sat, 6 Dec 2025 17:56:15 -0300 Subject: [PATCH 1/3] refactor: rename DocMdpLevel enum cases to match JSignPdf naming - NOT_CERTIFIED (was NONE) - CERTIFIED_NO_CHANGES_ALLOWED (was NO_CHANGES) - CERTIFIED_FORM_FILLING (was FORM_FILL) - CERTIFIED_FORM_FILLING_AND_ANNOTATIONS (was FORM_FILL_AND_ANNOTATIONS) This aligns enum case names with JSignPdf -cl parameter values, allowing direct use of enum->name without conversion layer. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- lib/Enum/DocMdpLevel.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/Enum/DocMdpLevel.php b/lib/Enum/DocMdpLevel.php index 8dac8d283f..c354dd91ab 100644 --- a/lib/Enum/DocMdpLevel.php +++ b/lib/Enum/DocMdpLevel.php @@ -12,30 +12,30 @@ use OCP\IL10N; enum DocMdpLevel: int { - case NONE = 0; - case NO_CHANGES = 1; - case FORM_FILL = 2; - case FORM_FILL_AND_ANNOTATIONS = 3; + case NOT_CERTIFIED = 0; + case CERTIFIED_NO_CHANGES_ALLOWED = 1; + case CERTIFIED_FORM_FILLING = 2; + case CERTIFIED_FORM_FILLING_AND_ANNOTATIONS = 3; public function isCertifying(): bool { - return $this !== self::NONE; + return $this !== self::NOT_CERTIFIED; } public function getLabel(IL10N $l10n): string { return match($this) { - self::NONE => $l10n->t('No certification'), - self::NO_CHANGES => $l10n->t('No changes allowed'), - self::FORM_FILL => $l10n->t('Form filling and additional signatures'), - self::FORM_FILL_AND_ANNOTATIONS => $l10n->t('Form filling, annotations and additional signatures'), + self::NOT_CERTIFIED => $l10n->t('No certification'), + self::CERTIFIED_NO_CHANGES_ALLOWED => $l10n->t('No changes allowed'), + self::CERTIFIED_FORM_FILLING => $l10n->t('Form filling and additional signatures'), + self::CERTIFIED_FORM_FILLING_AND_ANNOTATIONS => $l10n->t('Form filling, annotations and additional signatures'), }; } public function getDescription(IL10N $l10n): string { return match($this) { - self::NONE => $l10n->t('Document is not certified. No restrictions on modifications.'), - self::NO_CHANGES => $l10n->t('No changes allowed. Additional approval signatures are prohibited.'), - self::FORM_FILL => $l10n->t('Form filling allowed. Additional approval signatures are allowed.'), - self::FORM_FILL_AND_ANNOTATIONS => $l10n->t('Form filling and annotations allowed. Additional approval signatures are allowed.'), + self::NOT_CERTIFIED => $l10n->t('Document is not certified. No restrictions on modifications.'), + self::CERTIFIED_NO_CHANGES_ALLOWED => $l10n->t('No changes allowed. Additional approval signatures are prohibited.'), + self::CERTIFIED_FORM_FILLING => $l10n->t('Form filling allowed. Additional approval signatures are allowed.'), + self::CERTIFIED_FORM_FILLING_AND_ANNOTATIONS => $l10n->t('Form filling and annotations allowed. Additional approval signatures are allowed.'), }; } } From 957114bf3d8a40a1b780ed0fe8cd7065e28fbbe7 Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Sat, 6 Dec 2025 17:56:27 -0300 Subject: [PATCH 2/3] refactor: update DocMdpHandler to use new enum names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update all references to DocMdpLevel enum cases: - NONE → NOT_CERTIFIED - NO_CHANGES → CERTIFIED_NO_CHANGES_ALLOWED - FORM_FILL → CERTIFIED_FORM_FILLING - FORM_FILL_AND_ANNOTATIONS → CERTIFIED_FORM_FILLING_AND_ANNOTATIONS Updated in: - ALLOWED_MODIFICATIONS constant - extractDocMdpLevel() fallback values - getAllowedModificationMessage() match expression - getViolationMessage() match expression - validateModifications() condition checks Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- lib/Handler/DocMdpHandler.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/Handler/DocMdpHandler.php b/lib/Handler/DocMdpHandler.php index 3f2978371e..01f5d3e155 100644 --- a/lib/Handler/DocMdpHandler.php +++ b/lib/Handler/DocMdpHandler.php @@ -16,9 +16,9 @@ class DocMdpHandler { /** @var array Allowed modification types per DocMDP level */ private const ALLOWED_MODIFICATIONS = [ - 'NO_CHANGES' => [], - 'FORM_FILL' => ['form_field', 'template', 'signature'], - 'FORM_FILL_AND_ANNOTATIONS' => ['form_field', 'template', 'annotation', 'signature'], + 'CERTIFIED_NO_CHANGES_ALLOWED' => [], + 'CERTIFIED_FORM_FILLING' => ['form_field', 'template', 'signature'], + 'CERTIFIED_FORM_FILLING_AND_ANNOTATIONS' => ['form_field', 'template', 'annotation', 'signature'], ]; public function __construct( @@ -70,15 +70,15 @@ private function extractDocMdpLevel($pdfResource): DocMdpLevel { $content = stream_get_contents($pdfResource); if (!$this->validateIsoCompliance($content)) { - return DocMdpLevel::NONE; + return DocMdpLevel::NOT_CERTIFIED; } $pValue = $this->extractPValue($content); if ($pValue === null) { - return DocMdpLevel::NONE; + return DocMdpLevel::NOT_CERTIFIED; } - return DocMdpLevel::tryFrom($pValue) ?? DocMdpLevel::NONE; + return DocMdpLevel::tryFrom($pValue) ?? DocMdpLevel::NOT_CERTIFIED; } /** @@ -249,7 +249,7 @@ private function validateModifications(DocMdpLevel $docmdpLevel, array $modifica ); } - if ($docmdpLevel === DocMdpLevel::NONE) { + if ($docmdpLevel === DocMdpLevel::NOT_CERTIFIED) { return $this->buildValidationResult( true, File::MODIFICATION_ALLOWED, @@ -307,9 +307,9 @@ private function buildValidationResult(bool $valid, int $status, string $message */ private function getAllowedModificationMessage(DocMdpLevel $level): string { return match ($level) { - DocMdpLevel::NO_CHANGES => 'Invalid: Document was modified after signing (DocMDP violation - no changes allowed)', - DocMdpLevel::FORM_FILL => 'Document form fields were modified (allowed by DocMDP P=2)', - DocMdpLevel::FORM_FILL_AND_ANNOTATIONS => 'Document form fields or annotations were modified (allowed by DocMDP P=3)', + DocMdpLevel::CERTIFIED_NO_CHANGES_ALLOWED => 'Invalid: Document was modified after signing (DocMDP violation - no changes allowed)', + DocMdpLevel::CERTIFIED_FORM_FILLING => 'Document form fields were modified (allowed by DocMDP P=2)', + DocMdpLevel::CERTIFIED_FORM_FILLING_AND_ANNOTATIONS => 'Document form fields or annotations were modified (allowed by DocMDP P=3)', default => 'Document was modified after signing', }; } @@ -322,9 +322,9 @@ private function getAllowedModificationMessage(DocMdpLevel $level): string { */ private function getViolationMessage(DocMdpLevel $level): string { return match ($level) { - DocMdpLevel::NO_CHANGES => 'Invalid: Document was modified after signing (DocMDP violation - no changes allowed)', - DocMdpLevel::FORM_FILL => 'Invalid: Document was modified after signing (DocMDP P=2 only allows form field changes)', - DocMdpLevel::FORM_FILL_AND_ANNOTATIONS => 'Invalid: Document was modified after signing (DocMDP P=3 only allows form fields and annotations)', + DocMdpLevel::CERTIFIED_NO_CHANGES_ALLOWED => 'Invalid: Document was modified after signing (DocMDP violation - no changes allowed)', + DocMdpLevel::CERTIFIED_FORM_FILLING => 'Invalid: Document was modified after signing (DocMDP P=2 only allows form field changes)', + DocMdpLevel::CERTIFIED_FORM_FILLING_AND_ANNOTATIONS => 'Invalid: Document was modified after signing (DocMDP P=3 only allows form fields and annotations)', default => 'Invalid: Document was modified after signing (DocMDP violation)', }; } From e204840926da9fab92e0d58573be6068800fc5a8 Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Sat, 6 Dec 2025 17:56:36 -0300 Subject: [PATCH 3/3] test: update DocMdpHandlerTest to use new enum names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update all test assertions and data providers to use renamed enum cases: - NONE → NOT_CERTIFIED - NO_CHANGES → CERTIFIED_NO_CHANGES_ALLOWED - FORM_FILL → CERTIFIED_FORM_FILLING - FORM_FILL_AND_ANNOTATIONS → CERTIFIED_FORM_FILLING_AND_ANNOTATIONS All 30 tests passing with new nomenclature. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- tests/php/Unit/Handler/DocMdpHandlerTest.php | 36 ++++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/php/Unit/Handler/DocMdpHandlerTest.php b/tests/php/Unit/Handler/DocMdpHandlerTest.php index 6f7bc8b864..e37dfcbbde 100644 --- a/tests/php/Unit/Handler/DocMdpHandlerTest.php +++ b/tests/php/Unit/Handler/DocMdpHandlerTest.php @@ -34,7 +34,7 @@ public function testUnsignedPdfIsDetectedAsLevelNone(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::NONE->value, $result['docmdp']['level']); + $this->assertSame(DocMdpLevel::NOT_CERTIFIED->value, $result['docmdp']['level']); } public function testP0AllowsAnyModification(): void { @@ -154,7 +154,7 @@ public function testExtractsDocMdpFromSignatureReferenceNotPerms(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::FORM_FILL->value, $result['docmdp']['level'], 'Must extract DocMDP from /Reference per ICP-Brasil recommendation (not /Perms)'); + $this->assertSame(DocMdpLevel::CERTIFIED_FORM_FILLING->value, $result['docmdp']['level'], 'Must extract DocMDP from /Reference per ICP-Brasil recommendation (not /Perms)'); } public function testExtractsDocMdpFromFirstCertifyingSignature(): void { @@ -164,7 +164,7 @@ public function testExtractsDocMdpFromFirstCertifyingSignature(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::NO_CHANGES->value, $result['docmdp']['level'], 'Must extract DocMDP from first CERTIFYING signature, not first signature in file'); + $this->assertSame(DocMdpLevel::CERTIFIED_NO_CHANGES_ALLOWED->value, $result['docmdp']['level'], 'Must extract DocMDP from first CERTIFYING signature, not first signature in file'); } public function testP2AllowsPageTemplateInstantiation(): void { @@ -196,7 +196,7 @@ public function testExtractsDocMdpWithIndirectReferenceItiStyle(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::FORM_FILL->value, $result['docmdp']['level'], 'Must extract DocMDP from indirect references per ICP-Brasil example'); + $this->assertSame(DocMdpLevel::CERTIFIED_FORM_FILLING->value, $result['docmdp']['level'], 'Must extract DocMDP from indirect references per ICP-Brasil example'); } public function testValidatesTransformParamsVersion(): void { @@ -206,7 +206,7 @@ public function testValidatesTransformParamsVersion(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::FORM_FILL->value, $result['docmdp']['level'], 'Must accept /V /1.2 in TransformParams per ICP-Brasil'); + $this->assertSame(DocMdpLevel::CERTIFIED_FORM_FILLING->value, $result['docmdp']['level'], 'Must accept /V /1.2 in TransformParams per ICP-Brasil'); } public function testRejectsDocMdpWithoutVersion(): void { @@ -216,7 +216,7 @@ public function testRejectsDocMdpWithoutVersion(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::NONE->value, $result['docmdp']['level'], 'Must reject DocMDP without /V version per ICP-Brasil requirement'); + $this->assertSame(DocMdpLevel::NOT_CERTIFIED->value, $result['docmdp']['level'], 'Must reject DocMDP without /V version per ICP-Brasil requirement'); } public function testRejectsDocMdpWithInvalidVersion(): void { @@ -226,7 +226,7 @@ public function testRejectsDocMdpWithInvalidVersion(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::NONE->value, $result['docmdp']['level'], 'Must reject DocMDP with /V 1.0 (only /V /1.2 allowed per ICP-Brasil)'); + $this->assertSame(DocMdpLevel::NOT_CERTIFIED->value, $result['docmdp']['level'], 'Must reject DocMDP with /V 1.0 (only /V /1.2 allowed per ICP-Brasil)'); } public function testRejectsDocMdpWithInvalidVersionIndirectRef(): void { @@ -236,15 +236,15 @@ public function testRejectsDocMdpWithInvalidVersionIndirectRef(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::NONE->value, $result['docmdp']['level'], 'Must reject indirect DocMDP with /V 1.3 (only /V /1.2 allowed)'); + $this->assertSame(DocMdpLevel::NOT_CERTIFIED->value, $result['docmdp']['level'], 'Must reject indirect DocMDP with /V 1.3 (only /V /1.2 allowed)'); } public static function docMdpLevelExtractionProvider(): array { return [ - 'Level P=0 NONE' => [0, DocMdpLevel::NONE], - 'Level P=1 NO_CHANGES' => [1, DocMdpLevel::NO_CHANGES], - 'Level P=2 FORM_FILL' => [2, DocMdpLevel::FORM_FILL], - 'Level P=3 FORM_FILL_AND_ANNOTATIONS' => [3, DocMdpLevel::FORM_FILL_AND_ANNOTATIONS], + 'Level P=0 NOT_CERTIFIED' => [0, DocMdpLevel::NOT_CERTIFIED], + 'Level P=1 CERTIFIED_NO_CHANGES_ALLOWED' => [1, DocMdpLevel::CERTIFIED_NO_CHANGES_ALLOWED], + 'Level P=2 CERTIFIED_FORM_FILLING' => [2, DocMdpLevel::CERTIFIED_FORM_FILLING], + 'Level P=3 CERTIFIED_FORM_FILLING_AND_ANNOTATIONS' => [3, DocMdpLevel::CERTIFIED_FORM_FILLING_AND_ANNOTATIONS], ]; } @@ -726,7 +726,7 @@ public function testRejectsSignatureDictionaryWithoutTypeWhenPresent(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::NONE->value, $result['docmdp']['level'], 'ISO 32000-1 Table 252: if /Type present in signature dict, must be /Sig'); + $this->assertSame(DocMdpLevel::NOT_CERTIFIED->value, $result['docmdp']['level'], 'ISO 32000-1 Table 252: if /Type present in signature dict, must be /Sig'); } public function testRejectsSignatureWithoutFilterEntry(): void { @@ -744,7 +744,7 @@ public function testRejectsSignatureWithoutFilterEntry(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::NONE->value, $result['docmdp']['level'], 'ISO 32000-1 Table 252: /Filter is Required in signature dictionary'); + $this->assertSame(DocMdpLevel::NOT_CERTIFIED->value, $result['docmdp']['level'], 'ISO 32000-1 Table 252: /Filter is Required in signature dictionary'); } public function testRejectsSignatureWithoutByteRange(): void { @@ -762,7 +762,7 @@ public function testRejectsSignatureWithoutByteRange(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::NONE->value, $result['docmdp']['level'], 'ISO 32000-1: ByteRange required when DocMDP transform method is used'); + $this->assertSame(DocMdpLevel::NOT_CERTIFIED->value, $result['docmdp']['level'], 'ISO 32000-1: ByteRange required when DocMDP transform method is used'); } public function testRejectsMultipleDocMdpSignatures(): void { @@ -792,7 +792,7 @@ public function testRejectsMultipleDocMdpSignatures(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::NONE->value, $result['docmdp']['level'], 'ISO 32000-1 12.8.2.2.1: A document can contain only one signature field that contains a DocMDP transform method'); + $this->assertSame(DocMdpLevel::NOT_CERTIFIED->value, $result['docmdp']['level'], 'ISO 32000-1 12.8.2.2.1: A document can contain only one signature field that contains a DocMDP transform method'); } public function testRejectsDocMdpNotFirstSignature(): void { @@ -820,7 +820,7 @@ public function testRejectsDocMdpNotFirstSignature(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::NONE->value, $result['docmdp']['level'], 'ISO 32000-1 12.8.2.2.1: DocMDP signature shall be the first signed field in the document'); + $this->assertSame(DocMdpLevel::NOT_CERTIFIED->value, $result['docmdp']['level'], 'ISO 32000-1 12.8.2.2.1: DocMDP signature shall be the first signed field in the document'); } public function testRejectsSigRefWithoutTransformMethod(): void { @@ -839,6 +839,6 @@ public function testRejectsSigRefWithoutTransformMethod(): void { $result = $this->handler->extractDocMdpData($resource); fclose($resource); - $this->assertSame(DocMdpLevel::NONE->value, $result['docmdp']['level'], 'ISO 32000-1 Table 253: /TransformMethod is Required in signature reference dictionary'); + $this->assertSame(DocMdpLevel::NOT_CERTIFIED->value, $result['docmdp']['level'], 'ISO 32000-1 Table 253: /TransformMethod is Required in signature reference dictionary'); } }