[stable32] feat: docmdp implementation#6029
Merged
vitormattos merged 45 commits intostable32from Dec 8, 2025
Merged
Conversation
Add database columns to support DocMDP (Document Modification Detection and Prevention): - libresign_sign_request.docmdp_level (SMALLINT, default 0) Stores certification level: 0=none, 1=no changes, 2=form fill, 3=form fill + annotations - libresign_file.modification_status (SMALLINT, default 0) Tracks modification detection: 0=unchecked, 1=unmodified, 2=allowed, 3=violation Both tables checked for existence before adding columns for safe migration. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add docmdpLevel field (SMALLINT) to store DocMDP certification level for each signature request. Includes getter/setter and type mapping. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Service to manage DocMDP configuration stored in app settings: - isEnabled(): check if DocMDP is enabled - setEnabled(bool): enable/disable DocMDP - getLevel(): get default certification level (DocMdpLevel enum) - setLevel(DocMdpLevel): set default certification level - getConfig(): return full config with enabled status and available levels Configuration stored in single key 'docmdp_level' for simplicity. When disabled, key is deleted from database. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add DocMDP support to JSignPdf signing process: - Inject DocMdpConfigService to access admin configuration - Add getCertificationLevel() to retrieve enabled level name - Append -cl parameter to JSignParam when DocMDP is enabled - Uses enum->name directly for JSignPdf compatibility When DocMDP is enabled, JSignPdf will certify PDFs with configured level: NOT_CERTIFIED, CERTIFIED_NO_CHANGES_ALLOWED, CERTIFIED_FORM_FILLING, or CERTIFIED_FORM_FILLING_AND_ANNOTATIONS. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add POST /api/v1/admin/docmdp/config endpoint: - Accepts 'enabled' (bool) and 'defaultLevel' (int) parameters - Validates DocMDP level with DocMdpLevel::tryFrom() - Saves configuration via DocMdpConfigService - Returns success message or error with appropriate HTTP status Allows admins to enable/disable DocMDP and set default certification level. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Inject DocMdpConfigService and provide docmdp_config to frontend: - Includes enabled status - Includes default level - Includes available levels with labels and descriptions Makes DocMDP configuration available to admin settings UI. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add Vue component for DocMDP configuration in admin settings: - Toggle switch to enable/disable DocMDP - Radio buttons for certification level selection: * No certification (P=0) * No changes allowed (P=1) * Form filling allowed (P=2) * Form filling and annotations (P=3) - Loading/saving/error indicators - Saves via POST /api/v1/admin/docmdp/config Uses Nextcloud Vue components (NcCheckboxRadioSwitch, NcLoadingIcon, NcSavingIndicatorIcon, NcNoteCard). Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add DocMDP information to signers array in getFileData(): - docmdp: certification level and compliance status - modifications: detected modification types - modification_validation: validation result details Also improve error handling with structured logging when file content retrieval fails, including fileId and exception context. Makes DocMDP validation results available to frontend for display. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add proper PHPDoc annotations: - Detailed parameter descriptions for enabled and defaultLevel - Complete DataResponse return type with status codes and schemas - HTTP status code documentation (200, 400, 500) Fixes OpenAPI generation errors. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Regenerate OpenAPI documentation files to include setDocMdpConfig endpoint: - openapi-administration.json - openapi-full.json - TypeScript type definitions Generated from updated PHPDoc annotations. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Remove unused import and fix PHPDoc formatting: - Remove unused DocMdpLevel import from JSignPdfHandler - Fix trailing whitespace in AdminController PHPDoc Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- AdminTest: Add DocMdpConfigService mock parameter to Admin constructor - FileServiceTest: Remove DocMDP fields (docmdp, modifications, modification_validation) from test comparisons These tests were failing because: 1. Admin class now requires DocMdpConfigService as 9th constructor parameter 2. FileService.getFileData() now includes DocMDP-related fields in signers array Both fixes ensure tests properly handle the new DocMDP feature additions. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Remove duplicate getLabel() and getDescription() methods from DocMdpConfigService - Use enum methods directly by passing IL10N instance - Improve descriptions to differentiate between approval and certifying signatures - Align descriptions with ISO 32000 DocMDP specification terminology The new descriptions clearly distinguish: - Approval signature (NOT_CERTIFIED): allows all modifications - Certifying signature (levels 1-3): restricts modifications based on level Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Consolidate PDF generation logic into a reusable trait to: - Eliminate code duplication across test files - Provide single source of truth for PDF fixtures - Support both minimal (DocMdpHandler) and FPDI-valid (FileService) PDFs - Cover all DocMDP levels and ISO 32000-1 validation scenarios Includes 25 fixture methods covering: - DocMDP levels 0-3 - Form field/annotation/structural modifications - ISO signature validation edge cases - ICP-Brasil compliance testing Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add public method to check if DocMDP level allows additional signatures. Returns false only for CERTIFIED_NO_CHANGES_ALLOWED (level 1). Required for FileService to validate signature requests against DocMDP policy. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Extract file validation logic from getNodeFromData() into dedicated methods: - validateFileContent(): public method for PDF validation with FPDI - validateDocMdpAllowsSignatures(): private method for DocMDP level 1 check Benefits: - Improved testability with public validation interface - Separation of concerns (validation vs node creation) - Enables DocMDP policy enforcement before file processing - Adds comprehensive @throws documentation Requires DocMdpHandler injection via FileService constructor. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add DocMdpHandler dependency to FileService constructor to enable DocMDP validation in TFile trait. Assigns to TFile::docMdpHandler property for validateDocMdpAllowsSignatures(). Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Fix test setup and assertion patterns: - Add missing appConfig mock initialization - Inject DocMdpHandler from server container - Use expectNotToPerformAssertions() for validation tests - Place expectations at method start (PHPUnit best practice) Validation tests assert 'no exception thrown' behavior: - testValidateFileContentAllowsDocMdpLevel2/3 - testValidateFileContentAllowsUnsignedPdf - testValidateFileContentSkipsNonPdfFiles - testValidateFileContentRejectsDocMdpLevel1 Uses PdfFixtureTrait for all PDF generation. All 98 tests passing (154 assertions). Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Replace all inline PDF generation with PdfFixtureTrait methods. Achieves 100% fixture consolidation across 39 tests. Benefits: - Zero code duplication - Consistent PDF structures - Easier maintenance - Better test clarity All tests passing. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add DocMdpHandler dependency to enable future DocMDP validation during signature request processing. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Add DocMDP admin configuration component and enhance validation view: Settings.vue: - Import and register DocMDP component - Add to admin settings panel Validation.vue: - Display document certification level - Show modification validation status - Add collapsible DocMDP details section - Visual indicators for modification status (success/warning/error) - Icons: mdiShieldCheck, mdiShieldOff, mdiInformationOutline - Revision count display with pluralization Modification status mapping (File::MODIFICATION_*): - 1 (unmodified) → green checkmark - 2 (allowed modifications) → yellow alert - 3 (violations) → red cancel - 0 (unchecked) → help icon Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Sort use statements alphabetically. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Remove unused $scenarioName parameter from test method and data provider - Use expectNotToPerformAssertions() for scenarios that shouldn't throw exceptions - Consolidate exception expectations into if-else block for better readability - Simplify data provider by removing redundant scenario name keys Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Extract PDF-to-resource conversion logic from validateDocMdpAllowsSignatures - New protected method getLibreSignFileAsResource() handles file retrieval and resource creation - Improves testability by separating I/O operations from validation logic - Enables mocking of file access layer independently from DocMDP validation - Maintains resource cleanup with try-finally block in validateDocMdpAllowsSignatures Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Implement DocMdpHandler to validate PDF Document Modification Detection and Prevention (DocMDP) - Add allowsAdditionalSignatures() method to check if PDF permits additional signatures - Support detection of DocMDP level 1 (no changes allowed) certification - Parse PDF signature dictionaries and transformation parameters - Prevent signatures on DocMDP level 1 certified documents per PDF specification - Enable compliance with PDF document certification and signature workflows Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Test allowsAdditionalSignatures() with various DocMDP permission levels - Verify unsigned PDFs allow additional signatures - Test DocMDP level 0 (not certified) allows signatures - Test DocMDP level 1 (no changes) blocks additional signatures - Test DocMDP levels 2 and 3 allow signatures with form filling/annotations - Validate DocMDP detection with real-world ICP-Brasil certificate example - Test complete certificate chain validation (LYSEON TECH 4-level chain) - Use PdfFixtureTrait for generating test PDFs with various DocMDP configurations - Ensure proper resource handling and edge case coverage Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
- Add validation to ensure fopen() returns valid resource - Throw LibresignException if temporary resource creation fails - Prevents false return value that violates psalm type contract - Add @throws LibresignException to method documentation - Fixes psalm FalsableReturnStatement error Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> [skip ci]
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…on failure Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…memory only) Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…memory resource creation Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…dliness Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
… line 344 to improve behavior as required.\n\nSigned-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Changed implementation at line 172 as required. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…rror messages for loading and saving configuration to be more generic and user-friendly. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Tests now only check for exception type, not message, for DocMDP-related logic. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Removes translated message assertion for robustness. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Simplifies test setup and improves maintainability. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of #6021
Warning, This backport's changes differ from the original and might be incomplete⚠️
Todo
Learn more about backports at https://docs.nextcloud.com/server/stable/go.php?to=developer-backports.