This is an automated email from the ASF dual-hosted git repository.

jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git


The following commit(s) were added to refs/heads/main by this push:
     new 162a4b90cd Fix PDF encryption in native mode
162a4b90cd is described below

commit 162a4b90cd01cc07b55f4433041a03672d9a7271
Author: James Netherton <[email protected]>
AuthorDate: Fri Jun 24 10:40:56 2022 +0100

    Fix PDF encryption in native mode
    
    Fixes #3871
---
 .../component/pdf/deployment/PdfProcessor.java     |  7 ++++
 .../quarkus/component/pdf/it/PdfResource.java      | 45 ++++++++++++++++++++++
 .../camel/quarkus/component/pdf/it/PdfTest.java    | 34 ++++++++++++++++
 3 files changed, 86 insertions(+)

diff --git 
a/extensions/pdf/deployment/src/main/java/org/apache/camel/quarkus/component/pdf/deployment/PdfProcessor.java
 
b/extensions/pdf/deployment/src/main/java/org/apache/camel/quarkus/component/pdf/deployment/PdfProcessor.java
index 5c0510c2d2..f2e477e212 100644
--- 
a/extensions/pdf/deployment/src/main/java/org/apache/camel/quarkus/component/pdf/deployment/PdfProcessor.java
+++ 
b/extensions/pdf/deployment/src/main/java/org/apache/camel/quarkus/component/pdf/deployment/PdfProcessor.java
@@ -20,7 +20,9 @@ import io.quarkus.deployment.annotations.BuildProducer;
 import io.quarkus.deployment.annotations.BuildStep;
 import io.quarkus.deployment.builditem.FeatureBuildItem;
 import 
io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
 import 
io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
+import org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler;
 
 class PdfProcessor {
 
@@ -76,4 +78,9 @@ class PdfProcessor {
             runtimeInitializedClass.produce(new 
RuntimeInitializedClassBuildItem(className));
         }
     }
+
+    @BuildStep
+    ReflectiveClassBuildItem registerForReflection() {
+        return new ReflectiveClassBuildItem(true, false, false, 
StandardSecurityHandler.class);
+    }
 }
diff --git 
a/integration-tests/pdf/src/main/java/org/apache/camel/quarkus/component/pdf/it/PdfResource.java
 
b/integration-tests/pdf/src/main/java/org/apache/camel/quarkus/component/pdf/it/PdfResource.java
index ffd6fa8797..64e1999e8e 100644
--- 
a/integration-tests/pdf/src/main/java/org/apache/camel/quarkus/component/pdf/it/PdfResource.java
+++ 
b/integration-tests/pdf/src/main/java/org/apache/camel/quarkus/component/pdf/it/PdfResource.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.quarkus.component.pdf.it;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.net.URI;
 
 import javax.enterprise.context.ApplicationScoped;
@@ -26,12 +28,16 @@ import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 import org.apache.camel.ProducerTemplate;
 import org.apache.camel.component.pdf.PdfHeaderConstants;
 import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
+import org.apache.pdfbox.pdmodel.encryption.StandardDecryptionMaterial;
+import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
 import org.jboss.logging.Logger;
 
 @Path("/pdf")
@@ -78,4 +84,43 @@ public class PdfResource {
         LOG.info("Extracting text from the PDDocument");
         return producerTemplate.requestBody("pdf:extractText", 
PDDocument.load(document), String.class);
     }
+
+    @Path("/encrypt/standard")
+    @POST
+    @Produces(MediaType.TEXT_PLAIN)
+    public Response encryptStandard(
+            @QueryParam("ownerPassword") String ownerPassword,
+            @QueryParam("userPassword") String userPassword,
+            String message) throws Exception {
+
+        AccessPermission permission = 
AccessPermission.getOwnerAccessPermission();
+        StandardProtectionPolicy policy = new 
StandardProtectionPolicy(ownerPassword, userPassword, permission);
+
+        byte[] document = producerTemplate.requestBodyAndHeader(
+                "pdf:create?fontSize=6&pageSize=PAGE_SIZE_A5&font=Courier",
+                message,
+                PdfHeaderConstants.PROTECTION_POLICY_HEADER_NAME,
+                policy,
+                byte[].class);
+
+        return Response.created(new 
URI("pdf/extractText")).entity(document).build();
+    }
+
+    @Path("/decrypt/standard")
+    @POST
+    @Produces(MediaType.TEXT_PLAIN)
+    public Response decryptStandard(@QueryParam("password") String password, 
byte[] rawDocument) throws IOException {
+        StandardDecryptionMaterial material = new 
StandardDecryptionMaterial(password);
+
+        PDDocument document = PDDocument.load(new 
ByteArrayInputStream(rawDocument), password);
+
+        String result = producerTemplate.requestBodyAndHeader(
+                "pdf:extractText",
+                document,
+                PdfHeaderConstants.DECRYPTION_MATERIAL_HEADER_NAME,
+                material,
+                String.class);
+
+        return Response.ok().entity(result).build();
+    }
 }
diff --git 
a/integration-tests/pdf/src/test/java/org/apache/camel/quarkus/component/pdf/it/PdfTest.java
 
b/integration-tests/pdf/src/test/java/org/apache/camel/quarkus/component/pdf/it/PdfTest.java
index 18fdddd123..a5a7e25149 100644
--- 
a/integration-tests/pdf/src/test/java/org/apache/camel/quarkus/component/pdf/it/PdfTest.java
+++ 
b/integration-tests/pdf/src/test/java/org/apache/camel/quarkus/component/pdf/it/PdfTest.java
@@ -22,10 +22,13 @@ import io.quarkus.test.junit.QuarkusTest;
 import io.restassured.RestAssured;
 import io.restassured.http.ContentType;
 import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
 import org.apache.pdfbox.text.PDFTextStripper;
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Order;
 import org.junit.jupiter.api.Test;
 
+import static org.hamcrest.Matchers.containsString;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -70,4 +73,35 @@ class PdfTest {
         assertTrue(pdfText.contains("content to be included in the created pdf 
document"));
         assertTrue(pdfText.contains("another line that should be appended"));
     }
+
+    @Test
+    public void encryptDecrypt() throws IOException {
+        final String ownerPassword = "p4ssw0rd";
+        final String userPassword = "2s3cr3t!";
+
+        // Encrypt
+        byte[] bytes = RestAssured.given()
+                .contentType(ContentType.TEXT)
+                .queryParam("ownerPassword", ownerPassword)
+                .queryParam("userPassword", userPassword)
+                .body("content to be included in the created pdf document")
+                .post("/pdf/encrypt/standard")
+                .then()
+                .statusCode(201)
+                .extract()
+                .asByteArray();
+
+        // Test loading the PDF without credentials
+        Assertions.assertThrows(InvalidPasswordException.class, () -> 
PDDocument.load(bytes));
+
+        // Decrypt
+        RestAssured.given()
+                .contentType(ContentType.BINARY)
+                .queryParam("password", ownerPassword)
+                .body(bytes)
+                .post("/pdf/decrypt/standard")
+                .then()
+                .statusCode(200)
+                .body(containsString("content to be included in the created 
pdf document"));
+    }
 }

Reply via email to