diff --git a/config/alfresco/bootstrap-context.xml b/config/alfresco/bootstrap-context.xml
index d516af35c2..df272fc08c 100644
--- a/config/alfresco/bootstrap-context.xml
+++ b/config/alfresco/bootstrap-context.xml
@@ -32,8 +32,11 @@
-->
- ${shutdown.backstop.timeout}
+ ${shutdown.backstop.timeout}
+
+ ${shutdown.backstop.enabled}
+
diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties
index cf83b9364a..cb4e1463b4 100644
--- a/config/alfresco/repository.properties
+++ b/config/alfresco/repository.properties
@@ -60,6 +60,7 @@ system.bootstrap.config_check.strict=true
# in ms, 10,000 is 10 seconds
#
shutdown.backstop.timeout=10000
+shutdown.backstop.enabled=true
# Server Single User Mode
# note:
diff --git a/source/java/org/alfresco/repo/security/authentication/AlfrescoSecureContextImpl.java b/source/java/org/alfresco/repo/security/authentication/AlfrescoSecureContextImpl.java
index cff606a330..896fb651ae 100644
--- a/source/java/org/alfresco/repo/security/authentication/AlfrescoSecureContextImpl.java
+++ b/source/java/org/alfresco/repo/security/authentication/AlfrescoSecureContextImpl.java
@@ -35,11 +35,11 @@ import net.sf.acegisecurity.context.ContextInvalidException;
*/
public class AlfrescoSecureContextImpl implements AlfrescoSecureContext
{
- Authentication storedAuthentication;
+ private Authentication storedAuthentication;
- Authentication realAuthentication;
+ private Authentication realAuthentication;
- Authentication effectiveAuthentication;
+ private Authentication effectiveAuthentication;
/**
* ACEGI
@@ -55,7 +55,6 @@ public class AlfrescoSecureContextImpl implements AlfrescoSecureContext
public void setAuthentication(Authentication newAuthentication)
{
setEffectiveAuthentication(newAuthentication);
- setRealAuthentication(newAuthentication);
}
/**
diff --git a/source/java/org/alfresco/repo/security/authentication/AuthenticationTest.java b/source/java/org/alfresco/repo/security/authentication/AuthenticationTest.java
index a704f009cd..bc48a802c0 100644
--- a/source/java/org/alfresco/repo/security/authentication/AuthenticationTest.java
+++ b/source/java/org/alfresco/repo/security/authentication/AuthenticationTest.java
@@ -48,6 +48,7 @@ import net.sf.acegisecurity.providers.dao.SaltSource;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cache.SimpleCache;
+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.tenant.TenantService;
@@ -58,6 +59,7 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AuthenticationService;
+import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.DynamicNamespacePrefixResolver;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.NamespaceService;
@@ -109,6 +111,12 @@ public class AuthenticationTest extends TestCase
private AuthenticationComponent authenticationComponentImpl;
+ private TransactionService transactionService;
+
+ private PersonService pubPersonService;
+
+ private PersonService personService;
+
public AuthenticationTest()
{
super();
@@ -132,6 +140,8 @@ public class AuthenticationTest extends TestCase
pubAuthenticationService = (AuthenticationService) ctx.getBean("AuthenticationService");
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
authenticationComponentImpl = (AuthenticationComponent) ctx.getBean("authenticationComponent");
+ pubPersonService = (PersonService) ctx.getBean("PersonService");
+ personService = (PersonService) ctx.getBean("personService");
// permissionServiceSPI = (PermissionServiceSPI)
// ctx.getBean("permissionService");
ticketsCache = (SimpleCache) ctx.getBean("ticketsCache");
@@ -140,7 +150,7 @@ public class AuthenticationTest extends TestCase
authenticationManager = (AuthenticationManager) ctx.getBean("authenticationManager");
saltSource = (SaltSource) ctx.getBean("saltSource");
- TransactionService transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE.getLocalName());
+ transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE.getLocalName());
userTransaction = transactionService.getUserTransaction();
userTransaction.begin();
@@ -176,6 +186,12 @@ public class AuthenticationTest extends TestCase
{
dao.deleteUser("andy");
}
+
+ if(personService.personExists("andy"))
+ {
+ personService.deletePerson("andy");
+ }
+
}
@Override
@@ -193,6 +209,76 @@ public class AuthenticationTest extends TestCase
return properties;
}
+ public void testSystemTicket() throws Exception
+ {
+ assertNull(AuthenticationUtil.getCurrentRealAuthentication());
+ assertNull(AuthenticationUtil.getCurrentEffectiveAuthentication());
+ assertNull(AuthenticationUtil.getCurrentStoredAuthentication());
+
+
+ authenticationComponent.setSystemUserAsCurrentUser();
+ pubAuthenticationService.createAuthentication("andy", "andy".toCharArray());
+
+ pubAuthenticationService.clearCurrentSecurityContext();
+
+ assertNull(AuthenticationUtil.getCurrentRealAuthentication());
+ assertNull(AuthenticationUtil.getCurrentEffectiveAuthentication());
+ assertNull(AuthenticationUtil.getCurrentStoredAuthentication());
+
+ // Authenticate
+ pubAuthenticationService.authenticate("andy", "andy".toCharArray());
+
+ // Get current user name
+ String userName = pubAuthenticationService.getCurrentUserName();
+ assertEquals("andy", userName);
+
+ // Get ticket
+ String ticket = pubAuthenticationService.getCurrentTicket();
+ assertEquals("andy", ticketComponent.getAuthorityForTicket(ticket));
+
+ // Get logged in user ...
+ // Get userName
+ userName = pubAuthenticationService.getCurrentUserName();
+ assertEquals("andy", userName);
+ // get Person
+ assertFalse(pubPersonService.personExists(userName));
+
+ AuthenticationUtil.runAs(new RunAsWork() {
+
+ public Object doWork() throws Exception
+ {
+ // TODO Auto-generated method stub
+ assertEquals("andy", ticketComponent.getAuthorityForTicket(pubAuthenticationService.getCurrentTicket()));
+ return null;
+ }}, AuthenticationUtil.getSystemUserName());
+
+ pubPersonService.getPerson(userName);
+ assertTrue(pubPersonService.personExists(userName));
+ // re-getTicket
+ String newticket = pubAuthenticationService.getCurrentTicket();
+ assertEquals(ticket, newticket);
+ assertEquals("andy", ticketComponent.getAuthorityForTicket(newticket));
+
+
+ userName = pubAuthenticationService.getCurrentUserName();
+ assertEquals("andy", userName);
+
+ // new TX
+
+ userTransaction.commit();
+ userTransaction = transactionService.getUserTransaction();
+ userTransaction.begin();
+
+ pubAuthenticationService.validate(ticket);
+ userName = pubAuthenticationService.getCurrentUserName();
+ assertEquals("andy", userName);
+
+ pubAuthenticationService.validate(newticket);
+ userName = pubAuthenticationService.getCurrentUserName();
+ assertEquals("andy", userName);
+
+ }
+
public void xtestScalability()
{
long create = 0;
diff --git a/source/java/org/alfresco/repo/security/authentication/AuthenticationUtil.java b/source/java/org/alfresco/repo/security/authentication/AuthenticationUtil.java
index b46b57445a..b70d9b6a30 100644
--- a/source/java/org/alfresco/repo/security/authentication/AuthenticationUtil.java
+++ b/source/java/org/alfresco/repo/security/authentication/AuthenticationUtil.java
@@ -30,17 +30,18 @@ import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.context.Context;
import net.sf.acegisecurity.context.ContextHolder;
-import net.sf.acegisecurity.context.security.SecureContext;
-import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import net.sf.acegisecurity.providers.dao.User;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.security.PermissionService;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.log4j.NDC;
public abstract class AuthenticationUtil
{
+ static Log s_logger = LogFactory.getLog(AuthenticationUtil.class);
public interface RunAsWork
{
@@ -249,7 +250,8 @@ public abstract class AuthenticationUtil
}
authentication.setAuthenticated(true);
// Sets real and effective
- sc.setAuthentication(authentication);
+ sc.setRealAuthentication(authentication);
+ sc.setEffectiveAuthentication(authentication);
// Support for logging tenant domain / username (via log4j NDC)
String userName = SYSTEM_USER_NAME;
@@ -606,7 +608,13 @@ public abstract class AuthenticationUtil
}
else
{
+ if(!AuthenticationUtil.getCurrentRealUserName().equals(realUser))
+ {
+ AuthenticationUtil.setCurrentRealUser(realUser);
+ s_logger.warn("Resetting real user which has changed in RunAs block");
+ }
AuthenticationUtil.setCurrentEffectiveUser(effectiveUser);
+
}
}
}
diff --git a/source/java/org/alfresco/repo/shutdown/ShutdownBackstop.java b/source/java/org/alfresco/repo/shutdown/ShutdownBackstop.java
index 5055bc2274..d3145e286e 100644
--- a/source/java/org/alfresco/repo/shutdown/ShutdownBackstop.java
+++ b/source/java/org/alfresco/repo/shutdown/ShutdownBackstop.java
@@ -54,6 +54,11 @@ public class ShutdownBackstop extends AbstractLifecycleBean
*/
private int timeout = 10000;
+ /**
+ * is the backstop enabled?
+ */
+ private boolean enabled = true;
+
protected final static Log log = LogFactory.getLog(ShutdownBackstop.class);
public void setTimeout(int timeout) {
@@ -79,11 +84,22 @@ public class ShutdownBackstop extends AbstractLifecycleBean
@Override
protected void onShutdown(ApplicationEvent event)
{
- log.info("Shutdown backstop timer started");
- Thread selfDestructThread = new ShutdownBackstopThread(timeout);
- selfDestructThread.start();
+ if(isEnabled())
+ {
+ log.info("Shutdown backstop timer started");
+ Thread selfDestructThread = new ShutdownBackstopThread(timeout);
+ selfDestructThread.start();
+ }
}
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
/**
* This is a dangerous class! It will kill the JVM after sleeping
* for timeout ms.