diff --git a/source/java/org/alfresco/rest/api/QuickShareLinks.java b/source/java/org/alfresco/rest/api/QuickShareLinks.java index 9375f9e056..2d8a271296 100644 --- a/source/java/org/alfresco/rest/api/QuickShareLinks.java +++ b/source/java/org/alfresco/rest/api/QuickShareLinks.java @@ -22,6 +22,7 @@ import org.alfresco.rest.api.model.QuickShareLink; import org.alfresco.rest.api.model.QuickShareLinkEmailRequest; import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; 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 java.util.List; @@ -86,4 +87,12 @@ public interface QuickShareLinks * @param parameters The {@link Parameters} object to get the parameters passed into the request */ void emailSharedLink(String nodeId, QuickShareLinkEmailRequest emailRequest, Parameters parameters); + + /** + * Find (search) for shared links visible to current user + * + * @param parameters + * @return + */ + CollectionWithPagingInfo findLinks(Parameters parameters); } \ No newline at end of file diff --git a/source/java/org/alfresco/rest/api/impl/QuickShareLinksImpl.java b/source/java/org/alfresco/rest/api/impl/QuickShareLinksImpl.java index 2fb1b1a57e..9fc27d1bf4 100644 --- a/source/java/org/alfresco/rest/api/impl/QuickShareLinksImpl.java +++ b/source/java/org/alfresco/rest/api/impl/QuickShareLinksImpl.java @@ -20,6 +20,7 @@ package org.alfresco.rest.api.impl; import org.alfresco.model.ContentModel; import org.alfresco.model.QuickShareModel; +import org.alfresco.query.PagingRequest; import org.alfresco.repo.quickshare.QuickShareServiceImpl.QuickShareEmailRequest; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.permissions.AccessDeniedException; @@ -33,9 +34,10 @@ import org.alfresco.rest.api.model.UserInfo; import org.alfresco.rest.framework.core.exceptions.DisabledServiceException; import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; -import org.alfresco.rest.framework.core.exceptions.NotFoundException; import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException; import org.alfresco.rest.framework.resource.content.BinaryResource; +import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; +import org.alfresco.rest.framework.resource.parameters.Paging; import org.alfresco.rest.framework.resource.parameters.Parameters; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.quickshare.InvalidSharedIdException; @@ -47,6 +49,10 @@ import org.alfresco.service.cmr.repository.MimetypeService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.cmr.search.ResultSetRow; +import org.alfresco.service.cmr.search.SearchParameters; +import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.namespace.QName; @@ -85,6 +91,7 @@ public class QuickShareLinksImpl implements QuickShareLinks, InitializingBean private PersonService personService; private AuthorityService authorityService; private MimetypeService mimeTypeService; + private SearchService searchService; public void setServiceRegistry(ServiceRegistry sr) { @@ -118,6 +125,7 @@ public class QuickShareLinksImpl implements QuickShareLinks, InitializingBean this.personService = sr.getPersonService(); this.authorityService = sr.getAuthorityService(); this.mimeTypeService = sr.getMimetypeService(); + this.searchService = sr.getSearchService(); } /** @@ -337,16 +345,74 @@ public class QuickShareLinksImpl implements QuickShareLinks, InitializingBean } } + // Helper find (search) method + + public CollectionWithPagingInfo findLinks(Parameters parameters) + { + checkEnabled(); + + /* + String currentUser = AuthenticationUtil.getFullyAuthenticatedUser(); + + String queryString = + "ASPECT:\"" + QuickShareModel.ASPECT_QSHARE.toString() + + "\" +@\\{http\\://www.alfresco.org/model/content/1.0\\}" + QuickShareModel.PROP_QSHARE_SHAREDBY.getLocalName() + ":\"" + currentUser + "\""; + */ + + String queryString = + "ASPECT:\"" + QuickShareModel.ASPECT_QSHARE.toString() + "\""; + + SearchParameters sp = new SearchParameters(); + sp.setLanguage(SearchService.LANGUAGE_LUCENE); + sp.setQuery(queryString); + sp.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE); + + Paging paging = parameters.getPaging(); + PagingRequest pagingRequest = Util.getPagingRequest(paging); + + sp.setSkipCount(pagingRequest.getSkipCount()); + sp.setMaxItems(pagingRequest.getMaxItems()); + + // TODO is perf ok with Solr 4 paging/sorting ? (otherwise make this optional via orderBy and leave default sort as undefined) + sp.addSort("@" + ContentModel.PROP_MODIFIED, false); + + ResultSet results = searchService.query(sp); + + List qsLinks = new ArrayList<>(results.length()); + + for (ResultSetRow row : results) + { + NodeRef nodeRef = row.getNodeRef(); + qsLinks.add(getQuickShareInfo(nodeRef, false)); + } + + results.close(); + + return CollectionWithPagingInfo.asPaged(paging, qsLinks, results.hasMore(), new Long(results.getNumberFound()).intValue()); + } + private QuickShareLink getQuickShareInfo(String sharedId, boolean noAuth) { checkValidShareId(sharedId); + Map map = (Map) quickShareService.getMetaData(sharedId).get("item"); + NodeRef nodeRef = new NodeRef((String) map.get("nodeRef")); + + return getQuickShareInfo(nodeRef, map, noAuth); + } + + private QuickShareLink getQuickShareInfo(NodeRef nodeRef, boolean noAuth) + { + Map map = (Map) quickShareService.getMetaData(nodeRef).get("item"); + return getQuickShareInfo(nodeRef, map , noAuth); + } + + private QuickShareLink getQuickShareInfo(NodeRef nodeRef, Map map, boolean noAuth) + { + String sharedId = (String)map.get("sharedId"); + try { - Map map = (Map)quickShareService.getMetaData(sharedId).get("item"); - - NodeRef nodeRef = new NodeRef((String) map.get("nodeRef")); - Map nodeProps = nodeService.getProperties(nodeRef); ContentData cd = (ContentData)nodeProps.get(ContentModel.PROP_CONTENT); diff --git a/source/java/org/alfresco/rest/api/quicksharelinks/QuickShareLinkEntityResource.java b/source/java/org/alfresco/rest/api/quicksharelinks/QuickShareLinkEntityResource.java index b5d0957d68..c37911efa0 100644 --- a/source/java/org/alfresco/rest/api/quicksharelinks/QuickShareLinkEntityResource.java +++ b/source/java/org/alfresco/rest/api/quicksharelinks/QuickShareLinkEntityResource.java @@ -30,6 +30,7 @@ import org.alfresco.rest.framework.resource.EntityResource; import org.alfresco.rest.framework.resource.actions.interfaces.BinaryResourceAction; import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction; 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.util.ParameterCheck; import org.springframework.beans.factory.InitializingBean; @@ -44,8 +45,11 @@ import java.util.List; */ @EntityResource(name="shared-links", title = "Shared Links") public class QuickShareLinkEntityResource implements EntityResourceAction.ReadById, - BinaryResourceAction.Read, EntityResourceAction.Delete, - EntityResourceAction.Create, InitializingBean + BinaryResourceAction.Read, + EntityResourceAction.Delete, + EntityResourceAction.Create, + EntityResourceAction.Read, + InitializingBean { private QuickShareLinks quickShareLinks; @@ -131,4 +135,16 @@ public class QuickShareLinkEntityResource implements EntityResourceAction.ReadBy { quickShareLinks.emailSharedLink(nodeId, emailRequest, parameters); } + + /** + * Find shared links + * + */ + @Override + @WebApiDescription(title="Find shared links", description = "Find ('search') & return result set of shared links") + public CollectionWithPagingInfo readAll(Parameters parameters) + { + return quickShareLinks.findLinks(parameters); + } + } diff --git a/source/test-java/org/alfresco/rest/api/tests/SharedLinkApiTest.java b/source/test-java/org/alfresco/rest/api/tests/SharedLinkApiTest.java index dd6f1f9ff5..41f8b851be 100644 --- a/source/test-java/org/alfresco/rest/api/tests/SharedLinkApiTest.java +++ b/source/test-java/org/alfresco/rest/api/tests/SharedLinkApiTest.java @@ -347,6 +347,98 @@ public class SharedLinkApiTest extends AbstractBaseApiTest } } + /** + * Tests find shared links to file (content) + * + * Note: relies on search service + * + *

