From 28a259ec95adb5bd483a8d379ea99717ba9b325a Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Tue, 3 Jun 2025 17:48:17 +0100 Subject: [PATCH] GetInfo summary #2388 (#3585) # Description of Changes Please provide a summary of the changes, including: - What was changed - Why the change was made - Any challenges encountered Closes #(issue_number) --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details. Co-authored-by: a --- .gitignore | 1 + .../controller/api/security/GetInfoOnPDF.java | 59 +++ src/main/resources/messages_en_GB.properties | 22 + .../templates/security/get-info-on-pdf.html | 443 +++++++++++++++++- 4 files changed, 522 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 90d48ccea..06602d03b 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ local.properties .recommenders .classpath .project +*.local.json version.properties #### Stirling-PDF Files ### diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java b/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java index 79ffae74f..c630106e4 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/GetInfoOnPDF.java @@ -91,6 +91,59 @@ public class GetInfoOnPDF { } } + /** + * Generates structured summary data about the PDF highlighting its unique characteristics such + * as encryption status, permission restrictions, and standards compliance. + * + * @param document The PDF document to analyze + * @return An ObjectNode containing structured summary data + */ + private ObjectNode generatePDFSummaryData(PDDocument document) { + ObjectNode summaryData = objectMapper.createObjectNode(); + + // Check if encrypted + if (document.isEncrypted()) { + summaryData.put("encrypted", true); + } + + // Check permissions + AccessPermission ap = document.getCurrentAccessPermission(); + ArrayNode restrictedPermissions = objectMapper.createArrayNode(); + + if (!ap.canAssembleDocument()) restrictedPermissions.add("document assembly"); + if (!ap.canExtractContent()) restrictedPermissions.add("content extraction"); + if (!ap.canExtractForAccessibility()) restrictedPermissions.add("accessibility extraction"); + if (!ap.canFillInForm()) restrictedPermissions.add("form filling"); + if (!ap.canModify()) restrictedPermissions.add("modification"); + if (!ap.canModifyAnnotations()) restrictedPermissions.add("annotation modification"); + if (!ap.canPrint()) restrictedPermissions.add("printing"); + + if (restrictedPermissions.size() > 0) { + summaryData.set("restrictedPermissions", restrictedPermissions); + summaryData.put("restrictedPermissionsCount", restrictedPermissions.size()); + } + + // Check standard compliance + if (checkForStandard(document, "PDF/A")) { + summaryData.put("standardCompliance", "PDF/A"); + summaryData.put("standardPurpose", "long-term archiving"); + } else if (checkForStandard(document, "PDF/X")) { + summaryData.put("standardCompliance", "PDF/X"); + summaryData.put("standardPurpose", "graphic exchange"); + } else if (checkForStandard(document, "PDF/UA")) { + summaryData.put("standardCompliance", "PDF/UA"); + summaryData.put("standardPurpose", "universal accessibility"); + } else if (checkForStandard(document, "PDF/E")) { + summaryData.put("standardCompliance", "PDF/E"); + summaryData.put("standardPurpose", "engineering workflows"); + } else if (checkForStandard(document, "PDF/VT")) { + summaryData.put("standardCompliance", "PDF/VT"); + summaryData.put("standardPurpose", "variable and transactional printing"); + } + + return summaryData; + } + public static boolean checkForStandard(PDDocument document, String standardKeyword) { // Check XMP Metadata try { @@ -191,6 +244,12 @@ public class GetInfoOnPDF { } jsonOutput.set("FormFields", formFieldsNode); + // Generate structured summary data about PDF characteristics + ObjectNode summaryData = generatePDFSummaryData(pdfBoxDoc); + if (summaryData != null && summaryData.size() > 0) { + jsonOutput.set("SummaryData", summaryData); + } + // embeed files TODO size if (catalog.getNames() != null) { PDEmbeddedFilesNameTreeNode efTree = catalog.getNames().getEmbeddedFiles(); diff --git a/src/main/resources/messages_en_GB.properties b/src/main/resources/messages_en_GB.properties index 56d31e749..b875859b6 100644 --- a/src/main/resources/messages_en_GB.properties +++ b/src/main/resources/messages_en_GB.properties @@ -807,6 +807,28 @@ getPdfInfo.title=Get Info on PDF getPdfInfo.header=Get Info on PDF getPdfInfo.submit=Get Info getPdfInfo.downloadJson=Download JSON +getPdfInfo.summary=PDF Summary +getPdfInfo.summary.encrypted=This PDF is encrypted so may face issues with some applications +getPdfInfo.summary.permissions=This PDF has {0} restricted permissions which may limit what you can do with it +getPdfInfo.summary.compliance=This PDF complies with the {0} standard +getPdfInfo.summary.basicInfo=Basic Information +getPdfInfo.summary.docInfo=Document Information +getPdfInfo.summary.encrypted.alert=Encrypted PDF - This document is password protected +getPdfInfo.summary.not.encrypted.alert=Unencrypted PDF - No password protection +getPdfInfo.summary.permissions.alert=Restricted Permissions - {0} actions are not allowed +getPdfInfo.summary.all.permissions.alert=All Permissions Allowed +getPdfInfo.summary.compliance.alert={0} Compliant +getPdfInfo.summary.no.compliance.alert=No Compliance Standards +getPdfInfo.summary.security.section=Security Status +getPdfInfo.section.BasicInfo=Basic Information about the PDF document including file size, page count, and language +getPdfInfo.section.Metadata=Document metadata including title, author, creation date and other document properties +getPdfInfo.section.DocumentInfo=Technical details about the PDF document structure and version +getPdfInfo.section.Compliancy=PDF standards compliance information (PDF/A, PDF/X, etc.) +getPdfInfo.section.Encryption=Security and encryption details of the document +getPdfInfo.section.Permissions=Document permission settings that control what actions can be performed +getPdfInfo.section.Other=Additional document components like bookmarks, layers, and embedded files +getPdfInfo.section.FormFields=Interactive form fields present in the document +getPdfInfo.section.PerPageInfo=Detailed information about each page in the document #markdown-to-pdf diff --git a/src/main/resources/templates/security/get-info-on-pdf.html b/src/main/resources/templates/security/get-info-on-pdf.html index 97ddf723a..95a5ad391 100644 --- a/src/main/resources/templates/security/get-info-on-pdf.html +++ b/src/main/resources/templates/security/get-info-on-pdf.html @@ -11,7 +11,7 @@

-
+
info @@ -22,6 +22,82 @@
+ + + -