From 5a03bde0dc9f0b8b7b83f8242019f24f1d9635c2 Mon Sep 17 00:00:00 2001 From: montgolfiere Date: Tue, 7 Dec 2021 17:21:31 +0000 Subject: [PATCH] PRODESC-5780: ACS Repo DAU APIs to also use non-attach allow list - back-port to 7.1.N (cherry-pick *and* resolve conflicts) --- .../opencmis/CMISServletDispatcher.java | 12 ++++-- .../org/alfresco/rest/api/impl/NodesImpl.java | 10 +++-- .../alfresco/public-rest-context.xml | 21 ++------- .../repo/content/ContentServiceImpl.java | 43 ++++++++++++++++++- .../alfresco/content-services-context.xml | 3 ++ .../resources/alfresco/repository.properties | 3 ++ 6 files changed, 66 insertions(+), 26 deletions(-) diff --git a/remote-api/src/main/java/org/alfresco/opencmis/CMISServletDispatcher.java b/remote-api/src/main/java/org/alfresco/opencmis/CMISServletDispatcher.java index d803a91951..54572babd0 100644 --- a/remote-api/src/main/java/org/alfresco/opencmis/CMISServletDispatcher.java +++ b/remote-api/src/main/java/org/alfresco/opencmis/CMISServletDispatcher.java @@ -2,7 +2,7 @@ * #%L * Alfresco Remote API * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited + * Copyright (C) 2005 - 2021 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of @@ -90,7 +90,8 @@ public abstract class CMISServletDispatcher implements CMISDispatcher protected CmisVersion cmisVersion; protected TenantAdminService tenantAdminService; - private Set nonAttachContentTypes = Collections.emptySet(); // pre-configured whitelist, eg. images & pdf + // pre-configured allow list of media/mime types, eg. specific types of images & also pdf + private Set nonAttachContentTypes = Collections.emptySet(); public void setTenantAdminService(TenantAdminService tenantAdminService) { @@ -137,9 +138,12 @@ public abstract class CMISServletDispatcher implements CMISDispatcher this.cmisVersion = CmisVersion.fromValue(cmisVersion); } - public void setNonAttachContentTypes(Set nonAttachWhiteList) + public void setNonAttachContentTypes(String nonAttachAllowListStr) { - this.nonAttachContentTypes = nonAttachWhiteList; + if ((nonAttachAllowListStr != null) && (! nonAttachAllowListStr.isEmpty())) + { + nonAttachContentTypes = Set.of(nonAttachAllowListStr.trim().split("\\s*,\\s*")); + } } protected synchronized Descriptor getCurrentDescriptor() diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java index 1f88b43ca7..130c437240 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java @@ -239,11 +239,15 @@ public class NodesImpl implements Nodes private ConcurrentHashMap ddCache = new ConcurrentHashMap<>(); - private Set nonAttachContentTypes = Collections.emptySet(); // pre-configured whitelist, eg. images & pdf + // pre-configured allow list of media/mime types, eg. specific types of images & also pdf + private Set nonAttachContentTypes = Collections.emptySet(); - public void setNonAttachContentTypes(Set nonAttachWhiteList) + public void setNonAttachContentTypes(String nonAttachAllowListStr) { - this.nonAttachContentTypes = nonAttachWhiteList; + if ((nonAttachAllowListStr != null) && (! nonAttachAllowListStr.isEmpty())) + { + nonAttachContentTypes = Set.of(nonAttachAllowListStr.trim().split("\\s*,\\s*")); + } } public void init() diff --git a/remote-api/src/main/resources/alfresco/public-rest-context.xml b/remote-api/src/main/resources/alfresco/public-rest-context.xml index 5116742b2b..c613864bcf 100644 --- a/remote-api/src/main/resources/alfresco/public-rest-context.xml +++ b/remote-api/src/main/resources/alfresco/public-rest-context.xml @@ -508,19 +508,6 @@ - - - - application/pdf - image/jpeg - image/gif - image/png - image/tiff - image/bmp - - - - @@ -541,7 +528,7 @@ - + @@ -1113,7 +1100,7 @@ - + @@ -1125,7 +1112,7 @@ - + @@ -1137,7 +1124,7 @@ - + nonAttachContentTypes = Collections.emptySet(); /** * The policy component @@ -150,6 +154,14 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa this.systemWideDirectUrlConfig = systemWideDirectUrlConfig; } + public void setNonAttachContentTypes(String nonAttachAllowListStr) + { + if ((nonAttachAllowListStr != null) && (! nonAttachAllowListStr.isEmpty())) + { + nonAttachContentTypes = Set.of(nonAttachAllowListStr.trim().split("\\s*,\\s*")); + } + } + public void setPolicyComponent(PolicyComponent policyComponent) { this.policyComponent = policyComponent; @@ -621,9 +633,19 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa throw new DirectAccessUrlDisabledException("Direct access url isn't available."); } - String contentUrl = getContentUrl(nodeRef); + ContentData contentData = getContentData(nodeRef, ContentModel.PROP_CONTENT); + // check that the content & URL is available + if (contentData == null || contentData.getContentUrl() == null) + { + throw new IllegalArgumentException("The supplied nodeRef " + nodeRef + " has no content."); + } + + String contentUrl = contentData.getContentUrl(); + String contentMimetype = contentData.getMimetype(); String fileName = getFileName(nodeRef); + validFor = adjustValidFor(validFor); + attachment = adjustAttachment(nodeRef, contentMimetype, attachment); DirectAccessUrl directAccessUrl = null; if (store.isContentDirectUrlEnabled()) @@ -676,4 +698,21 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa } return validFor; } -} \ No newline at end of file + + private boolean adjustAttachment(NodeRef nodeRef, String mimeType, boolean attachmentIn) + { + boolean attachment = true; + if (! attachmentIn) + { + if ((nonAttachContentTypes != null) && (nonAttachContentTypes.contains(mimeType))) + { + attachment = false; + } + else + { + logger.warn("Ignored attachment=false for " + nodeRef.getId() + " since " + mimeType + " is not in the whitelist for non-attach content types"); + } + } + return attachment; + } +} diff --git a/repository/src/main/resources/alfresco/content-services-context.xml b/repository/src/main/resources/alfresco/content-services-context.xml index dfbdf56633..3689d6c849 100644 --- a/repository/src/main/resources/alfresco/content-services-context.xml +++ b/repository/src/main/resources/alfresco/content-services-context.xml @@ -164,6 +164,9 @@ + + ${content.nonAttach.mimetypes} + diff --git a/repository/src/main/resources/alfresco/repository.properties b/repository/src/main/resources/alfresco/repository.properties index b31b3b0d4f..debd17d6f4 100644 --- a/repository/src/main/resources/alfresco/repository.properties +++ b/repository/src/main/resources/alfresco/repository.properties @@ -1308,3 +1308,6 @@ system.tempFileCleaner.maxTimeToRun= # Property to long running migration to remove alf_server in v7+ patch.db-V7.1.0-remove-alf_server-table system.remove-alf_server-table-from-db.ignored=true + +# pre-configured allow list of media/mime types to allow inline instead of attachment (via Content-Disposition response header) +content.nonAttach.mimetypes=application/pdf,image/jpeg,image/gif,image/png,image/tiff,image/bmp