GET:

+ * {@literal :/alfresco/api//public/alfresco/versions/1/shared-links} + */ + @Test + public void testSharedLinkFind() throws Exception + { + Paging paging = getPaging(0, 100); + + HttpResponse response = getAll(URL_SHARED_LINKS, user1, paging, 200); + List sharedLinks = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), QuickShareLink.class); + assertEquals(0, sharedLinks.size()); + + // As user 1 ... + + AuthenticationUtil.setFullyAuthenticatedUser(user1); + + // create doc d1 + + String sharedFolderNodeId = getSharedNodeId(user1); + + String contentText = "The quick brown fox jumps over the lazy dog."; + + String docName1 = "content" + RUNID + "_1.txt"; + NodeRef d1Ref = repoService.createDocument(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, sharedFolderNodeId), + docName1, contentText); + String d1Id = d1Ref.getId(); + + // create doc d2 + + String myFolderNodeId = getMyNodeId(user1); + + String docName2 = "content" + RUNID + "_2.txt"; + NodeRef d2Ref = repoService.createDocument(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, myFolderNodeId), + docName2, contentText); + String d2Id = d2Ref.getId(); + + AuthenticationUtil.clearCurrentSecurityContext(); + + // As user 2 ... + + // create shared link + Map body = new HashMap<>(); + body.put("nodeId", d1Id); + response = post(URL_SHARED_LINKS, user2, toJsonAsStringNonNull(body), 201); + QuickShareLink resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class); + String shared1Id = resp.getSharedId(); + + // As user 1 ... + + // create shared link + body = new HashMap<>(); + body.put("nodeId", d2Id); + response = post(URL_SHARED_LINKS, user1, toJsonAsStringNonNull(body), 201); + resp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), QuickShareLink.class); + String shared2Id = resp.getSharedId(); + + // + // find links + // + + response = getAll(URL_SHARED_LINKS, user1, paging, 200); + sharedLinks = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), QuickShareLink.class); + assertEquals(2, sharedLinks.size()); + assertEquals(shared2Id, sharedLinks.get(0).getSharedId()); + assertEquals(d2Id, sharedLinks.get(0).getNodeId()); + assertEquals(shared1Id, sharedLinks.get(1).getSharedId()); + assertEquals(d1Id, sharedLinks.get(1).getNodeId()); + + response = getAll(URL_SHARED_LINKS, user2, paging, 200); + sharedLinks = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), QuickShareLink.class); + assertEquals(1, sharedLinks.size()); + assertEquals(shared1Id, sharedLinks.get(0).getSharedId()); + assertEquals(d1Id, sharedLinks.get(0).getNodeId()); + + + // TODO if and when these tests are optionally runnable via remote env then we could skip this part of the test + // (else need to verify test mechanism for enterprise admin via jmx ... etc) + + QuickShareLinksImpl quickShareLinks = applicationContext.getBean("quickShareLinks", QuickShareLinksImpl.class); + quickShareLinks.setEnabled(false); + + // -ve - disabled service tests + { + getAll(URL_SHARED_LINKS, user1, paging, 501); + } + } + @Override public String getScope() {