Merged 5.2.0 (5.2.0) to HEAD (5.2)

133219 jkaabimofrad: Merged WEBAPP-API (5.2.1) to 5.2.N (5.2.1)
      133145 jkaabimofrad: APPSREPO-54: Added support to the quick-share V1 API to allow setting an optional expiry date when creating a shared link.
                 - Also, fixed the overloaded shareContent method which was missed during code clean-up.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@133404 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Alan Davis
2016-12-06 17:22:36 +00:00
parent 8edcef3a38
commit 3bebc4d444
3 changed files with 159 additions and 6 deletions

View File

@@ -29,6 +29,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.model.QuickShareModel; import org.alfresco.model.QuickShareModel;
import org.alfresco.query.PagingRequest; import org.alfresco.query.PagingRequest;
import org.alfresco.repo.quickshare.QuickShareClientNotFoundException; import org.alfresco.repo.quickshare.QuickShareClientNotFoundException;
import org.alfresco.repo.quickshare.QuickShareLinkExpiryActionException;
import org.alfresco.repo.quickshare.QuickShareServiceImpl.QuickShareEmailRequest; import org.alfresco.repo.quickshare.QuickShareServiceImpl.QuickShareEmailRequest;
import org.alfresco.repo.search.QueryParameterDefImpl; import org.alfresco.repo.search.QueryParameterDefImpl;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
@@ -329,13 +330,17 @@ public class QuickShareLinksImpl implements QuickShareLinks, RecognizedParamsExt
// Note: since we already check node exists above, we can assume that InvalidNodeRefException (=> 404) here means not content (see type check) // Note: since we already check node exists above, we can assume that InvalidNodeRefException (=> 404) here means not content (see type check)
try try
{ {
QuickShareDTO qsDto = quickShareService.shareContent(nodeRef); QuickShareDTO qsDto = quickShareService.shareContent(nodeRef, qs.getExpiresAt());
result.add(getQuickShareInfo(qsDto.getId(), false, includeParam)); result.add(getQuickShareInfo(qsDto.getId(), false, includeParam));
} }
catch (InvalidNodeRefException inre) catch (InvalidNodeRefException inre)
{ {
throw new InvalidArgumentException("Unable to create shared link to non-file content: " + nodeId); throw new InvalidArgumentException("Unable to create shared link to non-file content: " + nodeId);
} }
catch (QuickShareLinkExpiryActionException ex)
{
throw new InvalidArgumentException(ex.getMessage());
}
} }
catch (AccessDeniedException ade) catch (AccessDeniedException ade)
{ {
@@ -576,6 +581,7 @@ public class QuickShareLinksImpl implements QuickShareLinks, RecognizedParamsExt
qs.setModifiedAt((Date) map.get("modified")); qs.setModifiedAt((Date) map.get("modified"));
qs.setModifiedByUser(modifiedByUser); qs.setModifiedByUser(modifiedByUser);
qs.setSharedByUser(sharedByUser); qs.setSharedByUser(sharedByUser);
qs.setExpiresAt((Date) map.get("expiryDate"));
// note: if noAuth mode then do not return allowable operations (eg. but can be optionally returned when finding shared links) // note: if noAuth mode then do not return allowable operations (eg. but can be optionally returned when finding shared links)
if ((! noAuth) && includeParam.contains(PARAM_INCLUDE_ALLOWABLEOPERATIONS)) if ((! noAuth) && includeParam.contains(PARAM_INCLUDE_ALLOWABLEOPERATIONS))

View File

@@ -48,6 +48,8 @@ public class QuickShareLink
// unique short id (ie. shorter than a guid, 22 vs 36 chars) // unique short id (ie. shorter than a guid, 22 vs 36 chars)
private String sharedId; private String sharedId;
private Date expiresAt;
private String nodeId; private String nodeId;
private String name; private String name;
@@ -79,7 +81,17 @@ public class QuickShareLink
this.sharedId = sharedId; this.sharedId = sharedId;
} }
public String getNodeId() { public Date getExpiresAt()
{
return expiresAt;
}
public void setExpiresAt(Date expiresAt)
{
this.expiresAt = expiresAt;
}
public String getNodeId() {
return nodeId; return nodeId;
} }
@@ -160,6 +172,7 @@ public class QuickShareLink
sb.append(", sharedByUser=").append(getSharedByUser()); sb.append(", sharedByUser=").append(getSharedByUser());
sb.append(", content=").append(getContent()); sb.append(", content=").append(getContent());
sb.append(", allowableOperations=").append(getAllowableOperations()); sb.append(", allowableOperations=").append(getAllowableOperations());
sb.append(", expiresAt=").append(getExpiresAt());
sb.append("]"); sb.append("]");
return sb.toString(); return sb.toString();
} }

