Merged V3.0 to HEAD

12218: MT - fix ETHREEOH-992
  12224: MT - fix ETHREEOH-1000
  12230: Abstracted ThreadLocal usage for authentication stacks


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12527 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jan Vonka
2008-12-22 10:50:01 +00:00
parent e534978b95
commit ee74529c57
5 changed files with 95 additions and 44 deletions

View File

@@ -127,6 +127,11 @@
</property> </property>
</bean> </bean>
<!-- Bootstrap MT (multi-tenancy) if applicable -->
<bean id="multiTenantBootstrap" class="org.alfresco.repo.tenant.MultiTenantBootstrap" >
<property name="tenantAdminService" ref="tenantAdminService" />
</bean>
<!-- Load models --> <!-- Load models -->
<bean id="dictionaryRepositoryBootstrap" class="org.alfresco.repo.dictionary.DictionaryRepositoryBootstrap"> <bean id="dictionaryRepositoryBootstrap" class="org.alfresco.repo.dictionary.DictionaryRepositoryBootstrap">
@@ -333,10 +338,6 @@
</property> </property>
</bean> </bean>
<bean id="multiTenantBootstrap" class="org.alfresco.repo.tenant.MultiTenantBootstrap" >
<property name="tenantAdminService" ref="tenantAdminService" />
</bean>
<bean id="workflowBootstrap" parent="workflowDeployer"> <bean id="workflowBootstrap" parent="workflowDeployer">
<property name="workflowDefinitions"> <property name="workflowDefinitions">
<list> <list>

View File

