Merged API-STRIKES-BACK (5.2.0) to HEAD (5.2)

125708 jvonka: RA-779 / RA-780: Sites API - fix (create site + permanent delete + create site with same site id)
   - RA-967


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@127561 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jamal Kaabi-Mofrad
2016-06-02 21:37:56 +00:00
parent f31d286c8c
commit aee533110c
4 changed files with 96 additions and 18 deletions

View File

@@ -652,6 +652,8 @@
<property name="preferenceService" ref="PreferenceService" /> <property name="preferenceService" ref="PreferenceService" />
<property name="importerService" ref="importerComponent"/> <property name="importerService" ref="importerComponent"/>
<property name="siteSurfConfig" ref="siteSurfConfig" /> <property name="siteSurfConfig" ref="siteSurfConfig" />
<property name="permissionService" ref="PermissionService" />
<property name="siteServiceImpl" ref="siteService" />
</bean> </bean>
<bean id="siteSurfConfig" class="org.alfresco.rest.api.impl.SiteSurfConfig"> <bean id="siteSurfConfig" class="org.alfresco.rest.api.impl.SiteSurfConfig">

View File

@@ -40,10 +40,12 @@ import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults; import org.alfresco.query.PagingResults;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authority.UnknownAuthorityException; import org.alfresco.repo.security.authority.UnknownAuthorityException;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.site.SiteMembership; import org.alfresco.repo.site.SiteMembership;
import org.alfresco.repo.site.SiteMembershipComparator; import org.alfresco.repo.site.SiteMembershipComparator;
import org.alfresco.repo.site.SiteModel; import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.site.SiteServiceException; import org.alfresco.repo.site.SiteServiceException;
import org.alfresco.repo.site.SiteServiceImpl;
import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.People; import org.alfresco.rest.api.People;
import org.alfresco.rest.api.Sites; import org.alfresco.rest.api.Sites;
@@ -70,6 +72,8 @@ import org.alfresco.service.cmr.preference.PreferenceService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.site.SiteInfo; import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService; import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.site.SiteVisibility; import org.alfresco.service.cmr.site.SiteVisibility;
@@ -115,6 +119,8 @@ public class SitesImpl implements Sites
protected PreferenceService preferenceService; protected PreferenceService preferenceService;
protected ImporterService importerService; protected ImporterService importerService;
protected SiteSurfConfig siteSurfConfig; protected SiteSurfConfig siteSurfConfig;
protected PermissionService permissionService;
protected SiteServiceImpl siteServiceImpl;
public void setPreferenceService(PreferenceService preferenceService) public void setPreferenceService(PreferenceService preferenceService)
{ {
@@ -161,6 +167,17 @@ public class SitesImpl implements Sites
this.siteSurfConfig = siteSurfConfig; this.siteSurfConfig = siteSurfConfig;
} }
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setSiteServiceImpl(SiteServiceImpl siteServiceImpl)
{
this.siteServiceImpl = siteServiceImpl;
}
public SiteInfo validateSite(NodeRef guid) public SiteInfo validateSite(NodeRef guid)
{ {
SiteInfo siteInfo = null; SiteInfo siteInfo = null;
@@ -850,13 +867,24 @@ public class SitesImpl implements Sites
} }
siteId = siteInfo.getShortName(); siteId = siteInfo.getShortName();
NodeRef siteNodeRef = siteInfo.getNodeRef();
// belt-and-braces - double-check before purge/delete (rather than rollback)
if (permissionService.hasPermission(siteNodeRef, PermissionService.DELETE) != AccessStatus.ALLOWED)
{
throw new AccessDeniedException("Cannot delete site: "+siteId);
}
// default false (if not provided) // default false (if not provided)
boolean permanentDelete = Boolean.valueOf(parameters.getParameter(PARAM_PERMANENT)); boolean permanentDelete = Boolean.valueOf(parameters.getParameter(PARAM_PERMANENT));
if (permanentDelete == true) if (permanentDelete == true)
{ {
// Set as temporary to delete node instead of archiving. // Set as temporary to delete node instead of archiving.
nodeService.addAspect(siteInfo.getNodeRef(), ContentModel.ASPECT_TEMPORARY, null); nodeService.addAspect(siteNodeRef, ContentModel.ASPECT_TEMPORARY, null);
// bypassing trashcan means that purge behaviour will not fire, so explicitly force cleanup here
siteServiceImpl.beforePurgeNode(siteNodeRef);
} }
siteService.deleteSite(siteId); siteService.deleteSite(siteId);

View File

