mirror of
https://github.com/Alfresco/alfresco-transform-core.git
synced 2026-09-16 18:12:54 +00:00
ACS-10505 modifying libreoffice workdir and user's registryconfig file to block external links
This commit is contained in:
@@ -85,6 +85,11 @@ RUN groupadd -g ${GROUPID} ${GROUPNAME} && \
|
||||
useradd -u ${USERID} -G ${GROUPNAME} ${AIOUSERNAME} && \
|
||||
chgrp -R ${GROUPNAME} /usr/bin/${env.project_artifactId}.jar
|
||||
|
||||
RUN mkdir -p /opt/libreoffice-profile/workDir && \
|
||||
mkdir -p /opt/libreoffice-profile/templateProfileDir/user && \
|
||||
chown -R ${USERID}:${GROUPID} /opt/libreoffice-profile && \
|
||||
chmod -R 775 /opt/libreoffice-profile
|
||||
|
||||
EXPOSE 8090
|
||||
|
||||
USER ${AIOUSERNAME}
|
||||
|
||||
@@ -10,8 +10,11 @@ transform:
|
||||
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
|
||||
imagemagick:
|
||||
root: ${IMAGEMAGICK_ROOT:/usr/lib64/ImageMagick-7.1.2}
|
||||
dyn: ${IMAGEMAGICK_DYN:/usr/lib64/ImageMagick-7.1.2/lib}
|
||||
|
||||
@@ -46,6 +46,11 @@ RUN groupadd -g ${GROUPID} ${GROUPNAME} && \
|
||||
useradd -u ${USERID} -G ${GROUPNAME} ${LIBREUSERNAME} && \
|
||||
chgrp -R ${GROUPNAME} /usr/bin/${env.project_artifactId}.jar
|
||||
|
||||
RUN mkdir -p /opt/libreoffice-profile/workDir && \
|
||||
mkdir -p /opt/libreoffice-profile/templateProfileDir/user && \
|
||||
chown -R ${USERID}:${GROUPID} /opt/libreoffice-profile && \
|
||||
chmod -R 775 /opt/libreoffice-profile
|
||||
|
||||
EXPOSE 8090
|
||||
|
||||
USER ${LIBREUSERNAME}
|
||||
|
||||
+276
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* #%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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.transform.libreoffice.patch;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.artofsolving.jodconverter.OfficeDocumentConverter;
|
||||
import org.artofsolving.jodconverter.office.OfficeManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Manages LibreOffice template user profile and work directory, including apply patches to disable external link updates.
|
||||
*
|
||||
* @author Sayan Bhattacharya
|
||||
*/
|
||||
|
||||
public class LibreOfficeProfileManager
|
||||
{
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(LibreOfficeProfileManager.class);
|
||||
private static final String PROBE_RESOURCE = "/probe.doc";
|
||||
private static final String PATCH_RESOURCE = "/disable-external-link-patch.txt";
|
||||
private static final String REGISTRY_FILE = "registrymodifications.xcu";
|
||||
private static final String USER_PROFILE_DIR = "user";
|
||||
|
||||
private final File workDir;
|
||||
private final File templateProfileDir;
|
||||
private final OfficeManager officeManager;
|
||||
private final boolean disableExternalLinks;
|
||||
|
||||
public LibreOfficeProfileManager(File workDir, File templateProfileDir,
|
||||
OfficeManager officeManager, boolean disableExternalLinks)
|
||||
{
|
||||
this.workDir = workDir;
|
||||
this.templateProfileDir = templateProfileDir;
|
||||
this.officeManager = officeManager;
|
||||
this.disableExternalLinks = disableExternalLinks;
|
||||
}
|
||||
|
||||
public void setupTemplateUserProfileWithProbeTransformation() throws Exception
|
||||
{
|
||||
if (workDir == null || templateProfileDir == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
|
||||
convertProbeDocument(converter);
|
||||
copyUserProfile();
|
||||
|
||||
if (disableExternalLinks)
|
||||
{
|
||||
patchLibreOfficeRegistry();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a probe document conversion to ensure the user profile is created
|
||||
*
|
||||
* @param converter
|
||||
* @throws Exception
|
||||
*/
|
||||
private void convertProbeDocument(OfficeDocumentConverter converter) throws Exception
|
||||
{
|
||||
InputStream probeInput = getClass().getResourceAsStream(PROBE_RESOURCE);
|
||||
if (probeInput == null)
|
||||
{
|
||||
throw new IllegalStateException("probe.docx resource not found!");
|
||||
}
|
||||
|
||||
File tempProbeFile = new File(workDir, "probe.doc");
|
||||
FileUtils.copyInputStreamToFile(probeInput, tempProbeFile);
|
||||
converter.convert(tempProbeFile, new File(workDir, "probeoutput.pdf"));
|
||||
}
|
||||
|
||||
private void copyUserProfile() throws Exception
|
||||
{
|
||||
File officeUserProfile = findLibreOfficeUserProfile(workDir);
|
||||
if (officeUserProfile != null)
|
||||
{
|
||||
File destination = new File(templateProfileDir, officeUserProfile.getName());
|
||||
FileUtils.copyDirectory(officeUserProfile, destination);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Patches the LibreOffice user profile to disable external link updates.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private void patchLibreOfficeRegistry() throws Exception
|
||||
{
|
||||
File userProfileDir = findLibreOfficeUserProfile(templateProfileDir);
|
||||
if (userProfileDir == null)
|
||||
{
|
||||
throw new IllegalStateException("Cannot find LO user profile to patch");
|
||||
}
|
||||
|
||||
File registry = new File(userProfileDir, REGISTRY_FILE);
|
||||
if (!registry.exists())
|
||||
{
|
||||
throw new IllegalStateException(REGISTRY_FILE + " not found!");
|
||||
}
|
||||
|
||||
String registryContent = FileUtils.readFileToString(registry, StandardCharsets.UTF_8);
|
||||
List<PatchItem> patchItems = readPatchItemsFromJson();
|
||||
|
||||
// Remove existing matching items
|
||||
for (PatchItem item : patchItems)
|
||||
{
|
||||
String pattern = String.format(
|
||||
"<item oor:path=\"%s\"><prop oor:name=\"%s\"[^>]*>.*?</prop></item>",
|
||||
Pattern.quote(item.path),
|
||||
Pattern.quote(item.propName));
|
||||
registryContent = registryContent.replaceAll(pattern, "");
|
||||
}
|
||||
|
||||
// Insert the new patch before closing tag
|
||||
String patch = generatePatchXml(patchItems);
|
||||
registryContent = registryContent.replace("</oor:items>", " " + patch + "\n</oor:items>");
|
||||
|
||||
FileUtils.writeStringToFile(registry, registryContent, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
private String readPatchFromResource() throws Exception
|
||||
{
|
||||
InputStream inputStream = getClass().getResourceAsStream(PATCH_RESOURCE);
|
||||
if (inputStream == null)
|
||||
{
|
||||
throw new IllegalStateException("disable-external-link-patch.txt resource not found!");
|
||||
}
|
||||
return IOUtils.toString(inputStream, StandardCharsets.UTF_8).trim();
|
||||
}
|
||||
|
||||
private File findLibreOfficeUserProfile(File dir)
|
||||
{
|
||||
File userDir = findDirectChild(dir, USER_PROFILE_DIR);
|
||||
if (userDir != null)
|
||||
{
|
||||
return userDir;
|
||||
}
|
||||
return findUserInJodConverterDirs(dir);
|
||||
}
|
||||
|
||||
private File findDirectChild(File dir, String name)
|
||||
{
|
||||
File[] children = dir.listFiles(File::isDirectory);
|
||||
if (children != null)
|
||||
{
|
||||
for (File child : children)
|
||||
{
|
||||
if (name.equals(child.getName()))
|
||||
{
|
||||
return child;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private File findUserInJodConverterDirs(File dir)
|
||||
{
|
||||
File[] jodDirs = dir.listFiles(f -> f.isDirectory() && f.getName().startsWith(".jodconverter_"));
|
||||
if (jodDirs == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (File d : jodDirs)
|
||||
{
|
||||
File user = new File(d, "user");
|
||||
if (user.exists())
|
||||
{
|
||||
return user;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<PatchItem> readPatchItemsFromJson() throws Exception
|
||||
{
|
||||
InputStream inputStream = getClass().getResourceAsStream("/disable-external-link-patch.json");
|
||||
if (inputStream == null)
|
||||
{
|
||||
throw new IllegalStateException("disable-external-link-patch.json not found!");
|
||||
}
|
||||
|
||||
String jsonContent = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode root = mapper.readTree(jsonContent);
|
||||
|
||||
JsonNode items = root.get("items");
|
||||
if (items == null || !items.isArray() || items.size() == 0)
|
||||
{
|
||||
throw new IllegalStateException("JSON 'items' array is missing or empty!");
|
||||
}
|
||||
|
||||
List<PatchItem> patchItems = new ArrayList<>();
|
||||
for (JsonNode item : items)
|
||||
{
|
||||
String path = item.get("oor:path").asText();
|
||||
JsonNode prop = item.get("prop");
|
||||
String name = prop.get("oor:name").asText();
|
||||
String op = prop.get("oor:op").asText();
|
||||
String value = prop.get("value").asText();
|
||||
|
||||
patchItems.add(new PatchItem(path, name, op, value));
|
||||
}
|
||||
|
||||
return patchItems;
|
||||
}
|
||||
|
||||
private String generatePatchXml(List<PatchItem> items)
|
||||
{
|
||||
StringBuilder xml = new StringBuilder();
|
||||
for (PatchItem item : items)
|
||||
{
|
||||
xml.append("<item oor:path=\"").append(item.path).append("\">");
|
||||
xml.append("<prop oor:name=\"").append(item.propName).append("\" oor:op=\"").append(item.op).append("\">");
|
||||
xml.append("<value>").append(item.value).append("</value>");
|
||||
xml.append("</prop></item>");
|
||||
}
|
||||
return xml.toString();
|
||||
}
|
||||
|
||||
private class PatchItem
|
||||
{
|
||||
String path;
|
||||
String propName;
|
||||
String op;
|
||||
String value;
|
||||
|
||||
PatchItem(String path, String propName, String op, String value)
|
||||
{
|
||||
this.path = path;
|
||||
this.propName = propName;
|
||||
this.op = op;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+56
-4
@@ -36,12 +36,15 @@ 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 /////////////
|
||||
|
||||
/**
|
||||
@@ -75,12 +78,14 @@ 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)
|
||||
{
|
||||
@@ -163,10 +168,38 @@ public class JodConverterSharedInstance implements JodConverter
|
||||
throw new RuntimeException(
|
||||
"OpenOffice template profile directory " + templateProfileDir + " does not exist.");
|
||||
}
|
||||
|
||||
// //making sure 'user' subdir exists
|
||||
// Optional<File> userFile = Arrays.stream(requireNonNull(tmp.listFiles()))
|
||||
// .filter(File::isDirectory)
|
||||
// .filter(f->f.getName().equals("user"))
|
||||
// .findAny();
|
||||
// if(userFile.isEmpty()) {
|
||||
// File userDir = new File(tmp, "user");
|
||||
// }
|
||||
|
||||
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());
|
||||
@@ -270,7 +303,7 @@ public class JodConverterSharedInstance implements JodConverter
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see org.alfresco.repo.content.JodConverter#isAvailable() */
|
||||
public boolean isAvailable()
|
||||
{
|
||||
@@ -278,7 +311,7 @@ public class JodConverterSharedInstance implements JodConverter
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */
|
||||
@PostConstruct
|
||||
public void afterPropertiesSet()
|
||||
@@ -346,13 +379,26 @@ public class JodConverterSharedInstance implements JodConverter
|
||||
{
|
||||
defaultOfficeMgrConfig.setTemplateProfileDir(templateProfileDir);
|
||||
}
|
||||
if (workDir != null)
|
||||
{
|
||||
defaultOfficeMgrConfig.setWorkDir(workDir);
|
||||
}
|
||||
if (connectTimeout != null)
|
||||
{
|
||||
defaultOfficeMgrConfig.setConnectTimeout(connectTimeout);
|
||||
}
|
||||
|
||||
// Try to configure and start the JodConverter library.
|
||||
officeManager = defaultOfficeMgrConfig.buildOfficeManager();
|
||||
officeManager.start();
|
||||
|
||||
LibreOfficeProfileManager profileManager = new LibreOfficeProfileManager(
|
||||
workDir,
|
||||
templateProfileDir,
|
||||
officeManager,
|
||||
disableExternalLinks);
|
||||
profileManager.setupTemplateUserProfileWithProbeTransformation();
|
||||
|
||||
}
|
||||
catch (IllegalStateException e)
|
||||
{
|
||||
@@ -487,7 +533,7 @@ public class JodConverterSharedInstance implements JodConverter
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see org.springframework.beans.factory.DisposableBean#destroy() */
|
||||
@PreDestroy
|
||||
public void destroy()
|
||||
@@ -507,11 +553,17 @@ public class JodConverterSharedInstance implements JodConverter
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see org.alfresco.repo.content.JodConverterWorker#getOfficeManager() */
|
||||
@Override
|
||||
public OfficeManager getOfficeManager()
|
||||
{
|
||||
return officeManager;
|
||||
}
|
||||
|
||||
public void setDisableExternalLinks(boolean disableExternalLinks)
|
||||
{
|
||||
this.disableExternalLinks = disableExternalLinks;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-1
@@ -76,6 +76,12 @@ 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;
|
||||
|
||||
private JodConverter jodconverter;
|
||||
|
||||
@@ -118,8 +124,13 @@ public class LibreOfficeTransformer implements JavaExecutor, CustomTransformerFi
|
||||
sharedInstance.setTaskQueueTimeout(timeout);
|
||||
sharedInstance.setConnectTimeout(timeout);
|
||||
sharedInstance.setPortNumbers(portNumbers);
|
||||
sharedInstance.setTemplateProfileDir(templateProfileDir);
|
||||
sharedInstance.setEnabled(isEnabled);
|
||||
if (enableTemplateProfile)
|
||||
{
|
||||
sharedInstance.setTemplateProfileDir(templateProfileDir);
|
||||
sharedInstance.setWorkDir(workdir);
|
||||
sharedInstance.setDisableExternalLinks(disableExternalLinks);
|
||||
}
|
||||
sharedInstance.afterPropertiesSet();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,12 @@ 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}
|
||||
isEnabled: ${LIBREOFFICE_IS_ENABLED:true}
|
||||
enableTemplateProfile: false
|
||||
templateProfileDir: ${LIBREOFFICE_TEMPLATE_PROFILE_DIR:C:\Users\sabhattacharya\Alfresco\libreoffice-profile\templateProfileDir}
|
||||
workdir: ${LIBREOFFICE_WORK_PROFILE_DIR:C:\Users\sabhattacharya\Alfresco\libreoffice-profile\workDir}
|
||||
disableExternalLinks: true
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"oor:path": "/org.openoffice.Office.Common/Security/Scripting",
|
||||
"prop": {
|
||||
"oor:name": "BlockUntrustedRefererLinks",
|
||||
"oor:op": "fuse"
|
||||
},
|
||||
"value": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
<acs-compatible.java.version>11</acs-compatible.java.version>
|
||||
<image.tag>latest</image.tag>
|
||||
<image.registry>quay.io</image.registry>
|
||||
<dependency.pdfbox.version>3.0.5</dependency.pdfbox.version>
|
||||
<dependency.pdfbox.version>3.0.6</dependency.pdfbox.version>
|
||||
<dependency.alfresco-jodconverter-core.version>3.0.1.20</dependency.alfresco-jodconverter-core.version>
|
||||
<env.project_version>${project.version}</env.project_version>
|
||||
<dependency.jackson.version>2.19.2</dependency.jackson.version>
|
||||
@@ -316,7 +316,7 @@
|
||||
</excludes>
|
||||
<failOnMissingHeader>true</failOnMissingHeader>
|
||||
<licenseName>community</licenseName>
|
||||
<licenseResolver>file:${project.parent.basedir}/license</licenseResolver>
|
||||
<licenseResolver>file:C:/Users/sabhattacharya/Alfresco/license</licenseResolver>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
@@ -335,7 +335,8 @@
|
||||
<LIBREOFFICE_MAX_TASKS_PER_PROCESS>200</LIBREOFFICE_MAX_TASKS_PER_PROCESS>
|
||||
<LIBREOFFICE_TIMEOUT>1200000</LIBREOFFICE_TIMEOUT>
|
||||
<LIBREOFFICE_PORT_NUMBERS>8100</LIBREOFFICE_PORT_NUMBERS>
|
||||
<LIBREOFFICE_TEMPLATE_PROFILE_DIR />
|
||||
<LIBREOFFICE_TEMPLATE_PROFILE_DIR>/opt/libreoffice-profile/templateProfileDir</LIBREOFFICE_TEMPLATE_PROFILE_DIR>
|
||||
<LIBREOFFICE_WORK_PROFILE_DIR>/opt/libreoffice-profile/workDir</LIBREOFFICE_WORK_PROFILE_DIR>
|
||||
<LIBREOFFICE_IS_ENABLED>true</LIBREOFFICE_IS_ENABLED>
|
||||
<PDF_RENDERER_EXE>/usr/bin/alfresco-pdf-renderer</PDF_RENDERER_EXE>
|
||||
<SERVER_PORT>8090</SERVER_PORT>
|
||||
|
||||
Reference in New Issue
Block a user