From a8458e315fb128306a5e98fe1fc7d2d38bf0ec49 Mon Sep 17 00:00:00 2001 From: bsayan2 Date: Tue, 23 Dec 2025 18:25:37 +0530 Subject: [PATCH] ACS-10505 generating xcu file via script instead of officemanager --- engines/libreoffice/generate-registry.sh | 38 +++++ engines/libreoffice/pom.xml | 18 +++ .../patch/LibreOfficeProfileManagerV2.java | 151 ++++++++++++++++++ .../JodConverterSharedInstance.java | 58 ------- .../transformers/LibreOfficeTransformer.java | 26 +-- .../main/resources/application-default.yaml | 9 +- 6 files changed, 225 insertions(+), 75 deletions(-) create mode 100644 engines/libreoffice/generate-registry.sh create mode 100644 engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/patch/LibreOfficeProfileManagerV2.java 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