@@ -22,8 +22,10 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import org.alfresco.repo.tenant.TenantUtil; import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork; import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
@@ -156,9 +158,26 @@ public class TestSites extends EnterpriseTestApi
sitesProxy.removeSite(siteId); sitesProxy.removeSite(siteId);
// -ve test - ie. cannot get site after it has been deleted
sitesProxy.getSite(siteId, 404); sitesProxy.getSite(siteId, 404);
} }
// test create + permanent delete + create
{
String siteId = "bbb";
String siteTitle = "BBB site";
Site site = new SiteImpl(null, siteId, null, siteTitle, null, SiteVisibility.PUBLIC.toString(), null, null);
sitesProxy.createSite(site);
// permanent site delete (bypass trashcan/archive)
sitesProxy.removeSite(siteId, true, 204);
sitesProxy.createSite(site);
}
// -ve tests // -ve tests
{ {
// invalid auth // invalid auth
@@ -169,11 +188,11 @@ public class TestSites extends EnterpriseTestApi
// -ve - cannot view or delete a private site // -ve - cannot view or delete a private site
sitesProxy.getSite(site1.getSiteId(), 404); sitesProxy.getSite(site1.getSiteId(), 404);
sitesProxy.removeSite(site1.getSiteId(), 404); sitesProxy.removeSite(site1.getSiteId(), false, 404);
// -ve - test cannot delete a public site (but can view it) // -ve - test cannot delete a public site (but can view it)
sitesProxy.getSite(site2.getSiteId(), 200); sitesProxy.getSite(site2.getSiteId(), 200);
sitesProxy.removeSite(site2.getSiteId(), 403); sitesProxy.removeSite(site2.getSiteId(), false, 403);
// -ve - try to get unknown site // -ve - try to get unknown site
sitesProxy.getSite(GUID.generate(), 404); sitesProxy.getSite(GUID.generate(), 404);
@@ -223,9 +242,32 @@ public class TestSites extends EnterpriseTestApi
site = new SiteImpl(siteTitle, SiteVisibility.PRIVATE.toString()); site = new SiteImpl(siteTitle, SiteVisibility.PRIVATE.toString());
String siteId = sitesProxy.createSite(site, 201).getSiteId(); String siteId = sitesProxy.createSite(site, 201).getSiteId();
sitesProxy.createSite(site, 409); sitesProxy.createSite(site, 409);
sitesProxy.removeSite(siteId, 204); // cleanup sitesProxy.removeSite(siteId); // cleanup
sitesProxy.removeSite(GUID.generate(), 404); sitesProxy.removeSite(GUID.generate(), false, 404);
}
// -ve - cannot create site with same site id as an existing site (even if it is in the trashcan/archive)
{
String siteId = "aaa";
String siteTitle = "AAA site";
Site site = new SiteImpl(null, siteId, null, siteTitle, null, SiteVisibility.PUBLIC.toString(), null, null);
String siteNodeId = sitesProxy.createSite(site).getGuid();
// -ve - duplicate site id
sitesProxy.createSite(site, 409);
sitesProxy.removeSite(siteId);
// -ve - duplicate site id (even if site is in trashcan)
sitesProxy.createSite(site, 409);
// now purge the site
sitesProxy.remove("deleted-nodes", siteNodeId, null, null, "Cannot purge site");
sitesProxy.createSite(site);
} }
{ {

View File

@@ -27,6 +27,7 @@ import java.math.BigInteger;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -737,14 +738,14 @@ public class PublicApiClient
public HttpResponse remove(String entityCollectionName, String entityId, String relationCollectionName, String relationId, String errorMessage) throws PublicApiException public HttpResponse remove(String entityCollectionName, String entityId, String relationCollectionName, String relationId, String errorMessage) throws PublicApiException
{ {
return remove(entityCollectionName, entityId, relationCollectionName, relationId, errorMessage, HttpServletResponse.SC_NO_CONTENT); return remove(entityCollectionName, entityId, relationCollectionName, relationId, null, errorMessage, HttpServletResponse.SC_NO_CONTENT);
} }
public HttpResponse remove(String entityCollectionName, String entityId, String relationCollectionName, String relationId, String errorMessage, int expectedStatus) throws PublicApiException public HttpResponse remove(String entityCollectionName, String entityId, String relationCollectionName, String relationId, Map<String,String> params, String errorMessage, int expectedStatus) throws PublicApiException
{ {
try try
{ {
HttpResponse response = delete("public", entityCollectionName, entityId, relationCollectionName, relationId); HttpResponse response = delete("public", 1, entityCollectionName, entityId, relationCollectionName, relationId, params);
checkStatus(errorMessage, expectedStatus, response); checkStatus(errorMessage, expectedStatus, response);
return response; return response;
} }
@@ -838,12 +839,17 @@ public class PublicApiClient
public void removeSite(String siteId) throws PublicApiException public void removeSite(String siteId) throws PublicApiException
{ {
removeSite(siteId, 204); removeSite(siteId, false, 204);
} }
public void removeSite(String siteId, int expectedStatus) throws PublicApiException public void removeSite(String siteId, boolean permanent, int expectedStatus) throws PublicApiException
{ {
remove("sites", siteId, null, null, "Failed to remove site", expectedStatus); Map<String, String> params = null;
if (permanent)
{
params = Collections.singletonMap("permanent", "true");
}
remove("sites", siteId, null, null, params, "Failed to remove site", expectedStatus);
} }
public ListResponse<SiteContainer> getSiteContainers(String siteId, Map<String, String> params) throws PublicApiException public ListResponse<SiteContainer> getSiteContainers(String siteId, Map<String, String> params) throws PublicApiException