Merged 5.1.N (5.1.1) to HEAD (5.1)

120443 arebegea: Revert Merged 5.0.N (5.0.4) to 5.1.N (5.1.1)
      120350 aleahu: MNT-14845 : Site Export Rest API creates a corrupted ZIP if the site contains members synced from LDAP
         - Fixed by not exporting user node if it doesn't exist
         - Added unit tests for site export


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@123622 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Alan Davis
2016-03-11 21:36:10 +00:00
parent d3d2a6612a
commit 33bb9e3ad3
5 changed files with 98 additions and 363 deletions

View File

@@ -103,7 +103,7 @@ public class SiteExportGet extends AbstractWebScript
mainZip.putNextEntry(new ZipEntry("Contents.acp"));
doSiteACPExport(site, outputForNesting);
// Export the person details for the users who are members of the site's groups
// Export the users who are members of the site's groups
// Also includes the list of their site related groups
//
// If there are no users in this site (other than the built-ins like admin, guest)
@@ -126,7 +126,7 @@ public class SiteExportGet extends AbstractWebScript
mainZip.putNextEntry(new ZipEntry("Groups.txt"));
doGroupExport(site, outputForNesting);
// Export the User (authentication) details for the site users that have user(authenticator) nodes associated
// Export the User (authentication) details of those people
// Only does this if the repository based authenticator is enabled
RepositoryAuthenticationDao authenticationDao = null;
for(String contextName : authenticationContextManager.getInstanceIds())
@@ -138,8 +138,6 @@ public class SiteExportGet extends AbstractWebScript
ctx.getBean(RepositoryAuthenticationDao.class);
} catch(NoSuchBeanDefinitionException e) {}
}
List<NodeRef> userNodes = getUserNodesInSiteGroup(site, authenticationDao);
//authenticationDao is initialized only when using a repository-based authentication subsystem
if (authenticationDao == null)
{
mainZip.putNextEntry(new ZipEntry("Users_Skipped_As_Wrong_Authentication.txt"));
@@ -147,7 +145,7 @@ public class SiteExportGet extends AbstractWebScript
"Subsystem you are using is not repository based";
outputForNesting.write(text.getBytes("ASCII"));
}
else if (userNodes.isEmpty())
else if (peopleNodes.isEmpty())
{
mainZip.putNextEntry(new ZipEntry("No_Users_In_Site.txt"));
String text = "User nodes were not exported because the site does not contain\n"+
@@ -157,7 +155,7 @@ public class SiteExportGet extends AbstractWebScript
else
{
mainZip.putNextEntry(new ZipEntry("Users.acp"));
doUserACPExport(userNodes, site, outputForNesting);
doUserACPExport(site, outputForNesting, authenticationDao);
}
// Finish up
@@ -232,42 +230,6 @@ public class SiteExportGet extends AbstractWebScript
return peopleNodes;
}
/**
* Returns the user nodes (authentication nodes) if the authenticationDao exists
* @param site
* @param authenticationDao
* @return
*/
private List<NodeRef> getUserNodesInSiteGroup(SiteInfo site, RepositoryAuthenticationDao authenticationDao) {
List<NodeRef> userNodes = new ArrayList<NodeRef>();
if(authenticationDao == null)
{
return userNodes;
}
// Identify all the users
String siteGroup = AbstractSiteWebScript.buildSiteGroup(site);
Set<String> siteUsers = authorityService.getContainedAuthorities(
AuthorityType.USER, siteGroup, false);
for (String user : siteUsers)
{
if (USERS_NOT_TO_EXPORT.contains(user))
{
// Don't export these core users like admin
}
else
{
NodeRef userNodeRef = authenticationDao.getUserOrNull(user);
if(userNodeRef != null)
{
userNodes.add(userNodeRef);
}
}
}
return userNodes;
}
protected void doGroupExport(SiteInfo site, CloseIgnoringOutputStream writeTo) throws IOException
{
// Find the root group
@@ -325,12 +287,34 @@ public class SiteExportGet extends AbstractWebScript
out.close();
}
protected void doUserACPExport(List<NodeRef> userNodes, SiteInfo site,
CloseIgnoringOutputStream writeTo) throws IOException
protected void doUserACPExport(SiteInfo site, CloseIgnoringOutputStream writeTo,
RepositoryAuthenticationDao authenticationDao) throws IOException
{
List<NodeRef> exportNodes = new ArrayList<NodeRef>();
// Identify all the users
String siteGroup = AbstractSiteWebScript.buildSiteGroup(site);
Set<String> siteUsers = authorityService.getContainedAuthorities(
AuthorityType.USER, siteGroup, false);
// Now export them, and only them
for (String user : siteUsers)
{
if (USERS_NOT_TO_EXPORT.contains(user))
{
// Don't export these core users like admin
}
else
{
//NodeRef personNodeRef = authorityService.getAuthorityNodeRef(user);
NodeRef userNodeRef = authenticationDao.getUserOrNull(user);
exportNodes.add(userNodeRef);
}
}
// Build the parameters
ExporterCrawlerParameters parameters = new ExporterCrawlerParameters();
parameters.setExportFrom(new Location(userNodes.toArray(new NodeRef[userNodes.size()])));
parameters.setExportFrom(new Location(exportNodes.toArray(new NodeRef[exportNodes.size()])));
parameters.setCrawlChildNodes(true);
parameters.setCrawlSelf(true);
parameters.setCrawlContent(true);

View File

@@ -1,142 +0,0 @@
/*
* Copyright (C) 2005-2016 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.site;
import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.util.PropertyMap;
import org.json.JSONObject;
import org.springframework.extensions.webscripts.TestWebScriptServer.DeleteRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.PostRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.Response;
import com.google.common.collect.Lists;
/**
* Unit test for the Export Web Script API of the Site Object.
*/
public class AbstractSiteServiceTest extends BaseWebScriptTest
{
protected MutableAuthenticationService authenticationService;
protected AuthenticationComponent authenticationComponent;
protected PersonService personService;
private static final String URL_SITES = "/api/sites";
private static final String URL_MEMBERSHIPS = "/memberships";
protected List<String> createdSites = Lists.newArrayList();
@Override
protected void setUp() throws Exception
{
super.setUp();
this.authenticationComponent = (AuthenticationComponent) getServer()
.getApplicationContext().getBean("authenticationComponent");
this.authenticationService = (MutableAuthenticationService) getServer()
.getApplicationContext().getBean("AuthenticationService");
this.personService = (PersonService) getServer().getApplicationContext().getBean(
"PersonService");
// sets the testMode property to true via spring injection. This will
// prevent emails
// from being sent from within this test case.
this.authenticationComponent.setSystemUserAsCurrentUser();
}
@Override
protected void tearDown() throws Exception
{
super.tearDown();
this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
// Tidy-up any sites create during the execution of the test
for (String shortName : this.createdSites)
{
sendRequest(new DeleteRequest(URL_SITES + "/" + shortName), 0);
}
// Clear the list
this.createdSites.clear();
}
protected void createUser(String userName)
{
if (this.authenticationService.authenticationExists(userName) == false)
{
this.authenticationService.createAuthentication(userName, "PWD".toCharArray());
createPerson(userName);
}
}
protected void createPerson(String userName)
{
PropertyMap ppOne = new PropertyMap(4);
ppOne.put(ContentModel.PROP_USERNAME, userName);
ppOne.put(ContentModel.PROP_FIRSTNAME, "firstName");
ppOne.put(ContentModel.PROP_LASTNAME, "lastName");
ppOne.put(ContentModel.PROP_EMAIL, "email@email.com");
ppOne.put(ContentModel.PROP_JOBTITLE, "jobTitle");
this.personService.createPerson(ppOne);
}
protected void deleteUser(String username)
{
this.personService.deletePerson(username);
if (this.authenticationService.authenticationExists(username))
{
this.authenticationService.deleteAuthentication(username);
}
}
protected JSONObject createSite(String sitePreset, String shortName, String title,
String description, SiteVisibility visibility, int expectedStatus) throws Exception
{
JSONObject site = new JSONObject();
site.put("sitePreset", sitePreset);
site.put("shortName", shortName);
site.put("title", title);
site.put("description", description);
site.put("visibility", visibility.toString());
Response response = sendRequest(new PostRequest(URL_SITES, site.toString(),
"application/json"), expectedStatus);
this.createdSites.add(shortName);
return new JSONObject(response.getContentAsString());
}
protected void addSiteMember(String userName, String site) throws Exception
{
JSONObject membership = new JSONObject();
membership.put("role", SiteModel.SITE_CONSUMER);
JSONObject person = new JSONObject();
person.put("userName", userName);
membership.put("person", person);
sendRequest(new PostRequest(URL_SITES + "/" + site + URL_MEMBERSHIPS,
membership.toString(), "application/json"), 200);
}
}

View File

@@ -39,7 +39,6 @@ import org.junit.runners.Suite;
SiteServiceImplTest.class,
SiteServiceImplMoreTest.class,
SiteServiceTest.class,
SiteExportServiceTest.class,
SiteActivityTestCaseSensitivity.class,
SiteActivityTestCaseInsensitivity.class
})