@@ -38,6 +38,9 @@
<property name="behaviourFilter"> <property name="behaviourFilter">
<ref bean="policyBehaviourFilter"/> <ref bean="policyBehaviourFilter"/>
</property> </property>
<property name="tenantService">
<ref bean="tenantService"/>
</property>
<property name="transactionInvocationHandlerFactory"> <property name="transactionInvocationHandlerFactory">
<ref bean="policyTransactionHandlerFactory"/> <ref bean="policyTransactionHandlerFactory"/>
</property> </property>

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2007 Alfresco Software Limited. * Copyright (C) 2005-2008 Alfresco Software Limited.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@@ -32,6 +32,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.alfresco.repo.policy.Policy.Arg; import org.alfresco.repo.policy.Policy.Arg;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.ClassDefinition; import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
@@ -103,6 +104,16 @@ public class PolicyComponentImpl implements PolicyComponent
this.behaviourFilter = filter; this.behaviourFilter = filter;
} }
/**
* Sets the tenant service
*
* @param tenantService
*/
public void setTenantService(TenantService tenantService)
{
PolicyFactory.setTenantService(tenantService);
}
/** /**
* Sets the transaction-based policy invocation handler * Sets the transaction-based policy invocation handler

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2007 Alfresco Software Limited. * Copyright (C) 2005-2008 Alfresco Software Limited.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@@ -34,6 +34,11 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
import org.alfresco.repo.tenant.TenantService;
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.StoreRef;
/** /**
@@ -58,6 +63,9 @@ import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
// Transaction Invocation Handler Factory // Transaction Invocation Handler Factory
private static TransactionInvocationHandlerFactory transactionHandlerFactory = null; private static TransactionInvocationHandlerFactory transactionHandlerFactory = null;
// Tenant Service
private static TenantService tenantService = null;
/** /**
* Construct. * Construct.
@@ -82,6 +90,16 @@ import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
transactionHandlerFactory = factory; transactionHandlerFactory = factory;
} }
/**
* Sets the Tenant Service
*
* @param service
*/
protected static void setTenantService(TenantService service)
{
tenantService = service;
}
/** /**
* Gets the Policy class created by this factory * Gets the Policy class created by this factory
@@ -222,6 +240,43 @@ import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
*/ */
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{ {
if ((tenantService != null) && (tenantService.isEnabled()) && (args != null))
{
// Convert each of the arguments to the spoofed (no tenant prefix) reference
for (int i = 0; i < args.length; i++)
{
Object arg = args[i];
Object newArg = arg;
if (arg == null)
{
// No conversion possible
}
if (arg instanceof StoreRef)
{
StoreRef ref = (StoreRef) arg;
newArg = tenantService.getBaseName(ref);
}
else if (arg instanceof NodeRef)
{
NodeRef ref = (NodeRef) arg;
newArg = tenantService.getBaseName(ref);
}
else if (arg instanceof ChildAssociationRef)
{
ChildAssociationRef ref = (ChildAssociationRef) arg;
newArg = tenantService.getBaseName(ref);
}
else if (arg instanceof AssociationRef)
{
AssociationRef ref = (AssociationRef) arg;
newArg = tenantService.getBaseName(ref);
}
// Substitute the new value
args[i] = newArg;
}
}
// Handle PolicyList level methods // Handle PolicyList level methods
if (method.getDeclaringClass().equals(PolicyList.class)) if (method.getDeclaringClass().equals(PolicyList.class))
{ {

View File

@@ -463,14 +463,21 @@ public abstract class AuthenticationUtil
} }
} }
private static ThreadLocal<Stack<Authentication>> threadLocalFullAuthenticationStack; static class ThreadLocalStack extends ThreadLocal<Stack<Authentication>> {
private static ThreadLocal<Stack<Authentication>> threadLocalRunAsAuthenticationStack;
static /* (non-Javadoc)
* @see java.lang.ThreadLocal#initialValue()
*/
@Override
protected Stack<Authentication> initialValue()
{ {
threadLocalFullAuthenticationStack = new ThreadLocal<Stack<Authentication>>(); return new Stack<Authentication>();
threadLocalRunAsAuthenticationStack = new ThreadLocal<Stack<Authentication>>();
} }
}
private static ThreadLocal<Stack<Authentication>> threadLocalFullAuthenticationStack = new ThreadLocalStack();
private static ThreadLocal<Stack<Authentication>> threadLocalRunAsAuthenticationStack = new ThreadLocalStack();
/** /**
* Push the current authentication context onto a threadlocal stack. * Push the current authentication context onto a threadlocal stack.
*/ */
@@ -478,21 +485,8 @@ public abstract class AuthenticationUtil
{ {
Authentication originalFullAuthentication = AuthenticationUtil.getFullAuthentication(); Authentication originalFullAuthentication = AuthenticationUtil.getFullAuthentication();
Authentication originalRunAsAuthentication = AuthenticationUtil.getRunAsAuthentication(); Authentication originalRunAsAuthentication = AuthenticationUtil.getRunAsAuthentication();
threadLocalFullAuthenticationStack.get().push(originalFullAuthentication);
Stack<Authentication> fullAuthenticationStack = threadLocalFullAuthenticationStack.get(); threadLocalRunAsAuthenticationStack.get().push(originalRunAsAuthentication);
if (fullAuthenticationStack == null)
{
fullAuthenticationStack = new Stack<Authentication>();
threadLocalFullAuthenticationStack.set(fullAuthenticationStack);
}
Stack<Authentication> runAsAuthenticationStack = threadLocalRunAsAuthenticationStack.get();
if (runAsAuthenticationStack == null)
{
runAsAuthenticationStack = new Stack<Authentication>();
threadLocalRunAsAuthenticationStack.set(runAsAuthenticationStack);
}
fullAuthenticationStack.push(originalFullAuthentication);
runAsAuthenticationStack.push(originalRunAsAuthentication);
} }
/** /**
@@ -500,21 +494,8 @@ public abstract class AuthenticationUtil
*/ */
public static void popAuthentication() public static void popAuthentication()
{ {
Stack<Authentication> fullAuthenticationStack = threadLocalFullAuthenticationStack.get(); Authentication originalFullAuthentication = threadLocalFullAuthenticationStack.get().pop();
if (fullAuthenticationStack == null) Authentication originalRunAsAuthentication = threadLocalRunAsAuthenticationStack.get().pop();
{
fullAuthenticationStack = new Stack<Authentication>();
threadLocalFullAuthenticationStack.set(fullAuthenticationStack);
}
Stack<Authentication> runAsAuthenticationStack = threadLocalRunAsAuthenticationStack.get();
if (runAsAuthenticationStack == null)
{
runAsAuthenticationStack = new Stack<Authentication>();
threadLocalRunAsAuthenticationStack.set(runAsAuthenticationStack);
}
Authentication originalFullAuthentication = fullAuthenticationStack.pop();
Authentication originalRunAsAuthentication = runAsAuthenticationStack.pop();
if (originalFullAuthentication == null) if (originalFullAuthentication == null)
{ {
AuthenticationUtil.clearCurrentSecurityContext(); AuthenticationUtil.clearCurrentSecurityContext();