Merged V3.1 to HEAD

12943: Port of support for ADB-47 from V2.1-A to 3.1
   12948: Port of tests from CHK-2235 for ADB-20 from V2.1-A to 3.1
   12965: Activated index tracker Quartz job by default
   12974: Port for lazy creation of home folders with configuration from V2.1-A to V3.1: original CHK-2619, CHK-2716
   12976: Merged V2.1A to V3.1
      8562: (record-only) Fix to lazily create home folders - DO NOT MERGE
      8694: (record-only) Added configuration for lazy or eager creation of home folders
   12978: Merged V3.0 to V3.1
      12920: Merged V2.2 to V3.0
         12456: Wire up AVM locking service by interface to allow for potential over-ride
         12457: Make AVM ChildKey case insensitive
         12470: Merged V2.2.1-NBC-FIXES to V2.2
            12156: Optimizations to WCMWorkflowEvaluator and WCMWorkflowDeletedEvaluator    
            12605: Hide annoying "Virtualisation Server not started" warnings (by making them debug)
         12707: AVM console - "snap" also allows tag and description to be specified
   12979: Build/test fix
   ___________________________________________________________________
   Modified: svn:mergeinfo
      Merged /alfresco/BRANCHES/DEV/V2.2.1-NBC-FIXES:r12156
      Merged /alfresco/BRANCHES/V2.1-A:r8562,8694
      Merged /alfresco/BRANCHES/V3.0:r12920
      Merged /alfresco/BRANCHES/V2.2:r12456-12457,12470,12605,12707
      Merged /alfresco/BRANCHES/V3.1:r12943,12948,12965,12974,12976,12978-12979


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13544 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2009-03-11 01:06:49 +00:00
parent b30c8f915b
commit f77e816467
16 changed files with 423 additions and 196 deletions

View File

@@ -90,11 +90,11 @@
<property name="searchService"> <property name="searchService">
<ref bean="admSearchService" /> <ref bean="admSearchService" />
</property> </property>
<property name="retryingTransactionHelper"> <property name="retryingTransactionHelper">
<ref bean="retryingTransactionHelper"/> <ref bean="retryingTransactionHelper"/>
</property> </property>
<property name="userNamesAreCaseSensitive"> <property name="userNameMatcher">
<value>${user.name.caseSensitive}</value> <ref bean="userNameMatcher" />
</property> </property>
<property name="passwordEncoder"> <property name="passwordEncoder">
<ref bean="passwordEncoder" /> <ref bean="passwordEncoder" />
@@ -231,6 +231,20 @@
</bean> </bean>
<!-- support to match user names -->
<bean id="userNameMatcher" class="org.alfresco.repo.security.person.UserNameMatcherImpl">
<property name="userNamesAreCaseSensitive">
<value>${user.name.caseSensitive}</value>
</property>
<property name="domainNamesAreCaseSensitive">
<value>${domain.name.caseSensitive}</value>
</property>
<property name="domainSeparator">
<value>${domain.separator}</value>
</property>
</bean>
<!-- The person service. --> <!-- The person service. -->
<bean id="personService" class="org.alfresco.repo.security.person.PersonServiceImpl" init-method="init"> <bean id="personService" class="org.alfresco.repo.security.person.PersonServiceImpl" init-method="init">
@@ -288,8 +302,8 @@
<property name="createMissingPeople"> <property name="createMissingPeople">
<value>${server.transaction.allow-writes}</value> <value>${server.transaction.allow-writes}</value>
</property> </property>
<property name="userNamesAreCaseSensitive"> <property name="userNameMatcher">
<value>${user.name.caseSensitive}</value> <ref bean="userNameMatcher" />
</property> </property>
<!-- New properties after 1.4.0 to deal with duplicate user ids when found --> <!-- New properties after 1.4.0 to deal with duplicate user ids when found -->
<property name="processDuplicates"> <property name="processDuplicates">
@@ -304,6 +318,9 @@
</property> </property>
<property name="includeAutoCreated"> <property name="includeAutoCreated">
<value>false</value> <value>false</value>
</property>
<property name="homeFolderManager">
<ref bean="homeFolderManager" />
</property> </property>
</bean> </bean>
@@ -316,6 +333,10 @@
</property> </property>
<property name="defaultProvider"> <property name="defaultProvider">
<ref bean="userHomesHomeFolderProvider" /> <ref bean="userHomesHomeFolderProvider" />
</property>
<property name="enableHomeFolderCreationAsPeopleAreCreated">
<!--<value>false</value> -->
<value>${home.folder.creation.eager}</value>
</property> </property>
</bean> </bean>

View File

@@ -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 # 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. # By default, this is effectively never, but can be modified as required.
# Examples: # Examples:
# Never: * * * * * ? 2099
# Once every five seconds: 0/5 * * * * ? # Once every five seconds: 0/5 * * * * ?
# Once every two seconds : 0/2 * * * * ? # Once every two seconds : 0/2 * * * * ?
# See http://quartz.sourceforge.net/javadoc/org/quartz/CronTrigger.html # 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.adm.cronExpression=${index.tracking.cronExpression}
index.tracking.avm.cronExpression=${index.tracking.cronExpression} index.tracking.avm.cronExpression=${index.tracking.cronExpression}
# Other properties. # Other properties.
@@ -231,6 +232,8 @@ system.workflow_container.childname=sys:workflow
# Are user names case sensitive? # Are user names case sensitive?
user.name.caseSensitive=false user.name.caseSensitive=false
domain.name.caseSensitive=false
domain.separator=
# AVM Specific properties. # AVM Specific properties.
avm.remote.idlestream.timeout=30000 avm.remote.idlestream.timeout=30000
@@ -259,6 +262,9 @@ system.usages.enabled=true
# Repository endpoint - used by Activity Service # Repository endpoint - used by Activity Service
repo.remote.endpoint.url=http://localhost:8080/alfresco/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 # The well known RMI registry port is defined in the alfresco-shared.properties file
# alfresco.rmi.services.port=50500 # alfresco.rmi.services.port=50500
# #