View File

@@ -1,173 +0,0 @@
/*
* Copyright (C) 2005-2016 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.site;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipInputStream;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.util.GUID;
import org.junit.Ignore;
import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.Response;
import com.google.common.collect.Lists;
/**
* Unit test for the Export Web Script API of the Site Object.
*/
public class SiteExportServiceTest extends AbstractSiteServiceTest
{
private static final String USER_FROM_LDAP = "SiteUserLdap";
private static final String USER_ONE = "SiteUser";
@Override
protected void setUp() throws Exception
{
super.setUp();
// Create users
createUser(USER_ONE);
createPerson(USER_FROM_LDAP);
// Do tests as admin
this.authenticationComponent.setCurrentUser("admin");
}
@Override
protected void tearDown() throws Exception
{
super.tearDown();
// Clear the users
deleteUser(USER_ONE);
deleteUser(USER_FROM_LDAP);
}
public void testExportSiteWithMutipleUsers() throws Exception
{
// Create a site
String shortName = GUID.generate();
createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
// add a user and a person as members
addSiteMember(USER_FROM_LDAP, shortName);
addSiteMember(USER_ONE, shortName);
// Export site
Response response = sendRequest(new GetRequest(getExportUrl(shortName)), 200);
// check exported files
List<String> entries = getEntries(new ZipInputStream(new ByteArrayInputStream(
response.getContentAsByteArray())));
assertFalse(entries.contains("No_Users_In_Site.txt"));
assertFalse(entries.contains("No_Persons_In_Site.txt"));
assertTrue(entries.contains("People.acp"));
assertTrue(entries.contains(shortName + "-people.xml"));
assertTrue(entries.contains("Users.acp"));
assertTrue(entries.contains(shortName + "-users.xml"));
}
public void testExportSiteWithOneLDAPUser() throws Exception
{
// Create a site
String shortName = GUID.generate();
createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
// add a user synced from LDAP(authenticator node not present)
addSiteMember(USER_FROM_LDAP, shortName);
// Export site
Response response = sendRequest(new GetRequest(getExportUrl(shortName)), 200);
// check No_Users_In_Site.txt present
// because there is no user associated with the single member of the
// site
List<String> entries = getEntries(new ZipInputStream(new ByteArrayInputStream(
response.getContentAsByteArray())));
assertFalse(entries.contains("Users.acp"));
assertTrue(entries.contains("No_Users_In_Site.txt"));
assertTrue(entries.contains("People.acp"));
assertTrue(entries.contains(shortName + "-people.xml"));
}
public void testExportSiteWithNoUsers() throws Exception
{
// Create a site
String shortName = GUID.generate();
createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
// Export site
Response response = sendRequest(new GetRequest(getExportUrl(shortName)), 200);
// check No_Users_In_Site.txt and No_Persons_In_Site.txt present
List<String> entries = getEntries(new ZipInputStream(new ByteArrayInputStream(
response.getContentAsByteArray())));
assertTrue(entries.contains("No_Users_In_Site.txt"));
assertTrue(entries.contains("No_Persons_In_Site.txt"));
assertFalse(entries.contains("Users.acp"));
assertFalse(entries.contains("People.acp"));
}
private List<String> getEntries(ZipInputStream zipStream) throws Exception
{
ZipEntry entry = null;
List<String> entries = Lists.newArrayList();
while ((entry = zipStream.getNextEntry()) != null)
{
if (entry.getName().endsWith("acp"))
{
entries.addAll(getAcpEntries(zipStream));
}
entries.add(entry.getName());
zipStream.closeEntry();
}
zipStream.close();
return entries;
}
private List<String> getAcpEntries(InputStream inputStream) throws Exception
{
List<String> entries = Lists.newArrayList();
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ZipEntry entry = null;
try
{
while ((entry = zipInputStream.getNextEntry()) != null)
{
entries.add(entry.getName());
}
}
catch (ZipException e)
{
// ignore
}
return entries;
}
private String getExportUrl(String shortName)
{
return "/api/sites/" + shortName + "/export";
}
}

