mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	Compare commits
	
		
			16 Commits
		
	
	
		
			23.1.0.165
			...
			feature/20
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					0a8052d0ab | ||
| 
						 | 
					a996fe2d2f | ||
| 
						 | 
					e0db9362a4 | ||
| 
						 | 
					63d853750e | ||
| 
						 | 
					b66f9f604b | ||
| 
						 | 
					b423a7ae96 | ||
| 
						 | 
					114cec4987 | ||
| 
						 | 
					a480370459 | ||
| 
						 | 
					22cc54cc03 | ||
| 
						 | 
					af26f07cf3 | ||
| 
						 | 
					0e2ac5168c | ||
| 
						 | 
					2ed631d3c2 | ||
| 
						 | 
					3fd3b128be | ||
| 
						 | 
					cb4dde6035 | ||
| 
						 | 
					3215bc50c6 | ||
| 
						 | 
					70430ea96c | 
@@ -7,7 +7,7 @@
 | 
			
		||||
   <parent>
 | 
			
		||||
      <groupId>org.alfresco</groupId>
 | 
			
		||||
      <artifactId>alfresco-community-repo-amps</artifactId>
 | 
			
		||||
      <version>23.1.0.165</version>
 | 
			
		||||
      <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
   </parent>
 | 
			
		||||
 | 
			
		||||
   <modules>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
   <parent>
 | 
			
		||||
      <groupId>org.alfresco</groupId>
 | 
			
		||||
      <artifactId>alfresco-governance-services-community-parent</artifactId>
 | 
			
		||||
      <version>23.1.0.165</version>
 | 
			
		||||
      <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
   </parent>
 | 
			
		||||
 | 
			
		||||
   <modules>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
   <parent>
 | 
			
		||||
      <groupId>org.alfresco</groupId>
 | 
			
		||||
      <artifactId>alfresco-governance-services-automation-community-repo</artifactId>
 | 
			
		||||
      <version>23.1.0.165</version>
 | 
			
		||||
      <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
   </parent>
 | 
			
		||||
 | 
			
		||||
   <build>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
   <parent>
 | 
			
		||||
      <groupId>org.alfresco</groupId>
 | 
			
		||||
      <artifactId>alfresco-governance-services-community-parent</artifactId>
 | 
			
		||||
      <version>23.1.0.165</version>
 | 
			
		||||
      <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
   </parent>
 | 
			
		||||
 | 
			
		||||
   <modules>
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
   <parent>
 | 
			
		||||
      <groupId>org.alfresco</groupId>
 | 
			
		||||
      <artifactId>alfresco-governance-services-community-repo-parent</artifactId>
 | 
			
		||||
      <version>23.1.0.165</version>
 | 
			
		||||
      <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
   </parent>
 | 
			
		||||
 | 
			
		||||
   <properties>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-governance-services-community-repo-parent</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <build>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <modules>
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-amps</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
   <parent>
 | 
			
		||||
      <groupId>org.alfresco</groupId>
 | 
			
		||||
      <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
      <version>23.1.0.165</version>
 | 
			
		||||
      <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
   </parent>
 | 
			
		||||
 | 
			
		||||
   <dependencies>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,7 @@ public class DirectAccessUrl implements Serializable
 | 
			
		||||
    private String contentUrl;
 | 
			
		||||
    private Date expiryTime;
 | 
			
		||||
    private boolean attachment;
 | 
			
		||||
    private String fileName;
 | 
			
		||||
 | 
			
		||||
    public String getContentUrl()
 | 
			
		||||
    {
 | 
			
		||||
@@ -70,18 +71,28 @@ public class DirectAccessUrl implements Serializable
 | 
			
		||||
        this.attachment = attachment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getFileName()
 | 
			
		||||
    {
 | 
			
		||||
        return fileName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setFileName(String fileName)
 | 
			
		||||
    {
 | 
			
		||||
        this.fileName = fileName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override public boolean equals(Object obj)
 | 
			
		||||
    {
 | 
			
		||||
        if (this == obj) return true;
 | 
			
		||||
        if (obj == null || getClass() != obj.getClass()) return false;
 | 
			
		||||
 | 
			
		||||
        DirectAccessUrl that = (DirectAccessUrl) obj;
 | 
			
		||||
        return attachment == that.attachment && Objects.equals(contentUrl,
 | 
			
		||||
        return Objects.equals(fileName, that.fileName) && attachment == that.attachment && Objects.equals(contentUrl,
 | 
			
		||||
                that.contentUrl) && Objects.equals(expiryTime, that.expiryTime);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override public int hashCode()
 | 
			
		||||
    {
 | 
			
		||||
        return Objects.hash(contentUrl, expiryTime, attachment);
 | 
			
		||||
        return Objects.hash(contentUrl, expiryTime, attachment, fileName);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <dependencies>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,6 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-packaging</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
</project>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-packaging</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <modules>
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-packaging</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <modules>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <organization>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <developers>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <developers>
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,8 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.alfresco.rest.model;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonProperty;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.rest.core.IRestModel;
 | 
			
		||||
@@ -43,6 +45,7 @@ public class RestPersonFavoritesModel extends TestModel implements IRestModel<Re
 | 
			
		||||
 | 
			
		||||
    private String targetGuid;
 | 
			
		||||
    private String createdAt;
 | 
			
		||||
    private List<String> allowableOperations;
 | 
			
		||||
    
 | 
			
		||||
    private RestTargetModel target;
 | 
			
		||||
 | 
			
		||||
@@ -86,4 +89,12 @@ public class RestPersonFavoritesModel extends TestModel implements IRestModel<Re
 | 
			
		||||
    {
 | 
			
		||||
        this.createdAt = createdAt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<String> getAllowableOperations() {
 | 
			
		||||
        return allowableOperations;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setAllowableOperations(List<String> allowableOperations) {
 | 
			
		||||
        this.allowableOperations = allowableOperations;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -101,6 +101,8 @@ public class SearchNodeModel extends TestModel implements IRestModel<SearchNodeM
 | 
			
		||||
    
 | 
			
		||||
    private String location;
 | 
			
		||||
 | 
			
		||||
    private Boolean isFavorite;
 | 
			
		||||
 | 
			
		||||
    public Map<String, Object> getAssociation()
 | 
			
		||||
    {
 | 
			
		||||
        return association;
 | 
			
		||||
@@ -326,5 +328,12 @@ public class SearchNodeModel extends TestModel implements IRestModel<SearchNodeM
 | 
			
		||||
    {
 | 
			
		||||
        this.location = location;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    public Boolean isFavorite() {
 | 
			
		||||
        return isFavorite;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setIsFavorite(Boolean favorite) {
 | 
			
		||||
        isFavorite = favorite;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ import org.testng.annotations.Test;
 | 
			
		||||
 | 
			
		||||
public class GetFavoritesTests extends RestTest
 | 
			
		||||
{
 | 
			
		||||
    private static final String ALLOWABLE_OPERATIONS = "allowableOperations";
 | 
			
		||||
    private UserModel adminUserModel, userModel;
 | 
			
		||||
    private SiteModel firstSiteModel;
 | 
			
		||||
    private SiteModel secondSiteModel;
 | 
			
		||||
@@ -551,4 +552,17 @@ public class GetFavoritesTests extends RestTest
 | 
			
		||||
                .field("id").is(thirdSiteModel.getId()).and()
 | 
			
		||||
                .field("title").is(thirdSiteModel.getTitle());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test(groups = { TestGroup.REST_API, TestGroup.FAVORITES, TestGroup.REGRESSION })
 | 
			
		||||
    @TestRail(section = { TestGroup.REST_API, TestGroup.FAVORITES }, executionType = ExecutionType.REGRESSION, description = "Verify if get favorites response returns allowableOperations object when requested")
 | 
			
		||||
    public void checkResponseForGetFavoritesWithAllowableOperations()
 | 
			
		||||
    {
 | 
			
		||||
        RestPersonFavoritesModelsCollection adminFavorites =
 | 
			
		||||
                restClient.authenticateUser(adminUserModel).withCoreAPI().usingAuthUser().include(ALLOWABLE_OPERATIONS).getFavorites();
 | 
			
		||||
        restClient.assertStatusCodeIs(HttpStatus.OK);
 | 
			
		||||
 | 
			
		||||
        adminFavorites.getEntries().stream()
 | 
			
		||||
                .map(RestPersonFavoritesModel::onModel)
 | 
			
		||||
                .forEach(m -> m.assertThat().field(ALLOWABLE_OPERATIONS).isNotEmpty());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <developers>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-packaging</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								pom.xml
									
									
									
									
									
								
							@@ -2,7 +2,7 @@
 | 
			
		||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
    <version>23.1.0.165</version>
 | 
			
		||||
    <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    <packaging>pom</packaging>
 | 
			
		||||
    <name>Alfresco Community Repo Parent</name>
 | 
			
		||||
 | 
			
		||||
@@ -67,7 +67,7 @@
 | 
			
		||||
        <dependency.assertj.version>3.24.2</dependency.assertj.version>
 | 
			
		||||
        <dependency.org-json.version>20230618</dependency.org-json.version>
 | 
			
		||||
        <dependency.commons-dbcp.version>2.9.0</dependency.commons-dbcp.version>
 | 
			
		||||
        <dependency.commons-io.version>2.11.0</dependency.commons-io.version>
 | 
			
		||||
        <dependency.commons-io.version>2.13.0</dependency.commons-io.version>
 | 
			
		||||
        <dependency.gson.version>2.8.9</dependency.gson.version>
 | 
			
		||||
        <dependency.guava.version>32.1.1-jre</dependency.guava.version>
 | 
			
		||||
        <dependency.httpclient.version>4.5.13</dependency.httpclient.version>
 | 
			
		||||
@@ -150,7 +150,7 @@
 | 
			
		||||
        <connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
 | 
			
		||||
        <developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
 | 
			
		||||
        <url>https://github.com/Alfresco/alfresco-community-repo</url>
 | 
			
		||||
        <tag>23.1.0.165</tag>
 | 
			
		||||
        <tag>HEAD</tag>
 | 
			
		||||
    </scm>
 | 
			
		||||
 | 
			
		||||
    <distributionManagement>
 | 
			
		||||
@@ -635,7 +635,7 @@
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>com.github.junrar</groupId>
 | 
			
		||||
                <artifactId>junrar</artifactId>
 | 
			
		||||
                <version>7.5.4</version>
 | 
			
		||||
                <version>7.5.5</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>com.github.fge</groupId>
 | 
			
		||||
@@ -1023,4 +1023,4 @@
 | 
			
		||||
            </plugin>
 | 
			
		||||
        </plugins>
 | 
			
		||||
    </build>
 | 
			
		||||
</project>
 | 
			
		||||
</project>
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <dependencies>
 | 
			
		||||
 
 | 
			
		||||
@@ -102,18 +102,30 @@ public interface DeletedNodes
 | 
			
		||||
    CollectionWithPagingInfo<Rendition> getRenditions(String archivedId, Parameters parameters);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Gets a presigned URL to directly access content.
 | 
			
		||||
     * Gets a presigned URL to directly access content.
 | 
			
		||||
     *
 | 
			
		||||
    * @param archivedId The node id for which to obtain the direct access {@code URL}
 | 
			
		||||
    * @param renditionId The rendition 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}, {@code true} by default.
 | 
			
		||||
    * @return A direct access {@code URL} object for the content.
 | 
			
		||||
    */
 | 
			
		||||
     * @param archivedId The node id for which to obtain the direct access {@code URL}
 | 
			
		||||
     * @param renditionId The rendition 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}, {@code true} by default.
 | 
			
		||||
     * @return A direct access {@code URL} object for the content.
 | 
			
		||||
     */
 | 
			
		||||
    default DirectAccessUrl requestContentDirectUrl(String archivedId, String renditionId, boolean attachment)
 | 
			
		||||
    {
 | 
			
		||||
        return requestContentDirectUrl(archivedId, renditionId, attachment, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param archivedId The node id for which to obtain the direct access {@code URL}
 | 
			
		||||
     * @param renditionId The rendition 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}, {@code true} by default.
 | 
			
		||||
     * @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 archivedId, String renditionId, boolean attachment, Long validFor)
 | 
			
		||||
    {
 | 
			
		||||
        return requestContentDirectUrl(archivedId, renditionId, attachment, validFor, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets a presigned URL to directly access content.
 | 
			
		||||
     *
 | 
			
		||||
@@ -121,8 +133,9 @@ public interface DeletedNodes
 | 
			
		||||
     * @param renditionId The rendition 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}, {@code true} by default.
 | 
			
		||||
     * @param validFor The time at which the direct access {@code URL} will expire.
 | 
			
		||||
     * @param fileName Optional overide for file name
 | 
			
		||||
     * @return A direct access {@code URL} object for the content.
 | 
			
		||||
     */
 | 
			
		||||
    DirectAccessUrl requestContentDirectUrl(String archivedId, String renditionId, boolean attachment, Long validFor);
 | 
			
		||||
    DirectAccessUrl requestContentDirectUrl(String archivedId, String renditionId, boolean attachment, Long validFor, String fileName);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -63,4 +63,10 @@ public class DirectAccessUrlHelper
 | 
			
		||||
        }
 | 
			
		||||
        return attachment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    public String getFileName(DirectAccessUrlRequest directAccessUrlRequest)
 | 
			
		||||
    {
 | 
			
		||||
        return directAccessUrlRequest != null ? directAccessUrlRequest.getFileName() : null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -323,7 +323,20 @@ public interface Nodes
 | 
			
		||||
     * @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);
 | 
			
		||||
    default DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor)
 | 
			
		||||
    {
 | 
			
		||||
        return requestContentDirectUrl(nodeRef, attachment, validFor, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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.
 | 
			
		||||
     * @param fileName Optional name for the file when downloaded
 | 
			
		||||
     * @return A direct access {@code URL} object for the content.
 | 
			
		||||
     */
 | 
			
		||||
    DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor, String fileName);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert from node properties (map of QName to Serializable) retrieved from
 | 
			
		||||
 
 | 
			
		||||
@@ -251,7 +251,6 @@ public interface Renditions
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets a presigned URL to directly access content.
 | 
			
		||||
     * @param nodeRef     the node reference for which to obtain the direct access {@code URL}
 | 
			
		||||
     * @param versionId   the version id (aka version label)
 | 
			
		||||
     * @param renditionId the rendition id
 | 
			
		||||
@@ -259,6 +258,21 @@ public interface Renditions
 | 
			
		||||
     * @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, String versionId, String renditionId, boolean attachment, Long validFor);
 | 
			
		||||
    default DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, String versionId, String renditionId, boolean attachment, Long validFor)
 | 
			
		||||
    {
 | 
			
		||||
        return requestContentDirectUrl(nodeRef, versionId, renditionId, attachment, validFor, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets a presigned URL to directly access content.
 | 
			
		||||
     * @param nodeRef     the node reference for which to obtain the direct access {@code URL}
 | 
			
		||||
     * @param versionId   the version id (aka version label)
 | 
			
		||||
     * @param renditionId the rendition id
 | 
			
		||||
     * @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
 | 
			
		||||
     * @param fileName    optional name for the file when downloaded
 | 
			
		||||
     * @return            a direct access {@code URL} object for the content.
 | 
			
		||||
     */
 | 
			
		||||
    DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, String versionId, String renditionId, boolean attachment, Long validFor, String fileName);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -250,18 +250,18 @@ public class DeletedNodesImpl implements DeletedNodes, RecognizedParamsExtractor
 | 
			
		||||
     * {@inheritDoc}
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public DirectAccessUrl requestContentDirectUrl(String originalNodeId, String renditionId, boolean attachment, Long validFor)
 | 
			
		||||
    public DirectAccessUrl requestContentDirectUrl(String originalNodeId, String renditionId, boolean attachment, Long validFor, String fileName)
 | 
			
		||||
    {
 | 
			
		||||
        //First check the node is valid and has been archived.
 | 
			
		||||
        NodeRef validatedNodeRef = nodes.validateNode(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, originalNodeId);
 | 
			
		||||
 | 
			
		||||
        if (renditionId != null)
 | 
			
		||||
        {
 | 
			
		||||
            return renditions.requestContentDirectUrl(validatedNodeRef, null, renditionId, attachment, validFor);
 | 
			
		||||
            return renditions.requestContentDirectUrl(validatedNodeRef, null, renditionId, attachment, validFor, fileName);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return nodes.requestContentDirectUrl(validatedNodeRef, attachment, validFor);
 | 
			
		||||
            return nodes.requestContentDirectUrl(validatedNodeRef, attachment, validFor, fileName);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -25,13 +25,14 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.alfresco.rest.api.impl;
 | 
			
		||||
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ALLOWABLEOPERATIONS;
 | 
			
		||||
 | 
			
		||||
import java.util.AbstractList;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.LinkedList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
@@ -76,6 +77,7 @@ import org.alfresco.service.cmr.site.SiteService;
 | 
			
		||||
import org.alfresco.service.namespace.NamespaceService;
 | 
			
		||||
import org.alfresco.service.namespace.QName;
 | 
			
		||||
import org.alfresco.util.Pair;
 | 
			
		||||
import org.apache.commons.collections.CollectionUtils;
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
 | 
			
		||||
@@ -89,7 +91,9 @@ public class FavouritesImpl implements Favourites
 | 
			
		||||
{
 | 
			
		||||
    private static final Log logger = LogFactory.getLog(FavouritesImpl.class);
 | 
			
		||||
 | 
			
		||||
	private People people;
 | 
			
		||||
    private static final List<String> ALLOWED_INCLUDES = List.of(PARAM_INCLUDE_PROPERTIES, PARAM_INCLUDE_ALLOWABLEOPERATIONS);
 | 
			
		||||
 | 
			
		||||
    private People people;
 | 
			
		||||
	private Sites sites;
 | 
			
		||||
	private Nodes nodes;
 | 
			
		||||
	private FavouritesService favouritesService;
 | 
			
		||||
@@ -175,18 +179,23 @@ public class FavouritesImpl implements Favourites
 | 
			
		||||
		fav.setTarget(target);
 | 
			
		||||
 | 
			
		||||
		// REPO-1147 allow retrieving additional properties
 | 
			
		||||
        if (parameters.getInclude().contains(PARAM_INCLUDE_PROPERTIES))
 | 
			
		||||
        final List<String> paramsInclude = parameters.getInclude();
 | 
			
		||||
        if (!Collections.disjoint(paramsInclude, ALLOWED_INCLUDES))
 | 
			
		||||
        {
 | 
			
		||||
            List<String> includeProperties = new LinkedList<>();
 | 
			
		||||
            includeProperties.add(PARAM_INCLUDE_PROPERTIES);
 | 
			
		||||
            final List<String> includes = ALLOWED_INCLUDES.stream().filter(a -> paramsInclude.contains(a)).collect(Collectors.toList());
 | 
			
		||||
            // get node representation with only properties included
 | 
			
		||||
            Node node = nodes.getFolderOrDocument(personFavourite.getNodeRef(), null, null, includeProperties, null);
 | 
			
		||||
            Node node = nodes.getFolderOrDocument(personFavourite.getNodeRef(), null, null, includes, null);
 | 
			
		||||
            // Create a map from node properties excluding properties already in this Favorite
 | 
			
		||||
            Map<String, Object> filteredNodeProperties = filterProps(node.getProperties(), EXCLUDED_PROPS);
 | 
			
		||||
            if(filteredNodeProperties.size() > 0)
 | 
			
		||||
            if(filteredNodeProperties.size() > 0 && paramsInclude.contains(PARAM_INCLUDE_PROPERTIES))
 | 
			
		||||
            {
 | 
			
		||||
                fav.setProperties(filteredNodeProperties);
 | 
			
		||||
            }
 | 
			
		||||
            final List<String> allowableOperations = node.getAllowableOperations();
 | 
			
		||||
            if (CollectionUtils.isNotEmpty(allowableOperations) && paramsInclude.contains(PARAM_INCLUDE_ALLOWABLEOPERATIONS))
 | 
			
		||||
            {
 | 
			
		||||
                fav.setAllowableOperations(allowableOperations);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		return fav;
 | 
			
		||||
 
 | 
			
		||||
@@ -3443,9 +3443,9 @@ public class NodesImpl implements Nodes
 | 
			
		||||
     * {@inheritDoc}
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor)
 | 
			
		||||
    public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor, String fileName)
 | 
			
		||||
    {
 | 
			
		||||
        DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(nodeRef, ContentModel.PROP_CONTENT, attachment, validFor);
 | 
			
		||||
        DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(nodeRef, ContentModel.PROP_CONTENT, attachment, validFor, fileName);
 | 
			
		||||
        if (directAccessUrl == null)
 | 
			
		||||
        {
 | 
			
		||||
            throw new DisabledServiceException("Direct access url isn't available.");
 | 
			
		||||
 
 | 
			
		||||
@@ -512,7 +512,7 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
 | 
			
		||||
    /**
 | 
			
		||||
     * {@inheritDoc}
 | 
			
		||||
     */
 | 
			
		||||
    public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, String versionId, String renditionId, boolean attachment, Long validFor)
 | 
			
		||||
    public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, String versionId, String renditionId, boolean attachment, Long validFor, String fileName)
 | 
			
		||||
    {
 | 
			
		||||
        final NodeRef validatedNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId(), versionId, null);
 | 
			
		||||
        NodeRef renditionNodeRef = getRenditionByName(validatedNodeRef, renditionId, null);
 | 
			
		||||
@@ -522,7 +522,7 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
 | 
			
		||||
            throw new NotFoundException("The rendition with id: " + renditionId + " was not found.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return nodes.requestContentDirectUrl(renditionNodeRef, attachment, validFor);
 | 
			
		||||
        return nodes.requestContentDirectUrl(renditionNodeRef, attachment, validFor, fileName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private BinaryResource getContentImpl(NodeRef nodeRef, String renditionId, Parameters parameters)
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@ package org.alfresco.rest.api.model;
 | 
			
		||||
public class DirectAccessUrlRequest
 | 
			
		||||
{
 | 
			
		||||
    private Boolean attachment;
 | 
			
		||||
    private String fileName;
 | 
			
		||||
 | 
			
		||||
    public Boolean isAttachment()
 | 
			
		||||
    {
 | 
			
		||||
@@ -43,4 +44,14 @@ public class DirectAccessUrlRequest
 | 
			
		||||
    {
 | 
			
		||||
        this.attachment = attachment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getFileName()
 | 
			
		||||
    {
 | 
			
		||||
        return fileName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setFileName(String fileName)
 | 
			
		||||
    {
 | 
			
		||||
        this.fileName = fileName;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@
 | 
			
		||||
package org.alfresco.rest.api.model;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.rest.framework.resource.UniqueId;
 | 
			
		||||
@@ -42,6 +43,7 @@ public class Favourite
 | 
			
		||||
	private Date createdAt;
 | 
			
		||||
	private Target target;
 | 
			
		||||
	private Map<String, Object> properties;
 | 
			
		||||
	private List<String> allowableOperations;
 | 
			
		||||
 | 
			
		||||
	public Date getCreatedAt()
 | 
			
		||||
	{
 | 
			
		||||
@@ -84,10 +86,18 @@ public class Favourite
 | 
			
		||||
		this.properties = properties;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public List<String> getAllowableOperations() {
 | 
			
		||||
		return allowableOperations;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setAllowableOperations(List<String> allowableOperations) {
 | 
			
		||||
		this.allowableOperations = allowableOperations;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public String toString()
 | 
			
		||||
	{
 | 
			
		||||
		return "Favourite [targetGuid=" + targetGuid
 | 
			
		||||
				+ ", createdAt=" + createdAt + ", target=" + target + ", properties=" + properties + "]";
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -137,12 +137,13 @@ public class NodeRenditionsRelation implements RelationshipResourceAction.Read<R
 | 
			
		||||
    {
 | 
			
		||||
        boolean attachment = directAccessUrlHelper.getAttachment(directAccessUrlRequest);
 | 
			
		||||
        Long validFor = directAccessUrlHelper.getDefaultExpiryTimeInSec();
 | 
			
		||||
        String fileName = directAccessUrlHelper.getFileName(directAccessUrlRequest);
 | 
			
		||||
        NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
 | 
			
		||||
 | 
			
		||||
        DirectAccessUrl directAccessUrl;
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            directAccessUrl = renditions.requestContentDirectUrl(nodeRef, null, renditionId, attachment, validFor);
 | 
			
		||||
            directAccessUrl = renditions.requestContentDirectUrl(nodeRef, null, renditionId, attachment, validFor, fileName);
 | 
			
		||||
        }
 | 
			
		||||
        catch (DirectAccessUrlDisabledException ex)
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -149,13 +149,14 @@ public class NodeVersionRenditionsRelation implements RelationshipResourceAction
 | 
			
		||||
    {
 | 
			
		||||
        boolean attachment = directAccessUrlHelper.getAttachment(directAccessUrlRequest);
 | 
			
		||||
        Long validFor = directAccessUrlHelper.getDefaultExpiryTimeInSec();
 | 
			
		||||
        String fileName = directAccessUrlHelper.getFileName(directAccessUrlRequest);
 | 
			
		||||
        NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
 | 
			
		||||
        String renditionId = parameters.getRelationship2Id();
 | 
			
		||||
 | 
			
		||||
        DirectAccessUrl directAccessUrl;
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            directAccessUrl = renditions.requestContentDirectUrl(nodeRef, versionId, renditionId, attachment, validFor);
 | 
			
		||||
            directAccessUrl = renditions.requestContentDirectUrl(nodeRef, versionId, renditionId, attachment, validFor, fileName);
 | 
			
		||||
        }
 | 
			
		||||
        catch (DirectAccessUrlDisabledException ex)
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -311,6 +311,7 @@ public class NodeVersionsRelation extends AbstractNodeRelation implements
 | 
			
		||||
    {
 | 
			
		||||
        boolean attachment = directAccessUrlHelper.getAttachment(directAccessUrlRequest);
 | 
			
		||||
        Long validFor = directAccessUrlHelper.getDefaultExpiryTimeInSec();
 | 
			
		||||
        String fileName = directAccessUrlHelper.getFileName(directAccessUrlRequest);
 | 
			
		||||
        Version version = findVersion(nodeId, versionId);
 | 
			
		||||
        if (version != null)
 | 
			
		||||
        {
 | 
			
		||||
@@ -319,7 +320,7 @@ public class NodeVersionsRelation extends AbstractNodeRelation implements
 | 
			
		||||
            DirectAccessUrl directAccessUrl;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                directAccessUrl = nodes.requestContentDirectUrl(versionNodeRef, attachment, validFor);
 | 
			
		||||
                directAccessUrl = nodes.requestContentDirectUrl(versionNodeRef, attachment, validFor, fileName);
 | 
			
		||||
            }
 | 
			
		||||
            catch (DirectAccessUrlDisabledException ex)
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -211,12 +211,13 @@ public class NodesEntityResource implements
 | 
			
		||||
    {
 | 
			
		||||
        boolean attachment = directAccessUrlHelper.getAttachment(directAccessUrlRequest);
 | 
			
		||||
        Long validFor = directAccessUrlHelper.getDefaultExpiryTimeInSec();
 | 
			
		||||
        String fileName = directAccessUrlHelper.getFileName(directAccessUrlRequest);
 | 
			
		||||
        NodeRef nodeRef = nodes.validateNode(nodeId);
 | 
			
		||||
 | 
			
		||||
        DirectAccessUrl directAccessUrl;
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            directAccessUrl = nodes.requestContentDirectUrl(nodeRef, attachment, validFor);
 | 
			
		||||
            directAccessUrl = nodes.requestContentDirectUrl(nodeRef, attachment, validFor, fileName);
 | 
			
		||||
        }
 | 
			
		||||
        catch (DirectAccessUrlDisabledException ex)
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,7 @@ import static java.util.stream.Collectors.toList;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ALLOWABLEOPERATIONS;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ASPECTNAMES;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ASSOCIATION;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ISFAVORITE;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ISLINK;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ISLOCKED;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_PATH;
 | 
			
		||||
@@ -96,10 +97,9 @@ import java.util.stream.Collectors;
 | 
			
		||||
 */
 | 
			
		||||
public class SearchMapper
 | 
			
		||||
{
 | 
			
		||||
    public static final List<String> PERMITTED_INCLUDES
 | 
			
		||||
                = Arrays.asList(PARAM_INCLUDE_ALLOWABLEOPERATIONS,PARAM_INCLUDE_ASPECTNAMES,
 | 
			
		||||
                                PARAM_INCLUDE_ISLINK, PARAM_INCLUDE_PATH, PARAM_INCLUDE_PROPERTIES,
 | 
			
		||||
                                PARAM_INCLUDE_ASSOCIATION, PARAM_INCLUDE_ISLOCKED, PARAM_INCLUDE_PERMISSIONS);
 | 
			
		||||
    public static final List<String> PERMITTED_INCLUDES = Arrays.asList(PARAM_INCLUDE_ALLOWABLEOPERATIONS,PARAM_INCLUDE_ASPECTNAMES,
 | 
			
		||||
                                PARAM_INCLUDE_ISLINK, PARAM_INCLUDE_PATH, PARAM_INCLUDE_PROPERTIES, PARAM_INCLUDE_ASSOCIATION,
 | 
			
		||||
                                PARAM_INCLUDE_ISLOCKED, PARAM_INCLUDE_PERMISSIONS, PARAM_INCLUDE_ISFAVORITE);
 | 
			
		||||
 | 
			
		||||
    public static final String CMIS = "cmis";
 | 
			
		||||
    public static final String LUCENE = "lucene";
 | 
			
		||||
 
 | 
			
		||||
@@ -109,10 +109,11 @@ public class TrashcanEntityResource implements
 | 
			
		||||
    {
 | 
			
		||||
        boolean attachment = directAccessUrlHelper.getAttachment(directAccessUrlRequest);
 | 
			
		||||
        Long validFor = directAccessUrlHelper.getDefaultExpiryTimeInSec();
 | 
			
		||||
        String fileName = directAccessUrlHelper.getFileName(directAccessUrlRequest);
 | 
			
		||||
        DirectAccessUrl directAccessUrl;
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            directAccessUrl = deletedNodes.requestContentDirectUrl(originalNodeId, null, attachment, validFor);
 | 
			
		||||
            directAccessUrl = deletedNodes.requestContentDirectUrl(originalNodeId, null, attachment, validFor, fileName);
 | 
			
		||||
        }
 | 
			
		||||
        catch (DirectAccessUrlDisabledException ex)
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -98,10 +98,11 @@ public class TrashcanRenditionsRelation
 | 
			
		||||
    {
 | 
			
		||||
        boolean attachment = directAccessUrlHelper.getAttachment(directAccessUrlRequest);
 | 
			
		||||
        Long validFor = directAccessUrlHelper.getDefaultExpiryTimeInSec();
 | 
			
		||||
        String fileName = directAccessUrlHelper.getFileName(directAccessUrlRequest);
 | 
			
		||||
        DirectAccessUrl directAccessUrl;
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            directAccessUrl = deletedNodes.requestContentDirectUrl(originalNodeId, renditionId, attachment, validFor);
 | 
			
		||||
            directAccessUrl = deletedNodes.requestContentDirectUrl(originalNodeId, renditionId, attachment, validFor, fileName);
 | 
			
		||||
        }
 | 
			
		||||
        catch (DirectAccessUrlDisabledException ex)
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,7 @@ import static junit.framework.TestCase.fail;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ALLOWABLEOPERATIONS;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ASPECTNAMES;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ASSOCIATION;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ISFAVORITE;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ISLINK;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_ISLOCKED;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PARAM_INCLUDE_PATH;
 | 
			
		||||
@@ -300,7 +301,7 @@ public class SearchMapperTests
 | 
			
		||||
    {
 | 
			
		||||
        searchMapper.validateInclude(Arrays.asList(PARAM_INCLUDE_ALLOWABLEOPERATIONS,PARAM_INCLUDE_ASPECTNAMES,
 | 
			
		||||
                PARAM_INCLUDE_ISLINK, PARAM_INCLUDE_PATH, PARAM_INCLUDE_PROPERTIES,
 | 
			
		||||
                PARAM_INCLUDE_ASSOCIATION, PARAM_INCLUDE_ISLOCKED, PARAM_INCLUDE_PERMISSIONS));
 | 
			
		||||
                PARAM_INCLUDE_ASSOCIATION, PARAM_INCLUDE_ISLOCKED, PARAM_INCLUDE_PERMISSIONS, PARAM_INCLUDE_ISFAVORITE));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>23.1.0.165</version>
 | 
			
		||||
        <version>23.1.0.167-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <dependencies>
 | 
			
		||||
 
 | 
			
		||||
@@ -65,6 +65,7 @@ import org.alfresco.service.cmr.usage.ContentQuotaException;
 | 
			
		||||
import org.alfresco.service.namespace.QName;
 | 
			
		||||
import org.alfresco.util.EqualsHelper;
 | 
			
		||||
import org.alfresco.util.TempFileProvider;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
import org.springframework.beans.BeansException;
 | 
			
		||||
@@ -627,7 +628,7 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
 | 
			
		||||
     * {@inheritDoc}
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, QName propertyQName, boolean attachment, Long validFor)
 | 
			
		||||
    public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, QName propertyQName, boolean attachment, Long validFor, String fileNameOverride)
 | 
			
		||||
    {
 | 
			
		||||
        if (!systemWideDirectUrlConfig.isEnabled())
 | 
			
		||||
        {
 | 
			
		||||
@@ -643,7 +644,7 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
 | 
			
		||||
 | 
			
		||||
        String contentUrl = contentData.getContentUrl();
 | 
			
		||||
        String contentMimetype = contentData.getMimetype();
 | 
			
		||||
        String fileName = getFileName(nodeRef);
 | 
			
		||||
        String fileName = StringUtils.isEmpty(fileNameOverride) ? getFileName(nodeRef) : fileNameOverride;
 | 
			
		||||
 | 
			
		||||
        validFor = adjustValidFor(validFor);
 | 
			
		||||
        attachment = adjustAttachment(nodeRef, contentMimetype, attachment);
 | 
			
		||||
@@ -654,6 +655,9 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                directAccessUrl = store.requestContentDirectUrl(contentUrl, attachment, fileName, contentMimetype, validFor);
 | 
			
		||||
                if (directAccessUrl != null) {
 | 
			
		||||
                    directAccessUrl.setFileName(fileName);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (UnsupportedOperationException ex)
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -368,7 +368,10 @@ public class DocumentLinkServiceImpl implements DocumentLinkService, NodeService
 | 
			
		||||
    public void beforeDeleteLinkNode(NodeRef linkNodeRef)
 | 
			
		||||
    {
 | 
			
		||||
        final NodeRef nodeRef = getLinkDestination(linkNodeRef);
 | 
			
		||||
 | 
			
		||||
        if (nodeRef == null)
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        List<Long> nodeRefLinks = getNodeLinksIds(nodeRef);
 | 
			
		||||
 | 
			
		||||
        long linkNodeId = (Long) nodeService.getProperty(linkNodeRef, ContentModel.PROP_NODE_DBID);
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Repository
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2022 Alfresco Software Limited
 | 
			
		||||
 * Copyright (C) 2005 - 2023 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software. 
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of 
 | 
			
		||||
@@ -26,8 +26,8 @@
 | 
			
		||||
 | 
			
		||||
package org.alfresco.repo.virtual.bundle;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.io.UncheckedIOException;
 | 
			
		||||
import java.nio.charset.StandardCharsets;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
@@ -910,7 +910,7 @@ public class VirtualNodeServiceExtension extends VirtualSpringBeanExtension<Node
 | 
			
		||||
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
        catch (IOException e)
 | 
			
		||||
        catch (UncheckedIOException e)
 | 
			
		||||
        {
 | 
			
		||||
            throw new VirtualizationException(e);
 | 
			
		||||
        }
 | 
			
		||||
@@ -968,7 +968,7 @@ public class VirtualNodeServiceExtension extends VirtualSpringBeanExtension<Node
 | 
			
		||||
                }
 | 
			
		||||
                writer.putContent(text);
 | 
			
		||||
            }
 | 
			
		||||
            catch (IOException e)
 | 
			
		||||
            catch (UncheckedIOException e)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ActualEnvironmentException(e);
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -245,7 +245,25 @@ public interface ContentService
 | 
			
		||||
     * @throws UnsupportedOperationException if the store is unable to provide the information.
 | 
			
		||||
     */
 | 
			
		||||
    @Auditable(parameters = {"nodeRef", "propertyQName", "validFor"})
 | 
			
		||||
    DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, QName propertyQName, boolean attachment, Long validFor);
 | 
			
		||||
    default DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, QName propertyQName, boolean attachment, Long validFor)
 | 
			
		||||
    {
 | 
			
		||||
        return requestContentDirectUrl(nodeRef, propertyQName, attachment, validFor, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets a presigned URL to directly access the content. It is up to the actual store
 | 
			
		||||
     * implementation if it can fulfil this request with an expiry time or not.
 | 
			
		||||
     *
 | 
			
		||||
     * @param nodeRef Node ref for which to obtain the direct access {@code URL}.
 | 
			
		||||
     * @param propertyQName the name of the property, which must be of type <b>content</b>
 | 
			
		||||
     * @param attachment {@code true} if an attachment URL is requested, {@code false} for an embedded {@code URL}.
 | 
			
		||||
     * @param validFor The time at which the direct access {@code URL} will expire.
 | 
			
		||||
     * @param fileName Optional name for the file when downloaded
 | 
			
		||||
     * @return A direct access {@code URL} object for the content.
 | 
			
		||||
     * @throws UnsupportedOperationException if the store is unable to provide the information.
 | 
			
		||||
     */
 | 
			
		||||
    @Auditable(parameters = {"nodeRef", "propertyQName", "validFor"})
 | 
			
		||||
    DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, QName propertyQName, boolean attachment, Long validFor, String fileName);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets a key-value (String-String) collection of storage headers/properties with their respective values for a specific node reference.
 | 
			
		||||
 
 | 
			
		||||
@@ -72,7 +72,8 @@ public class ContentServiceImplUnitTest
 | 
			
		||||
 | 
			
		||||
    private static final NodeRef NODE_REF = new NodeRef("content://Node/Ref");
 | 
			
		||||
    public static final String SOME_CONTENT_URL = "someContentUrl";
 | 
			
		||||
    private static final NodeRef NODE_REF_2 = new NodeRef("content://Node/Ref2");;
 | 
			
		||||
    private static final NodeRef NODE_REF_2 = new NodeRef("content://Node/Ref2");
 | 
			
		||||
    public static final String SOME_FILE_NAME = "someFilename";
 | 
			
		||||
 | 
			
		||||
    private static final String X_AMZ_HEADER_1 = "x-amz-header1";
 | 
			
		||||
    private static final String VALUE_1 = "value1";
 | 
			
		||||
@@ -103,7 +104,7 @@ public class ContentServiceImplUnitTest
 | 
			
		||||
        when(mockNodeService.getProperty(NODE_REF, ContentModel.PROP_CONTENT)).thenReturn(mockContentData);
 | 
			
		||||
        when(mockContentData.getContentUrl()).thenReturn(SOME_CONTENT_URL);
 | 
			
		||||
        when(mockContentData.getMimetype()).thenReturn("someMimetype");
 | 
			
		||||
        when(mockNodeService.getProperty(NODE_REF, ContentModel.PROP_NAME)).thenReturn("someFilename");
 | 
			
		||||
        when(mockNodeService.getProperty(NODE_REF, ContentModel.PROP_NAME)).thenReturn(SOME_FILE_NAME);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
@@ -162,6 +163,52 @@ public class ContentServiceImplUnitTest
 | 
			
		||||
        verify(mockContentStore, times(1)).requestContentDirectUrl(anyString(), eq(true), anyString(), anyString(), anyLong());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testRequestContentDirectUrl_StoreRequestContentDirectUrlIsCalledWithFileNameOverride()
 | 
			
		||||
    {
 | 
			
		||||
        DirectAccessUrl mockDirectAccessUrl = new DirectAccessUrl();
 | 
			
		||||
        mockDirectAccessUrl.setAttachment(true);
 | 
			
		||||
        mockDirectAccessUrl.setContentUrl(SOME_CONTENT_URL);
 | 
			
		||||
        final String fileNameOverride = "fileNameOverride.txt";
 | 
			
		||||
        setupSystemWideDirectAccessConfig(ENABLED);
 | 
			
		||||
        when(mockContentStore.isContentDirectUrlEnabled()).thenReturn(ENABLED);
 | 
			
		||||
        when(mockContentStore.requestContentDirectUrl(anyString(), eq(true), eq(fileNameOverride), anyString(), anyLong())).thenReturn(mockDirectAccessUrl);
 | 
			
		||||
 | 
			
		||||
        DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(NODE_REF, PROP_CONTENT_QNAME, true, 20L, fileNameOverride);
 | 
			
		||||
        assertEquals("fileName was not set properly on the DirectAccessUrl response", fileNameOverride, directAccessUrl.getFileName());
 | 
			
		||||
        verify(mockContentStore, times(1)).requestContentDirectUrl(anyString(), eq(true), eq(fileNameOverride), anyString(), anyLong());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testRequestContentDirectUrl_StoreRequestContentDirectUrlIsCalledWithNodeNamePropertyWhenFileNameOverrideIsNull()
 | 
			
		||||
    {
 | 
			
		||||
        DirectAccessUrl mockDirectAccessUrl = new DirectAccessUrl();
 | 
			
		||||
        mockDirectAccessUrl.setAttachment(true);
 | 
			
		||||
        mockDirectAccessUrl.setContentUrl(SOME_CONTENT_URL);
 | 
			
		||||
        setupSystemWideDirectAccessConfig(ENABLED);
 | 
			
		||||
        when(mockContentStore.isContentDirectUrlEnabled()).thenReturn(ENABLED);
 | 
			
		||||
        when(mockContentStore.requestContentDirectUrl(anyString(), eq(true), eq(SOME_FILE_NAME), anyString(), anyLong())).thenReturn(mockDirectAccessUrl);
 | 
			
		||||
 | 
			
		||||
        DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(NODE_REF, PROP_CONTENT_QNAME, true, 20L, null);
 | 
			
		||||
        assertEquals("fileName was not set properly on the DirectAccessUrl response", SOME_FILE_NAME, directAccessUrl.getFileName());
 | 
			
		||||
        verify(mockContentStore, times(1)).requestContentDirectUrl(anyString(), eq(true), eq(SOME_FILE_NAME), anyString(), anyLong());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testRequestContentDirectUrl_StoreRequestContentDirectUrlIsCalledWithNodeNamePropertyWhenFileNameOverrideIsEmpty()
 | 
			
		||||
    {
 | 
			
		||||
        DirectAccessUrl mockDirectAccessUrl = new DirectAccessUrl();
 | 
			
		||||
        mockDirectAccessUrl.setAttachment(true);
 | 
			
		||||
        mockDirectAccessUrl.setContentUrl(SOME_CONTENT_URL);
 | 
			
		||||
        setupSystemWideDirectAccessConfig(ENABLED);
 | 
			
		||||
        when(mockContentStore.isContentDirectUrlEnabled()).thenReturn(ENABLED);
 | 
			
		||||
        when(mockContentStore.requestContentDirectUrl(anyString(), eq(true), eq(SOME_FILE_NAME), anyString(), anyLong())).thenReturn(mockDirectAccessUrl);
 | 
			
		||||
 | 
			
		||||
        DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(NODE_REF, PROP_CONTENT_QNAME, true, 20L, "");
 | 
			
		||||
        assertEquals("fileName was not set properly on the DirectAccessUrl response", SOME_FILE_NAME, directAccessUrl.getFileName());
 | 
			
		||||
        verify(mockContentStore, times(1)).requestContentDirectUrl(anyString(), eq(true), eq(SOME_FILE_NAME), anyString(), anyLong());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void shouldReturnStoragePropertiesWhenTheyExist()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user