diff --git a/source/java/org/alfresco/repo/security/authentication/RepositoryAuthenticationDao.java b/source/java/org/alfresco/repo/security/authentication/RepositoryAuthenticationDao.java index fb2d02175e..5a64853a93 100644 --- a/source/java/org/alfresco/repo/security/authentication/RepositoryAuthenticationDao.java +++ b/source/java/org/alfresco/repo/security/authentication/RepositoryAuthenticationDao.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2013 Alfresco Software Limited. + * Copyright (C) 2005-2014 Alfresco Software Limited. * * This file is part of Alfresco * @@ -295,15 +295,18 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In private NodeRef getUserFolderLocation(String caseSensitiveUserName) { - NodeRef userNodeRef = singletonCache.get(KEY_USERFOLDER_NODEREF); + // Use the tenant aware cache key + // see MNT-10338 + final String cacheKey = tenantService.getUserDomain(caseSensitiveUserName) + KEY_USERFOLDER_NODEREF; + NodeRef userNodeRef = singletonCache.get(cacheKey); if (userNodeRef == null) { QName qnameAssocSystem = QName.createQName("sys", "system", namespacePrefixResolver); QName qnameAssocUsers = QName.createQName("sys", "people", namespacePrefixResolver); - - //StoreRef userStoreRef = tenantService.getName(caseSensitiveUserName, new StoreRef(STOREREF_USERS.getProtocol(), STOREREF_USERS.getIdentifier())); - StoreRef userStoreRef = new StoreRef(STOREREF_USERS.getProtocol(), STOREREF_USERS.getIdentifier()); - + + // Use tenant domain to get a valid storeRef + StoreRef userStoreRef = tenantService.getName(caseSensitiveUserName, new StoreRef(STOREREF_USERS.getProtocol(), STOREREF_USERS.getIdentifier())); + // AR-527 NodeRef rootNode = nodeService.getRootNode(userStoreRef); List results = nodeService.getChildAssocs(rootNode, RegexQNamePattern.MATCH_ALL, qnameAssocSystem); @@ -325,7 +328,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In { userNodeRef = tenantService.getName(results.get(0).getChildRef()); } - singletonCache.put(KEY_USERFOLDER_NODEREF, userNodeRef); + singletonCache.put(cacheKey, userNodeRef); } return userNodeRef; } diff --git a/source/test-java/org/alfresco/repo/security/authentication/AuthenticationTest.java b/source/test-java/org/alfresco/repo/security/authentication/AuthenticationTest.java index 726f49404f..585801c11d 100644 --- a/source/test-java/org/alfresco/repo/security/authentication/AuthenticationTest.java +++ b/source/test-java/org/alfresco/repo/security/authentication/AuthenticationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2011 Alfresco Software Limited. + * Copyright (C) 2005-2014 Alfresco Software Limited. * * This file is part of Alfresco * @@ -51,7 +51,9 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl.ExpiryMode; import org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl.Ticket; import org.alfresco.repo.security.authentication.RepositoryAuthenticationDao.CacheEntry; +import org.alfresco.repo.tenant.TenantAdminService; import org.alfresco.repo.tenant.TenantService; +import org.alfresco.repo.tenant.TenantUtil; import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; @@ -96,6 +98,7 @@ public class AuthenticationTest extends TestCase private TransactionService transactionService; private PersonService pubPersonService; private PersonService personService; + private TenantAdminService tenantAdminService; private UserTransaction userTransaction; private NodeRef rootNodeRef; @@ -112,6 +115,11 @@ public class AuthenticationTest extends TestCase private SimpleCache authenticationCache; private SimpleCache immutableSingletonCache; + private static final String TEST_RUN = System.currentTimeMillis()+""; + private static final String TEST_TENANT_DOMAIN = TEST_RUN+".my.test"; + private static final String DEFAULT_ADMIN_PW = "admin"; + private static final String TENANT_ADMIN_PW = DEFAULT_ADMIN_PW + TEST_TENANT_DOMAIN; + public AuthenticationTest() { super(); @@ -152,6 +160,7 @@ public class AuthenticationTest extends TestCase // permissionServiceSPI = (PermissionServiceSPI) // ctx.getBean("permissionService"); ticketsCache = (SimpleCache) ctx.getBean("ticketsCache"); + tenantAdminService = (TenantAdminService) ctx.getBean("tenantAdminService"); dao = (MutableAuthenticationDao) ctx.getBean("authenticationDao"); @@ -440,6 +449,40 @@ public class AuthenticationTest extends TestCase return dao; } + /** + * Test for ALF-20680 + * Test of the {@link RepositoryAuthenticationDao#getUserFolderLocation(String)} in multitenancy + */ + public void testAuthenticateMultiTenant() + { + // Create a tenant domain + TenantUtil.runAsSystemTenant(new TenantUtil.TenantRunAsWork() + { + public Object doWork() throws Exception + { + if (!tenantAdminService.existsTenant(TEST_TENANT_DOMAIN)) + { + tenantAdminService.createTenant(TEST_TENANT_DOMAIN, TENANT_ADMIN_PW.toCharArray(), null); + } + return null; + } + }, TenantService.DEFAULT_DOMAIN); + + // Use default admin + authenticateMultiTenantWork(AuthenticationUtil.getAdminUserName(), DEFAULT_ADMIN_PW); + + // Use tenant admin + authenticateMultiTenantWork(AuthenticationUtil.getAdminUserName() + TenantService.SEPARATOR + TEST_TENANT_DOMAIN, TENANT_ADMIN_PW); + } + + private void authenticateMultiTenantWork(String userName, String password) + { + String hashedPassword = dao.getMD4HashedPassword(userName); + assertNotNull(hashedPassword); + UserDetails userDetails = (UserDetails) dao.loadUserByUsername(userName); + assertEquals(passwordEncoder.encodePassword(password, dao.getSalt(userDetails)), hashedPassword); + } + public void testCreateAndyUserAndOtherCRUD() throws NoSuchAlgorithmException, UnsupportedEncodingException { RepositoryAuthenticationDao dao = createRepositoryAuthenticationDao();