From 363782c54d4e58838dda4585e075a3142e5cb90a Mon Sep 17 00:00:00 2001 From: Sergey Linnik Date: Fri, 7 Apr 2023 18:52:28 +0500 Subject: [PATCH 01/76] si-LK empty files --- repo/src/main/resources/newdocs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo/src/main/resources/newdocs b/repo/src/main/resources/newdocs index 4b96e283..f00ab3a3 160000 --- a/repo/src/main/resources/newdocs +++ b/repo/src/main/resources/newdocs @@ -1 +1 @@ -Subproject commit 4b96e283924e0481299b6400520829649634c23e +Subproject commit f00ab3a3efe6e2f8542ba026d1fc1d72df7dfd5f From 80cc7920a95c98e3e386686c0d98092fb6061ec2 Mon Sep 17 00:00:00 2001 From: Aleksandr Fedorov Date: Tue, 18 Jul 2023 15:39:38 +0300 Subject: [PATCH 02/76] removed file type usage from file url --- CHANGELOG.md | 4 ++++ .../java/com/parashift/onlyoffice/scripts/CallBack.java | 9 ++++----- .../main/java/com/parashift/onlyoffice/util/Util.java | 8 -------- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index adab2a78..c3524300 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## +## Added +- document server v6.4 and earlier is no longer supported +- ## 6.1.0 ## Added - manage permissions from editor diff --git a/repo/src/main/java/com/parashift/onlyoffice/scripts/CallBack.java b/repo/src/main/java/com/parashift/onlyoffice/scripts/CallBack.java index b92dc379..1dd0ea2c 100644 --- a/repo/src/main/java/com/parashift/onlyoffice/scripts/CallBack.java +++ b/repo/src/main/java/com/parashift/onlyoffice/scripts/CallBack.java @@ -206,7 +206,7 @@ public Object execute() throws Throwable { break; case 2: logger.debug("Document Updated, changing content"); - updateNode(wc, callBackJSon.getString("url")); + updateNode(wc, callBackJSon.getString("url"), callBackJSon.getString("filetype")); logger.info("removing prop"); nodeService.removeProperty(wc, Util.EditingHashAspect); @@ -244,7 +244,7 @@ public Object execute() throws Throwable { } logger.debug("Forcesave request (type: " + callBackJSon.getInt("forcesavetype") + ")"); - updateNode(wc, callBackJSon.getString("url")); + updateNode(wc, callBackJSon.getString("url"), callBackJSon.getString("filetype")); String hash = (String) nodeService.getProperty(wc, Util.EditingHashAspect); String key = (String) nodeService.getProperty(wc, Util.EditingKeyAspect); @@ -275,7 +275,7 @@ public Object execute() throws Throwable { } } - private void updateNode(final NodeRef nodeRef, String url) throws Exception { + private void updateNode(final NodeRef nodeRef, String url, String fileType) throws Exception { logger.debug("Retrieving URL:" + url); final String currentUser = AuthenticationUtil.getFullyAuthenticatedUser(); @@ -295,8 +295,7 @@ public Void doWork() { if (converterService.shouldConvertBack(mimeType)) { try { logger.debug("Should convert back"); - String downloadExt = util.getFileExtension(url).replace(".", ""); - url = converterService.convert(util.getKey(nodeRef), downloadExt, mimetypeService.getExtension(mimeType), url, null); + url = converterService.convert(util.getKey(nodeRef), fileType, mimetypeService.getExtension(mimeType), url, null); } catch (Exception e) { throw new Exception("Error while converting document back to original format: " + e.getMessage(), e); } diff --git a/repo/src/main/java/com/parashift/onlyoffice/util/Util.java b/repo/src/main/java/com/parashift/onlyoffice/util/Util.java index 4d0a9bd3..395fa38d 100644 --- a/repo/src/main/java/com/parashift/onlyoffice/util/Util.java +++ b/repo/src/main/java/com/parashift/onlyoffice/util/Util.java @@ -193,14 +193,6 @@ public String getCorrectName(NodeRef nodeFolder, String title, String ext) { return name; } - public String getFileExtension(String url) - { - String fileName = getFileName(url); - if (fileName == null) return null; - String fileExt = fileName.substring(fileName.lastIndexOf(".")); - return fileExt.toLowerCase(); - } - public String getDocType(String ext) { List supportedFormats = Formats.getSupportedFormats(); From f89bdee082e79345394de4ac1483511a9ddebd52 Mon Sep 17 00:00:00 2001 From: Aleksandr Fedorov Date: Thu, 20 Jul 2023 11:39:48 +0300 Subject: [PATCH 03/76] si-LK to language dictionary --- repo/src/main/java/com/parashift/onlyoffice/util/Util.java | 1 + 1 file changed, 1 insertion(+) diff --git a/repo/src/main/java/com/parashift/onlyoffice/util/Util.java b/repo/src/main/java/com/parashift/onlyoffice/util/Util.java index 4d0a9bd3..3fdf2908 100644 --- a/repo/src/main/java/com/parashift/onlyoffice/util/Util.java +++ b/repo/src/main/java/com/parashift/onlyoffice/util/Util.java @@ -93,6 +93,7 @@ public class Util { put("pt-BR", "pt-BR"); put("pt", "pt-PT"); put("ru", "ru-RU"); + put("si", "si-LK"); put("sk", "sk-SK"); put("sv", "sv-SE"); put("tr", "tr-TR"); From 4a8511d3450102ecd5b1e91938bc6830c3be9b17 Mon Sep 17 00:00:00 2001 From: Aleksandr Fedorov Date: Tue, 5 Dec 2023 16:14:57 +0300 Subject: [PATCH 04/76] add: dependency sdk com.onlyoffice.docs-integration-sdk:0.0.1-SNAPSHOT --- pom.xml | 9 +++++++++ repo/pom.xml | 5 +++++ share/pom.xml | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/pom.xml b/pom.xml index 1efe3f7e..4a175dfa 100644 --- a/pom.xml +++ b/pom.xml @@ -113,6 +113,11 @@ jackson-databind 2.13.3 + + com.onlyoffice + docs-integration-sdk + 0.0.1-SNAPSHOT + @@ -188,6 +193,10 @@ Alfresco Maven Repositories --> + + ossrh + http://192.168.4.26:8081/repository/maven-public + alfresco-public https://artifacts.alfresco.com/nexus/content/groups/public diff --git a/repo/pom.xml b/repo/pom.xml index 12e16ccb..a30b6bee 100644 --- a/repo/pom.xml +++ b/repo/pom.xml @@ -25,6 +25,11 @@ com.fasterxml.jackson.core jackson-databind + + + com.onlyoffice + docs-integration-sdk + diff --git a/share/pom.xml b/share/pom.xml index ac304673..19d7aff7 100644 --- a/share/pom.xml +++ b/share/pom.xml @@ -31,6 +31,15 @@ spring-surf-api + + com.onlyoffice + docs-integration-sdk + + + com.fasterxml.jackson.core + jackson-databind + + javax.servlet javax.servlet-api From 6a91a601dbcb4f34b5c4b0b2a9c81bf4439ddd8d Mon Sep 17 00:00:00 2001 From: Aleksandr Fedorov Date: Tue, 5 Dec 2023 16:18:16 +0300 Subject: [PATCH 05/76] add: implementations sdk managers (DocumentManager, JwtManager, SettingsManager, UrlManager, RequestManger) --- .../manager/document/DocumentManagerImpl.java | 68 ++++++ .../manager/settings/SettingsManagerImpl.java | 27 +++ .../sdk/manager/url/UrlManager.java | 18 ++ .../sdk/manager/url/UrlManagerImpl.java | 196 ++++++++++++++++++ .../alfresco/extension/onlyoffice-context.xml | 26 +++ 5 files changed, 335 insertions(+) create mode 100644 repo/src/main/java/com/parashift/onlyoffice/sdk/manager/document/DocumentManagerImpl.java create mode 100644 repo/src/main/java/com/parashift/onlyoffice/sdk/manager/settings/SettingsManagerImpl.java create mode 100644 repo/src/main/java/com/parashift/onlyoffice/sdk/manager/url/UrlManager.java create mode 100644 repo/src/main/java/com/parashift/onlyoffice/sdk/manager/url/UrlManagerImpl.java diff --git a/repo/src/main/java/com/parashift/onlyoffice/sdk/manager/document/DocumentManagerImpl.java b/repo/src/main/java/com/parashift/onlyoffice/sdk/manager/document/DocumentManagerImpl.java new file mode 100644 index 00000000..8d4dbf69 --- /dev/null +++ b/repo/src/main/java/com/parashift/onlyoffice/sdk/manager/document/DocumentManagerImpl.java @@ -0,0 +1,68 @@ +package com.parashift.onlyoffice.sdk.manager.document; + +import com.onlyoffice.manager.document.DefaultDocumentManager; +import com.onlyoffice.manager.settings.SettingsManager; +import org.alfresco.model.ContentModel; +import org.alfresco.service.cmr.coci.CheckOutCheckInService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import java.io.Serializable; +import java.util.Map; + +/* + Copyright (c) Ascensio System SIA 2023. All rights reserved. + http://www.onlyoffice.com +*/ + +public class DocumentManagerImpl extends DefaultDocumentManager { + public static final QName EditingKeyAspect = QName.createQName("onlyoffice:editing-key"); + public static final QName EditingHashAspect = QName.createQName("onlyoffice:editing-hash"); + + @Autowired + @Qualifier("checkOutCheckInService") + CheckOutCheckInService cociService; + + @Autowired + NodeService nodeService; + + public DocumentManagerImpl(SettingsManager settingsManager) { + super(settingsManager); + } + + @Override + public String getDocumentKey(String fileId, boolean embedded) { + NodeRef nodeRef = new NodeRef(fileId); + + String key = null; + if (cociService.isCheckedOut(nodeRef)) { + key = (String) nodeService.getProperty(cociService.getWorkingCopy(nodeRef), EditingKeyAspect); + } + + if (key == null) { + Map properties = nodeService.getProperties(nodeRef); + String version = (String) properties.get(ContentModel.PROP_VERSION_LABEL); + + if (version == null || version.isEmpty()) { + key = nodeRef.getId() + "_1.0"; + } else { + key = nodeRef.getId() + "_" + version; + } + + key = embedded ? key + "_embedded" : key; + } + + return key; + } + + @Override + public String getDocumentName(String fileId) { + NodeRef nodeRef = new NodeRef(fileId); + + return (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); + } +} diff --git a/repo/src/main/java/com/parashift/onlyoffice/sdk/manager/settings/SettingsManagerImpl.java b/repo/src/main/java/com/parashift/onlyoffice/sdk/manager/settings/SettingsManagerImpl.java new file mode 100644 index 00000000..6ba44397 --- /dev/null +++ b/repo/src/main/java/com/parashift/onlyoffice/sdk/manager/settings/SettingsManagerImpl.java @@ -0,0 +1,27 @@ +package com.parashift.onlyoffice.sdk.manager.settings; + +import com.onlyoffice.manager.settings.DefaultSettingsManager; +import org.alfresco.service.cmr.attributes.AttributeService; +import org.springframework.beans.factory.annotation.Autowired; + +/* + Copyright (c) Ascensio System SIA 2023. All rights reserved. + http://www.onlyoffice.com +*/ + +public class SettingsManagerImpl extends DefaultSettingsManager { + private static final String SETTINGS_PREFIX = "onlyoffice."; + + @Autowired + AttributeService attributeService; + + @Override + public String getSetting(String name) { + return (String) attributeService.getAttribute(SETTINGS_PREFIX + name); + } + + @Override + public void setSetting(String name, String value) { + attributeService.setAttribute(value, SETTINGS_PREFIX + name); + } +} diff --git a/repo/src/main/java/com/parashift/onlyoffice/sdk/manager/url/UrlManager.java b/repo/src/main/java/com/parashift/onlyoffice/sdk/manager/url/UrlManager.java new file mode 100644 index 00000000..8de9e3df --- /dev/null +++ b/repo/src/main/java/com/parashift/onlyoffice/sdk/manager/url/UrlManager.java @@ -0,0 +1,18 @@ +package com.parashift.onlyoffice.sdk.manager.url; + +import org.alfresco.service.cmr.repository.NodeRef; + +/* + Copyright (c) Ascensio System SIA 2023. All rights reserved. + http://www.onlyoffice.com +*/ + +public interface UrlManager extends com.onlyoffice.manager.url.UrlManager { + String getHistoryDiffUrl(NodeRef nodeRef); + String getShareUrl(); + String getEmbeddedSaveUrl(String fileId, String sharedId); + String getEmbeddedSaveUrl(String fileId); + String getFavoriteUrl(NodeRef nodeRef); + String getHistoryInfoUrl(NodeRef nodeRef); + String getHistoryDataUrl(NodeRef nodeRef); +} diff --git a/repo/src/main/java/com/parashift/onlyoffice/sdk/manager/url/UrlManagerImpl.java b/repo/src/main/java/com/parashift/onlyoffice/sdk/manager/url/UrlManagerImpl.java new file mode 100644 index 00000000..c9a56ca6 --- /dev/null +++ b/repo/src/main/java/com/parashift/onlyoffice/sdk/manager/url/UrlManagerImpl.java @@ -0,0 +1,196 @@ +package com.parashift.onlyoffice.sdk.manager.url; + +import com.onlyoffice.manager.document.DocumentManager; +import com.onlyoffice.manager.settings.SettingsManager; +import com.onlyoffice.manager.url.DefaultUrlManager; +import com.onlyoffice.model.documenteditor.config.document.DocumentType; +import com.onlyoffice.model.settings.SettingsConstants; +import com.parashift.onlyoffice.util.Util; +import org.alfresco.repo.admin.SysAdminParams; +import org.alfresco.repo.imap.ImapService; +import org.alfresco.service.cmr.coci.CheckOutCheckInService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.security.AuthenticationService; +import org.alfresco.util.UrlUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.extensions.surf.util.URLEncoder; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/* + Copyright (c) Ascensio System SIA 2023. All rights reserved. + http://www.onlyoffice.com +*/ + +public class UrlManagerImpl extends DefaultUrlManager implements UrlManager { + + @Autowired + @Qualifier("checkOutCheckInService") + CheckOutCheckInService cociService; + @Autowired + NodeService nodeService; + @Autowired + AuthenticationService authenticationService; + @Autowired + SysAdminParams sysAdminParams; + @Autowired + DocumentManager documentManager; + @Autowired + ImapService imapService; + + public UrlManagerImpl(SettingsManager settingsManager) { + super(settingsManager); + } + + @Override + public String getFileUrl(String fileId) { + NodeRef nodeRef = new NodeRef(fileId); + + return getAlfrescoUrl() + + "s/parashift/onlyoffice/download/file?nodeRef=" + + nodeRef.toString() + + "&alf_ticket=" + + authenticationService.getCurrentTicket(); + } + + @Override + public String getCallbackUrl(String fileId) { + NodeRef nodeRef = new NodeRef(fileId); + + String hash = null; + if (cociService.isCheckedOut(nodeRef)) { + hash = (String) nodeService.getProperty(cociService.getWorkingCopy(nodeRef), Util.EditingHashAspect); + } + + return getAlfrescoUrl() + + "s/parashift/onlyoffice/callback?nodeRef=" + + nodeRef.toString() + + "&cb_key=" + + hash; + } + + @Override + public String getCreateUrl(String fileId) { + //Todo: check if user have access create new document in current folder + NodeRef nodeRef = new NodeRef(fileId); + + String fileName = documentManager.getDocumentName(fileId); + String folderNodeRef = this.nodeService.getPrimaryParent(nodeRef).getParentRef().toString(); + + DocumentType documentType = documentManager.getDocumentType(fileName); + + String docMime = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; + switch (documentType) { + case CELL: { + docMime = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + break; + } + case SLIDE: { + docMime = "application/vnd.openxmlformats-officedocument.presentationml.presentation"; + break; + } + } + return getShareUrl() + "page/onlyoffice-edit?parentNodeRef=" + folderNodeRef + "&new=" + docMime; + } + + @Override + public String getTestConvertUrl(String productUrl) { + if (productUrl != null && !productUrl.isEmpty()) { + return sanitizeUrl(productUrl) + + "alfresco/s/parashift/onlyoffice/convertertest?alf_ticket=" + + authenticationService.getCurrentTicket(); + } else { + return getAlfrescoUrl() + + "s/parashift/onlyoffice/convertertest?alf_ticket=" + + authenticationService.getCurrentTicket(); + } + } + + @Override + public String getGobackUrl(String fileId){ + NodeRef nodeRef = new NodeRef(fileId); + + String url = imapService.getContentFolderUrl(nodeRef); + + if (url.contains("?filter=path|")) { + List urlParts = Arrays.asList(url.split("\\|")); + url = urlParts.get(0) + URLEncoder.encodeUriComponent("|" + urlParts.get(1)); + } + + return url; + } + + public String getHistoryDiffUrl(NodeRef nodeRef) { + return getAlfrescoUrl() + + "s/parashift/onlyoffice/download/diff?nodeRef=" + + nodeRef.toString() + + "&alf_ticket=" + + authenticationService.getCurrentTicket(); + } + + public String getShareUrl() { + return UrlUtil.getShareUrl(sysAdminParams) + "/"; + } + + public String getEmbeddedSaveUrl(String fileId, String sharedId) { + String fileName = documentManager.getDocumentName(fileId); + + StringBuilder embeddedSaveUrl = new StringBuilder(8); + embeddedSaveUrl.append(UrlUtil.getShareUrl(sysAdminParams)); + embeddedSaveUrl.append("/proxy/alfresco-noauth/api/internal/shared/node/"); + embeddedSaveUrl.append(sharedId); + embeddedSaveUrl.append("/content/"); + embeddedSaveUrl.append(URLEncoder.encodeUriComponent(fileName)); + embeddedSaveUrl.append("?c=force"); + embeddedSaveUrl.append("&noCache=" + new Date().getTime()); + embeddedSaveUrl.append("&a=true"); + + return embeddedSaveUrl.toString(); + } + + public String getEmbeddedSaveUrl(String fileId) { + NodeRef nodeRef = new NodeRef(fileId); + String fileName = documentManager.getDocumentName(fileId); + + StringBuilder embeddedSaveUrl = new StringBuilder(7); + StoreRef storeRef = nodeRef.getStoreRef(); + embeddedSaveUrl.append(UrlUtil.getShareUrl(sysAdminParams)); + embeddedSaveUrl.append("/proxy/alfresco/slingshot/node/content"); + embeddedSaveUrl.append("/" + storeRef.getProtocol()); + embeddedSaveUrl.append("/" + storeRef.getIdentifier()); + embeddedSaveUrl.append("/" + nodeRef.getId()); + embeddedSaveUrl.append("/" + URLEncoder.encodeUriComponent(fileName)); + embeddedSaveUrl.append("?a=true"); + + return embeddedSaveUrl.toString(); + } + + public String getFavoriteUrl(NodeRef nodeRef) { + return "parashift/onlyoffice/editor-api/favorite?nodeRef=" + + nodeRef.toString(); + } + + public String getHistoryInfoUrl(NodeRef nodeRef) { + return "parashift/onlyoffice/history/info?nodeRef=" + + nodeRef.toString(); + } + + public String getHistoryDataUrl(NodeRef nodeRef) { + return "parashift/onlyoffice/history/data?nodeRef=" + + nodeRef.toString(); + } + + private String getAlfrescoUrl() { + String alfUrl = getSettingsManager().getSetting(SettingsConstants.PRODUCT_INNER_URL); + if (alfUrl == null || alfUrl.isEmpty()) { + return sanitizeUrl(UrlUtil.getAlfrescoUrl(sysAdminParams)) + "/"; + } else { + return sanitizeUrl(alfUrl) + "/alfresco/"; + } + } +} diff --git a/repo/src/main/resources/alfresco/extension/onlyoffice-context.xml b/repo/src/main/resources/alfresco/extension/onlyoffice-context.xml index f0af6a39..7f9d3d73 100644 --- a/repo/src/main/resources/alfresco/extension/onlyoffice-context.xml +++ b/repo/src/main/resources/alfresco/extension/onlyoffice-context.xml @@ -14,6 +14,32 @@ parent="action-executer"> + + + + + + + + + + + + + + + + + + + + + From eddfd0bba6dbaa9e03af0b11fea4b579fc9f8de5 Mon Sep 17 00:00:00 2001 From: Aleksandr Fedorov Date: Tue, 5 Dec 2023 16:21:13 +0300 Subject: [PATCH 06/76] add: implementations sdk services(CallbackService, ConfigService, SettingsValidationService, ConvertService) --- .../sdk/service/CallbackServiceImpl.java | 213 ++++++++++++++++++ .../sdk/service/ConfigServiceImpl.java | 145 ++++++++++++ .../service/SettingsValidationService.java | 14 ++ .../SettingsValidationServiceImpl.java | 129 +++++++++++ .../alfresco/extension/onlyoffice-context.xml | 28 +++ 5 files changed, 529 insertions(+) create mode 100644 repo/src/main/java/com/parashift/onlyoffice/sdk/service/CallbackServiceImpl.java create mode 100644 repo/src/main/java/com/parashift/onlyoffice/sdk/service/ConfigServiceImpl.java create mode 100644 repo/src/main/java/com/parashift/onlyoffice/sdk/service/SettingsValidationService.java create mode 100644 repo/src/main/java/com/parashift/onlyoffice/sdk/service/SettingsValidationServiceImpl.java diff --git a/repo/src/main/java/com/parashift/onlyoffice/sdk/service/CallbackServiceImpl.java b/repo/src/main/java/com/parashift/onlyoffice/sdk/service/CallbackServiceImpl.java new file mode 100644 index 00000000..5ea2ffea --- /dev/null +++ b/repo/src/main/java/com/parashift/onlyoffice/sdk/service/CallbackServiceImpl.java @@ -0,0 +1,213 @@ +package com.parashift.onlyoffice.sdk.service; + +import com.onlyoffice.manager.document.DocumentManager; +import com.onlyoffice.manager.request.RequestManager; +import com.onlyoffice.manager.security.JwtManager; +import com.onlyoffice.manager.settings.SettingsManager; +import com.onlyoffice.model.convertservice.ConvertRequest; +import com.onlyoffice.model.convertservice.ConvertResponse; +import com.onlyoffice.model.documenteditor.Callback; +import com.onlyoffice.model.documenteditor.callback.History; +import com.onlyoffice.service.convert.ConvertService; +import com.onlyoffice.service.documenteditor.callback.DefaultCallbackService; +import com.parashift.onlyoffice.util.HistoryManager; +import com.parashift.onlyoffice.util.Util; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.version.VersionModel; +import org.alfresco.service.cmr.coci.CheckOutCheckInService; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.version.VersionType; +import org.apache.http.HttpEntity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +import java.io.IOException; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/* + Copyright (c) Ascensio System SIA 2023. All rights reserved. + http://www.onlyoffice.com +*/ + +public class CallbackServiceImpl extends DefaultCallbackService { + @Autowired + @Qualifier("checkOutCheckInService") + CheckOutCheckInService cociService; + @Autowired + ContentService contentService; + @Autowired + NodeService nodeService; + @Autowired + HistoryManager historyManager; + @Autowired + Util util; + @Autowired + RequestManager requestManager; + @Autowired + ConvertService convertService; + @Autowired + DocumentManager documentManager; + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + public CallbackServiceImpl(JwtManager jwtManager, + SettingsManager settingsManager) { + super(jwtManager, settingsManager); + } + + public void handlerEditing(final Callback callback, final String fileId) throws Exception { + logger.debug("User has entered/exited ONLYOFFICE"); + } + + @Override + public void handlerSave(final Callback callback, final String fileId) throws Exception { + NodeRef nodeRef = new NodeRef(fileId); + NodeRef wc = cociService.getWorkingCopy(nodeRef); + Map versionProperties = new HashMap(); + + logger.debug("Document Updated, changing content"); + updateNode(wc, callback.getUrl(), callback.getFiletype()); + + logger.info("removing prop"); + nodeService.removeProperty(wc, Util.EditingHashAspect); + nodeService.removeProperty(wc, Util.EditingKeyAspect); + + versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR); + cociService.checkin(wc, versionProperties, null); + + History history = callback.getHistory(); + if (history != null) { + try { + historyManager.saveHistory( + nodeRef, + history, + callback.getChangesurl() + ); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + } + + util.postActivity(nodeRef, false); + + logger.debug("Save complete"); + } + + @Override + public void handlerSaveCorrupted(Callback callback, String fileId) throws Exception { + logger.error("ONLYOFFICE has reported that saving the document has failed"); + NodeRef nodeRef = new NodeRef(fileId); + NodeRef wc = cociService.getWorkingCopy(nodeRef); + AuthenticationUtil.setRunAsUser(AuthenticationUtil.getSystemUserName()); + cociService.cancelCheckout(wc); + } + + @Override + public void handlerClosed(Callback callback, String fileId) throws Exception { + logger.debug("No document updates, unlocking node"); + NodeRef nodeRef = new NodeRef(fileId); + NodeRef wc = cociService.getWorkingCopy(nodeRef); + AuthenticationUtil.setRunAsUser(AuthenticationUtil.getSystemUserName()); + cociService.cancelCheckout(wc); + } + + @Override + public void handlerForcesave(Callback callback, String fileId) throws Exception { + if (!super.getSettingsManager().getSettingBoolean("editor.customization.forcesave", false)) { + logger.debug("Forcesave is disabled, ignoring forcesave request"); + return; + } + + NodeRef nodeRef = new NodeRef(fileId); + NodeRef wc = cociService.getWorkingCopy(nodeRef); + Map versionProperties = new HashMap(); + + logger.debug("Forcesave request (type: " + callback.getForcesavetype() + ")"); + updateNode(wc, callback.getUrl(), callback.getFiletype()); + + String hash = (String) nodeService.getProperty(wc, Util.EditingHashAspect); + String key = (String) nodeService.getProperty(wc, Util.EditingKeyAspect); + + nodeService.removeProperty(wc, Util.EditingHashAspect); + nodeService.removeProperty(wc, Util.EditingKeyAspect); + + versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR); + cociService.checkin(wc, versionProperties, null, true); + + nodeService.setProperty(wc, Util.EditingHashAspect, hash); + nodeService.setProperty(wc, Util.EditingKeyAspect, key); + + History history = callback.getHistory(); + if (history != null) { + try { + historyManager.saveHistory( + nodeRef, + history, + callback.getChangesurl() + ); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + } + + util.postActivity(nodeRef, false); + + logger.debug("Forcesave complete"); + } + + private void updateNode(final NodeRef nodeRef, String url, String fileType) throws Exception { + logger.debug("Retrieving URL:" + url); + + String documentName = documentManager.getDocumentName(nodeRef.toString()); + String currentFileType = documentManager.getExtension(documentName); + final String currentUser = AuthenticationUtil.getFullyAuthenticatedUser(); + + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() { + public Void doWork() { + NodeRef sourcesNodeRef = cociService.getCheckedOut(nodeRef); + nodeService.setProperty(sourcesNodeRef, ContentModel.PROP_LOCK_OWNER, currentUser); + nodeService.setProperty(nodeRef, ContentModel.PROP_WORKING_COPY_OWNER, currentUser); + return null; + } + }, AuthenticationUtil.getSystemUserName()); + + if (!currentFileType.equals(fileType)) { + try { + logger.debug("Should convert back"); + ConvertRequest convert = ConvertRequest.builder() + .outputtype(currentFileType) + .url(url) + .build(); + + ConvertResponse convertResponse = convertService.processConvert(convert, nodeRef.toString()); + + if (convertResponse.getError() != null && convertResponse.getError().equals(ConvertResponse.Error.TOKEN)) { + throw new SecurityException(); + } + + if (convertResponse.getEndConvert() == null || !convertResponse.getEndConvert() + || convertResponse.getFileUrl() == null || convertResponse.getFileUrl().isEmpty()) { + throw new Exception("'endConvert' is false or 'fileUrl' is empty"); + } + + url = convertResponse.getFileUrl(); + } catch (Exception e) { + throw new Exception("Error while converting document back to original format: " + e.getMessage(), e); + } + } + + requestManager.executeGetRequest(url, new RequestManager.Callback() { + public Void doWork(Object response) throws IOException { + contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true).putContent(((HttpEntity)response).getContent()); + return null; + } + }); + } +} diff --git a/repo/src/main/java/com/parashift/onlyoffice/sdk/service/ConfigServiceImpl.java b/repo/src/main/java/com/parashift/onlyoffice/sdk/service/ConfigServiceImpl.java new file mode 100644 index 00000000..f8fa9db8 --- /dev/null +++ b/repo/src/main/java/com/parashift/onlyoffice/sdk/service/ConfigServiceImpl.java @@ -0,0 +1,145 @@ +package com.parashift.onlyoffice.sdk.service; + +import com.onlyoffice.manager.document.DocumentManager; +import com.onlyoffice.manager.security.JwtManager; +import com.onlyoffice.manager.settings.SettingsManager; +import com.onlyoffice.model.common.User; +import com.onlyoffice.model.documenteditor.config.document.DocumentType; +import com.onlyoffice.model.documenteditor.config.document.Info; +import com.onlyoffice.model.documenteditor.config.document.Permissions; +import com.onlyoffice.model.documenteditor.config.editorconfig.Embedded; +import com.onlyoffice.model.documenteditor.config.editorconfig.Template; +import com.onlyoffice.service.documenteditor.config.DefaultConfigService; +import com.parashift.onlyoffice.sdk.manager.url.UrlManager; +import com.parashift.onlyoffice.util.Util; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.service.cmr.favourites.FavouritesService; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.cmr.security.PersonService; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/* + Copyright (c) Ascensio System SIA 2023. All rights reserved. + http://www.onlyoffice.com +*/ + +public class ConfigServiceImpl extends DefaultConfigService { + @Autowired + PersonService personService; + @Autowired + PermissionService permissionService; + @Autowired + FavouritesService favouritesService; + @Autowired + NodeService nodeService; + @Autowired + Util util; + @Autowired + UrlManager urlManager; + + public ConfigServiceImpl(DocumentManager documentManager, + UrlManager urlManager, + JwtManager jwtManager, + SettingsManager settingsManager) { + super(documentManager, urlManager, jwtManager, settingsManager); + } + + @Override + public Info getInfo(String fileId) { + NodeRef nodeRef = new NodeRef(fileId); + String userName = AuthenticationUtil.getFullyAuthenticatedUser(); + + if (userName != null) { + try { + return Info.builder() + .favorite(favouritesService.isFavourite(userName, nodeRef)) + .build(); + } catch (Exception e) { } + } + + return null; + } + + @Override + public Permissions getPermissions(String fileId) { + NodeRef nodeRef = new NodeRef(fileId); + String fileName = super.getDocumentManager().getDocumentName(fileId); + + Boolean editPermission = permissionService.hasPermission(nodeRef, PermissionService.WRITE) + == AccessStatus.ALLOWED; + Boolean isEditable = super.getDocumentManager().isEditable(fileName) + || super.getDocumentManager().isFillable(fileName); + + return Permissions.builder() + .edit(editPermission && isEditable) + .build(); + } + + @Override + public User getUser() { + String userName = AuthenticationUtil.getFullyAuthenticatedUser(); + + NodeRef person = personService.getPersonOrNull(userName); + PersonService.PersonInfo personInfo = null; + if (person != null) { + personInfo = personService.getPerson(person); + } + + User user = User.builder() + .id(userName) + .build(); + + if (personInfo == null) { + user.setName(userName); + } else { + user.setName(personInfo.getFirstName() + " " + personInfo.getLastName()); + } + + return user; + } + + @Override + public List