View File

@@ -357,11 +357,15 @@ public class AVMInterpreter
} }
else if (command[0].equals("snap")) else if (command[0].equals("snap"))
{ {
if (command.length != 2) if ((command.length < 2) || (command.length > 4))
{ {
return "Syntax Error."; 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")) else if (command[0].equals("cat"))
{ {

View File

@@ -109,7 +109,7 @@ public class ChildKey implements Serializable
} }
ChildKey o = (ChildKey)other; ChildKey o = (ChildKey)other;
return fParent.equals(o.getParent()) && 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() public int hashCode()
{ {
return fParent.hashCode() + fName.hashCode(); return fParent.hashCode() + fName.toLowerCase().hashCode();
} }
} }

View File

@@ -25,32 +25,41 @@
package org.alfresco.repo.avm.locking; package org.alfresco.repo.avm.locking;
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
import org.alfresco.util.AbstractLifecycleBean; import org.alfresco.util.AbstractLifecycleBean;
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEvent;
/** /**
* Bootstrap for AVM Locking Service. * Bootstrap for AVM Locking Service.
*
* @author britt * @author britt
*/ */
public class AVMLockingBootstrap extends AbstractLifecycleBean public class AVMLockingBootstrap extends AbstractLifecycleBean
{ {
private AVMLockingServiceImpl fLockingService; private AVMLockingService fLockingService;
public void setAvmLockingService(AVMLockingServiceImpl service) public void setAvmLockingService(AVMLockingService service)
{ {
fLockingService = service; fLockingService = service;
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.alfresco.util.AbstractLifecycleBean#onBootstrap(org.springframework.context.ApplicationEvent) * @see org.alfresco.util.AbstractLifecycleBean#onBootstrap(org.springframework.context.ApplicationEvent)
*/ */
@Override @Override
protected void onBootstrap(ApplicationEvent event) 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) * @see org.alfresco.util.AbstractLifecycleBean#onShutdown(org.springframework.context.ApplicationEvent)
*/ */
@Override @Override

View File

@@ -51,6 +51,7 @@ import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl.ExpiryMode; import org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl.ExpiryMode;
import org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl.Ticket; 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.tenant.TenantService;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
@@ -118,6 +119,8 @@ public class AuthenticationTest extends TestCase
private PersonService personService; private PersonService personService;
private UserNameMatcher userNameMatcher;
public AuthenticationTest() public AuthenticationTest()
{ {
super(); super();
@@ -143,6 +146,7 @@ public class AuthenticationTest extends TestCase
authenticationComponentImpl = (AuthenticationComponent) ctx.getBean("authenticationComponent"); authenticationComponentImpl = (AuthenticationComponent) ctx.getBean("authenticationComponent");
pubPersonService = (PersonService) ctx.getBean("PersonService"); pubPersonService = (PersonService) ctx.getBean("PersonService");
personService = (PersonService) ctx.getBean("personService"); personService = (PersonService) ctx.getBean("personService");
userNameMatcher = (UserNameMatcher) ctx.getBean("userNameMatcher");
// permissionServiceSPI = (PermissionServiceSPI) // permissionServiceSPI = (PermissionServiceSPI)
// ctx.getBean("permissionService"); // ctx.getBean("permissionService");
ticketsCache = (SimpleCache<String, Ticket>) ctx.getBean("ticketsCache"); ticketsCache = (SimpleCache<String, Ticket>) ctx.getBean("ticketsCache");
@@ -182,6 +186,8 @@ public class AuthenticationTest extends TestCase
dao.setDictionaryService(dictionaryService); dao.setDictionaryService(dictionaryService);
dao.setNamespaceService(getNamespacePrefixReolsver("")); dao.setNamespaceService(getNamespacePrefixReolsver(""));
dao.setPasswordEncoder(passwordEncoder); dao.setPasswordEncoder(passwordEncoder);
dao.setUserNameMatcher(userNameMatcher);
dao.setRetryingTransactionHelper(transactionService.getRetryingTransactionHelper());
if (dao.getUserOrNull("andy") != null) if (dao.getUserOrNull("andy") != null)
{ {
@@ -388,6 +394,8 @@ public class AuthenticationTest extends TestCase
dao.setDictionaryService(dictionaryService); dao.setDictionaryService(dictionaryService);
dao.setNamespaceService(getNamespacePrefixReolsver("")); dao.setNamespaceService(getNamespacePrefixReolsver(""));
dao.setPasswordEncoder(passwordEncoder); dao.setPasswordEncoder(passwordEncoder);
dao.setUserNameMatcher(userNameMatcher);
dao.setRetryingTransactionHelper(transactionService.getRetryingTransactionHelper());
dao.createUser("Andy", "cabbage".toCharArray()); dao.createUser("Andy", "cabbage".toCharArray());
assertNotNull(dao.getUserOrNull("Andy")); assertNotNull(dao.getUserOrNull("Andy"));

View File

@@ -39,9 +39,9 @@ import net.sf.acegisecurity.providers.encoding.PasswordEncoder;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.person.UserNameMatcher;
import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.Managed;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
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.InvalidNodeRefException;
@@ -63,6 +63,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
private static final StoreRef STOREREF_USERS = new StoreRef("user", "alfrescoUserStore"); private static final StoreRef STOREREF_USERS = new StoreRef("user", "alfrescoUserStore");
private NodeService nodeService; private NodeService nodeService;
private TenantService tenantService; private TenantService tenantService;
private NamespacePrefixResolver namespacePrefixResolver; private NamespacePrefixResolver namespacePrefixResolver;
@@ -71,22 +72,26 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
private DictionaryService dictionaryService; private DictionaryService dictionaryService;
private SearchService searchService; private SearchService searchService;
private RetryingTransactionHelper retryingTransactionHelper; private RetryingTransactionHelper retryingTransactionHelper;
private PasswordEncoder passwordEncoder; private PasswordEncoder passwordEncoder;
private boolean userNamesAreCaseSensitive; private UserNameMatcher userNameMatcher;
public RepositoryAuthenticationDao()
{
super();
}
public boolean getUserNamesAreCaseSensitive() public boolean getUserNamesAreCaseSensitive()
{ {
return userNamesAreCaseSensitive; return userNameMatcher.getUserNamesAreCaseSensitive();
} }
@Managed(category="Security") public void setUserNameMatcher(UserNameMatcher userNameMatcher)
public void setUserNamesAreCaseSensitive(boolean userNamesAreCaseSensitive)
{ {
this.userNamesAreCaseSensitive = userNamesAreCaseSensitive; this.userNameMatcher = userNameMatcher;
} }
public void setDictionaryService(DictionaryService dictionaryService) public void setDictionaryService(DictionaryService dictionaryService)
@@ -103,7 +108,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
{ {
this.nodeService = nodeService; this.nodeService = nodeService;
} }
public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper) public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
{ {
this.retryingTransactionHelper = retryingTransactionHelper; this.retryingTransactionHelper = retryingTransactionHelper;
@@ -124,8 +129,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
this.searchService = searchService; this.searchService = searchService;
} }
public UserDetails loadUserByUsername(String incomingUserName) throws UsernameNotFoundException, public UserDetails loadUserByUsername(String incomingUserName) throws UsernameNotFoundException, DataAccessException
DataAccessException
{ {
NodeRef userRef = getUserOrNull(incomingUserName); NodeRef userRef = getUserOrNull(incomingUserName);
if (userRef == null) if (userRef == null)
@@ -134,28 +138,25 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
} }
Map<QName, Serializable> properties = nodeService.getProperties(userRef); Map<QName, Serializable> properties = nodeService.getProperties(userRef);
String password = DefaultTypeConverter.INSTANCE.convert(String.class, properties String password = DefaultTypeConverter.INSTANCE.convert(String.class, properties.get(ContentModel.PROP_PASSWORD));
.get(ContentModel.PROP_PASSWORD));
// Report back the user name as stored on the user // Report back the user name as stored on the user
String userName = DefaultTypeConverter.INSTANCE.convert(String.class, properties String userName = DefaultTypeConverter.INSTANCE.convert(String.class, properties.get(ContentModel.PROP_USER_USERNAME));
.get(ContentModel.PROP_USER_USERNAME));
GrantedAuthority[] gas = new GrantedAuthority[1]; GrantedAuthority[] gas = new GrantedAuthority[1];
gas[0] = new GrantedAuthorityImpl("ROLE_AUTHENTICATED"); gas[0] = new GrantedAuthorityImpl("ROLE_AUTHENTICATED");
UserDetails ud = new User(userName, password, getEnabled(userRef), !getAccountHasExpired(userRef), UserDetails ud = new User(userName, password, getEnabled(userRef), !getAccountHasExpired(userRef), !getCredentialsHaveExpired(userRef), !getAccountlocked(userRef), gas);
!getCredentialsHaveExpired(userRef), !getAccountlocked(userRef), gas);
return ud; return ud;
} }
public NodeRef getUserOrNull(String searchUserName) public NodeRef getUserOrNull(String searchUserName)
{ {
if(searchUserName == null) if (searchUserName == null)
{ {
return null; return null;
} }
if(searchUserName.length() == 0) if (searchUserName.length() == 0)
{ {
return null; return null;
} }
@@ -189,75 +190,37 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
final NodeRef nodeRef = row.getNodeRef(); final NodeRef nodeRef = row.getNodeRef();
if (nodeService.exists(nodeRef)) if (nodeService.exists(nodeRef))
{ {
String realUserName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty( String realUserName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_USER_USERNAME));
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<Object>()
{
public Object execute() throws Throwable
{
// Delete the extra user node references
RepositoryAuthenticationDao.this.nodeService.deleteNode(nodeRef);
return null;
}
}, false, true);
} }
else catch (InvalidNodeRefException exception)
{ {
try // Ignore this exception as the node has already been deleted
{
this.retryingTransactionHelper.doInTransaction(
new RetryingTransactionHelper.RetryingTransactionCallback<Object>()
{
public Object execute()
throws Throwable
{
// Delete the extra user node references
RepositoryAuthenticationDao.this.nodeService.deleteNode(nodeRef);
return null;
}
}, false, true);
}
catch (InvalidNodeRefException exception)
{
// Ignore this exception as the node has already been deleted
}
}
}
}
else
{
if (realUserName.equalsIgnoreCase(searchUserName))
{
if(returnRef == null)
{
returnRef = nodeRef;
}
else
{
try
{
this.retryingTransactionHelper.doInTransaction(
new RetryingTransactionHelper.RetryingTransactionCallback<Object>()
{
public Object execute()
throws Throwable
{
// Delete the extra user node references
RepositoryAuthenticationDao.this.nodeService.deleteNode(nodeRef);
return null;
}
}, false, true);
}
catch (InvalidNodeRefException exception)
{
// Ignore this exception as the node has already been deleted
}
} }
} }
} }
} }
} }
@@ -291,8 +254,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
properties.put(ContentModel.PROP_CREDENTIALS_EXPIRE, Boolean.valueOf(false)); properties.put(ContentModel.PROP_CREDENTIALS_EXPIRE, Boolean.valueOf(false));
properties.put(ContentModel.PROP_ENABLED, Boolean.valueOf(true)); properties.put(ContentModel.PROP_ENABLED, Boolean.valueOf(true));
properties.put(ContentModel.PROP_ACCOUNT_LOCKED, Boolean.valueOf(false)); properties.put(ContentModel.PROP_ACCOUNT_LOCKED, Boolean.valueOf(false));
nodeService.createNode(typesNode, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_USER, ContentModel.TYPE_USER, nodeService.createNode(typesNode, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_USER, ContentModel.TYPE_USER, properties);
properties);
} }
private NodeRef getUserFolderLocation(String caseSensitiveUserName) private NodeRef getUserFolderLocation(String caseSensitiveUserName)
@@ -304,8 +266,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
// AR-527 // AR-527
NodeRef rootNode = nodeService.getRootNode(userStoreRef); NodeRef rootNode = nodeService.getRootNode(userStoreRef);
List<ChildAssociationRef> results = nodeService.getChildAssocs(rootNode, RegexQNamePattern.MATCH_ALL, List<ChildAssociationRef> results = nodeService.getChildAssocs(rootNode, RegexQNamePattern.MATCH_ALL, qnameAssocSystem);
qnameAssocSystem);
NodeRef sysNodeRef = null; NodeRef sysNodeRef = null;
if (results.size() == 0) if (results.size() == 0)
{ {
@@ -404,11 +365,9 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
{ {
return null; return null;
} }
if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, ContentModel.PROP_ACCOUNT_EXPIRES)))
ContentModel.PROP_ACCOUNT_EXPIRES)))
{ {
return DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode, return DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode, ContentModel.PROP_ACCOUNT_EXPIRY_DATE));
ContentModel.PROP_ACCOUNT_EXPIRY_DATE));
} }
else else
{ {
@@ -427,11 +386,9 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
{ {
return false; return false;
} }
if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, ContentModel.PROP_ACCOUNT_EXPIRES)))
ContentModel.PROP_ACCOUNT_EXPIRES)))
{ {
Date date = DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode, Date date = DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode, ContentModel.PROP_ACCOUNT_EXPIRY_DATE));
ContentModel.PROP_ACCOUNT_EXPIRY_DATE));
if (date == null) if (date == null)
{ {
return false; return false;
@@ -498,11 +455,9 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
{ {
return null; return null;
} }
if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRE)))
ContentModel.PROP_CREDENTIALS_EXPIRE)))
{ {
return DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode, return DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRY_DATE));
ContentModel.PROP_CREDENTIALS_EXPIRY_DATE));
} }
else else
{ {
@@ -521,11 +476,9 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
{ {
return false; return false;
} }
if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRE)))
ContentModel.PROP_CREDENTIALS_EXPIRE)))
{ {
Date date = DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode, Date date = DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRY_DATE));
ContentModel.PROP_CREDENTIALS_EXPIRY_DATE));
if (date == null) if (date == null)
{ {
return false; return false;
@@ -634,8 +587,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao
} }
else else
{ {
String password = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(userNode, String password = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(userNode, ContentModel.PROP_PASSWORD));
ContentModel.PROP_PASSWORD));
return password; return password;
} }
} }

View File

@@ -590,6 +590,26 @@ public class PermissionServiceTest extends AbstractPermissionTest
assertEquals(permissionService.hasPermission(rootNodeRef, (PermissionService.CONSUMER)), AccessStatus.DENIED); assertEquals(permissionService.hasPermission(rootNodeRef, (PermissionService.CONSUMER)), AccessStatus.DENIED);
} }
public void testEqualBarCaseAuthorities()
{
runAs("admin");
NodeRef n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}one"), ContentModel.TYPE_FOLDER).getChildRef();
permissionService.setPermission(new SimplePermissionEntry(n1, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(n1, getPermission(PermissionService.READ), "Andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(n1, getPermission(PermissionService.READ), "ANDY", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(n1, getPermission(PermissionService.READ), "woof/adobe", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(n1, getPermission(PermissionService.READ), "woof/Adobe", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(n1, getPermission(PermissionService.READ), "woof/ADOBE", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(n1, getPermission(PermissionService.READ), "Woof/Adobe", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(n1, getPermission(PermissionService.READ), "WOOF/ADOBE", AccessStatus.ALLOWED));
assertEquals(8, permissionService.getAllSetPermissions(n1).size());
}
public void testGetAllSetPermissions() public void testGetAllSetPermissions()
{ {
runAs("andy"); runAs("andy");

View File

@@ -49,6 +49,8 @@ public class HomeFolderManager implements InitializingBean, NodeServicePolicies.
private PolicyComponent policyComponent; private PolicyComponent policyComponent;
private NodeService nodeService; private NodeService nodeService;
private boolean enableHomeFolderCreationAsPeopleAreCreated = false;
/** /**
* A default provider * A default provider
@@ -61,12 +63,19 @@ public class HomeFolderManager implements InitializingBean, NodeServicePolicies.
private Map<String, HomeFolderProvider> providers = new HashMap<String, HomeFolderProvider>(); private Map<String, HomeFolderProvider> providers = new HashMap<String, HomeFolderProvider>();
/** /**
* Bind the calss behaviour to this implementation * Bind the class behaviour to this implementation
*/ */
public void afterPropertiesSet() throws Exception public void afterPropertiesSet() throws Exception
{ {
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"), if (enableHomeFolderCreationAsPeopleAreCreated)
ContentModel.TYPE_PERSON, new JavaBehaviour(this, "onCreateNode")); {
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"), ContentModel.TYPE_PERSON, new JavaBehaviour(this, "onCreateNode"));
}
}
public void setEnableHomeFolderCreationAsPeopleAreCreated(boolean enableHomeFolderCreationAsPeopleAreCreated)
{
this.enableHomeFolderCreationAsPeopleAreCreated = enableHomeFolderCreationAsPeopleAreCreated;
} }
/** /**

View File

@@ -31,7 +31,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
public interface PersonDao public interface PersonDao
{ {
public List<NodeRef> getPersonOrNull(String searchUserName, boolean userNamesAreCaseSensitive); public List<NodeRef> getPersonOrNull(final String searchUserName, UserNameMatcher matcher);
public Set<NodeRef> getAllPeople(); public Set<NodeRef> getAllPeople();
} }

View File

@@ -51,8 +51,9 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao
{ {
private static final String QUERY_PERSON_GET_PERSON = "person.getPerson"; private static final String QUERY_PERSON_GET_PERSON = "person.getPerson";
private static final String QUERY_PERSON_GET_ALL_PEOPLE = "person.getAllPeople";
private static final String QUERY_PERSON_GET_ALL_PEOPLE = "person.getAllPeople";
private QNameDAO qnameDAO; private QNameDAO qnameDAO;
@@ -61,33 +62,33 @@ public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao
private LocaleDAO localeDAO; private LocaleDAO localeDAO;
private DictionaryService dictionaryService; private DictionaryService dictionaryService;
private StoreRef storeRef; private StoreRef storeRef;
private TenantService tenantService; private TenantService tenantService;
public void setStoreUrl(String storeUrl) public void setStoreUrl(String storeUrl)
{ {
this.storeRef = new StoreRef(storeUrl); this.storeRef = new StoreRef(storeUrl);
} }
public void setTenantService(TenantService tenantService) public void setTenantService(TenantService tenantService)
{ {
this.tenantService = tenantService; this.tenantService = tenantService;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<NodeRef> getPersonOrNull(final String searchUserName, boolean userNamesAreCaseSensitive) public List<NodeRef> getPersonOrNull(final String searchUserName, UserNameMatcher matcher)
{ {
final StoreRef personStoreRef = tenantService.getName(storeRef); final StoreRef personStoreRef = tenantService.getName(storeRef);
List<NodeRef> answer = new ArrayList<NodeRef>(); List<NodeRef> answer = new ArrayList<NodeRef>();
HibernateCallback callback = new HibernateCallback() HibernateCallback callback = new HibernateCallback()
{ {
public Object doInHibernate(Session session) public Object doInHibernate(Session session)
{ {
SQLQuery query = (SQLQuery) session.getNamedQuery(QUERY_PERSON_GET_PERSON); SQLQuery query = (SQLQuery) session.getNamedQuery(QUERY_PERSON_GET_PERSON);
query.setParameter("qnameId", qNameId); query.setParameter("qnameId", qNameId);
query.setParameter("userName1", searchUserName); query.setParameter("userName1", searchUserName);
query.setParameter("userName2", searchUserName); query.setParameter("userName2", searchUserName);
@@ -111,19 +112,9 @@ public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao
Serializable value = converted.get(ContentModel.PROP_USERNAME); Serializable value = converted.get(ContentModel.PROP_USERNAME);
String realUserName = DefaultTypeConverter.INSTANCE.convert(String.class, value); String realUserName = DefaultTypeConverter.INSTANCE.convert(String.class, value);
if (userNamesAreCaseSensitive) if (matcher.matches(searchUserName, realUserName))
{ {
if (realUserName.equals(searchUserName)) answer.add(nodeRef);
{
answer.add(nodeRef);
}
}
else
{
if (realUserName.equalsIgnoreCase(searchUserName))
{
answer.add(nodeRef);
}
} }
} }
@@ -133,21 +124,21 @@ public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao
public void init() public void init()
{ {
qNameId = qnameDAO.getOrCreateQName(ContentModel.PROP_USERNAME).getFirst(); qNameId = qnameDAO.getOrCreateQName(ContentModel.PROP_USERNAME).getFirst();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Set<NodeRef> getAllPeople() public Set<NodeRef> getAllPeople()
{ {
final StoreRef personStoreRef = tenantService.getName(storeRef); final StoreRef personStoreRef = tenantService.getName(storeRef);
Set<NodeRef> answer = new HashSet<NodeRef>(); Set<NodeRef> answer = new HashSet<NodeRef>();
HibernateCallback callback = new HibernateCallback() HibernateCallback callback = new HibernateCallback()
{ {
public Object doInHibernate(Session session) public Object doInHibernate(Session session)
{ {
SQLQuery query = (SQLQuery) session.getNamedQuery(QUERY_PERSON_GET_ALL_PEOPLE); SQLQuery query = (SQLQuery) session.getNamedQuery(QUERY_PERSON_GET_ALL_PEOPLE);
query.setParameter("qnameId", qNameId); query.setParameter("qnameId", qNameId);
query.setParameter("False", Boolean.FALSE); query.setParameter("False", Boolean.FALSE);
query.setParameter("storeProtocol", personStoreRef.getProtocol()); query.setParameter("storeProtocol", personStoreRef.getProtocol());

View File

@@ -67,6 +67,7 @@ import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
import org.alfresco.util.Pair;
import org.alfresco.util.PropertyCheck; import org.alfresco.util.PropertyCheck;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -92,27 +93,27 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
private TransactionService transactionService; private TransactionService transactionService;
private NodeService nodeService; private NodeService nodeService;
private TenantService tenantService; private TenantService tenantService;
private SearchService searchService; private SearchService searchService;
private AuthorityService authorityService; private AuthorityService authorityService;
private DictionaryService dictionaryService; private DictionaryService dictionaryService;
private PermissionServiceSPI permissionServiceSPI; private PermissionServiceSPI permissionServiceSPI;
private NamespacePrefixResolver namespacePrefixResolver; private NamespacePrefixResolver namespacePrefixResolver;
private HomeFolderManager homeFolderManager;
private PolicyComponent policyComponent; private PolicyComponent policyComponent;
private boolean createMissingPeople; private boolean createMissingPeople;
private static Set<QName> mutableProperties; private static Set<QName> mutableProperties;
private boolean userNamesAreCaseSensitive = false;
private String defaultHomeFolderProvider; private String defaultHomeFolderProvider;
private boolean processDuplicates = true; private boolean processDuplicates = true;
@@ -128,6 +129,8 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
/** a transactionally-safe cache to be injected */ /** a transactionally-safe cache to be injected */
private SimpleCache<String, NodeRef> personCache; private SimpleCache<String, NodeRef> personCache;
private UserNameMatcher userNameMatcher;
static static
{ {
Set<QName> props = new HashSet<QName>(); Set<QName> props = new HashSet<QName>();
@@ -168,20 +171,21 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
PropertyCheck.mandatory(this, "personCache", personCache); PropertyCheck.mandatory(this, "personCache", personCache);
PropertyCheck.mandatory(this, "personDao", personDao); PropertyCheck.mandatory(this, "personDao", personDao);
this.policyComponent // Avoid clash with home folder registration
.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"), ContentModel.TYPE_PERSON, new JavaBehaviour(this, "onCreateNode")); //this.policyComponent
// .bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"), ContentModel.TYPE_PERSON, new JavaBehaviour(this, "onCreateNode"));
this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"), ContentModel.TYPE_PERSON, new JavaBehaviour(this, this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"), ContentModel.TYPE_PERSON, new JavaBehaviour(this,
"beforeDeleteNode")); "beforeDeleteNode"));
} }
public boolean getUserNamesAreCaseSensitive() public UserNameMatcher getUserNameMatcher()
{ {
return userNamesAreCaseSensitive; return userNameMatcher;
} }
public void setUserNamesAreCaseSensitive(boolean userNamesAreCaseSensitive) public void setUserNameMatcher(UserNameMatcher userNameMatcher)
{ {
this.userNamesAreCaseSensitive = userNamesAreCaseSensitive; this.userNameMatcher = userNameMatcher;
} }
void setDefaultHomeFolderProvider(String defaultHomeFolderProvider) void setDefaultHomeFolderProvider(String defaultHomeFolderProvider)
@@ -208,6 +212,11 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
{ {
this.processDuplicates = processDuplicates; this.processDuplicates = processDuplicates;
} }
public void setHomeFolderManager(HomeFolderManager homeFolderManager)
{
this.homeFolderManager = homeFolderManager;
}
public void setPersonDao(PersonDao personDao) public void setPersonDao(PersonDao personDao)
{ {
@@ -287,7 +296,7 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
NodeRef returnRef = this.personCache.get(searchUserName); NodeRef returnRef = this.personCache.get(searchUserName);
if (returnRef == null) if (returnRef == null)
{ {
List<NodeRef> refs = personDao.getPersonOrNull(searchUserName, userNamesAreCaseSensitive); List<NodeRef> refs = personDao.getPersonOrNull(searchUserName, userNameMatcher);
if (refs.size() > 1) if (refs.size() > 1)
{ {
returnRef = handleDuplicates(refs, searchUserName); returnRef = handleDuplicates(refs, searchUserName);
@@ -300,6 +309,7 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
// add to cache // add to cache
this.personCache.put(searchUserName, returnRef); this.personCache.put(searchUserName, returnRef);
} }
makeHomeFolderIfRequired(returnRef);
return returnRef; return returnRef;
} }
@@ -316,14 +326,14 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
} }
else else
{ {
if (userNamesAreCaseSensitive) String userNameSensitivity = " (user name is case-" + (userNameMatcher.getUserNamesAreCaseSensitive() ? "sensitive" : "insensitive") + ")";
String domainNameSensitivity = "";
if (! userNameMatcher.getDomainSeparator().equals(""))
{ {
throw new AlfrescoRuntimeException("Found more than one user for " + searchUserName + " (case sensitive)"); domainNameSensitivity = " (domain name is case-" + (userNameMatcher.getDomainNamesAreCaseSensitive() ? "sensitive" : "insensitive") + ")";
}
else
{
throw new AlfrescoRuntimeException("Found more than one user for " + searchUserName + " (case insensitive)");
} }
throw new AlfrescoRuntimeException("Found more than one user for " + searchUserName + userNameSensitivity + domainNameSensitivity);
} }
} }
@@ -510,7 +520,7 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
} }
Map<QName, Serializable> update = nodeService.getProperties(personNode); Map<QName, Serializable> update = nodeService.getProperties(personNode);
update.putAll(properties); update.putAll(properties);
nodeService.setProperties(personNode, update); nodeService.setProperties(personNode, update);
} }
@@ -522,9 +532,31 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
private NodeRef createMissingPerson(String userName) private NodeRef createMissingPerson(String userName)
{ {
HashMap<QName, Serializable> properties = getDefaultProperties(userName); HashMap<QName, Serializable> properties = getDefaultProperties(userName);
return createPerson(properties); NodeRef person = createPerson(properties);
makeHomeFolderIfRequired(person);
return person;
} }
private void makeHomeFolderIfRequired(NodeRef person)
{
if (person != null)
{
NodeRef homeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER));
if (homeFolder == null)
{
final ChildAssociationRef ref = nodeService.getPrimaryParent(person);
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
homeFolderManager.onCreateNode(ref);
return null;
}
}, transactionService.isReadOnly(), false);
}
}
}
private HashMap<QName, Serializable> getDefaultProperties(String userName) private HashMap<QName, Serializable> getDefaultProperties(String userName)
{ {
HashMap<QName, Serializable> properties = new HashMap<QName, Serializable>(); HashMap<QName, Serializable> properties = new HashMap<QName, Serializable>();
@@ -534,48 +566,46 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
properties.put(ContentModel.PROP_EMAIL, ""); properties.put(ContentModel.PROP_EMAIL, "");
properties.put(ContentModel.PROP_ORGID, ""); properties.put(ContentModel.PROP_ORGID, "");
properties.put(ContentModel.PROP_HOME_FOLDER_PROVIDER, defaultHomeFolderProvider); properties.put(ContentModel.PROP_HOME_FOLDER_PROVIDER, defaultHomeFolderProvider);
properties.put(ContentModel.PROP_SIZE_CURRENT, 0L); properties.put(ContentModel.PROP_SIZE_CURRENT, 0L);
properties.put(ContentModel.PROP_SIZE_QUOTA, -1L); // no quota properties.put(ContentModel.PROP_SIZE_QUOTA, -1L); // no quota
return properties; return properties;
} }
public NodeRef createPerson(Map<QName, Serializable> properties) public NodeRef createPerson(Map<QName, Serializable> properties)
{ {
String userName = DefaultTypeConverter.INSTANCE.convert(String.class, properties.get(ContentModel.PROP_USERNAME)); String userName = DefaultTypeConverter.INSTANCE.convert(String.class, properties.get(ContentModel.PROP_USERNAME));
tenantService.checkDomainUser(userName); tenantService.checkDomainUser(userName);
properties.put(ContentModel.PROP_USERNAME, userName); properties.put(ContentModel.PROP_USERNAME, userName);
properties.put(ContentModel.PROP_SIZE_CURRENT, 0L); properties.put(ContentModel.PROP_SIZE_CURRENT, 0L);
return nodeService.createNode( return nodeService.createNode(getPeopleContainer(), ContentModel.ASSOC_CHILDREN, QName.createQName("cm", userName, namespacePrefixResolver), ContentModel.TYPE_PERSON,
getPeopleContainer(), properties).getChildRef();
ContentModel.ASSOC_CHILDREN,
QName.createQName("cm", userName, namespacePrefixResolver),
ContentModel.TYPE_PERSON, properties).getChildRef();
} }
public NodeRef getPeopleContainer() public NodeRef getPeopleContainer()
{ {
NodeRef rootNodeRef = nodeService.getRootNode(tenantService.getName(storeRef)); NodeRef rootNodeRef = nodeService.getRootNode(tenantService.getName(storeRef));
List<ChildAssociationRef> children = nodeService.getChildAssocs(rootNodeRef, RegexQNamePattern.MATCH_ALL, QName.createQName(SYSTEM_FOLDER_SHORT_QNAME, namespacePrefixResolver)); List<ChildAssociationRef> children = nodeService.getChildAssocs(rootNodeRef, RegexQNamePattern.MATCH_ALL, QName.createQName(SYSTEM_FOLDER_SHORT_QNAME,
namespacePrefixResolver));
if (children.size() == 0) if (children.size() == 0)
{ {
throw new AlfrescoRuntimeException("Required people system path not found: " + SYSTEM_FOLDER_SHORT_QNAME); throw new AlfrescoRuntimeException("Required people system path not found: " + SYSTEM_FOLDER_SHORT_QNAME);
} }
NodeRef systemNodeRef = children.get(0).getChildRef(); NodeRef systemNodeRef = children.get(0).getChildRef();
children = nodeService.getChildAssocs(systemNodeRef, RegexQNamePattern.MATCH_ALL, QName.createQName(PEOPLE_FOLDER_SHORT_QNAME, namespacePrefixResolver)); children = nodeService.getChildAssocs(systemNodeRef, RegexQNamePattern.MATCH_ALL, QName.createQName(PEOPLE_FOLDER_SHORT_QNAME, namespacePrefixResolver));
if (children.size() == 0) if (children.size() == 0)
{ {
throw new AlfrescoRuntimeException("Required people system path not found: " + PEOPLE_FOLDER_SHORT_QNAME); throw new AlfrescoRuntimeException("Required people system path not found: " + PEOPLE_FOLDER_SHORT_QNAME);
} }
NodeRef peopleNodeRef = children.get(0).getChildRef(); NodeRef peopleNodeRef = children.get(0).getChildRef();
return peopleNodeRef; return peopleNodeRef;
} }
@@ -612,16 +642,15 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
// and throw exception if it isn't // and throw exception if it isn't
if (this.dictionaryService.getProperty(ContentModel.TYPE_PERSON, propertyKey) == null) if (this.dictionaryService.getProperty(ContentModel.TYPE_PERSON, propertyKey) == null)
{ {
throw new AlfrescoRuntimeException("Property '" + propertyKey + "' is not defined " throw new AlfrescoRuntimeException("Property '" + propertyKey + "' is not defined " + "for content model type cm:person");
+ "for content model type cm:person");
} }
LinkedHashSet<NodeRef> people = new LinkedHashSet<NodeRef>(); LinkedHashSet<NodeRef> people = new LinkedHashSet<NodeRef>();
// //
// Search for people using the given property // Search for people using the given property
// //
SearchParameters sp = new SearchParameters(); SearchParameters sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_LUCENE); sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery("@cm\\:" + propertyKey.getLocalName() + ":\"" + propertyValue + "\""); sp.setQuery("@cm\\:" + propertyKey.getLocalName() + ":\"" + propertyValue + "\"");
@@ -650,10 +679,10 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
rs.close(); rs.close();
} }
} }
return people; return people;
} }
// Policies // Policies
/* /*
@@ -695,7 +724,7 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
{ {
this.authorityService = authorityService; this.authorityService = authorityService;
} }
public void setDictionaryService(DictionaryService dictionaryService) public void setDictionaryService(DictionaryService dictionaryService)
{ {
this.dictionaryService = dictionaryService; this.dictionaryService = dictionaryService;
@@ -715,17 +744,17 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
{ {
this.nodeService = nodeService; this.nodeService = nodeService;
} }
public void setTenantService(TenantService tenantService) public void setTenantService(TenantService tenantService)
{ {
this.tenantService = tenantService; this.tenantService = tenantService;
} }
public void setSearchService(SearchService searchService) public void setSearchService(SearchService searchService)
{ {
this.searchService = searchService; this.searchService = searchService;
} }
public void setPolicyComponent(PolicyComponent policyComponent) public void setPolicyComponent(PolicyComponent policyComponent)
{ {
this.policyComponent = policyComponent; this.policyComponent = policyComponent;
@@ -789,4 +818,11 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
} }
} }
public boolean getUserNamesAreCaseSensitive()
{
return userNameMatcher.getUserNamesAreCaseSensitive();
}
} }

View File

@@ -28,6 +28,10 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.AuthenticationService;
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.ApplicationContextHelper; import org.alfresco.util.ApplicationContextHelper;
@@ -106,6 +110,51 @@ public class PersonServiceLoader
PersonServiceLoader loader = new PersonServiceLoader(ctx, batchSize, batchCount); PersonServiceLoader loader = new PersonServiceLoader(ctx, batchSize, batchCount);
loader.run(user, pwd, threads); loader.run(user, pwd, threads);
// check the lazy creation
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName());
final ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
final AuthenticationService authenticationService = serviceRegistry.getAuthenticationService();
final PersonService personService = serviceRegistry.getPersonService();
final TransactionService transactionService = serviceRegistry.getTransactionService();
final NodeService nodeService = serviceRegistry.getNodeService();
String firstName = "" + System.currentTimeMillis();
String lastName = String.format("%05d", -1);
String username = GUID.generate();
String emailAddress = String.format("%s.%s@xyz.com", firstName, lastName);
PropertyMap properties = new PropertyMap(7);
properties.put(ContentModel.PROP_USERNAME, username);
properties.put(ContentModel.PROP_FIRSTNAME, firstName);
properties.put(ContentModel.PROP_LASTNAME, lastName);
properties.put(ContentModel.PROP_EMAIL, emailAddress);
NodeRef madePerson = personService.createPerson(properties);
NodeRef homeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, nodeService.getProperty(madePerson, ContentModel.PROP_HOMEFOLDER));
if(homeFolder != null)
{
throw new IllegalStateException("Home folder created eagerly");
}
NodeRef person = personService.getPerson(username);
homeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER));
if(homeFolder == null)
{
throw new IllegalStateException("Home folder not created lazily");
}
NodeRef autoPerson = personService.getPerson(GUID.generate());
NodeRef autoHomeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, nodeService.getProperty(autoPerson, ContentModel.PROP_HOMEFOLDER));
if(autoHomeFolder == null)
{
throw new IllegalStateException("Home folder not created lazily for auto created users");
}
// All done // All done
ApplicationContextHelper.closeApplicationContext(); ApplicationContextHelper.closeApplicationContext();
System.exit(0); System.exit(0);

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.security.person;
/**
* Check if userNames match
* @author andyh
*
*/
public interface UserNameMatcher
{
/**
* Do the two user names match?
*
* @param userName1
* @param userName2
* @return
*/
public boolean matches(String userName1, String userName2);
public boolean getUserNamesAreCaseSensitive();
public boolean getDomainNamesAreCaseSensitive();
public String getDomainSeparator();
}

