Merged BRANCHES/DEV/THOR1 to HEAD:

=> CLOUD-1347 / CLOUD-1348 
   30569: THOR-156
   30776: THOR-172


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@46551 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jan Vonka
2013-02-13 09:42:13 +00:00
parent 1be15184cb
commit 1616d63a25
9 changed files with 127 additions and 299 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2013 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -32,14 +32,18 @@ import net.sf.acegisecurity.providers.dao.User;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.sync.UserRegistrySynchronizer; import org.alfresco.repo.security.sync.UserRegistrySynchronizer;
import org.alfresco.repo.tenant.TenantContextHolder;
import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState; import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.Pair;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -456,20 +460,20 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
{ {
AuthenticationException ae = null; AuthenticationException ae = null;
String userName; String userNameIn;
CurrentUserCallback(String userName) CurrentUserCallback(String userNameIn)
{ {
this.userName = userName; this.userNameIn = userNameIn;
} }
} }
class CheckCurrentUserCallback extends CurrentUserCallback class CheckCurrentUserCallback extends CurrentUserCallback
{ {
CheckCurrentUserCallback(String userName) CheckCurrentUserCallback(String userNameIn)
{ {
super(userName); super(userNameIn);
} }
public Authentication execute() throws Throwable public Authentication execute() throws Throwable
@@ -477,6 +481,10 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
try try
{ {
// We must set full authentication before calling runAs in order to retain tickets // We must set full authentication before calling runAs in order to retain tickets
Pair<String, String> userTenant = AuthenticationUtil.getUserTenant(userNameIn);
final String userName = userTenant.getFirst();
final String tenantDomain = userTenant.getSecond();
Authentication authentication = setCurrentUserImpl(userName); Authentication authentication = setCurrentUserImpl(userName);
AuthenticationUtil.runAs(new RunAsWork<Object>() AuthenticationUtil.runAs(new RunAsWork<Object>()
{ {
@@ -495,7 +503,9 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
} }
return null; return null;
} }
}, getSystemUserName(getUserDomain(userName))); }, tenantDomain);
TenantContextHolder.setTenantDomain(tenantDomain);
return authentication; return authentication;
} }
catch (AuthenticationException ae) catch (AuthenticationException ae)
@@ -508,16 +518,20 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
class FixCurrentUserCallback extends CurrentUserCallback class FixCurrentUserCallback extends CurrentUserCallback
{ {
FixCurrentUserCallback(String userName) FixCurrentUserCallback(String userNameIn)
{ {
super(userName); super(userNameIn);
} }
public Authentication execute() throws Throwable public Authentication execute() throws Throwable
{ {
try try
{ {
return setCurrentUserImpl(AuthenticationUtil.runAs(new RunAsWork<String>() Pair<String, String> userTenant = AuthenticationUtil.getUserTenant(userNameIn);
final String userName = userTenant.getFirst();
final String tenantDomain = userTenant.getSecond();
Authentication authentication = setCurrentUserImpl(TenantUtil.runAsSystemTenant(new TenantRunAsWork<String>()
{ {
public String doWork() throws Exception public String doWork() throws Exception
{ {
@@ -543,7 +557,10 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
// checks // checks
return (String) nodeService.getProperty(userNode, ContentModel.PROP_USERNAME); return (String) nodeService.getProperty(userNode, ContentModel.PROP_USERNAME);
} }
}, getSystemUserName(getUserDomain(userName)))); }, tenantDomain));
TenantContextHolder.setTenantDomain(tenantDomain);
return authentication;
} }
catch (AuthenticationException ae) catch (AuthenticationException ae)
{ {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2013 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -32,7 +32,9 @@ import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.authentication.ntlm.NLTMAuthenticator; import org.alfresco.repo.security.authentication.ntlm.NLTMAuthenticator;
import org.alfresco.repo.tenant.TenantContextHolder;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.util.Pair;
public class AuthenticationComponentImpl extends AbstractAuthenticationComponent implements NLTMAuthenticator public class AuthenticationComponentImpl extends AbstractAuthenticationComponent implements NLTMAuthenticator
{ {
@@ -69,10 +71,14 @@ public class AuthenticationComponentImpl extends AbstractAuthenticationComponent
* Authenticate * Authenticate
*/ */
@Override @Override
protected void authenticateImpl(final String userName, final char[] password) throws AuthenticationException protected void authenticateImpl(final String userNameIn, final char[] password) throws AuthenticationException
{ {
try try
{ {
Pair<String, String> userTenant = AuthenticationUtil.getUserTenant(userNameIn);
final String userName = userTenant.getFirst();
final String tenantDomain = userTenant.getSecond();
String normalized = getTransactionService().getRetryingTransactionHelper().doInTransaction( String normalized = getTransactionService().getRetryingTransactionHelper().doInTransaction(
new RetryingTransactionCallback<String>() new RetryingTransactionCallback<String>()
{ {
@@ -90,7 +96,8 @@ public class AuthenticationComponentImpl extends AbstractAuthenticationComponent
} }
}, getSystemUserName(getUserDomain(userName))); }, getSystemUserName(getUserDomain(userName)));
} }
}, true); }, true);
if (normalized == null) if (normalized == null)
{ {
setCurrentUser(userName, UserNameValidationMode.CHECK_AND_FIX); setCurrentUser(userName, UserNameValidationMode.CHECK_AND_FIX);
@@ -99,6 +106,8 @@ public class AuthenticationComponentImpl extends AbstractAuthenticationComponent
{ {
setCurrentUser(normalized, UserNameValidationMode.NONE); setCurrentUser(normalized, UserNameValidationMode.NONE);
} }
TenantContextHolder.setTenantDomain(tenantDomain);
} }
catch (net.sf.acegisecurity.AuthenticationException ae) catch (net.sf.acegisecurity.AuthenticationException ae)
{ {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2013 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -23,6 +23,8 @@ import java.util.Set;
import org.alfresco.repo.management.subsystems.ActivateableBean; import org.alfresco.repo.management.subsystems.ActivateableBean;
import org.alfresco.repo.security.authentication.AuthenticationComponent.UserNameValidationMode; import org.alfresco.repo.security.authentication.AuthenticationComponent.UserNameValidationMode;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil;
public class AuthenticationServiceImpl extends AbstractAuthenticationService implements ActivateableBean public class AuthenticationServiceImpl extends AbstractAuthenticationService implements ActivateableBean
{ {
@@ -70,7 +72,7 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService imp
throw ae; throw ae;
} }
ticketComponent.clearCurrentTicket(); ticketComponent.clearCurrentTicket();
getCurrentTicket(); getCurrentTicket();
} }
public String getCurrentUserName() throws AuthenticationException public String getCurrentUserName() throws AuthenticationException
@@ -125,6 +127,7 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService imp
public String getCurrentTicket() throws AuthenticationException public String getCurrentTicket() throws AuthenticationException
{ {
String userName = getCurrentUserName(); String userName = getCurrentUserName();
// So that preAuthenticationCheck can constrain the creation of new tickets, we first ask for the current ticket // So that preAuthenticationCheck can constrain the creation of new tickets, we first ask for the current ticket
// without auto-creation // without auto-creation
String ticket = ticketComponent.getCurrentTicket(userName, false); String ticket = ticketComponent.getCurrentTicket(userName, false);
@@ -140,6 +143,7 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService imp
public String getNewTicket() public String getNewTicket()
{ {
String userName = getCurrentUserName(); String userName = getCurrentUserName();
try try
{ {
preAuthenticationCheck(userName); preAuthenticationCheck(userName);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2012 Alfresco Software Limited. * Copyright (C) 2005-2013 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -73,7 +73,6 @@ import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.invitation.InvitationException; import org.alfresco.service.cmr.invitation.InvitationException;
import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
@@ -419,23 +418,7 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
*/ */
public NodeRef getPerson(final String userName, final boolean autoCreateHomeFolderAndMissingPersonIfAllowed) public NodeRef getPerson(final String userName, final boolean autoCreateHomeFolderAndMissingPersonIfAllowed)
{ {
// MT share - for activity service system callback return getPersonImpl(userName, autoCreateHomeFolderAndMissingPersonIfAllowed);
if (tenantService.isEnabled() && (AuthenticationUtil.SYSTEM_USER_NAME.equals(AuthenticationUtil.getRunAsUser())) && tenantService.isTenantUser(userName))
{
final String tenantDomain = tenantService.getUserDomain(userName);
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<NodeRef>()
{
public NodeRef doWork() throws Exception
{
return getPersonImpl(userName, autoCreateHomeFolderAndMissingPersonIfAllowed);
}
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
}
else
{
return getPersonImpl(userName, autoCreateHomeFolderAndMissingPersonIfAllowed);
}
} }
private NodeRef getPersonImpl(String userName, boolean autoCreateHomeFolderAndMissingPersonIfAllowed) private NodeRef getPersonImpl(String userName, boolean autoCreateHomeFolderAndMissingPersonIfAllowed)

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2012 Alfresco Software Limited. * Copyright (C) 2005-2013 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -40,8 +40,8 @@ import org.alfresco.query.PagingRequest;
import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.model.Repository; import org.alfresco.repo.model.Repository;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.permissions.impl.AccessPermissionImpl; import org.alfresco.repo.security.permissions.impl.AccessPermissionImpl;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.admin.RepoAdminService; import org.alfresco.service.cmr.admin.RepoAdminService;
import org.alfresco.service.cmr.coci.CheckOutCheckInService; import org.alfresco.service.cmr.coci.CheckOutCheckInService;
@@ -186,6 +186,8 @@ public class MultiTDemoTest extends TestCase
repositoryHelper = (Repository) ctx.getBean("repositoryHelper"); repositoryHelper = (Repository) ctx.getBean("repositoryHelper");
siteService = (SiteService) ctx.getBean("SiteService"); siteService = (SiteService) ctx.getBean("SiteService");
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); // authenticate as super-admin
createTenants(); createTenants();
} }
@@ -225,7 +227,7 @@ public class MultiTDemoTest extends TestCase
private void deleteTestAuthoritiesForTenant(final String[] uniqueGroupNames, final String tenantName) private void deleteTestAuthoritiesForTenant(final String[] uniqueGroupNames, final String tenantName)
{ {
// Check deletion for tenant1 // Check deletion for tenant1
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -246,7 +248,7 @@ public class MultiTDemoTest extends TestCase
private void createTestAuthoritiesForTenant(final String[] uniqueGroupNames, final String tenantName) private void createTestAuthoritiesForTenant(final String[] uniqueGroupNames, final String tenantName)
{ {
// Create groups for tenant // Create groups for tenant
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -269,7 +271,7 @@ public class MultiTDemoTest extends TestCase
private void checkTestAuthoritiesPresence(final String[] uniqueGroupNames, final String tenantName, final boolean shouldPresent) private void checkTestAuthoritiesPresence(final String[] uniqueGroupNames, final String tenantName, final boolean shouldPresent)
{ {
// Check that created permissions are not visible to tenant 2 // Check that created permissions are not visible to tenant 2
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -459,7 +461,7 @@ public class MultiTDemoTest extends TestCase
private void createTenant(final String tenantDomain) private void createTenant(final String tenantDomain)
{ {
// create tenants (if not already created) // create tenants (if not already created)
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -483,7 +485,7 @@ public class MultiTDemoTest extends TestCase
public Object execute() throws Throwable public Object execute() throws Throwable
{ {
// delete tenant (if it exists) // delete tenant (if it exists)
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -512,7 +514,7 @@ public class MultiTDemoTest extends TestCase
createTenant(tenantDomain1); createTenant(tenantDomain1);
String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain1); String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain1);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -558,7 +560,7 @@ public class MultiTDemoTest extends TestCase
{ {
String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -579,7 +581,7 @@ public class MultiTDemoTest extends TestCase
{ {
String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -700,7 +702,7 @@ public class MultiTDemoTest extends TestCase
assertTrue(tenants.size() > 0); assertTrue(tenants.size() > 0);
final int rootGrpsOrigCnt = AuthenticationUtil.runAs(new RunAsWork<Integer>() final int rootGrpsOrigCnt = TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Integer>()
{ {
public Integer doWork() throws Exception public Integer doWork() throws Exception
{ {
@@ -713,7 +715,7 @@ public class MultiTDemoTest extends TestCase
{ {
final String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); final String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -742,7 +744,7 @@ public class MultiTDemoTest extends TestCase
{ {
final String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); final String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -780,7 +782,7 @@ public class MultiTDemoTest extends TestCase
logger.info("Create demo categories"); logger.info("Create demo categories");
// super admin // super admin
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -795,7 +797,7 @@ public class MultiTDemoTest extends TestCase
{ {
String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -903,7 +905,7 @@ public class MultiTDemoTest extends TestCase
{ {
final String tenantUserName = tenantService.getDomainUser(baseUserName, tenantDomain); final String tenantUserName = tenantService.getDomainUser(baseUserName, tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -946,7 +948,7 @@ public class MultiTDemoTest extends TestCase
{ {
final String tenantUserName = tenantService.getDomainUser(baseUserName, tenantDomain); final String tenantUserName = tenantService.getDomainUser(baseUserName, tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -974,7 +976,7 @@ public class MultiTDemoTest extends TestCase
logger.info("Get tenant stores"); logger.info("Get tenant stores");
// system // system
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -989,7 +991,7 @@ public class MultiTDemoTest extends TestCase
}, AuthenticationUtil.getSystemUserName()); }, AuthenticationUtil.getSystemUserName());
// super admin // super admin
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -1002,7 +1004,7 @@ public class MultiTDemoTest extends TestCase
{ {
String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -1023,7 +1025,7 @@ public class MultiTDemoTest extends TestCase
{ {
String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -1056,7 +1058,7 @@ public class MultiTDemoTest extends TestCase
{ {
final String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); final String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -1099,6 +1101,7 @@ public class MultiTDemoTest extends TestCase
} }
} }
// TODO pending THOR-201 / CLOUD-1349 fix
public void test16DeleteArchiveAndRestoreContent() public void test16DeleteArchiveAndRestoreContent()
{ {
logger.info("test delete/archive & restore content"); logger.info("test delete/archive & restore content");
@@ -1107,7 +1110,7 @@ public class MultiTDemoTest extends TestCase
{ {
final String tenantUserName = tenantService.getDomainUser(TEST_USER1, tenantDomain); final String tenantUserName = tenantService.getDomainUser(TEST_USER1, tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -1140,7 +1143,7 @@ public class MultiTDemoTest extends TestCase
{ {
final String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); final String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -1192,7 +1195,7 @@ public class MultiTDemoTest extends TestCase
{ {
final String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain); final String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -1220,7 +1223,7 @@ public class MultiTDemoTest extends TestCase
{ {
final String tenantUserName = tenantService.getDomainUser(TEST_USER1, tenantDomain); final String tenantUserName = tenantService.getDomainUser(TEST_USER1, tenantDomain);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -1253,7 +1256,8 @@ public class MultiTDemoTest extends TestCase
} }
} }
public void test21_ALF_12732() // TODO pending CLOUD-1350 fix
public void xtest21_ALF_12732()
{ {
final String tenantDomain1 = TEST_RUN+".one.alf12732"; final String tenantDomain1 = TEST_RUN+".one.alf12732";
@@ -1265,7 +1269,7 @@ public class MultiTDemoTest extends TestCase
{ {
AuthenticationUtil.setFullyAuthenticatedUser(tenantAdminName); // note: since SiteServiceImpl.setupSitePermissions currently uses getCurrentUserName (rather than runAs) AuthenticationUtil.setFullyAuthenticatedUser(tenantAdminName); // note: since SiteServiceImpl.setupSitePermissions currently uses getCurrentUserName (rather than runAs)
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -1302,7 +1306,7 @@ public class MultiTDemoTest extends TestCase
createTenant(tenantDomain2); createTenant(tenantDomain2);
String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain1); String tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain1);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
@@ -1315,7 +1319,7 @@ public class MultiTDemoTest extends TestCase
}, tenantAdminName); }, tenantAdminName);
tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain2); tenantAdminName = tenantService.getDomainUser(AuthenticationUtil.getAdminUserName(), tenantDomain2);
AuthenticationUtil.runAs(new RunAsWork<Object>() TenantUtil.runAsPrimaryTenant(new TenantRunAsWork<Object>()
{ {
public Object doWork() throws Exception public Object doWork() throws Exception
{ {

View File

@@ -1,19 +1,19 @@
/* /*
* Copyright (C) 2005-2012 Alfresco Software Limited. * Copyright (C) 2005-2013 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
* Alfresco is free software: you can redistribute it and/or modify * 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 * 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 * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.alfresco.repo.tenant; package org.alfresco.repo.tenant;
@@ -46,10 +46,9 @@ import org.springframework.aop.support.DelegatingIntroductionInterceptor;
* Interceptor to translate Node * Interceptor to translate Node
* *
* @since 3.0 * @since 3.0
* @author Derek Hulley * @author Derek Hulley, janv
* @author janv
*/ */
public class MultiTNodeServiceInterceptor extends DelegatingIntroductionInterceptor//implements NodeService public class MultiTNodeServiceInterceptor extends DelegatingIntroductionInterceptor //implements NodeService
{ {
private static final long serialVersionUID = -5462852271914961462L; private static final long serialVersionUID = -5462852271914961462L;
@@ -99,8 +98,8 @@ public class MultiTNodeServiceInterceptor extends DelegatingIntroductionIntercep
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Object invoke(MethodInvocation invocation) throws Throwable public Object invoke(MethodInvocation invocation) throws Throwable
{ {
// See if we can shortcut (for super 'System' only) // See if we can shortcut
if (AuthenticationUtil.getSystemUserName().equals(AuthenticationUtil.getRunAsUser()) || !AuthenticationUtil.isMtEnabled()) if (!AuthenticationUtil.isMtEnabled())
{ {
return invocation.proceed(); return invocation.proceed();
} }
@@ -251,7 +250,7 @@ public class MultiTNodeServiceInterceptor extends DelegatingIntroductionIntercep
// done // done
return ret; return ret;
} }
/** /**
* Convert outbound collection to spoofed (ie. without tenant prefix) values. * Convert outbound collection to spoofed (ie. without tenant prefix) values.
*/ */

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2012 Alfresco Software Limited. * Copyright (C) 2005-2013 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -529,24 +529,28 @@ public class MultiTServiceImpl implements TenantService
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.repo.tenant.TenantService#isTenantUser() * @see org.alfresco.repo.tenant.TenantService#isTenantUser()
*/ */
// TODO review usages (re: cloud external user => more than one domain)
public boolean isTenantUser() public boolean isTenantUser()
{ {
return isTenantUser(AuthenticationUtil.getRunAsUser()); //return isTenantUser(AuthenticationUtil.getRunAsUser());
return (! getCurrentUserDomain().equals(TenantService.DEFAULT_DOMAIN));
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.repo.tenant.TenantService#isTenantUser(java.lang.String) * @see org.alfresco.repo.tenant.TenantService#isTenantUser(java.lang.String)
*/ */
// TODO review usages (re: cloud external user => more than one domain)
public boolean isTenantUser(String username) public boolean isTenantUser(String username)
{ {
// can be null (e.g. for System user / during app ctx init) // can be null (e.g. for System user / during app ctx init)
if (username != null) { if (username != null)
{
int idx = username.lastIndexOf(SEPARATOR); int idx = username.lastIndexOf(SEPARATOR);
if ((idx > 0) && (idx < (username.length()-1))) if ((idx > 0) && (idx < (username.length()-1)))
{ {
return true; return true;
} }
} }
return false; return false;
} }
@@ -687,8 +691,13 @@ public class MultiTServiceImpl implements TenantService
protected void checkTenantEnabled(String tenantDomain) protected void checkTenantEnabled(String tenantDomain)
{ {
Tenant tenant = getTenant(tenantDomain);
if (tenant == null)
{
throw new AlfrescoRuntimeException("Tenant does not exist: " + tenantDomain);
}
// note: System user can access disabled tenants // note: System user can access disabled tenants
if (!AuthenticationUtil.isRunAsUserTheSystemUser() && !(getTenant(tenantDomain).isEnabled())) if (!AuthenticationUtil.isRunAsUserTheSystemUser() && (! tenant.isEnabled()))
{ {
throw new TenantDisabledException(tenantDomain); throw new TenantDisabledException(tenantDomain);
} }

View File

@@ -1,201 +0,0 @@
/*
* Copyright (C) 2005-2012 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.tenant;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
/**
* Utility helper methods to change the tenant context for threads.
*
* @since Thor
*/
public class TenantUtil
{
public interface TenantRunAsWork<Result>
{
/**
* Method containing the work to be done
*
* @return Return the result of the operation
*/
Result doWork() throws Exception;
}
/**
* Execute a unit of work in a given tenant context. The thread's tenant context will be returned to its normal state
* after the call.
*
* @param runAsWork the unit of work to do
* @param uid the user ID
* @return Returns the work's return value
*/
public static <R> R runAsPrimaryTenant(final TenantRunAsWork<R> runAsWork, String user)
{
// TODO need to differentiate between
// - tenant user - with implied context (in MT Ent world)
// - system users as a tenant
// - super tenant only
// etc
// TODO for now, this is just a brute force change of tenant regardless of above
// scenarios
String runAsUser = AuthenticationUtil.getRunAsUser();
if (runAsUser == null || runAsUser.equals(user))
{
return runAsWork(runAsWork);
}
else
{
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<R>()
{
public R doWork()
{
return runAsWork(runAsWork);
}
}, user);
}
}
/**
* Execute a unit of work in a given tenant context. The thread's tenant context will be returned to its normal state
* after the call.
*
* @param runAsWork the unit of work to do
* @param uid the user ID
* @param tenanDomain the tenant domain
* @return Returns the work's return value
*/
public static <R> R runAsUserTenant(final TenantRunAsWork<R> runAsWork, final String uid, final String tenantDomain)
{
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<R>()
{
public R doWork()
{
return runAsTenant(runAsWork, tenantDomain);
}
}, uid);
}
/**
* Execute a unit of work in a given tenant context. The thread's tenant context will be returned to its normal state
* after the call.
*
* @param runAsWork the unit of work to do
* @param uid the user ID
* @return Returns the work's return value
*/
public static <R> R runAsTenant(final TenantRunAsWork<R> runAsWork, String tenantDomain)
{
// TODO need to differentiate between
// - tenant user - with implied context (in MT Ent world)
// - system users as a tenant
// - super tenant only
// etc
// TODO for now, this is just a brute force change of tenant regardless of above
// scenarios
if (getCurrentDomain().equals(tenantDomain))
{
return runAsWork(runAsWork);
}
else
{
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<R>()
{
public R doWork()
{
return runAsWork(runAsWork);
}
}, AuthenticationUtil.getRunAsUser() + TenantService.SEPARATOR + tenantDomain);
}
}
public static <R> R runAsDefaultTenant(final TenantRunAsWork<R> runAsWork)
{
// Note: with MT Enterprise, if you're current user is not already part of the default domain then this will switch to System
if (getCurrentDomain().equals(TenantService.DEFAULT_DOMAIN))
{
return runAsWork(runAsWork);
}
else
{
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<R>()
{
public R doWork()
{
return runAsWork(runAsWork);
}
}, AuthenticationUtil.getSystemUserName() + TenantService.SEPARATOR); // force default domain;
}
}
// switch tenant and run as System within that tenant
public static <R> R runAsSystemTenant(final TenantRunAsWork<R> runAsWork, final String tenantDomain)
{
StringBuffer systemUser = new StringBuffer().append(AuthenticationUtil.getSystemUserName());
if (AuthenticationUtil.isMtEnabled())
{
systemUser.append(TenantService.SEPARATOR).append(tenantDomain);
}
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<R>()
{
public R doWork()
{
return runAsWork(runAsWork);
}
}, systemUser.toString());
}
private static <R> R runAsWork(final TenantRunAsWork<R> runAsWork)
{
try
{
return runAsWork.doWork();
}
catch (Throwable exception)
{
// Re-throw the exception
if (exception instanceof RuntimeException)
{
throw (RuntimeException) exception;
}
throw new RuntimeException("Error during run as.", exception);
}
}
// note: this does not check if tenant is enabled (unlike non-static MultiTServiceImpl.getCurrentUserDomain)
public static String getCurrentDomain()
{
if (AuthenticationUtil.isMtEnabled())
{
String runAsUser = AuthenticationUtil.getRunAsUser();
if (runAsUser != null)
{
int idx = runAsUser.lastIndexOf(TenantService.SEPARATOR);
if ((idx > 0) && (idx < (runAsUser.length()-1)))
{
return runAsUser.substring(idx+1);
}
}
}
return TenantService.DEFAULT_DOMAIN;
}
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2013 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -18,10 +18,13 @@
*/ */
package org.alfresco.repo.transaction; package org.alfresco.repo.transaction;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
/** /**
@@ -45,7 +48,8 @@ public class TransactionAwareSingleton<T> extends TransactionListenerAdapter
private final String txnKey; private final String txnKey;
private final ReadLock singletonReadLock; private final ReadLock singletonReadLock;
private final WriteLock singletonWriteLock; private final WriteLock singletonWriteLock;
private Object singletonValue;
private Map<String, Object> tenantSingletonValue = new HashMap<String, Object>(1); // tenant-aware
public TransactionAwareSingleton() public TransactionAwareSingleton()
{ {
@@ -61,7 +65,7 @@ public class TransactionAwareSingleton<T> extends TransactionListenerAdapter
singletonWriteLock.lock(); singletonWriteLock.lock();
try try
{ {
singletonValue = value; tenantSingletonValue.put(TenantUtil.getCurrentDomain(), value);
} }
finally finally
{ {
@@ -75,7 +79,7 @@ public class TransactionAwareSingleton<T> extends TransactionListenerAdapter
singletonReadLock.lock(); singletonReadLock.lock();
try try
{ {
return singletonValue; return tenantSingletonValue.get(TenantUtil.getCurrentDomain());
} }
finally finally
{ {
@@ -144,4 +148,4 @@ public class TransactionAwareSingleton<T> extends TransactionListenerAdapter
{ {
public Object newValue; public Object newValue;
} }
} }