From 0445571a45361b45c03d1be0fee4f06ab6f949b2 Mon Sep 17 00:00:00 2001 From: Derek Hulley Date: Mon, 15 Dec 2008 15:36:36 +0000 Subject: [PATCH] Merged V3.0 to HEAD 11259: MT - make new PersonDao MT-aware, re-enable MT demo/test 11261: MT - fix ETHREEOH-190, partial fix for ETHREEOH-189 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12392 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../authentication-services-context.xml | 7 + .../repo/security/person/PersonDaoImpl.java | 28 +++- .../repo/tenant/MultiTAdminServiceImpl.java | 4 +- .../alfresco/repo/tenant/MultiTDemoTest.java | 129 +++++++++++++++--- .../tenant/MultiTNodeServiceInterceptor.java | 62 ++++++++- 5 files changed, 201 insertions(+), 29 deletions(-) diff --git a/config/alfresco/authentication-services-context.xml b/config/alfresco/authentication-services-context.xml index 19c1d3e0a4..ed422745ee 100644 --- a/config/alfresco/authentication-services-context.xml +++ b/config/alfresco/authentication-services-context.xml @@ -221,6 +221,13 @@ + + + + + + ${spaces.store} + diff --git a/source/java/org/alfresco/repo/security/person/PersonDaoImpl.java b/source/java/org/alfresco/repo/security/person/PersonDaoImpl.java index e40bd4ad62..85d575778f 100644 --- a/source/java/org/alfresco/repo/security/person/PersonDaoImpl.java +++ b/source/java/org/alfresco/repo/security/person/PersonDaoImpl.java @@ -39,8 +39,10 @@ import org.alfresco.repo.domain.PropertyMapKey; import org.alfresco.repo.domain.QNameDAO; import org.alfresco.repo.domain.hibernate.NodeImpl; import org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl; +import org.alfresco.repo.tenant.TenantService; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.namespace.QName; import org.hibernate.SQLQuery; @@ -61,22 +63,40 @@ public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao private LocaleDAO localeDAO; private DictionaryService dictionaryService; + + private StoreRef storeRef; + + private TenantService tenantService; + + public void setStoreUrl(String storeUrl) + { + this.storeRef = new StoreRef(storeUrl); + } + + public void setTenantService(TenantService tenantService) + { + this.tenantService = tenantService; + } @SuppressWarnings("unchecked") public List getPersonOrNull(final String searchUserName, boolean userNamesAreCaseSensitive) { + final StoreRef personStoreRef = tenantService.getName(storeRef); + List answer = new ArrayList(); HibernateCallback callback = new HibernateCallback() { public Object doInHibernate(Session session) { - SQLQuery query = getSession().createSQLQuery("SELECT {n.*} FROM alf_node n JOIN alf_node_properties p ON n.id = p.node_id JOIN alf_child_assoc c on c.child_node_id = n.id WHERE c.qname_localname = :userName1 AND p.qname_id = :qnameId AND p.string_value = :userName2 and n.node_deleted = :False"); + SQLQuery query = getSession().createSQLQuery("SELECT {n.*} FROM alf_node n JOIN alf_node_properties p ON n.id = p.node_id JOIN alf_child_assoc c on c.child_node_id = n.id JOIN alf_store s on s.id = n.store_id WHERE c.qname_localname = :userName1 AND p.qname_id = :qnameId AND p.string_value = :userName2 and n.node_deleted = :False and s.protocol = :storeProtocol and s.identifier = :storeIdentifier"); query.addEntity("n", NodeImpl.class); query.setParameter("qnameId", qNameId); query.setParameter("userName1", searchUserName); query.setParameter("userName2", searchUserName); query.setParameter("False", Boolean.FALSE); + query.setParameter("storeProtocol", personStoreRef.getProtocol()); + query.setParameter("storeIdentifier", personStoreRef.getIdentifier()); return query.list(); } }; @@ -122,16 +142,20 @@ public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao @SuppressWarnings("unchecked") public Set getAllPeople() { + final StoreRef personStoreRef = tenantService.getName(storeRef); + Set answer = new HashSet(); HibernateCallback callback = new HibernateCallback() { public Object doInHibernate(Session session) { - SQLQuery query = getSession().createSQLQuery("SELECT {n.*} FROM alf_node n JOIN alf_node_properties p ON n.id = p.node_id WHERE p.qname_id = :qnameId and n.node_deleted = :False"); + SQLQuery query = getSession().createSQLQuery("SELECT {n.*} FROM alf_node n JOIN alf_node_properties p ON n.id = p.node_id JOIN alf_store s on s.id = n.store_id WHERE p.qname_id = :qnameId and n.node_deleted = :False and s.protocol = :storeProtocol and s.identifier = :storeIdentifier"); query.addEntity("n", NodeImpl.class); query.setParameter("qnameId", qNameId); query.setParameter("False", Boolean.FALSE); + query.setParameter("storeProtocol", personStoreRef.getProtocol()); + query.setParameter("storeIdentifier", personStoreRef.getIdentifier()); return query.list(); } }; diff --git a/source/java/org/alfresco/repo/tenant/MultiTAdminServiceImpl.java b/source/java/org/alfresco/repo/tenant/MultiTAdminServiceImpl.java index d79e25a07c..bb089532b9 100755 --- a/source/java/org/alfresco/repo/tenant/MultiTAdminServiceImpl.java +++ b/source/java/org/alfresco/repo/tenant/MultiTAdminServiceImpl.java @@ -50,8 +50,6 @@ import org.alfresco.repo.node.db.DbNodeServiceImpl; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; -import org.alfresco.repo.usage.UserUsageBootstrapJob; -import org.alfresco.repo.usage.UserUsageTrackingComponent; import org.alfresco.repo.workflow.WorkflowDeployer; import org.alfresco.service.cmr.admin.RepoAdminService; import org.alfresco.service.cmr.attributes.AttributeService; @@ -895,9 +893,11 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo spacesImporterBootstrap.bootstrap(); + /* TODO - pending fix for ETHREEOH-283 // calculate any missing usages UserUsageTrackingComponent userUsageTrackingComponent = (UserUsageTrackingComponent)ctx.getBean(UserUsageBootstrapJob.KEY_COMPONENT); userUsageTrackingComponent.bootstrapInternal(); + */ logger.debug("Bootstrapped store: " + tenantService.getBaseName(bootstrapStoreRef)); } diff --git a/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java b/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java index 26a80eac8e..04290a5cdb 100644 --- a/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java +++ b/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java @@ -32,6 +32,7 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import junit.framework.TestCase; @@ -104,6 +105,7 @@ public class MultiTDemoTest extends TestCase public static final String TEST_USER1 = "alice"; public static final String TEST_USER2 = "bob"; public static final String TEST_USER3 = "eve"; + public static final String TEST_USER4 = "fred"; private static final int DEFAULT_DM_STORE_COUNT = 6; @@ -146,6 +148,17 @@ public class MultiTDemoTest extends TestCase { logger.info("Create tenants"); + Set personRefs = personService.getAllPeople(); + //assertEquals(2, personRefs.size()); // super-tenant: admin, guest (note: checking for 2 assumes that this test is run in a fresh bootstrap env) + for (NodeRef personRef : personRefs) + { + String userName = (String)nodeService.getProperty(personRef, ContentModel.PROP_USERNAME); + for (final String tenantDomain : tenants) + { + assertFalse("Unexpected (tenant) user: "+userName, userName.endsWith(tenantDomain)); + } + } + try { for (final String tenantDomain : tenants) @@ -181,6 +194,17 @@ public class MultiTDemoTest extends TestCase { logger.info("Create demo users"); + Set personRefs = personService.getAllPeople(); + //assertEquals(2, personRefs.size()); // super-tenant: admin, guest (note: checking for 2 assumes that this test is run in a fresh bootstrap env) + for (NodeRef personRef : personRefs) + { + String userName = (String)nodeService.getProperty(personRef, ContentModel.PROP_USERNAME); + for (final String tenantDomain : tenants) + { + assertFalse("Unexpected (tenant) user: "+userName, userName.endsWith(tenantDomain)); + } + } + try { for (final String tenantDomain : tenants) @@ -188,22 +212,50 @@ public class MultiTDemoTest extends TestCase String tenantAdminName = tenantService.getDomainUser(TenantService.ADMIN_BASENAME, tenantDomain); AuthenticationUtil.runAs(new RunAsWork() + { + public Object doWork() throws Exception + { + createUser(TEST_USER1, tenantDomain, "welcome"); + createUser(TEST_USER2, tenantDomain, "welcome"); + + if (tenantDomain.equals(TEST_TENANT_DOMAIN2)) { - public Object doWork() throws Exception - { - createUser(TEST_USER1, tenantDomain, "welcome"); - - createUser(TEST_USER2, tenantDomain, "welcome"); - - if (tenantDomain.equals(TEST_TENANT_DOMAIN2)) - { - createUser(TEST_USER3, tenantDomain, "welcome"); - } - - return null; - } - }, tenantAdminName); + createUser(TEST_USER3, tenantDomain, "welcome"); + } + + return null; + } + }, tenantAdminName); + } + + for (final String tenantDomain : tenants) + { + String tenantAdminName = tenantService.getDomainUser(TenantService.ADMIN_BASENAME, tenantDomain); + AuthenticationUtil.runAs(new RunAsWork() + { + public Object doWork() throws Exception + { + Set personRefs = personService.getAllPeople(); + + if (tenantDomain.equals(TEST_TENANT_DOMAIN2)) + { + assertEquals(5, personRefs.size()); // admin@tenant, guest@tenant, alice@tenant, bob@tenant, eve@tenant + } + else + { + assertEquals(4, personRefs.size()); // admin@tenant, guest@tenant, alice@tenant, bob@tenant + } + + for (NodeRef personRef : personRefs) + { + String userName = (String)nodeService.getProperty(personRef, ContentModel.PROP_USERNAME); + assertTrue(userName.endsWith(tenantDomain)); + } + + return null; + } + }, tenantAdminName); } } catch (Throwable t) @@ -212,7 +264,7 @@ public class MultiTDemoTest extends TestCase t.printStackTrace(new PrintWriter(stackTrace)); System.err.println(stackTrace.toString()); throw t; - } + } } public void testLoginUsers() throws Throwable @@ -431,6 +483,37 @@ public class MultiTDemoTest extends TestCase } } + public void testGetProperty() + { + logger.info("Test get property"); + + final String tenantDomain = TEST_TENANT_DOMAIN1; + String tenantAdminName = tenantService.getDomainUser(TenantService.ADMIN_BASENAME, tenantDomain); + + AuthenticationUtil.runAs(new RunAsWork() + { + public Object doWork() throws Exception + { + NodeRef personNodeRef = createUser(TEST_USER4, tenantDomain, "welcome"); + + // Test nodeRef property + NodeRef homeFolderNodeRef = (NodeRef)nodeService.getProperty(personNodeRef, ContentModel.PROP_HOMEFOLDER); + assertFalse(homeFolderNodeRef.toString().contains(tenantDomain)); + + Map props = (Map)nodeService.getProperties(personNodeRef); + assertFalse(props.get(ContentModel.PROP_HOMEFOLDER).toString().contains(tenantDomain)); + + // Test "store-identifier" property + String storeId = (String)nodeService.getProperty(personNodeRef, ContentModel.PROP_STORE_IDENTIFIER); + assertFalse(storeId.contains(tenantDomain)); + + assertFalse(props.get(ContentModel.PROP_STORE_IDENTIFIER).toString().contains(tenantDomain)); + + return null; + } + }, tenantAdminName); + } + private void createGroup(String shortName, String parentShortName) { // create new Group using authority Service @@ -458,10 +541,12 @@ public class MultiTDemoTest extends TestCase } - private void createUser(String baseUserName, String tenantDomain, String password) + private NodeRef createUser(String baseUserName, String tenantDomain, String password) { String userName = tenantService.getDomainUser(baseUserName, tenantDomain); + NodeRef personNodeRef = null; + if (! this.authenticationService.authenticationExists(userName)) { NodeRef baseHomeFolder = getUserHomesNodeRef(SPACES_STORE); @@ -483,13 +568,21 @@ public class MultiTDemoTest extends TestCase personProperties.put(ContentModel.PROP_LASTNAME, baseUserName+"-"+tenantDomain); // add domain suffix here for demo only personProperties.put(ContentModel.PROP_EMAIL, userName); - NodeRef newPerson = this.personService.createPerson(personProperties); + personNodeRef = this.personService.createPerson(personProperties); // ensure the user can access their own Person object - this.permissionService.setPermission(newPerson, userName, permissionService.getAllPermission(), true); + this.permissionService.setPermission(personNodeRef, userName, permissionService.getAllPermission(), true); logger.info("Created user " + userName); } + else + { + personNodeRef = personService.getPerson(userName); + + logger.info("Found existing user " + userName); + } + + return personNodeRef; } private void loginLogoutUser(String username, String password) diff --git a/source/java/org/alfresco/repo/tenant/MultiTNodeServiceInterceptor.java b/source/java/org/alfresco/repo/tenant/MultiTNodeServiceInterceptor.java index e17035925e..adf27b34ef 100644 --- a/source/java/org/alfresco/repo/tenant/MultiTNodeServiceInterceptor.java +++ b/source/java/org/alfresco/repo/tenant/MultiTNodeServiceInterceptor.java @@ -24,17 +24,23 @@ */ package org.alfresco.repo.tenant; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; +import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; +import org.alfresco.model.ContentModel; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.namespace.QName; import org.alfresco.util.EqualsHelper; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; @@ -164,8 +170,53 @@ public class MultiTNodeServiceInterceptor extends DelegatingIntroductionIntercep // Make the call Object ret = invocation.proceed(); - if (methodName.equals("getStores")) + if (methodName.equals("getProperty")) { + if (ret != null) + { + // Convert the outbound value + QName qname = (QName)args[1]; + if (qname.equals(ContentModel.PROP_STORE_IDENTIFIER)) + { + String rawStoreId = (String)ret; + ret = tenantService.getBaseName(rawStoreId); + } + else + { + ret = convertOutboundValue(ret); + } + } + + return ret; + } + else if (methodName.equals("getProperties")) + { + if (ret != null) + { + // Convert the outbound values + Map rawValues = (Map)ret; + for (Map.Entry rawValue : rawValues.entrySet()) + { + QName qname = rawValue.getKey(); + Serializable value = rawValue.getValue(); + + if (qname.equals(ContentModel.PROP_STORE_IDENTIFIER) && (value != null)) + { + rawValues.put(ContentModel.PROP_STORE_IDENTIFIER, tenantService.getBaseName((String)value)); + } + else + { + rawValues.put(qname, (Serializable)convertOutboundValue(value)); + } + } + + ret = rawValues; + } + + return ret; + } + else if (methodName.equals("getStores")) + { if ((ret == null) || (! (ret instanceof List))) { return null; @@ -254,8 +305,6 @@ public class MultiTNodeServiceInterceptor extends DelegatingIntroductionIntercep return null; } - // TODO use getBaseName ... - // Deal with collections Object value = rawValue; if (rawValue instanceof Collection) @@ -265,7 +314,7 @@ public class MultiTNodeServiceInterceptor extends DelegatingIntroductionIntercep else if (rawValue instanceof StoreRef) { StoreRef ref = (StoreRef) rawValue; - value = tenantService.getName(ref); + value = tenantService.getBaseName(ref); } else if (rawValue instanceof NodeRef) { @@ -275,14 +324,14 @@ public class MultiTNodeServiceInterceptor extends DelegatingIntroductionIntercep else if (rawValue instanceof ChildAssociationRef) { ChildAssociationRef ref = (ChildAssociationRef) rawValue; + // TODO use getBaseName ... fix tenant bootstrap value = tenantService.getName(ref); } else if (rawValue instanceof AssociationRef) { AssociationRef ref = (AssociationRef) rawValue; - value = tenantService.getName(ref); + value = tenantService.getBaseName(ref); } - /* TODO else if (rawValue instanceof Path) { Path ref = (Path)rawValue; @@ -299,7 +348,6 @@ public class MultiTNodeServiceInterceptor extends DelegatingIntroductionIntercep } value = outboundPath; } - */ // Done return value; }