mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merged 1.4 to HEAD
svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4380 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4386 . git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4659 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -255,6 +255,20 @@
|
|||||||
<property name="userNamesAreCaseSensitive">
|
<property name="userNamesAreCaseSensitive">
|
||||||
<value>${user.name.caseSensitive}</value>
|
<value>${user.name.caseSensitive}</value>
|
||||||
</property>
|
</property>
|
||||||
|
<!-- New properties after 1.4.0 to deal with duplicate user ids when found -->
|
||||||
|
<property name="processDuplicates">
|
||||||
|
<value>true</value>
|
||||||
|
</property>
|
||||||
|
<!-- one of: LEAVE, SPLIT, DELETE -->
|
||||||
|
<property name="duplicateMode">
|
||||||
|
<value>SPLIT</value>
|
||||||
|
</property>
|
||||||
|
<property name="lastIsBest">
|
||||||
|
<value>true</value>
|
||||||
|
</property>
|
||||||
|
<property name="includeAutoCreated">
|
||||||
|
<value>false</value>
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean name="homeFolderManager" class="org.alfresco.repo.security.person.HomeFolderManager">
|
<bean name="homeFolderManager" class="org.alfresco.repo.security.person.HomeFolderManager">
|
||||||
@@ -342,6 +356,9 @@
|
|||||||
<!-- The ticket component. -->
|
<!-- The ticket component. -->
|
||||||
<!-- Used for reauthentication -->
|
<!-- Used for reauthentication -->
|
||||||
<bean id="ticketComponent" class="org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl">
|
<bean id="ticketComponent" class="org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl">
|
||||||
|
<property name="ticketsCache">
|
||||||
|
<ref bean="ticketsCache"/>
|
||||||
|
</property>
|
||||||
<!-- The period for which tickets are valid in XML duration format. -->
|
<!-- The period for which tickets are valid in XML duration format. -->
|
||||||
<!-- The default is P1H for one hour. -->
|
<!-- The default is P1H for one hour. -->
|
||||||
<property name="validDuration">
|
<property name="validDuration">
|
||||||
|
@@ -153,4 +153,46 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<!-- ===================================== -->
|
||||||
|
<!-- Authentication Ticket Cache -->
|
||||||
|
<!-- ===================================== -->
|
||||||
|
|
||||||
|
<!-- The cross-transaction shared cache for In-Memory Tickets -->
|
||||||
|
|
||||||
|
<bean name="ticketsSharedCache" class="org.alfresco.repo.cache.EhCacheAdapter">
|
||||||
|
<property name="cache">
|
||||||
|
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean" >
|
||||||
|
<property name="cacheManager">
|
||||||
|
<ref bean="internalEHCacheManager" />
|
||||||
|
</property>
|
||||||
|
<property name="cacheName">
|
||||||
|
<value>ticketsCache</value>
|
||||||
|
</property>
|
||||||
|
<property name="maxElementsInMemory">
|
||||||
|
<value>1000</value>
|
||||||
|
</property>
|
||||||
|
<property name="overflowToDisk">
|
||||||
|
<value>false</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!-- The transactional cache for In-Memory Tickets -->
|
||||||
|
|
||||||
|
<bean name="ticketsCache" class="org.alfresco.repo.cache.TransactionalCache">
|
||||||
|
<property name="sharedCache">
|
||||||
|
<ref bean="ticketsSharedCache" />
|
||||||
|
</property>
|
||||||
|
<property name="cacheManager" >
|
||||||
|
<ref bean="transactionalEHCacheManager" />
|
||||||
|
</property>
|
||||||
|
<property name="name">
|
||||||
|
<value>ticketsTransactionalCache</value>
|
||||||
|
</property>
|
||||||
|
<property name="maxCacheSize">
|
||||||
|
<value>10</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
@@ -475,11 +475,8 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
|
|||||||
}
|
}
|
||||||
catch (Throwable exception)
|
catch (Throwable exception)
|
||||||
{
|
{
|
||||||
// Log the exception
|
// DH: No logging of the exception. Leave the logging decision to the client code,
|
||||||
logger.error(
|
// which can handle the rethrown exception.
|
||||||
"An error was encountered whilst executing the action '" + action.getActionDefinitionName() + "'.",
|
|
||||||
exception);
|
|
||||||
|
|
||||||
if (executedAsynchronously == true)
|
if (executedAsynchronously == true)
|
||||||
{
|
{
|
||||||
// If one is specified, queue the compensating action ready for execution
|
// If one is specified, queue the compensating action ready for execution
|
||||||
|
@@ -3,9 +3,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.admin.patch.util;
|
package org.alfresco.repo.admin.patch.util;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.FileReader;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -35,6 +40,12 @@ public class ImportFileUpdater
|
|||||||
/** The destination export version number **/
|
/** The destination export version number **/
|
||||||
private static String EXPORT_VERSION = "1.4.0";
|
private static String EXPORT_VERSION = "1.4.0";
|
||||||
|
|
||||||
|
/** Default encoding **/
|
||||||
|
private static String DEFAULT_ENCODING = "UTF-8";
|
||||||
|
|
||||||
|
/** File encoding */
|
||||||
|
private String fileEncoding = DEFAULT_ENCODING;
|
||||||
|
|
||||||
/** Element names **/
|
/** Element names **/
|
||||||
private static String NAME_EXPORTER_VERSION = "exporterVersion";
|
private static String NAME_EXPORTER_VERSION = "exporterVersion";
|
||||||
private static String NAME_RULE = "rule";
|
private static String NAME_RULE = "rule";
|
||||||
@@ -43,6 +54,16 @@ public class ImportFileUpdater
|
|||||||
private String version;
|
private String version;
|
||||||
private boolean shownWarning = false;
|
private boolean shownWarning = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the file encoding.
|
||||||
|
*
|
||||||
|
* @param fileEncoding the file encoding
|
||||||
|
*/
|
||||||
|
public void setFileEncoding(String fileEncoding)
|
||||||
|
{
|
||||||
|
this.fileEncoding = fileEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the passed import file into the equivalent 1.4 format.
|
* Updates the passed import file into the equivalent 1.4 format.
|
||||||
*
|
*
|
||||||
@@ -95,8 +116,11 @@ public class ImportFileUpdater
|
|||||||
XmlPullParserFactory factory = XmlPullParserFactory.newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
|
XmlPullParserFactory factory = XmlPullParserFactory.newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
|
||||||
factory.setNamespaceAware(true);
|
factory.setNamespaceAware(true);
|
||||||
|
|
||||||
|
InputStream inputStream = new FileInputStream(source);
|
||||||
|
Reader inputReader = new InputStreamReader(inputStream, this.fileEncoding);
|
||||||
|
|
||||||
XmlPullParser xpp = factory.newPullParser();
|
XmlPullParser xpp = factory.newPullParser();
|
||||||
xpp.setInput(new FileReader(source));
|
xpp.setInput(new BufferedReader(inputReader));
|
||||||
|
|
||||||
return xpp;
|
return xpp;
|
||||||
}
|
}
|
||||||
@@ -108,6 +132,10 @@ public class ImportFileUpdater
|
|||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("The source file could not be loaded.", fileNotFound);
|
throw new AlfrescoRuntimeException("The source file could not be loaded.", fileNotFound);
|
||||||
}
|
}
|
||||||
|
catch (UnsupportedEncodingException exception)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Unsupported encoding", exception);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,7 +152,7 @@ public class ImportFileUpdater
|
|||||||
OutputFormat format = OutputFormat.createPrettyPrint();
|
OutputFormat format = OutputFormat.createPrettyPrint();
|
||||||
format.setNewLineAfterDeclaration(false);
|
format.setNewLineAfterDeclaration(false);
|
||||||
format.setIndentSize(INDENT_SIZE);
|
format.setIndentSize(INDENT_SIZE);
|
||||||
format.setEncoding("UTF-8");
|
format.setEncoding(this.fileEncoding);
|
||||||
|
|
||||||
return new XMLWriter(new FileOutputStream(destination), format);
|
return new XMLWriter(new FileOutputStream(destination), format);
|
||||||
}
|
}
|
||||||
@@ -573,11 +601,18 @@ public class ImportFileUpdater
|
|||||||
ImportFileUpdater util = new ImportFileUpdater();
|
ImportFileUpdater util = new ImportFileUpdater();
|
||||||
util.updateImportFile(args[0], args[1]);
|
util.updateImportFile(args[0], args[1]);
|
||||||
}
|
}
|
||||||
|
else if (args.length == 3)
|
||||||
|
{
|
||||||
|
ImportFileUpdater util = new ImportFileUpdater();
|
||||||
|
util.setFileEncoding(args[2]);
|
||||||
|
util.updateImportFile(args[0], args[1]);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
System.out.println(" ImportFileUpdater <source> <destination>");
|
System.out.println(" ImportFileUpdater <source> <destination>");
|
||||||
System.out.println(" source - 1.3 import file name to be updated");
|
System.out.println(" source - 1.3 import file name to be updated");
|
||||||
System.out.println(" destination - name of the generated 1.4 import file");
|
System.out.println(" destination - name of the generated 1.4 import file");
|
||||||
|
System.out.println(" file encoding (optional) - the file encoding, default is UTF-8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
package org.alfresco.repo.cache;
|
package org.alfresco.repo.cache;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import javax.transaction.Status;
|
import javax.transaction.Status;
|
||||||
import javax.transaction.UserTransaction;
|
import javax.transaction.UserTransaction;
|
||||||
@@ -86,6 +87,9 @@ public class CacheTest extends TestCase
|
|||||||
|
|
||||||
assertEquals("AAA", backingCache.get("A"));
|
assertEquals("AAA", backingCache.get("A"));
|
||||||
|
|
||||||
|
Collection<String> keys = backingCache.getKeys();
|
||||||
|
assertEquals("Backing cache didn't return correct number of keys", 1, keys.size());
|
||||||
|
|
||||||
backingCache.remove("A");
|
backingCache.remove("A");
|
||||||
assertNull(backingCache.get("A"));
|
assertNull(backingCache.get("A"));
|
||||||
}
|
}
|
||||||
@@ -141,6 +145,11 @@ public class CacheTest extends TestCase
|
|||||||
assertEquals("Item not updated in txn cache", "XXX", transactionalCache.get(updatedTxnThree));
|
assertEquals("Item not updated in txn cache", "XXX", transactionalCache.get(updatedTxnThree));
|
||||||
assertFalse("Item was put into backing cache", backingCache.contains(updatedTxnThree));
|
assertFalse("Item was put into backing cache", backingCache.contains(updatedTxnThree));
|
||||||
|
|
||||||
|
// check that the keys collection is correct
|
||||||
|
Collection<String> transactionalKeys = transactionalCache.getKeys();
|
||||||
|
assertFalse("Transactionally removed item found in keys", transactionalKeys.contains(newGlobalOne));
|
||||||
|
assertTrue("Transactionally added item not found in keys", transactionalKeys.contains(updatedTxnThree));
|
||||||
|
|
||||||
// commit the transaction
|
// commit the transaction
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
package org.alfresco.repo.cache;
|
package org.alfresco.repo.cache;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import net.sf.ehcache.Cache;
|
import net.sf.ehcache.Cache;
|
||||||
import net.sf.ehcache.CacheException;
|
import net.sf.ehcache.CacheException;
|
||||||
@@ -64,6 +65,12 @@ public class EhCacheAdapter<K extends Serializable, V extends Serializable>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Collection<K> getKeys()
|
||||||
|
{
|
||||||
|
return cache.getKeys();
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public V get(K key)
|
public V get(K key)
|
||||||
{
|
{
|
||||||
|
72
source/java/org/alfresco/repo/cache/NullCache.java
vendored
Normal file
72
source/java/org/alfresco/repo/cache/NullCache.java
vendored
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005 Alfresco, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Mozilla Public License version 1.1
|
||||||
|
* with a permitted attribution clause. You may obtain a
|
||||||
|
* copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.alfresco.org/legal/license.txt
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
* either express or implied. See the License for the specific
|
||||||
|
* language governing permissions and limitations under the
|
||||||
|
* License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.cache;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cache that does nothing - always.
|
||||||
|
* <P/>
|
||||||
|
* There are conditions under which code that expects to be caching, should not be. Using this
|
||||||
|
* cache, it becomes possible to configure a valid cache in whilst still ensuring that the
|
||||||
|
* actual caching is not performed.
|
||||||
|
*
|
||||||
|
* @author Derek Hulley
|
||||||
|
*/
|
||||||
|
public class NullCache<K extends Serializable, V extends Serializable> implements SimpleCache<K, V>
|
||||||
|
{
|
||||||
|
public NullCache()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/** NO-OP */
|
||||||
|
public boolean contains(K key)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<K> getKeys()
|
||||||
|
{
|
||||||
|
return Collections.<K>emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** NO-OP */
|
||||||
|
public V get(K key)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** NO-OP */
|
||||||
|
public void put(K key, V value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** NO-OP */
|
||||||
|
public void remove(K key)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** NO-OP */
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
@@ -17,6 +17,7 @@
|
|||||||
package org.alfresco.repo.cache;
|
package org.alfresco.repo.cache;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic caching interface.
|
* Basic caching interface.
|
||||||
@@ -32,6 +33,8 @@ public interface SimpleCache<K extends Serializable, V extends Serializable>
|
|||||||
{
|
{
|
||||||
public boolean contains(K key);
|
public boolean contains(K key);
|
||||||
|
|
||||||
|
public Collection<K> getKeys();
|
||||||
|
|
||||||
public V get(K key);
|
public V get(K key);
|
||||||
|
|
||||||
public void put(K key, V value);
|
public void put(K key, V value);
|
||||||
|
@@ -17,6 +17,8 @@
|
|||||||
package org.alfresco.repo.cache;
|
package org.alfresco.repo.cache;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import net.sf.ehcache.Cache;
|
import net.sf.ehcache.Cache;
|
||||||
@@ -227,6 +229,39 @@ public class TransactionalCache<K extends Serializable, V extends Serializable>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The keys returned are a union of the set of keys in the current transaction and
|
||||||
|
* those in the backing cache.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Collection<K> getKeys()
|
||||||
|
{
|
||||||
|
Collection<K> keys = null;
|
||||||
|
// in-txn layering
|
||||||
|
if (AlfrescoTransactionSupport.getTransactionId() != null)
|
||||||
|
{
|
||||||
|
keys = new HashSet<K>(23);
|
||||||
|
TransactionData txnData = getTransactionData();
|
||||||
|
if (!txnData.isClearOn)
|
||||||
|
{
|
||||||
|
// the backing cache is not due for a clear
|
||||||
|
Collection<K> backingKeys = (Collection<K>) sharedCache.getKeys();
|
||||||
|
keys.addAll(backingKeys);
|
||||||
|
}
|
||||||
|
// add keys
|
||||||
|
keys.addAll((Collection<K>) txnData.updatedItemsCache.getKeys());
|
||||||
|
// remove keys
|
||||||
|
keys.removeAll((Collection<K>) txnData.removedItemsCache.getKeys());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no transaction, so just use the backing cache
|
||||||
|
keys = (Collection<K>) sharedCache.getKeys();
|
||||||
|
}
|
||||||
|
// done
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the per-transaction caches for the object before going to the shared cache.
|
* Checks the per-transaction caches for the object before going to the shared cache.
|
||||||
* If the thread is not in a transaction, then the shared cache is accessed directly.
|
* If the thread is not in a transaction, then the shared cache is accessed directly.
|
||||||
|
@@ -39,6 +39,8 @@ import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
|||||||
import net.sf.acegisecurity.providers.dao.SaltSource;
|
import net.sf.acegisecurity.providers.dao.SaltSource;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
|
import org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl.Ticket;
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
@@ -54,6 +56,7 @@ import org.alfresco.service.transaction.TransactionService;
|
|||||||
import org.alfresco.util.ApplicationContextHelper;
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public class AuthenticationTest extends TestCase
|
public class AuthenticationTest extends TestCase
|
||||||
{
|
{
|
||||||
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
||||||
@@ -82,6 +85,8 @@ public class AuthenticationTest extends TestCase
|
|||||||
|
|
||||||
private TicketComponent ticketComponent;
|
private TicketComponent ticketComponent;
|
||||||
|
|
||||||
|
private SimpleCache<String, Ticket> ticketsCache;
|
||||||
|
|
||||||
private AuthenticationService authenticationService;
|
private AuthenticationService authenticationService;
|
||||||
|
|
||||||
private AuthenticationService pubAuthenticationService;
|
private AuthenticationService pubAuthenticationService;
|
||||||
@@ -116,6 +121,7 @@ public class AuthenticationTest extends TestCase
|
|||||||
authenticationComponentImpl = (AuthenticationComponent) ctx.getBean("authenticationComponentImpl");
|
authenticationComponentImpl = (AuthenticationComponent) ctx.getBean("authenticationComponentImpl");
|
||||||
// permissionServiceSPI = (PermissionServiceSPI)
|
// permissionServiceSPI = (PermissionServiceSPI)
|
||||||
// ctx.getBean("permissionService");
|
// ctx.getBean("permissionService");
|
||||||
|
ticketsCache = (SimpleCache<String, Ticket>) ctx.getBean("ticketsCache");
|
||||||
|
|
||||||
dao = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
|
dao = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
|
||||||
authenticationManager = (AuthenticationManager) ctx.getBean("authenticationManager");
|
authenticationManager = (AuthenticationManager) ctx.getBean("authenticationManager");
|
||||||
@@ -143,7 +149,6 @@ public class AuthenticationTest extends TestCase
|
|||||||
|
|
||||||
deleteAndy();
|
deleteAndy();
|
||||||
authenticationComponent.clearCurrentSecurityContext();
|
authenticationComponent.clearCurrentSecurityContext();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteAndy()
|
private void deleteAndy()
|
||||||
@@ -476,6 +481,7 @@ public class AuthenticationTest extends TestCase
|
|||||||
tc.setOneOff(false);
|
tc.setOneOff(false);
|
||||||
tc.setTicketsExpire(false);
|
tc.setTicketsExpire(false);
|
||||||
tc.setValidDuration("P0D");
|
tc.setValidDuration("P0D");
|
||||||
|
tc.setTicketsCache(ticketsCache);
|
||||||
|
|
||||||
dao.createUser("Andy", "ticket".toCharArray());
|
dao.createUser("Andy", "ticket".toCharArray());
|
||||||
|
|
||||||
@@ -499,6 +505,7 @@ public class AuthenticationTest extends TestCase
|
|||||||
tc.setOneOff(true);
|
tc.setOneOff(true);
|
||||||
tc.setTicketsExpire(false);
|
tc.setTicketsExpire(false);
|
||||||
tc.setValidDuration("P0D");
|
tc.setValidDuration("P0D");
|
||||||
|
tc.setTicketsCache(ticketsCache);
|
||||||
|
|
||||||
dao.createUser("Andy", "ticket".toCharArray());
|
dao.createUser("Andy", "ticket".toCharArray());
|
||||||
|
|
||||||
@@ -530,6 +537,7 @@ public class AuthenticationTest extends TestCase
|
|||||||
tc.setOneOff(false);
|
tc.setOneOff(false);
|
||||||
tc.setTicketsExpire(true);
|
tc.setTicketsExpire(true);
|
||||||
tc.setValidDuration("P5S");
|
tc.setValidDuration("P5S");
|
||||||
|
tc.setTicketsCache(ticketsCache);
|
||||||
|
|
||||||
dao.createUser("Andy", "ticket".toCharArray());
|
dao.createUser("Andy", "ticket".toCharArray());
|
||||||
|
|
||||||
@@ -619,6 +627,7 @@ public class AuthenticationTest extends TestCase
|
|||||||
tc.setOneOff(false);
|
tc.setOneOff(false);
|
||||||
tc.setTicketsExpire(true);
|
tc.setTicketsExpire(true);
|
||||||
tc.setValidDuration("P1D");
|
tc.setValidDuration("P1D");
|
||||||
|
tc.setTicketsCache(ticketsCache);
|
||||||
|
|
||||||
dao.createUser("Andy", "ticket".toCharArray());
|
dao.createUser("Andy", "ticket".toCharArray());
|
||||||
|
|
||||||
|
@@ -16,11 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.security.authentication;
|
package org.alfresco.repo.security.authentication;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
import org.alfresco.service.cmr.repository.datatype.Duration;
|
import org.alfresco.service.cmr.repository.datatype.Duration;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
public class InMemoryTicketComponentImpl implements TicketComponent
|
public class InMemoryTicketComponentImpl implements TicketComponent
|
||||||
@@ -33,13 +34,18 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
|
|
||||||
private boolean oneOff;
|
private boolean oneOff;
|
||||||
|
|
||||||
private HashMap<String, Ticket> tickets = new HashMap<String, Ticket>();
|
private SimpleCache<String, Ticket> ticketsCache; // Can't use Ticket as it's private
|
||||||
|
|
||||||
public InMemoryTicketComponentImpl()
|
public InMemoryTicketComponentImpl()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTicketsCache(SimpleCache<String, Ticket> ticketsCache)
|
||||||
|
{
|
||||||
|
this.ticketsCache = ticketsCache;
|
||||||
|
}
|
||||||
|
|
||||||
public String getTicket(String userName) throws AuthenticationException
|
public String getTicket(String userName) throws AuthenticationException
|
||||||
{
|
{
|
||||||
Date expiryDate = null;
|
Date expiryDate = null;
|
||||||
@@ -48,7 +54,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
expiryDate = Duration.add(new Date(), validDuration);
|
expiryDate = Duration.add(new Date(), validDuration);
|
||||||
}
|
}
|
||||||
Ticket ticket = new Ticket(ticketsExpire, expiryDate, userName);
|
Ticket ticket = new Ticket(ticketsExpire, expiryDate, userName);
|
||||||
tickets.put(ticket.getTicketId(), ticket);
|
ticketsCache.put(ticket.getTicketId(), ticket);
|
||||||
|
|
||||||
return GRANTED_AUTHORITY_TICKET_PREFIX + ticket.getTicketId();
|
return GRANTED_AUTHORITY_TICKET_PREFIX + ticket.getTicketId();
|
||||||
}
|
}
|
||||||
@@ -61,7 +67,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
String key = ticketString.substring(GRANTED_AUTHORITY_TICKET_PREFIX.length());
|
String key = ticketString.substring(GRANTED_AUTHORITY_TICKET_PREFIX.length());
|
||||||
Ticket ticket = tickets.get(key);
|
Ticket ticket = ticketsCache.get(key);
|
||||||
if (ticket == null)
|
if (ticket == null)
|
||||||
{
|
{
|
||||||
throw new AuthenticationException("Missing ticket for " + ticketString);
|
throw new AuthenticationException("Missing ticket for " + ticketString);
|
||||||
@@ -74,7 +80,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
// TODO: Strengthen ticket as GUID is predicatble
|
// TODO: Strengthen ticket as GUID is predicatble
|
||||||
if(oneOff)
|
if(oneOff)
|
||||||
{
|
{
|
||||||
tickets.remove(key);
|
ticketsCache.remove(key);
|
||||||
}
|
}
|
||||||
return ticket.getUserName();
|
return ticket.getUserName();
|
||||||
}
|
}
|
||||||
@@ -82,16 +88,16 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
public void invalidateTicketById(String ticketString)
|
public void invalidateTicketById(String ticketString)
|
||||||
{
|
{
|
||||||
String key = ticketString.substring(GRANTED_AUTHORITY_TICKET_PREFIX.length());
|
String key = ticketString.substring(GRANTED_AUTHORITY_TICKET_PREFIX.length());
|
||||||
tickets.remove(key);
|
ticketsCache.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invalidateTicketByUser(String userName)
|
public void invalidateTicketByUser(String userName)
|
||||||
{
|
{
|
||||||
Set<String> toRemove = new HashSet<String>();
|
Set<String> toRemove = new HashSet<String>();
|
||||||
|
|
||||||
for(String key: tickets.keySet())
|
for(String key: ticketsCache.getKeys())
|
||||||
{
|
{
|
||||||
Ticket ticket = tickets.get(key);
|
Ticket ticket = ticketsCache.get(key);
|
||||||
if(ticket.getUserName().equals(userName))
|
if(ticket.getUserName().equals(userName))
|
||||||
{
|
{
|
||||||
toRemove.add(ticket.getTicketId());
|
toRemove.add(ticket.getTicketId());
|
||||||
@@ -100,14 +106,16 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
|
|
||||||
for(String id: toRemove)
|
for(String id: toRemove)
|
||||||
{
|
{
|
||||||
tickets.remove(id);
|
ticketsCache.remove(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static class Ticket
|
public static class Ticket implements Serializable
|
||||||
{
|
{
|
||||||
|
private static final long serialVersionUID = -5904510560161261049L;
|
||||||
|
|
||||||
private boolean expires;
|
private boolean expires;
|
||||||
|
|
||||||
private Date expiryDate;
|
private Date expiryDate;
|
||||||
|
@@ -21,6 +21,7 @@ import java.io.File;
|
|||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.naming.NamingEnumeration;
|
import javax.naming.NamingEnumeration;
|
||||||
@@ -147,6 +148,8 @@ public class LDAPPersonExportSource implements ExportSource
|
|||||||
writer.startElement(NamespaceService.REPOSITORY_VIEW_PREFIX, "view",
|
writer.startElement(NamespaceService.REPOSITORY_VIEW_PREFIX, "view",
|
||||||
NamespaceService.REPOSITORY_VIEW_PREFIX + ":" + "view", new AttributesImpl());
|
NamespaceService.REPOSITORY_VIEW_PREFIX + ":" + "view", new AttributesImpl());
|
||||||
|
|
||||||
|
HashSet<String> uids = new HashSet<String>();
|
||||||
|
|
||||||
InitialDirContext ctx = null;
|
InitialDirContext ctx = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -161,32 +164,41 @@ public class LDAPPersonExportSource implements ExportSource
|
|||||||
userSearchCtls.setCountLimit(Integer.MAX_VALUE);
|
userSearchCtls.setCountLimit(Integer.MAX_VALUE);
|
||||||
|
|
||||||
NamingEnumeration searchResults = ctx.search(searchBase, personQuery, userSearchCtls);
|
NamingEnumeration searchResults = ctx.search(searchBase, personQuery, userSearchCtls);
|
||||||
while (searchResults.hasMoreElements())
|
RESULT_LOOP: while (searchResults.hasMoreElements())
|
||||||
{
|
{
|
||||||
SearchResult result = (SearchResult) searchResults.next();
|
SearchResult result = (SearchResult) searchResults.next();
|
||||||
Attributes attributes = result.getAttributes();
|
Attributes attributes = result.getAttributes();
|
||||||
Attribute uidAttribute = attributes.get(userIdAttributeName);
|
Attribute uidAttribute = attributes.get(userIdAttributeName);
|
||||||
if (uidAttribute == null)
|
if (uidAttribute == null)
|
||||||
{
|
{
|
||||||
if(errorOnMissingUID)
|
if (errorOnMissingUID)
|
||||||
{
|
{
|
||||||
throw new ExportSourceImporterException(
|
throw new ExportSourceImporterException(
|
||||||
"User returned by user search does not have mandatory user id attribute " + attributes);
|
"User returned by user search does not have mandatory user id attribute "
|
||||||
|
+ attributes);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s_logger.warn("User returned by user search does not have mandatory user id attribute " + attributes);
|
s_logger.warn("User returned by user search does not have mandatory user id attribute "
|
||||||
continue;
|
+ attributes);
|
||||||
|
continue RESULT_LOOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String uid = (String) uidAttribute.get(0);
|
String uid = (String) uidAttribute.get(0);
|
||||||
|
|
||||||
|
if (uids.contains(uid))
|
||||||
|
{
|
||||||
|
s_logger.warn("Duplicate uid found - there will be more than one person object for this user - "
|
||||||
|
+ uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
uids.add(uid);
|
||||||
|
|
||||||
if (s_logger.isDebugEnabled())
|
if (s_logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
s_logger.debug("Adding user for " + uid);
|
s_logger.debug("Adding user for " + uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
writer.startElement(ContentModel.TYPE_PERSON.getNamespaceURI(), ContentModel.TYPE_PERSON
|
writer.startElement(ContentModel.TYPE_PERSON.getNamespaceURI(), ContentModel.TYPE_PERSON
|
||||||
.getLocalName(), ContentModel.TYPE_PERSON.toPrefixString(namespaceService), attrs);
|
.getLocalName(), ContentModel.TYPE_PERSON.toPrefixString(namespaceService), attrs);
|
||||||
|
|
||||||
@@ -234,7 +246,7 @@ public class LDAPPersonExportSource implements ExportSource
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
String defaultValue = attributeDefaults.get(key);
|
String defaultValue = attributeDefaults.get(key);
|
||||||
if(defaultValue != null)
|
if (defaultValue != null)
|
||||||
{
|
{
|
||||||
writer.characters(defaultValue.toCharArray(), 0, defaultValue.length());
|
writer.characters(defaultValue.toCharArray(), 0, defaultValue.length());
|
||||||
}
|
}
|
||||||
@@ -243,7 +255,7 @@ public class LDAPPersonExportSource implements ExportSource
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
String defaultValue = attributeDefaults.get(key);
|
String defaultValue = attributeDefaults.get(key);
|
||||||
if(defaultValue != null)
|
if (defaultValue != null)
|
||||||
{
|
{
|
||||||
writer.characters(defaultValue.toCharArray(), 0, defaultValue.length());
|
writer.characters(defaultValue.toCharArray(), 0, defaultValue.length());
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
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.authentication.ldap.LDAPPersonExportSource;
|
||||||
import org.alfresco.repo.security.permissions.PermissionServiceSPI;
|
import org.alfresco.repo.security.permissions.PermissionServiceSPI;
|
||||||
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;
|
||||||
@@ -41,9 +42,20 @@ import org.alfresco.service.cmr.security.NoSuchPersonException;
|
|||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.util.GUID;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
public class PersonServiceImpl implements PersonService
|
public class PersonServiceImpl implements PersonService
|
||||||
{
|
{
|
||||||
|
private static Log s_logger = LogFactory.getLog(PersonServiceImpl.class);
|
||||||
|
|
||||||
|
private static final String DELETE = "DELETE";
|
||||||
|
|
||||||
|
private static final String SPLIT = "SPLIT";
|
||||||
|
|
||||||
|
private static final String LEAVE = "LEAVE";
|
||||||
|
|
||||||
public static final String SYSTEM_FOLDER = "/sys:system";
|
public static final String SYSTEM_FOLDER = "/sys:system";
|
||||||
|
|
||||||
public static final String PEOPLE_FOLDER = SYSTEM_FOLDER + "/sys:people";
|
public static final String PEOPLE_FOLDER = SYSTEM_FOLDER + "/sys:people";
|
||||||
@@ -70,6 +82,14 @@ public class PersonServiceImpl implements PersonService
|
|||||||
|
|
||||||
private String defaultHomeFolderProvider;
|
private String defaultHomeFolderProvider;
|
||||||
|
|
||||||
|
private boolean processDuplicates = true;
|
||||||
|
|
||||||
|
private String duplicateMode = LEAVE;
|
||||||
|
|
||||||
|
private boolean lastIsBest = true;
|
||||||
|
|
||||||
|
private boolean includeAutoCreated = false;
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
Set<QName> props = new HashSet<QName>();
|
Set<QName> props = new HashSet<QName>();
|
||||||
@@ -102,6 +122,26 @@ public class PersonServiceImpl implements PersonService
|
|||||||
this.defaultHomeFolderProvider = defaultHomeFolderProvider;
|
this.defaultHomeFolderProvider = defaultHomeFolderProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDuplicateMode(String duplicateMode)
|
||||||
|
{
|
||||||
|
this.duplicateMode = duplicateMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIncludeAutoCreated(boolean includeAutoCreated)
|
||||||
|
{
|
||||||
|
this.includeAutoCreated = includeAutoCreated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastIsBest(boolean lastIsBest)
|
||||||
|
{
|
||||||
|
this.lastIsBest = lastIsBest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProcessDuplicates(boolean processDuplicates)
|
||||||
|
{
|
||||||
|
this.processDuplicates = processDuplicates;
|
||||||
|
}
|
||||||
|
|
||||||
public NodeRef getPerson(String userName)
|
public NodeRef getPerson(String userName)
|
||||||
{
|
{
|
||||||
NodeRef personNode = getPersonOrNull(userName);
|
NodeRef personNode = getPersonOrNull(userName);
|
||||||
@@ -130,21 +170,23 @@ public class PersonServiceImpl implements PersonService
|
|||||||
|
|
||||||
public NodeRef getPersonOrNull(String searchUserName)
|
public NodeRef getPersonOrNull(String searchUserName)
|
||||||
{
|
{
|
||||||
|
NodeRef returnRef = null;
|
||||||
|
|
||||||
SearchParameters sp = new SearchParameters();
|
SearchParameters sp = new SearchParameters();
|
||||||
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
|
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||||
sp.setQuery("TYPE:\\{http\\://www.alfresco.org/model/content/1.0\\}person +@cm\\:userName:\"" + searchUserName
|
sp.setQuery("TYPE:\\{http\\://www.alfresco.org/model/content/1.0\\}person +@cm\\:userName:\""
|
||||||
+ "\"");
|
+ searchUserName + "\"");
|
||||||
sp.addStore(storeRef);
|
sp.addStore(storeRef);
|
||||||
sp.excludeDataInTheCurrentTransaction(false);
|
sp.excludeDataInTheCurrentTransaction(false);
|
||||||
|
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
|
|
||||||
|
boolean singleton = true;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
rs = searchService.query(sp);
|
rs = searchService.query(sp);
|
||||||
|
|
||||||
NodeRef returnRef = null;
|
|
||||||
|
|
||||||
for (ResultSetRow row : rs)
|
for (ResultSetRow row : rs)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -164,8 +206,8 @@ public class PersonServiceImpl implements PersonService
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("Found more than one user for " + searchUserName
|
singleton = false;
|
||||||
+ " (case sensitive)");
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,15 +221,13 @@ public class PersonServiceImpl implements PersonService
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("Found more than one user for " + searchUserName
|
singleton = false;
|
||||||
+ " (case insensitive)");
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnRef;
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -196,6 +236,269 @@ public class PersonServiceImpl implements PersonService
|
|||||||
rs.close();
|
rs.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (singleton)
|
||||||
|
{
|
||||||
|
return returnRef;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return handleDuplicates(searchUserName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeRef handleDuplicates(String searchUserName)
|
||||||
|
{
|
||||||
|
if (processDuplicates)
|
||||||
|
{
|
||||||
|
NodeRef best = findBest(searchUserName);
|
||||||
|
if (duplicateMode.equalsIgnoreCase(SPLIT))
|
||||||
|
{
|
||||||
|
split(searchUserName, best);
|
||||||
|
s_logger.info("Split duplicate person objects for uid " + searchUserName);
|
||||||
|
}
|
||||||
|
else if (duplicateMode.equalsIgnoreCase(DELETE))
|
||||||
|
{
|
||||||
|
delete(searchUserName, best);
|
||||||
|
s_logger.info("Deleted duplicate person objects for uid " + searchUserName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (s_logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
s_logger.debug("Duplicate person objects exist for uid " + searchUserName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (userNamesAreCaseSensitive)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Found more than one user for "
|
||||||
|
+ searchUserName + " (case sensitive)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Found more than one user for "
|
||||||
|
+ searchUserName + " (case insensitive)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void delete(String searchUserName, NodeRef best)
|
||||||
|
{
|
||||||
|
SearchParameters sp = new SearchParameters();
|
||||||
|
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||||
|
sp.setQuery("TYPE:\\{http\\://www.alfresco.org/model/content/1.0\\}person +@cm\\:userName:\""
|
||||||
|
+ searchUserName + "\"");
|
||||||
|
sp.addStore(storeRef);
|
||||||
|
sp.excludeDataInTheCurrentTransaction(false);
|
||||||
|
|
||||||
|
ResultSet rs = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
rs = searchService.query(sp);
|
||||||
|
|
||||||
|
for (ResultSetRow row : rs)
|
||||||
|
{
|
||||||
|
NodeRef nodeRef = row.getNodeRef();
|
||||||
|
// Do not delete the best
|
||||||
|
if ((!best.equals(nodeRef)) && (nodeService.exists(nodeRef)))
|
||||||
|
{
|
||||||
|
String realUserName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(
|
||||||
|
nodeRef, ContentModel.PROP_USERNAME));
|
||||||
|
|
||||||
|
if (userNamesAreCaseSensitive)
|
||||||
|
{
|
||||||
|
if (realUserName.equals(searchUserName))
|
||||||
|
{
|
||||||
|
nodeService.deleteNode(nodeRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (realUserName.equalsIgnoreCase(searchUserName))
|
||||||
|
{
|
||||||
|
nodeService.deleteNode(nodeRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (rs != null)
|
||||||
|
{
|
||||||
|
rs.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void split(String searchUserName, NodeRef best)
|
||||||
|
{
|
||||||
|
SearchParameters sp = new SearchParameters();
|
||||||
|
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||||
|
sp.setQuery("TYPE:\\{http\\://www.alfresco.org/model/content/1.0\\}person +@cm\\:userName:\""
|
||||||
|
+ searchUserName + "\"");
|
||||||
|
sp.addStore(storeRef);
|
||||||
|
sp.excludeDataInTheCurrentTransaction(false);
|
||||||
|
|
||||||
|
ResultSet rs = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
rs = searchService.query(sp);
|
||||||
|
|
||||||
|
for (ResultSetRow row : rs)
|
||||||
|
{
|
||||||
|
NodeRef nodeRef = row.getNodeRef();
|
||||||
|
// Do not delete the best
|
||||||
|
if ((!best.equals(nodeRef)) && (nodeService.exists(nodeRef)))
|
||||||
|
{
|
||||||
|
String realUserName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(
|
||||||
|
nodeRef, ContentModel.PROP_USERNAME));
|
||||||
|
|
||||||
|
if (userNamesAreCaseSensitive)
|
||||||
|
{
|
||||||
|
if (realUserName.equals(searchUserName))
|
||||||
|
{
|
||||||
|
nodeService.setProperty(nodeRef, ContentModel.PROP_USERNAME, searchUserName
|
||||||
|
+ "(" + GUID.generate() + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (realUserName.equalsIgnoreCase(searchUserName))
|
||||||
|
{
|
||||||
|
nodeService.setProperty(nodeRef, ContentModel.PROP_USERNAME, searchUserName
|
||||||
|
+ GUID.generate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (rs != null)
|
||||||
|
{
|
||||||
|
rs.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeRef findBest(String searchUserName)
|
||||||
|
{
|
||||||
|
SearchParameters sp = new SearchParameters();
|
||||||
|
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||||
|
sp.setQuery("TYPE:\\{http\\://www.alfresco.org/model/content/1.0\\}person +@cm\\:userName:\""
|
||||||
|
+ searchUserName + "\"");
|
||||||
|
sp.addStore(storeRef);
|
||||||
|
sp.excludeDataInTheCurrentTransaction(false);
|
||||||
|
if (lastIsBest)
|
||||||
|
{
|
||||||
|
sp.addSort(SearchParameters.SORT_IN_DOCUMENT_ORDER_DESCENDING);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sp.addSort(SearchParameters.SORT_IN_DOCUMENT_ORDER_ASCENDING);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultSet rs = null;
|
||||||
|
|
||||||
|
NodeRef fallBack = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
rs = searchService.query(sp);
|
||||||
|
|
||||||
|
for (ResultSetRow row : rs)
|
||||||
|
{
|
||||||
|
NodeRef nodeRef = row.getNodeRef();
|
||||||
|
if (fallBack == null)
|
||||||
|
{
|
||||||
|
fallBack = nodeRef;
|
||||||
|
}
|
||||||
|
// Do not delete the best
|
||||||
|
if (nodeService.exists(nodeRef))
|
||||||
|
{
|
||||||
|
String realUserName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(
|
||||||
|
nodeRef, ContentModel.PROP_USERNAME));
|
||||||
|
|
||||||
|
if (userNamesAreCaseSensitive)
|
||||||
|
{
|
||||||
|
if (realUserName.equals(searchUserName))
|
||||||
|
{
|
||||||
|
if (includeAutoCreated || !wasAutoCreated(nodeRef, searchUserName))
|
||||||
|
{
|
||||||
|
return nodeRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (realUserName.equalsIgnoreCase(searchUserName))
|
||||||
|
{
|
||||||
|
if (includeAutoCreated || !wasAutoCreated(nodeRef, searchUserName))
|
||||||
|
{
|
||||||
|
return nodeRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (rs != null)
|
||||||
|
{
|
||||||
|
rs.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fallBack;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean wasAutoCreated(NodeRef nodeRef, String userName)
|
||||||
|
{
|
||||||
|
String testString = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef,
|
||||||
|
ContentModel.PROP_FIRSTNAME));
|
||||||
|
if ((testString == null) || !testString.equals(userName))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
testString = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef,
|
||||||
|
ContentModel.PROP_LASTNAME));
|
||||||
|
if ((testString == null) || !testString.equals(""))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
testString = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef,
|
||||||
|
ContentModel.PROP_EMAIL));
|
||||||
|
if ((testString == null) || !testString.equals(""))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
testString = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef,
|
||||||
|
ContentModel.PROP_ORGID));
|
||||||
|
if ((testString == null) || !testString.equals(""))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
testString = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef,
|
||||||
|
ContentModel.PROP_HOME_FOLDER_PROVIDER));
|
||||||
|
if ((testString == null) || !testString.equals(defaultHomeFolderProvider))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean createMissingPeople()
|
public boolean createMissingPeople()
|
||||||
@@ -225,8 +528,8 @@ public class PersonServiceImpl implements PersonService
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String realUserName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(personNode,
|
String realUserName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(
|
||||||
ContentModel.PROP_USERNAME));
|
personNode, ContentModel.PROP_USERNAME));
|
||||||
properties.put(ContentModel.PROP_USERNAME, realUserName);
|
properties.put(ContentModel.PROP_USERNAME, realUserName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -53,6 +53,12 @@ public class UIDBasedHomeFolderProvider extends ExistingPathBasedHomeFolderProvi
|
|||||||
{
|
{
|
||||||
String uid = DefaultTypeConverter.INSTANCE.convert(String.class, getServiceRegistry().getNodeService()
|
String uid = DefaultTypeConverter.INSTANCE.convert(String.class, getServiceRegistry().getNodeService()
|
||||||
.getProperty(person, ContentModel.PROP_USERNAME));
|
.getProperty(person, ContentModel.PROP_USERNAME));
|
||||||
|
|
||||||
|
if((uid == null) || (uid.length() == 0))
|
||||||
|
{
|
||||||
|
throw new PersonException("Can not create a home space when the uid is null or empty");
|
||||||
|
}
|
||||||
|
|
||||||
FileInfo fileInfo;
|
FileInfo fileInfo;
|
||||||
|
|
||||||
// Test if it already exists
|
// Test if it already exists
|
||||||
|
Reference in New Issue
Block a user