diff --git a/engines/libreoffice/generate-registry.sh b/engines/libreoffice/generate-registry.sh
new file mode 100644
index 00000000..8085a111
--- /dev/null
+++ b/engines/libreoffice/generate-registry.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+# Read properties file
+PROPS_FILE="src/main/resources/application-default.yaml"
+OUTPUT_FILE="src/main/resources/templateRegistrymodifications.xcu"
+
+echo "Generating registry modifications..."
+
+# More flexible extraction that handles indentation
+BLOCK_UNTRUSTED=$(awk '/blockUntrustedRefererLinks:/ {print $2}' "$PROPS_FILE")
+echo "blockUntrustedRefererLinks: $BLOCK_UNTRUSTED"
+
+
+# Start XML file
+cat > "$OUTPUT_FILE" << EOF
+
+
+EOF
+
+# Item 1
+if [ "$BLOCK_UNTRUSTED" = "true" ]; then
+ cat >> "$OUTPUT_FILE" << EOF
+ -
+
+ true
+
+
+EOF
+fi
+
+# Close XML
+cat >> "$OUTPUT_FILE" << EOF
+
+EOF
+
+
diff --git a/engines/libreoffice/pom.xml b/engines/libreoffice/pom.xml
index ecba48c0..5092bc9f 100644
--- a/engines/libreoffice/pom.xml
+++ b/engines/libreoffice/pom.xml
@@ -92,6 +92,24 @@
org.apache.maven.plugins
maven-source-plugin
+
+ org.codehaus.mojo
+ exec-maven-plugin
+
+
+ generate-resources
+
+ exec
+
+
+ bash
+
+ generate-registry.sh
+
+
+
+
+
diff --git a/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/patch/LibreOfficeProfileManagerV2.java b/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/patch/LibreOfficeProfileManagerV2.java
new file mode 100644
index 00000000..41a06e17
--- /dev/null
+++ b/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/patch/LibreOfficeProfileManagerV2.java
@@ -0,0 +1,151 @@
+/*
+ * #%L
+ * Alfresco Transform Core
+ * %%
+ * Copyright (C) 2005 - 2025 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * -
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ * -
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * -
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * -
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.transform.libreoffice.patch;
+
+import java.io.File;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LibreOfficeProfileManagerV2
+{
+ private static final Logger logger = LoggerFactory.getLogger(LibreOfficeProfileManagerV2.class);
+
+ private final String TEMP_PROFILE_DIR_NAME = "libreoffice-tempProfileDir";
+ private final String USER_DIR_NAME = "user";
+ private final String REGISTRY_FILE_NAME = "registrymodifications.xcu";
+ private final String LOCAL_TEMP_REGISTRY_FILE = "templateRegistrymodifications.xcu";
+
+ private final String userTemplateDir;
+ private String systemTempUserDir = "";
+ private final boolean blockUntrustedRefererLinks;
+
+ public LibreOfficeProfileManagerV2(String templateProfileDir, boolean blockUntrustedRefererLinks)
+ {
+ this.userTemplateDir = templateProfileDir;
+ this.blockUntrustedRefererLinks = blockUntrustedRefererLinks;
+ }
+
+ public String getTemplateProfileDir()
+ {
+ execute();
+
+ if (StringUtils.isNotBlank(userTemplateDir))
+ {
+ return userTemplateDir;
+ }
+ else if (StringUtils.isNotBlank(systemTempUserDir))
+ {
+ return systemTempUserDir;
+ }
+ else
+ {
+ return "";
+ }
+ }
+
+ private void execute()
+ {
+ if (StringUtils.isBlank(userTemplateDir))
+ {
+ validateAndCreateRegistryTemplate();
+ }
+ else
+ {
+ checkUserProvidedRegistry();
+ }
+ }
+
+ private void validateAndCreateRegistryTemplate()
+ {
+ if (blockUntrustedRefererLinks)
+ {
+ try (InputStream regStream = getClass().getClassLoader().getResourceAsStream(LOCAL_TEMP_REGISTRY_FILE))
+ {
+ if (regStream == null)
+ {
+ logger.error("Local temporary registry file not found: {}", LOCAL_TEMP_REGISTRY_FILE);
+ return;
+ }
+ Path tempProfilePath = Files.createTempDirectory(TEMP_PROFILE_DIR_NAME);
+ File registryFile = getRegistryFile(tempProfilePath);
+ Files.copy(regStream, registryFile.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
+ this.systemTempUserDir = tempProfilePath.toString();
+ }
+ catch (Exception e)
+ {
+ logger.error("Error creating temporary directory for LibreOffice profile", e);
+ }
+ }
+ }
+
+ private File getRegistryFile(Path tempProfilePath)
+ {
+ File userDir = new File(tempProfilePath.toFile(), USER_DIR_NAME);
+ if (!userDir.exists())
+ {
+ boolean dirCreated = userDir.mkdirs();
+ if (!dirCreated)
+ {
+ throw new RuntimeException("Failed to create user directory: " + userDir.getAbsolutePath());
+ }
+ }
+ return new File(userDir, REGISTRY_FILE_NAME);
+ }
+
+ private void checkUserProvidedRegistry()
+ {
+ File tempDir = new File(userTemplateDir);
+ if (!tempDir.exists() || !tempDir.isDirectory())
+ {
+ logger.warn("The provided template profile directory does not exist or is not a directory: {}", userTemplateDir);
+ return;
+ }
+ File userDir = new File(tempDir, USER_DIR_NAME);
+ if (!userDir.exists())
+ {
+ logger.warn("The user directory does not exist in the provided template profile directory: {}", userDir.getAbsolutePath());
+ return;
+ }
+ File registryFile = new File(userDir, REGISTRY_FILE_NAME);
+ if (!registryFile.exists())
+ {
+ logger.warn("The registrymodifications.xcu file does not exist in the provided template profile directory: {}", registryFile.getAbsolutePath());
+ }
+ else
+ {
+ // TODO: read registryModifications.xcu and check for blocking referer links setting
+
+ }
+ }
+
+}
diff --git a/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/transformers/JodConverterSharedInstance.java b/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/transformers/JodConverterSharedInstance.java
index 60ae0850..036cde95 100644
--- a/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/transformers/JodConverterSharedInstance.java
+++ b/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/transformers/JodConverterSharedInstance.java
@@ -36,15 +36,12 @@ import java.util.StringTokenizer;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
-import org.apache.commons.lang3.StringUtils;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeException;
import org.artofsolving.jodconverter.office.OfficeManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.alfresco.transform.libreoffice.patch.LibreOfficeProfileManager;
-
///////// THIS FILE WAS A COPY OF THE CODE IN alfresco-repository /////////////
/**
@@ -78,14 +75,12 @@ public class JodConverterSharedInstance implements JodConverter
private Long taskExecutionTimeout;
private Long taskQueueTimeout;
private File templateProfileDir;
- private File workDir;
private Boolean enabled;
private Long connectTimeout;
private String deprecatedOooExe;
private Boolean deprecatedOooEnabled;
private int[] deprecatedOooPortNumbers;
- private boolean disableExternalLinks;
void setMaxTasksPerProcess(String maxTasksPerProcess)
{
@@ -168,42 +163,10 @@ public class JodConverterSharedInstance implements JodConverter
throw new RuntimeException(
"OpenOffice template profile directory " + templateProfileDir + " does not exist.");
}
- else
- {
- // check if it contains user subdir and create a sub dir if not
- File userDir = new File(tmp, "user");
- if (!userDir.exists() || !userDir.isDirectory())
- {
- File newUserDir = new File(tmp, "user");
- if (!newUserDir.mkdir())
- {
- throw new RuntimeException(
- "Could not create user subdirectory in template profile directory " + templateProfileDir);
- }
- }
- }
this.templateProfileDir = tmp;
}
}
- void setWorkDir(String workDir)
- {
- if (StringUtils.isBlank(workDir))
- {
- this.workDir = null;
- }
- else
- {
- File tmp = new File(workDir);
- if (!tmp.isDirectory())
- {
- throw new RuntimeException(
- "OpenOffice work directory " + workDir + " does not exist.");
- }
- this.workDir = tmp;
- }
- }
-
void setTaskQueueTimeout(String taskQueueTimeout)
{
this.taskQueueTimeout = parseStringForLong(taskQueueTimeout.trim());
@@ -383,28 +346,13 @@ public class JodConverterSharedInstance implements JodConverter
{
defaultOfficeMgrConfig.setTemplateProfileDir(templateProfileDir);
}
- if (workDir != null)
- {
- defaultOfficeMgrConfig.setWorkDir(workDir);
- }
if (connectTimeout != null)
{
defaultOfficeMgrConfig.setConnectTimeout(connectTimeout);
}
-
- if (workDir != null && templateProfileDir != null)
- {
- LibreOfficeProfileManager.initializeTemplateUserProfile(
- workDir,
- templateProfileDir,
- defaultOfficeMgrConfig,
- disableExternalLinks);
- }
-
// Try to configure and start the JodConverter library.
officeManager = defaultOfficeMgrConfig.buildOfficeManager();
officeManager.start();
-
}
catch (IllegalStateException e)
{
@@ -566,10 +514,4 @@ public class JodConverterSharedInstance implements JodConverter
{
return officeManager;
}
-
- public void setDisableExternalLinks(boolean disableExternalLinks)
- {
- this.disableExternalLinks = disableExternalLinks;
- }
-
}
diff --git a/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/transformers/LibreOfficeTransformer.java b/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/transformers/LibreOfficeTransformer.java
index 717d1e5c..db314016 100644
--- a/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/transformers/LibreOfficeTransformer.java
+++ b/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/transformers/LibreOfficeTransformer.java
@@ -53,6 +53,7 @@ import org.alfresco.transform.base.TransformManager;
import org.alfresco.transform.base.executors.JavaExecutor;
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
import org.alfresco.transform.exceptions.TransformException;
+import org.alfresco.transform.libreoffice.patch.LibreOfficeProfileManagerV2;
/**
* JavaExecutor implementation for running LibreOffice transformations. It loads the transformation logic in the same JVM (check the {@link JodConverter} implementation).
@@ -76,12 +77,15 @@ public class LibreOfficeTransformer implements JavaExecutor, CustomTransformerFi
private String templateProfileDir;
@Value("${transform.core.libreoffice.isEnabled}")
private String isEnabled;
- @Value("${transform.core.libreoffice.workdir}")
- private String workdir;
- @Value("${transform.core.libreoffice.disableExternalLinks}")
- private boolean disableExternalLinks;
- @Value("${transform.core.libreoffice.enableTemplateProfile}")
- private boolean enableTemplateProfile;
+ // @Value("${transform.core.libreoffice.workdir}")
+ // private String workdir;
+ // @Value("${transform.core.libreoffice.disableExternalLinks}")
+ // private boolean disableExternalLinks;
+ // @Value("${transform.core.libreoffice.enableTemplateProfile}")
+ // private boolean enableTemplateProfile;
+
+ @Value("${transform.core.libreoffice.security.blockUntrustedRefererLinks}")
+ private boolean blockUntrustedRefererLinks;
private JodConverter jodconverter;
@@ -116,6 +120,9 @@ public class LibreOfficeTransformer implements JavaExecutor, CustomTransformerFi
throw new IllegalArgumentException("LibreOfficeTransformer LIBREOFFICE_IS_ENABLED variable must be set to true/false");
}
+ LibreOfficeProfileManagerV2 lib = new LibreOfficeProfileManagerV2(templateProfileDir, blockUntrustedRefererLinks);
+ String tempDir = lib.getTemplateProfileDir();
+
JodConverterSharedInstance sharedInstance = new JodConverterSharedInstance();
jodconverter = sharedInstance;
sharedInstance.setOfficeHome(path);
@@ -125,12 +132,7 @@ public class LibreOfficeTransformer implements JavaExecutor, CustomTransformerFi
sharedInstance.setConnectTimeout(timeout);
sharedInstance.setPortNumbers(portNumbers);
sharedInstance.setEnabled(isEnabled);
- if (enableTemplateProfile)
- {
- sharedInstance.setTemplateProfileDir(templateProfileDir);
- sharedInstance.setWorkDir(workdir);
- sharedInstance.setDisableExternalLinks(disableExternalLinks);
- }
+ sharedInstance.setTemplateProfileDir(tempDir);
sharedInstance.afterPropertiesSet();
}
diff --git a/engines/libreoffice/src/main/resources/application-default.yaml b/engines/libreoffice/src/main/resources/application-default.yaml
index 059923e8..2fa3e40d 100644
--- a/engines/libreoffice/src/main/resources/application-default.yaml
+++ b/engines/libreoffice/src/main/resources/application-default.yaml
@@ -3,12 +3,11 @@ queue:
transform:
core:
libreoffice:
- path: ${LIBREOFFICE_HOME:/opt/libreoffice7.2}
+ path: ${LIBREOFFICE_HOME:C:\Users\sabhattacharya\Alfresco\LibreOffice25}
maxTasksPerProcess: ${LIBREOFFICE_MAX_TASKS_PER_PROCESS:200}
timeout: ${LIBREOFFICE_TIMEOUT:1200000}
portNumbers: ${LIBREOFFICE_PORT_NUMBERS:8100}
+ templateProfileDir: ${LIBREOFFICE_TEMPLATE_PROFILE_DIR:}
isEnabled: ${LIBREOFFICE_IS_ENABLED:true}
- enableTemplateProfile: false
- templateProfileDir: ${LIBREOFFICE_TEMPLATE_PROFILE_DIR:/opt/libreoffice-profile/templateProfileDir}
- workdir: ${LIBREOFFICE_WORK_PROFILE_DIR:/opt/libreoffice-profile/workDir}
- disableExternalLinks: true
\ No newline at end of file
+ security:
+ blockUntrustedRefererLinks: true
\ No newline at end of file