View File

@@ -0,0 +1,74 @@
package org.alfresco.repo.security.person;
import org.alfresco.util.Pair;
public class UserNameMatcherImpl implements UserNameMatcher
{
private boolean userNamesAreCaseSensitive = false;
private boolean domainNamesAreCaseSensitive = false;
private String domainSeparator = "";
public boolean getUserNamesAreCaseSensitive()
{
return userNamesAreCaseSensitive;
}
public void setUserNamesAreCaseSensitive(boolean userNamesAreCaseSensitive)
{
this.userNamesAreCaseSensitive = userNamesAreCaseSensitive;
}
public boolean getDomainNamesAreCaseSensitive()
{
return domainNamesAreCaseSensitive;
}
public void setDomainNamesAreCaseSensitive(boolean domainNamesAreCaseSensitive)
{
this.domainNamesAreCaseSensitive = domainNamesAreCaseSensitive;
}
public String getDomainSeparator()
{
return domainSeparator;
}
public void setDomainSeparator(String domainSeparator)
{
this.domainSeparator = domainSeparator;
}
public boolean matches(String realUserName, String searchUserName)
{
// note: domain string may be empty
Pair<String, String> real = splitByDomain(realUserName, domainSeparator);
Pair<String, String> search = splitByDomain(searchUserName, domainSeparator);
return (((userNamesAreCaseSensitive && (real.getFirst().equals(search.getFirst()))) || (!userNamesAreCaseSensitive && (real.getFirst().equalsIgnoreCase(search
.getFirst())))) &&
((domainNamesAreCaseSensitive && (real.getSecond().equals(search.getSecond()))) || (!domainNamesAreCaseSensitive && (real.getSecond().equalsIgnoreCase(search
.getSecond())))));
}
// Trailing domain only
private Pair<String, String> splitByDomain(String name, String domainSeparator)
{
int idx = name.lastIndexOf(domainSeparator);
if (idx != -1)
{
if ((idx + 1) > name.length())
{
return new Pair<String, String>(name.substring(0, idx), "");
}
else
{
return new Pair<String, String>(name.substring(0, idx), name.substring(idx + 1));
}
}
return new Pair<String, String>(name, "");
}
}

View File

@@ -82,7 +82,7 @@ public class UserUsageTrackingComponentTest extends TestCase
nodeService = (NodeService)applicationContext.getBean("NodeService"); nodeService = (NodeService)applicationContext.getBean("NodeService");
authenticationService = (AuthenticationService)applicationContext.getBean("authenticationService"); authenticationService = (AuthenticationService)applicationContext.getBean("authenticationService");
transactionService = (TransactionService)applicationContext.getBean("transactionComponent"); transactionService = (TransactionService)applicationContext.getBean("transactionComponent");
personService = (PersonService)applicationContext.getBean("personService"); personService = (PersonService)applicationContext.getBean("PersonService");
contentService = (ContentService)applicationContext.getBean("ContentService"); contentService = (ContentService)applicationContext.getBean("ContentService");
contentUsageService = (ContentUsageService)applicationContext.getBean("ContentUsageService"); contentUsageService = (ContentUsageService)applicationContext.getBean("ContentUsageService");