View File

@@ -19,17 +19,21 @@
package org.alfresco.repo.web.scripts.site;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import junit.framework.AssertionFailedError;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
@@ -39,13 +43,16 @@ import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.alfresco.util.PropertyMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -61,8 +68,11 @@ import org.springframework.extensions.webscripts.TestWebScriptServer.Response;
*
* @author Roy Wetherall
*/
public class SiteServiceTest extends AbstractSiteServiceTest
public class SiteServiceTest extends BaseWebScriptTest
{
private MutableAuthenticationService authenticationService;
private AuthenticationComponent authenticationComponent;
private PersonService personService;
private SiteService siteService;
private NodeService nodeService;
private PermissionService permissionService;
@@ -80,17 +90,25 @@ public class SiteServiceTest extends AbstractSiteServiceTest
private static final String URL_MEMBERSHIPS = "/memberships";
private static final String URL_SITES_ADMIN = "/api/admin-sites";
private List<String> createdSites = new ArrayList<String>(5);
@Override
protected void setUp() throws Exception
{
super.setUp();
this.authenticationService = (MutableAuthenticationService)getServer().getApplicationContext().getBean("AuthenticationService");
this.authenticationComponent = (AuthenticationComponent)getServer().getApplicationContext().getBean("authenticationComponent");
this.personService = (PersonService)getServer().getApplicationContext().getBean("PersonService");
this.siteService = (SiteService)getServer().getApplicationContext().getBean("SiteService");
this.nodeService = (NodeService)getServer().getApplicationContext().getBean("NodeService");
this.permissionService = (PermissionService)getServer().getApplicationContext().getBean("PermissionService");
this.authorityService = (AuthorityService)getServer().getApplicationContext().getBean("AuthorityService");
this.fileFolderService = (FileFolderService)getServer().getApplicationContext().getBean("FileFolderService");
// sets the testMode property to true via spring injection. This will prevent emails
// from being sent from within this test case.
this.authenticationComponent.setSystemUserAsCurrentUser();
// Create users
createUser(USER_ONE);
@@ -106,10 +124,36 @@ public class SiteServiceTest extends AbstractSiteServiceTest
this.authenticationComponent.setCurrentUser(USER_ONE);
}
private void createUser(String userName)
{
if (this.authenticationService.authenticationExists(userName) == false)
{
this.authenticationService.createAuthentication(userName, "PWD".toCharArray());
PropertyMap ppOne = new PropertyMap(4);
ppOne.put(ContentModel.PROP_USERNAME, userName);
ppOne.put(ContentModel.PROP_FIRSTNAME, "firstName");
ppOne.put(ContentModel.PROP_LASTNAME, "lastName");
ppOne.put(ContentModel.PROP_EMAIL, "email@email.com");
ppOne.put(ContentModel.PROP_JOBTITLE, "jobTitle");
this.personService.createPerson(ppOne);
}
}
private void deleteUser(String username)
{
this.personService.deletePerson(username);
if(this.authenticationService.authenticationExists(username))
{
this.authenticationService.deleteAuthentication(username);
}
}
@Override
protected void tearDown() throws Exception
{
super.tearDown();
this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
// Clear the users
deleteUser(USER_ONE);
@@ -117,6 +161,15 @@ public class SiteServiceTest extends AbstractSiteServiceTest
deleteUser(USER_THREE);
deleteUser(USER_NUMERIC);
deleteUser(USER_FOUR_AS_SITE_ADMIN);
// Tidy-up any site's create during the execution of the test
for (String shortName : this.createdSites)
{
sendRequest(new DeleteRequest(URL_SITES + "/" + shortName), 0);
}
// Clear the list
this.createdSites.clear();
}
public void testCreateSite() throws Exception
@@ -138,6 +191,20 @@ public class SiteServiceTest extends AbstractSiteServiceTest
createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 400);
}
private JSONObject createSite(String sitePreset, String shortName, String title, String description, SiteVisibility visibility, int expectedStatus)
throws Exception
{
JSONObject site = new JSONObject();
site.put("sitePreset", sitePreset);
site.put("shortName", shortName);
site.put("title", title);
site.put("description", description);
site.put("visibility", visibility.toString());
Response response = sendRequest(new PostRequest(URL_SITES, site.toString(), "application/json"), expectedStatus);
this.createdSites.add(shortName);
return new JSONObject(response.getContentAsString());
}
public void testGetSites() throws Exception
{
int preexistingSiteCount = 0;