diff --git a/remote-api/src/main/java/org/alfresco/rest/api/DirectAccessUrlHelper.java b/remote-api/src/main/java/org/alfresco/rest/api/DirectAccessUrlHelper.java
new file mode 100644
index 0000000000..93d49d3c93
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/DirectAccessUrlHelper.java
@@ -0,0 +1,66 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * 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
+ * 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.rest.api;
+
+import org.alfresco.rest.api.impl.directurl.RestApiDirectUrlConfig;
+import org.alfresco.rest.api.model.DirectAccessUrlRequest;
+import org.alfresco.rest.framework.core.exceptions.DisabledServiceException;
+import org.apache.commons.lang3.BooleanUtils;
+
+/**
+ * Helper class for retrieving direct access URLs options.
+ *
+ * @author Sara Aspery
+ */
+public class DirectAccessUrlHelper
+{
+ private RestApiDirectUrlConfig restApiDirectUrlConfig;
+
+ public void setRestApiDirectUrlConfig(RestApiDirectUrlConfig restApiDirectUrlConfig)
+ {
+ this.restApiDirectUrlConfig = restApiDirectUrlConfig;
+ }
+
+ public Long getDefaultExpiryTimeInSec()
+ {
+ if (restApiDirectUrlConfig ==null || !restApiDirectUrlConfig.isEnabled())
+ {
+ throw new DisabledServiceException("Direct access url isn't available.");
+ }
+
+ return restApiDirectUrlConfig.getDefaultExpiryTimeInSec();
+ }
+
+ public boolean getAttachment(DirectAccessUrlRequest directAccessUrlRequest)
+ {
+ boolean attachment = true;
+ if (directAccessUrlRequest != null )
+ {
+ attachment = BooleanUtils.toBooleanDefaultIfNull(directAccessUrlRequest.isAttachment(), true);
+ }
+ return attachment;
+ }
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java b/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java
index 48f1332d83..6fa9272e3d 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2017 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
@@ -44,6 +44,7 @@ import org.alfresco.rest.framework.resource.content.BinaryResource;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.DirectAccessUrl;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName;
@@ -266,6 +267,49 @@ public interface Nodes
*/
Node unlock(String nodeId, Parameters parameters);
+ /**
+ * Gets a presigned URL to directly access content.
+ * @param nodeId The node id for which to obtain the direct access {@code URL}
+ * @param attachment {@code true} if an attachment {@code URL} is requested, {@code false} for an embedded {@code URL}.
+ * @return A direct access {@code URL} object for the content.
+ */
+ default DirectAccessUrl requestContentDirectUrl(String nodeId, boolean attachment)
+ {
+ return requestContentDirectUrl(validateNode(nodeId), attachment);
+ }
+
+ /**
+ * Gets a presigned URL to directly access content.
+ * @param nodeRef The node reference for which to obtain the direct access {@code URL}
+ * @param attachment {@code true} if an attachment {@code URL} is requested, {@code false} for an embedded {@code URL}.
+ * @return A direct access {@code URL} object for the content.
+ */
+ default DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment)
+ {
+ return requestContentDirectUrl(nodeRef, attachment, null);
+ }
+
+ /**
+ * Gets a presigned URL to directly access content.
+ * @param nodeId The node id for which to obtain the direct access {@code URL}
+ * @param attachment {@code true} if an attachment {@code URL} is requested, {@code false} for an embedded {@code URL}.
+ * @param validFor The time at which the direct access {@code URL} will expire.
+ * @return A direct access {@code URL} object for the content.
+ */
+ default DirectAccessUrl requestContentDirectUrl(String nodeId, boolean attachment, Long validFor)
+ {
+ return requestContentDirectUrl(validateNode(nodeId), attachment, validFor);
+ }
+
+ /**
+ * Gets a presigned URL to directly access content.
+ * @param nodeRef The node reference for which to obtain the direct access {@code URL}
+ * @param attachment {@code true} if an attachment {@code URL} is requested, {@code false} for an embedded {@code URL}.
+ * @param validFor The time at which the direct access {@code URL} will expire.
+ * @return A direct access {@code URL} object for the content.
+ */
+ DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor);
+
/**
* Convert from node properties (map of QName to Serializable) retrieved from
* the respository to a map of String to Object that can be formatted/expressed
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 ed8bb25a44..1f88b43ca7 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
@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2019 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
@@ -139,6 +139,7 @@ import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
+import org.alfresco.service.cmr.repository.DirectAccessUrl;
import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.MimetypeService;
@@ -3413,6 +3414,20 @@ public class NodesImpl implements Nodes
return getFolderOrDocument(nodeId, parameters);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor)
+ {
+ DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(nodeRef, attachment, validFor);
+ if (directAccessUrl == null)
+ {
+ throw new DisabledServiceException("Direct access url isn't available.");
+ }
+ return directAccessUrl;
+ }
+
/**
* Checks if same permission is sent more than once
* @param locallySetPermissions
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/DirectAccessUrlRequest.java b/remote-api/src/main/java/org/alfresco/rest/api/model/DirectAccessUrlRequest.java
new file mode 100644
index 0000000000..6dde68adb2
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/DirectAccessUrlRequest.java
@@ -0,0 +1,46 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * 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
+ * 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.rest.api.model;
+
+/**
+ * Direct Access URL request.
+ *
+ * @author Sara Aspery
+ */
+public class DirectAccessUrlRequest
+{
+ private Boolean attachment;
+
+ public Boolean isAttachment()
+ {
+ return attachment;
+ }
+
+ public void setAttachment(Boolean attachment)
+ {
+ this.attachment = attachment;
+ }
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodesEntityResource.java b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodesEntityResource.java
index 7d7777aa31..c7cf7bca95 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodesEntityResource.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodesEntityResource.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
@@ -25,11 +25,13 @@
*/
package org.alfresco.rest.api.nodes;
+import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
-import javax.servlet.http.HttpServletResponse;
-
+import org.alfresco.repo.content.directurl.DirectAccessUrlDisabledException;
+import org.alfresco.rest.api.DirectAccessUrlHelper;
import org.alfresco.rest.api.Nodes;
+import org.alfresco.rest.api.model.DirectAccessUrlRequest;
import org.alfresco.rest.api.model.LockInfo;
import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.api.model.NodeTarget;
@@ -37,6 +39,8 @@ import org.alfresco.rest.framework.BinaryProperties;
import org.alfresco.rest.framework.Operation;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.WebApiParam;
+import org.alfresco.rest.framework.core.ResourceParameter;
+import org.alfresco.rest.framework.core.exceptions.DisabledServiceException;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.resource.EntityResource;
import org.alfresco.rest.framework.resource.actions.interfaces.BinaryResourceAction;
@@ -45,7 +49,10 @@ import org.alfresco.rest.framework.resource.content.BasicContentInfo;
import org.alfresco.rest.framework.resource.content.BinaryResource;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.webscripts.WithResponse;
+import org.alfresco.service.cmr.repository.DirectAccessUrl;
+import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.ParameterCheck;
+
import org.springframework.beans.factory.InitializingBean;
/**
@@ -61,13 +68,19 @@ public class NodesEntityResource implements
BinaryResourceAction.Read, BinaryResourceAction.Update, InitializingBean
{
private Nodes nodes;
+ private DirectAccessUrlHelper directAccessUrlHelper;
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
- @Override
+ public void setDirectAccessUrlHelper(DirectAccessUrlHelper directAccessUrlHelper)
+ {
+ this.directAccessUrlHelper = directAccessUrlHelper;
+ }
+
+ @Override
public void afterPropertiesSet()
{
ParameterCheck.mandatory("nodes", this.nodes);
@@ -189,5 +202,27 @@ public class NodesEntityResource implements
return nodes.unlock(nodeId, parameters);
}
+ @Operation("requestNodeDirectAccessUrl")
+ @WebApiParam(name = "requestNodeDirectAccessUrl", title = "Request direct access url", description = "Request direct access url", kind = ResourceParameter.KIND.HTTP_BODY_OBJECT)
+ @WebApiDescription(title = "Request content url",
+ description="Generates a direct access URL.",
+ successStatus = HttpServletResponse.SC_OK)
+ public DirectAccessUrl requestContentDirectUrl(String nodeId, DirectAccessUrlRequest directAccessUrlRequest, Parameters parameters, WithResponse withResponse)
+ {
+ boolean attachment = directAccessUrlHelper.getAttachment(directAccessUrlRequest);
+ Long validFor = directAccessUrlHelper.getDefaultExpiryTimeInSec();
+ NodeRef nodeRef = nodes.validateNode(nodeId);
+
+ DirectAccessUrl directAccessUrl;
+ try
+ {
+ directAccessUrl = nodes.requestContentDirectUrl(nodeRef, attachment, validFor);
+ }
+ catch (DirectAccessUrlDisabledException ex)
+ {
+ throw new DisabledServiceException(ex.getMessage());
+ }
+ return directAccessUrl;
+ }
}
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 9f659bc8b2..d0b9b18e7b 100644
--- a/remote-api/src/main/resources/alfresco/public-rest-context.xml
+++ b/remote-api/src/main/resources/alfresco/public-rest-context.xml
@@ -942,8 +942,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/repository/src/main/resources/alfresco/public-services-security-context.xml b/repository/src/main/resources/alfresco/public-services-security-context.xml
index d0506a5e62..c3c0aee115 100644
--- a/repository/src/main/resources/alfresco/public-services-security-context.xml
+++ b/repository/src/main/resources/alfresco/public-services-security-context.xml
@@ -494,7 +494,7 @@
org.alfresco.service.cmr.repository.ContentService.getRawReader=ACL_METHOD.ROLE_ADMINISTRATOR
org.alfresco.service.cmr.repository.ContentService.getReader=ACL_NODE.0.sys:base.ReadContent
org.alfresco.service.cmr.repository.ContentService.getWriter=ACL_NODE.0.sys:base.WriteContent
- org.alfresco.service.cmr.repository.ContentService.getDirectAccessUrl=ACL_NODE.0.sys:base.ReadContent
+ org.alfresco.service.cmr.repository.ContentService.requestContentDirectUrl=ACL_NODE.0.sys:base.ReadContent
org.alfresco.service.cmr.repository.ContentService.getTempWriter=ACL_ALLOW
org.alfresco.service.cmr.repository.ContentService.isContentDirectUrlEnabled=ACL_ALLOW
org.alfresco.service.cmr.repository.ContentService.*=ACL_DENY