diff --git a/config/alfresco/authentication-services-context.xml b/config/alfresco/authentication-services-context.xml
index 8d85b92220..c038bb6e38 100644
--- a/config/alfresco/authentication-services-context.xml
+++ b/config/alfresco/authentication-services-context.xml
@@ -90,11 +90,11 @@
-
-
-
-
- ${user.name.caseSensitive}
+
+
+
+
+
@@ -231,6 +231,20 @@
+
+
+
+
+ ${user.name.caseSensitive}
+
+
+ ${domain.name.caseSensitive}
+
+
+ ${domain.separator}
+
+
+
@@ -288,8 +302,8 @@
${server.transaction.allow-writes}
-
- ${user.name.caseSensitive}
+
+
@@ -304,6 +318,9 @@
false
+
+
+
@@ -316,6 +333,10 @@
+
+
+
+ ${home.folder.creation.eager}
diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties
index 3b886c144c..7c0af4d308 100644
--- a/config/alfresco/repository.properties
+++ b/config/alfresco/repository.properties
@@ -38,10 +38,11 @@ index.recovery.maximumPoolSize=5
# http://wiki.alfresco.com/wiki/High_Availability_Configuration_V1.4_to_V2.1#Version_1.4.5.2C_2.1.1_and_later
# By default, this is effectively never, but can be modified as required.
# Examples:
+# Never: * * * * * ? 2099
# Once every five seconds: 0/5 * * * * ?
# Once every two seconds : 0/2 * * * * ?
# See http://quartz.sourceforge.net/javadoc/org/quartz/CronTrigger.html
-index.tracking.cronExpression=* * * * * ? 2099
+index.tracking.cronExpression=0/5 * * * * ?
index.tracking.adm.cronExpression=${index.tracking.cronExpression}
index.tracking.avm.cronExpression=${index.tracking.cronExpression}
# Other properties.
@@ -231,6 +232,8 @@ system.workflow_container.childname=sys:workflow
# Are user names case sensitive?
user.name.caseSensitive=false
+domain.name.caseSensitive=false
+domain.separator=
# AVM Specific properties.
avm.remote.idlestream.timeout=30000
@@ -259,6 +262,9 @@ system.usages.enabled=true
# Repository endpoint - used by Activity Service
repo.remote.endpoint.url=http://localhost:8080/alfresco/service
+# Create home folders as people are created (true) or create them lazily (false)
+home.folder.creation.eager=true
+
# The well known RMI registry port is defined in the alfresco-shared.properties file
# alfresco.rmi.services.port=50500
#
diff --git a/source/java/org/alfresco/repo/avm/AVMInterpreter.java b/source/java/org/alfresco/repo/avm/AVMInterpreter.java
index 0290072327..6a41c70a9c 100644
--- a/source/java/org/alfresco/repo/avm/AVMInterpreter.java
+++ b/source/java/org/alfresco/repo/avm/AVMInterpreter.java
@@ -357,11 +357,15 @@ public class AVMInterpreter
}
else if (command[0].equals("snap"))
{
- if (command.length != 2)
+ if ((command.length < 2) || (command.length > 4))
{
return "Syntax Error.";
}
- fService.createSnapshot(command[1], null, null);
+
+ String tag = (command.length > 2) ? command[2] : null;
+ String description = (command.length > 3) ? command[3] : null;
+
+ fService.createSnapshot(command[1], tag, description);
}
else if (command[0].equals("cat"))
{
diff --git a/source/java/org/alfresco/repo/avm/ChildKey.java b/source/java/org/alfresco/repo/avm/ChildKey.java
index d6258fd101..39b72c16d8 100644
--- a/source/java/org/alfresco/repo/avm/ChildKey.java
+++ b/source/java/org/alfresco/repo/avm/ChildKey.java
@@ -109,7 +109,7 @@ public class ChildKey implements Serializable
}
ChildKey o = (ChildKey)other;
return fParent.equals(o.getParent()) &&
- fName.equals(o.getName());
+ fName.equalsIgnoreCase(o.getName());
}
/**
@@ -117,6 +117,6 @@ public class ChildKey implements Serializable
*/
public int hashCode()
{
- return fParent.hashCode() + fName.hashCode();
+ return fParent.hashCode() + fName.toLowerCase().hashCode();
}
}
diff --git a/source/java/org/alfresco/repo/avm/locking/AVMLockingBootstrap.java b/source/java/org/alfresco/repo/avm/locking/AVMLockingBootstrap.java
index f2cde86fb5..a446b839f3 100644
--- a/source/java/org/alfresco/repo/avm/locking/AVMLockingBootstrap.java
+++ b/source/java/org/alfresco/repo/avm/locking/AVMLockingBootstrap.java
@@ -25,32 +25,41 @@
package org.alfresco.repo.avm.locking;
+import org.alfresco.service.cmr.avm.locking.AVMLockingService;
import org.alfresco.util.AbstractLifecycleBean;
import org.springframework.context.ApplicationEvent;
/**
* Bootstrap for AVM Locking Service.
+ *
* @author britt
*/
public class AVMLockingBootstrap extends AbstractLifecycleBean
{
- private AVMLockingServiceImpl fLockingService;
-
- public void setAvmLockingService(AVMLockingServiceImpl service)
+ private AVMLockingService fLockingService;
+
+ public void setAvmLockingService(AVMLockingService service)
{
fLockingService = service;
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.alfresco.util.AbstractLifecycleBean#onBootstrap(org.springframework.context.ApplicationEvent)
*/
@Override
protected void onBootstrap(ApplicationEvent event)
{
- fLockingService.init();
+ if (fLockingService instanceof AVMLockingServiceImpl)
+ {
+ ((AVMLockingServiceImpl) fLockingService).init();
+ }
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.alfresco.util.AbstractLifecycleBean#onShutdown(org.springframework.context.ApplicationEvent)
*/
@Override
diff --git a/source/java/org/alfresco/repo/security/authentication/AuthenticationTest.java b/source/java/org/alfresco/repo/security/authentication/AuthenticationTest.java
index 543ced0f61..0082156b1b 100644
--- a/source/java/org/alfresco/repo/security/authentication/AuthenticationTest.java
+++ b/source/java/org/alfresco/repo/security/authentication/AuthenticationTest.java
@@ -51,6 +51,7 @@ 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.security.person.UserNameMatcher;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry;
@@ -118,6 +119,8 @@ public class AuthenticationTest extends TestCase
private PersonService personService;
+ private UserNameMatcher userNameMatcher;
+
public AuthenticationTest()
{
super();
@@ -143,6 +146,7 @@ public class AuthenticationTest extends TestCase
authenticationComponentImpl = (AuthenticationComponent) ctx.getBean("authenticationComponent");
pubPersonService = (PersonService) ctx.getBean("PersonService");
personService = (PersonService) ctx.getBean("personService");
+ userNameMatcher = (UserNameMatcher) ctx.getBean("userNameMatcher");
// permissionServiceSPI = (PermissionServiceSPI)
// ctx.getBean("permissionService");
ticketsCache = (SimpleCache) ctx.getBean("ticketsCache");
@@ -182,6 +186,8 @@ public class AuthenticationTest extends TestCase
dao.setDictionaryService(dictionaryService);
dao.setNamespaceService(getNamespacePrefixReolsver(""));
dao.setPasswordEncoder(passwordEncoder);
+ dao.setUserNameMatcher(userNameMatcher);
+ dao.setRetryingTransactionHelper(transactionService.getRetryingTransactionHelper());
if (dao.getUserOrNull("andy") != null)
{
@@ -388,6 +394,8 @@ public class AuthenticationTest extends TestCase
dao.setDictionaryService(dictionaryService);
dao.setNamespaceService(getNamespacePrefixReolsver(""));
dao.setPasswordEncoder(passwordEncoder);
+ dao.setUserNameMatcher(userNameMatcher);
+ dao.setRetryingTransactionHelper(transactionService.getRetryingTransactionHelper());
dao.createUser("Andy", "cabbage".toCharArray());
assertNotNull(dao.getUserOrNull("Andy"));
diff --git a/source/java/org/alfresco/repo/security/authentication/RepositoryAuthenticationDao.java b/source/java/org/alfresco/repo/security/authentication/RepositoryAuthenticationDao.java
index 18b4082c8d..ee5b0edd6a 100644
--- a/source/java/org/alfresco/repo/security/authentication/RepositoryAuthenticationDao.java
+++ b/source/java/org/alfresco/repo/security/authentication/RepositoryAuthenticationDao.java
@@ -39,9 +39,9 @@ import net.sf.acegisecurity.providers.encoding.PasswordEncoder;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
+import org.alfresco.repo.security.person.UserNameMatcher;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
-import org.alfresco.service.Managed;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
@@ -63,6 +63,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
private static final StoreRef STOREREF_USERS = new StoreRef("user", "alfrescoUserStore");
private NodeService nodeService;
+
private TenantService tenantService;
private NamespacePrefixResolver namespacePrefixResolver;
@@ -71,22 +72,26 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
private DictionaryService dictionaryService;
private SearchService searchService;
-
+
private RetryingTransactionHelper retryingTransactionHelper;
private PasswordEncoder passwordEncoder;
- private boolean userNamesAreCaseSensitive;
+ private UserNameMatcher userNameMatcher;
+ public RepositoryAuthenticationDao()
+ {
+ super();
+ }
+
public boolean getUserNamesAreCaseSensitive()
{
- return userNamesAreCaseSensitive;
+ return userNameMatcher.getUserNamesAreCaseSensitive();
}
- @Managed(category="Security")
- public void setUserNamesAreCaseSensitive(boolean userNamesAreCaseSensitive)
+ public void setUserNameMatcher(UserNameMatcher userNameMatcher)
{
- this.userNamesAreCaseSensitive = userNamesAreCaseSensitive;
+ this.userNameMatcher = userNameMatcher;
}
public void setDictionaryService(DictionaryService dictionaryService)
@@ -103,7 +108,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
{
this.nodeService = nodeService;
}
-
+
public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
{
this.retryingTransactionHelper = retryingTransactionHelper;
@@ -124,8 +129,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
this.searchService = searchService;
}
- public UserDetails loadUserByUsername(String incomingUserName) throws UsernameNotFoundException,
- DataAccessException
+ public UserDetails loadUserByUsername(String incomingUserName) throws UsernameNotFoundException, DataAccessException
{
NodeRef userRef = getUserOrNull(incomingUserName);
if (userRef == null)
@@ -134,28 +138,25 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
}
Map properties = nodeService.getProperties(userRef);
- String password = DefaultTypeConverter.INSTANCE.convert(String.class, properties
- .get(ContentModel.PROP_PASSWORD));
+ String password = DefaultTypeConverter.INSTANCE.convert(String.class, properties.get(ContentModel.PROP_PASSWORD));
// Report back the user name as stored on the user
- String userName = DefaultTypeConverter.INSTANCE.convert(String.class, properties
- .get(ContentModel.PROP_USER_USERNAME));
+ String userName = DefaultTypeConverter.INSTANCE.convert(String.class, properties.get(ContentModel.PROP_USER_USERNAME));
GrantedAuthority[] gas = new GrantedAuthority[1];
gas[0] = new GrantedAuthorityImpl("ROLE_AUTHENTICATED");
- UserDetails ud = new User(userName, password, getEnabled(userRef), !getAccountHasExpired(userRef),
- !getCredentialsHaveExpired(userRef), !getAccountlocked(userRef), gas);
+ UserDetails ud = new User(userName, password, getEnabled(userRef), !getAccountHasExpired(userRef), !getCredentialsHaveExpired(userRef), !getAccountlocked(userRef), gas);
return ud;
}
public NodeRef getUserOrNull(String searchUserName)
{
- if(searchUserName == null)
+ if (searchUserName == null)
{
return null;
}
- if(searchUserName.length() == 0)
+ if (searchUserName.length() == 0)
{
return null;
}
@@ -189,75 +190,37 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
final NodeRef nodeRef = row.getNodeRef();
if (nodeService.exists(nodeRef))
{
- String realUserName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(
- nodeRef, ContentModel.PROP_USER_USERNAME));
+ String realUserName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_USER_USERNAME));
- if (userNamesAreCaseSensitive)
+ if(userNameMatcher.matches(realUserName, searchUserName))
{
- if (realUserName.equals(searchUserName))
+ if (returnRef == null)
{
- if(returnRef == null)
+ returnRef = nodeRef;
+ }
+ else
+ {
+ try
{
- returnRef = nodeRef;
+ this.retryingTransactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback