/* * 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