View File

@@ -25,7 +25,15 @@
*/ */
package org.alfresco.rest.api.tests; package org.alfresco.rest.api.tests;
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsStringNonNull;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.quickshare.QuickShareLinkExpiryActionImpl;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.rest.api.People; import org.alfresco.rest.api.People;
import org.alfresco.rest.api.QuickShareLinks; import org.alfresco.rest.api.QuickShareLinks;
import org.alfresco.rest.api.impl.QuickShareLinksImpl; import org.alfresco.rest.api.impl.QuickShareLinksImpl;
@@ -41,6 +49,11 @@ import org.alfresco.rest.api.tests.client.data.Rendition;
import org.alfresco.rest.api.tests.client.data.UserInfo; import org.alfresco.rest.api.tests.client.data.UserInfo;
import org.alfresco.rest.api.tests.util.MultiPartBuilder; import org.alfresco.rest.api.tests.util.MultiPartBuilder;
import org.alfresco.rest.api.tests.util.RestApiUtil; import org.alfresco.rest.api.tests.util.RestApiUtil;
import org.alfresco.service.cmr.action.scheduled.ScheduledPersistedActionService;
import org.alfresco.service.cmr.quickshare.QuickShareLinkExpiryAction;
import org.alfresco.service.cmr.quickshare.QuickShareLinkExpiryActionPersister;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.io.File; import java.io.File;
@@ -54,9 +67,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsStringNonNull;
import static org.junit.Assert.*;
/** /**
* V1 REST API tests for Shared Links (aka public "quick shares") * V1 REST API tests for Shared Links (aka public "quick shares")
* *
@@ -70,7 +80,18 @@ import static org.junit.Assert.*;
public class SharedLinkApiTest extends AbstractBaseApiTest public class SharedLinkApiTest extends AbstractBaseApiTest
{ {
private static final String URL_SHARED_LINKS = "shared-links"; private static final String URL_SHARED_LINKS = "shared-links";
private QuickShareLinkExpiryActionPersister quickShareLinkExpiryActionPersister;
private ScheduledPersistedActionService scheduledPersistedActionService;
@Before
public void setup() throws Exception
{
super.setup();
quickShareLinkExpiryActionPersister = applicationContext.getBean("quickShareLinkExpiryActionPersister", QuickShareLinkExpiryActionPersister.class);
scheduledPersistedActionService = applicationContext.getBean("scheduledPersistedActionService", ScheduledPersistedActionService.class);
}
/** /**
* Tests shared links to file (content) * Tests shared links to file (content)
* *
@@ -854,6 +875,94 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
deleteSharedLink(shared1Id); deleteSharedLink(shared1Id);
} }
/**
* Tests shared links to file with expiry date.
* <p>POST:</p>
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/shared-links}
*/
@Test
public void testSharedLinkWithExpiryDate() throws Exception
{
final int numOfSchedules = getSchedules();
setRequestContext(user1);
// Create plain text document
String myFolderNodeId = getMyNodeId();
String contentText = "The quick brown fox jumps over the lazy dog.";
String fileName = "file-" + RUNID + ".txt";
String docId = createTextFile(myFolderNodeId, fileName, contentText).getId();
// Create shared link to document
QuickShareLink body = new QuickShareLink();
body.setNodeId(docId);
// Invalid time - passed time
body.setExpiresAt(DateTime.now().minusSeconds(20).toDate());
post(URL_SHARED_LINKS, RestApiUtil.toJsonAsString(body), 400);
// The default expiryDate period is DAYS (see: 'system.quickshare.expiry_date.enforce.period' property),
// so the expiry date must be at least 1 day from now
body.setExpiresAt(DateTime.now().plusMinutes(5).toDate());
post(URL_SHARED_LINKS, RestApiUtil.toJsonAsString(body), 400);
// Set the expiry date to be in the next 2 days
Date time = DateTime.now().plusDays(2).toDate();
body.setExpiresAt(time);
// Post the share request
HttpResponse response = post(URL_SHARED_LINKS, RestApiUtil.toJsonAsString(body), 201);
QuickShareLink resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class);
assertNotNull(resp.getId());
assertEquals(fileName, resp.getName());
assertEquals(time, resp.getExpiresAt());
// Check that the schedule is persisted
// Note: No need to check for expiry actions here, as the scheduledPersistedActionService
// checks that the expiry action is persisted first and if it wasn't will throw an exception.
assertEquals(numOfSchedules + 1, getSchedules());
// Delete the shared link
deleteSharedLink(resp.getId());
// Check the shred link has been deleted
getSingle(QuickShareLinkEntityResource.class, resp.getId(), null, 404);
// As we deleted the shared link, the expiry action and its related schedule should have been removed as well.
// Check that the schedule is deleted
assertEquals(numOfSchedules, getSchedules());
// Set the expiry date to be in the next 24 hours
time = DateTime.now().plusDays(1).toDate();
body.setExpiresAt(time);
// Post the share request
response = post(URL_SHARED_LINKS, RestApiUtil.toJsonAsString(body), 201);
resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class);
assertNotNull(resp.getId());
// Check that the schedule is persisted
assertEquals(numOfSchedules + 1, getSchedules());
// Get the shared link info
response = getSingle(QuickShareLinkEntityResource.class, resp.getId(), null, 200);
resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class);
assertEquals(fileName, resp.getName());
assertEquals(time, resp.getExpiresAt());
// Change the expiry time to be in the next 6 seconds.
// Here we'll bypass the QuickShareService in order to force the new time.
// As the QuickShareService by default will enforce the expiry date to not be less than 24 hours.
forceNewExpiryTime(resp.getId(), DateTime.now().plusSeconds(6).toDate());
// Wait for 10 seconds - the expiry action should be triggered in the next 6 seconds.
Thread.sleep((10000));
// Check that the expiry action unshared the link
getSingle(QuickShareLinkEntityResource.class, resp.getId(), null, 404);
// The expiry action and its related schedule should have been removed after the link unshared by the action executor.
// Check that the schedule is deleted
assertEquals(numOfSchedules, getSchedules());
// Create a shared link without an expiry date
body.setExpiresAt(null);
response = post(URL_SHARED_LINKS, RestApiUtil.toJsonAsString(body), 201);
resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class);
assertNotNull(resp.getId());
assertNull("The 'expiryDate' property should have benn null.", resp.getExpiresAt());
assertEquals(numOfSchedules, getSchedules());
// Delete the share link that hasn't got an expiry date
deleteSharedLink(resp.getId());
}
@Override @Override
public String getScope() public String getScope()
{ {
@@ -874,4 +983,29 @@ public class SharedLinkApiTest extends AbstractBaseApiTest
{ {
delete(URL_SHARED_LINKS, sharedId, expectedStatus); delete(URL_SHARED_LINKS, sharedId, expectedStatus);
} }
private void forceNewExpiryTime(String sharedId, Date date)
{
TenantUtil.runAsSystemTenant(() -> {
// Load the expiry action and attach the schedule
QuickShareLinkExpiryAction linkExpiryAction = quickShareLinkExpiryActionPersister
.loadQuickShareLinkExpiryAction(QuickShareLinkExpiryActionImpl.createQName(sharedId));
linkExpiryAction.setSchedule(scheduledPersistedActionService.getSchedule(linkExpiryAction));
linkExpiryAction.setScheduleStart(date);
// save the expiry action and the schedule
transactionHelper.doInTransaction(() -> {
quickShareLinkExpiryActionPersister.saveQuickShareLinkExpiryAction(linkExpiryAction);
scheduledPersistedActionService.saveSchedule(linkExpiryAction.getSchedule());
return null;
});
return null;
}, TenantUtil.getCurrentDomain());
}
private int getSchedules()
{
return TenantUtil.runAsSystemTenant(() -> scheduledPersistedActionService.listSchedules().size(), TenantUtil.getCurrentDomain());
}
} }