/* * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program 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 General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * As a special exception to the terms and conditions of version 2.0 of * the GPL, you may redistribute this Program in connection with Free/Libre * and Open Source Software ("FLOSS") applications as described in Alfresco's * FLOSS exception. You should have received a copy of the text describing * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ package org.alfresco.repo.security.sync; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import org.alfresco.model.ContentModel; import org.alfresco.repo.management.subsystems.ChildApplicationContextManager; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.util.BaseSpringTest; import org.alfresco.util.PropertyMap; import org.hibernate.SessionFactory; import org.hibernate.engine.SessionFactoryImplementor; import org.springframework.context.ApplicationContext; import org.springframework.context.support.StaticApplicationContext; /** * Tests the {@link ChainingUserRegistrySynchronizer} using a simulated {@link UserRegistry}. * * @author dward */ public class ChainingUserRegistrySynchronizerTest extends BaseSpringTest { /** The context locations, in reverse priority order. */ private static final String[] CONFIG_LOCATIONS = { "classpath:alfresco/application-context.xml", "classpath:sync-test-context.xml" }; /** The synchronizer we are testing. */ private UserRegistrySynchronizer synchronizer; /** The application context manager. */ private MockApplicationContextManager applicationContextManager; /** The person service. */ private PersonService personService; /** The authority service. */ private AuthorityService authorityService; /** The node service. */ private NodeService nodeService; /* * (non-Javadoc) * @see org.springframework.test.AbstractTransactionalSpringContextTests#onSetUpInTransaction() */ @Override protected void onSetUpInTransaction() throws Exception { ApplicationContext context = getApplicationContext(); this.synchronizer = (UserRegistrySynchronizer) context.getBean("testUserRegistrySynchronizer"); this.applicationContextManager = (MockApplicationContextManager) context .getBean("testApplicationContextManager"); this.personService = (PersonService) context.getBean("personService"); this.authorityService = (AuthorityService) context.getBean("authorityService"); this.nodeService = (NodeService) context.getBean("nodeService"); } /* * (non-Javadoc) * @see org.springframework.test.AbstractTransactionalSpringContextTests#onTearDownInTransaction() */ protected void onTearDownInTransaction() throws Exception { flushAndClear(); // Try to clear the Hibernate L2 cache so we have consistency after a rollback SessionFactory sessionFactory = getSession().getSessionFactory(); String[] persistentClasses = ((SessionFactoryImplementor) sessionFactory).getImplementors("java.lang.Object"); for (String persistentClass : persistentClasses) { sessionFactory.evictEntity(persistentClass); } } /* * (non-Javadoc) * @see org.alfresco.util.BaseSpringTest#getConfigLocations() */ @Override protected String[] getConfigLocations() { return ChainingUserRegistrySynchronizerTest.CONFIG_LOCATIONS; } /** * Sets up the test users and groups in two zones, "Z1" and "Z2", by doing a forced synchronize with a Mock user * registry. Note that the zones have some overlapping entries. The layout is as follows * *
* Z1
* G1
* G2 - U1, G3 - U2, G4, G5
*
* Z2
* G2 - U1, U3, U4
* G6 - U3, U4, G7 - U5
*
*
* @throws Exception
* the exception
*/
public void setUpTestUsersAndGroups() throws Exception
{
this.applicationContextManager.setUserRegistries(new MockUserRegistry("Z1", new NodeDescription[]
{
newPerson("U1"), newPerson("U2")
}, new NodeDescription[]
{
newGroup("G1"), newGroup("G2", "U1", "G3"), newGroup("G3", "U2", "G4", "G5"), newGroup("G4"),
newGroup("G5")
}), new MockUserRegistry("Z2", new NodeDescription[]
{
newPerson("U1"), newPerson("U3"), newPerson("U4"), newPerson("U5")
}, new NodeDescription[]
{
newGroup("G2", "U1", "U3", "U4"), newGroup("G6", "U3", "U4", "G7"), newGroup("G7", "U5")
}));
this.synchronizer.synchronize(true);
assertExists("Z1", "U1");
assertExists("Z1", "U2");
assertExists("Z1", "G1");
assertExists("Z1", "G2", "U1", "G3");
assertExists("Z1", "G3", "U2", "G4", "G5");
assertExists("Z1", "G4");
assertExists("Z1", "G5");
assertExists("Z2", "U3");
assertExists("Z2", "U4");
assertExists("Z2", "U5");
assertExists("Z2", "G6", "U3", "U4", "G7");
assertExists("Z2", "G7", "U5");
}
/**
* Tests a differential update of the test users and groups. The layout is as follows
*
*
* Z1
* G1 - U1, U6
* G2 - U1
* G3 - U2, G4, G5 - U6
*
* Z2
* G2 - U1, U3, U4, U6
* G6 - U3, U4, G7
*
*
* @throws Exception
* the exception
*/
public void testDifferentialUpdate() throws Exception
{
setUpTestUsersAndGroups();
this.applicationContextManager.setUserRegistries(new MockUserRegistry("Z1", new NodeDescription[]
{
newPerson("U1", "changeofemail@alfresco.com"), newPerson("U6")
}, new NodeDescription[]
{
newGroup("G1", "U1", "U6"), newGroup("G2", "U1"), newGroup("G5", "U6")
}), new MockUserRegistry("Z2", new NodeDescription[]
{
newPerson("U1", "shouldbeignored@alfresco.com"), newPerson("U5", "u5email@alfresco.com"), newPerson("U6")
}, new NodeDescription[]
{
newGroup("G2", "U1", "U3", "U4", "U6"), newGroup("G7")
}));
this.synchronizer.synchronize(false);
assertExists("Z1", "U1");
assertEmailEquals("U1", "changeofemail@alfresco.com");
assertExists("Z1", "U2");
assertExists("Z1", "U6");
assertExists("Z1", "G1", "U1", "U6");
assertExists("Z1", "G2", "U1");
assertExists("Z1", "G3", "U2", "G4", "G5");
assertExists("Z1", "G4");
assertExists("Z1", "G5", "U6");
assertExists("Z2", "U3");
assertExists("Z2", "U4");
assertExists("Z2", "U5");
assertEmailEquals("U5", "u5email@alfresco.com");
assertExists("Z2", "G6", "U3", "U4", "G7");
assertExists("Z2", "G7");
}
/**
* Tests a forced update of the test users and groups. Also tests that groups and users that previously existed in
* Z2 get moved when they appear in Z1. The layout is as follows
*
*
* Z1
* G1 - U6
* G2 -
* G3 - U2, G5 - U6
* G6 - U3
*
* Z2
* G2 - U1, U3, U6
* G6 - U3, G7
*
*
* @throws Exception
* the exception
*/
public void testForcedUpdate() throws Exception
{
setUpTestUsersAndGroups();
this.applicationContextManager.setUserRegistries(new MockUserRegistry("Z1", new NodeDescription[]
{
newPerson("U2"), newPerson("U3"), newPerson("U6")
}, new NodeDescription[]
{
newGroup("G1", "U6"), newGroup("G2"), newGroup("G3", "U2", "G5"), newGroup("G5", "U6"),
newGroup("G6", "U3")
}), new MockUserRegistry("Z2", new NodeDescription[]
{
newPerson("U1", "somenewemail@alfresco.com"), newPerson("U3"), newPerson("U6")
}, new NodeDescription[]
{
newGroup("G2", "U1", "U3", "U6"), newGroup("G6", "U3", "G7"), newGroup("G7")
}));
this.synchronizer.synchronize(true);
assertExists("Z1", "U2");
assertExists("Z1", "U3");
assertExists("Z1", "U6");
assertExists("Z1", "G1", "U6");
assertExists("Z1", "G2");
assertExists("Z1", "G3", "U2", "G5");
assertNotExists("G4");
assertExists("Z1", "G5", "U6");
assertExists("Z1", "G6", "U3");
assertExists("Z2", "U1");
assertEmailEquals("U1", "somenewemail@alfresco.com");
assertNotExists("U4");
assertNotExists("U5");
assertExists("Z2", "G7");
}
/**
* Constructs a description of a test group
*
* @param name
* the name
* @param members
* the members
* @return the node description
*/
private NodeDescription newGroup(String name, String... members)
{
NodeDescription group = new NodeDescription();
PropertyMap properties = group.getProperties();
properties.put(ContentModel.PROP_AUTHORITY_NAME, longName(name));
if (members.length > 0)
{
Set