diff --git a/config/alfresco/cache-context.xml b/config/alfresco/cache-context.xml index af8ce63be2..53258595b0 100644 --- a/config/alfresco/cache-context.xml +++ b/config/alfresco/cache-context.xml @@ -24,7 +24,7 @@ - + diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties index 5740253d0c..9c73533789 100644 --- a/config/alfresco/messages/patch-service.properties +++ b/config/alfresco/messages/patch-service.properties @@ -269,8 +269,8 @@ patch.imapFolders.result.created=The 'Imap Configs' folder was successfully crea patch.zonedAuthorities.description=Adds the remodelled cm:authority container to the spaces store patch.authorityMigration.description=Copies any old authorities from the user store to the spaces store. -patch.authorityMigration.progress.authority={0} groups migrated -patch.authorityMigration.progress.assoc={0} group associations migrated +patch.authorityMigration.process.name=Authority Migration +patch.authorityMigration.warning.assoc=Ignoring group memberships of non-existent user {1} patch.authorityMigration.result=Migrated {0} groups and {1} group associations to the spaces store. patch.authorityDefaultZonesPatch.description=Adds groups and people to the appropriate zones for wcm, share and everything else. @@ -281,7 +281,7 @@ patch.authorityDefaultZonesPatch.groups= Adding groups to zones ... patch.fixNameCrcValues.description=Fixes name and qname CRC32 values to match UTF-8 encoding. patch.fixNameCrcValues.result=Fixed CRC32 values for UTF-8 encoding for {0} node child associations. See file {1} for details. patch.fixNameCrcValues.fixed=Updated CRC32 values for node ID {0}, name ''{1}'': {2} -> {3}, qname ''{4}'': {5} -> {6}. -patch.fixNameCrcValues.unableToChange=Failed to update the CRC32 value for node ID {0}: \n Node name: {1} \n name CRC old: {2} \n name CRC new: {3} \n qname CRC old: {4} \n qname CRC new: {5} \n Error: {6} +patch.fixNameCrcValues.unableToChange=Failed to update the CRC32 value for node ID {0}: \n Node name: {1} \n name CRC old: {2} \n name CRC new: {3} \n Node qname: {4} \n qname CRC old: {5} \n qname CRC new: {6} \n Error: {7} patch.personUsagePatch.description=Add person 'cm:sizeCurrent' property (if missing). patch.personUsagePatch.result1=Added 'cm:sizeCurrent' property to {0} people that were missing this property. diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml index 72775651b4..de266089f5 100644 --- a/config/alfresco/patch/patch-services-context.xml +++ b/config/alfresco/patch/patch-services-context.xml @@ -1805,6 +1805,9 @@ + + + diff --git a/config/alfresco/public-services-security-context.xml b/config/alfresco/public-services-security-context.xml index b3fea8bbf7..5c25627fb8 100644 --- a/config/alfresco/public-services-security-context.xml +++ b/config/alfresco/public-services-security-context.xml @@ -748,6 +748,7 @@ org.alfresco.service.cmr.security.MutableAuthenticationService.isAuthenticationMutable=ACL_ALLOW + org.alfresco.service.cmr.security.MutableAuthenticationService.isAuthenticationCreationAllowed=ACL_ALLOW org.alfresco.service.cmr.security.MutableAuthenticationService.createAuthentication=ACL_METHOD.ROLE_ADMINISTRATOR org.alfresco.service.cmr.security.MutableAuthenticationService.updateAuthentication=ACL_ALLOW org.alfresco.service.cmr.security.MutableAuthenticationService.setAuthentication=ACL_METHOD.ROLE_ADMINISTRATOR diff --git a/source/java/org/alfresco/email/server/AliasableAspect.java b/source/java/org/alfresco/email/server/AliasableAspect.java index 1c33eaaf88..114e0300e5 100644 --- a/source/java/org/alfresco/email/server/AliasableAspect.java +++ b/source/java/org/alfresco/email/server/AliasableAspect.java @@ -108,15 +108,22 @@ public class AliasableAspect implements NodeServicePolicies.OnAddAspectPolicy, N // Create search string like this: ASPECT:"emailserver:aliasable" +@emailserver\:alias:"alias_string" String query = String.format(SEARCH_TEMPLATE, alias); ResultSet res = searchService.query(storeRef, SearchService.LANGUAGE_LUCENE, query); - for (int i = 0; i < res.length(); i++) + try { - NodeRef resRef = res.getNodeRef(i); - Object otherAlias = nodeService.getProperty(resRef, EmailServerModel.PROP_ALIAS); - if (!resRef.equals(nodeRef) && alias.equals(otherAlias)) + for (int i = 0; i < res.length(); i++) { - throw new AlfrescoRuntimeException("Node with alias=\"" + alias + "\" already exists. Duplicate isn't allowed."); + NodeRef resRef = res.getNodeRef(i); + Object otherAlias = nodeService.getProperty(resRef, EmailServerModel.PROP_ALIAS); + if (!resRef.equals(nodeRef) && alias.equals(otherAlias)) + { + throw new AlfrescoRuntimeException("Node with alias=\"" + alias + "\" already exists. Duplicate isn't allowed."); + } } } + finally + { + res.close(); + } } /** diff --git a/source/java/org/alfresco/email/server/EmailServiceImpl.java b/source/java/org/alfresco/email/server/EmailServiceImpl.java index 881878d8e2..354d7ca37b 100644 --- a/source/java/org/alfresco/email/server/EmailServiceImpl.java +++ b/source/java/org/alfresco/email/server/EmailServiceImpl.java @@ -287,25 +287,38 @@ public class EmailServiceImpl implements EmailService StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"); String query = String.format(AliasableAspect.SEARCH_TEMPLATE, parts[0]); ResultSet resultSet = searchService.query(storeRef, SearchService.LANGUAGE_LUCENE, query); - - // Sometimes result contains trash. For example if we look for node with alias='target' after searching, - // we will get all nodes wich contain word 'target' in them alias property. - for (int i = 0; i < resultSet.length(); i++) + try { - NodeRef resRef = resultSet.getNodeRef(i); - Object alias = nodeService.getProperty(resRef, EmailServerModel.PROP_ALIAS); - if (parts[0].equals(alias)) + // Sometimes result contains trash. For example if we look for node with alias='target' after searching, + // we will get all nodes wich contain word 'target' in them alias property. + for (int i = 0; i < resultSet.length(); i++) { - return resRef; + NodeRef resRef = resultSet.getNodeRef(i); + Object alias = nodeService.getProperty(resRef, EmailServerModel.PROP_ALIAS); + if (parts[0].equals(alias)) + { + return resRef; + } } } + finally + { + resultSet.close(); + } // Ok, alias wasn't found, let's try to interpret recipient address as 'node-bdid' value query = "@sys\\:node-dbid:" + parts[0]; - resultSet = searchService.query(storeRef, SearchService.LANGUAGE_LUCENE, query); - if (resultSet.length() > 0) + try { - return resultSet.getNodeRef(0); + resultSet = searchService.query(storeRef, SearchService.LANGUAGE_LUCENE, query); + if (resultSet.length() > 0) + { + return resultSet.getNodeRef(0); + } + } + finally + { + resultSet.close(); } throw new EmailMessageException(ERR_INVALID_NODE_ADDRESS, recipient); } @@ -324,32 +337,38 @@ public class EmailServiceImpl implements EmailService String query = "TYPE:cm\\:person +@cm\\:email:\"" + from + "\""; ResultSet resultSet = searchService.query(storeRef, SearchService.LANGUAGE_LUCENE, query); - - if (resultSet.length() == 0) + try { - if (unknownUser == null || unknownUser.length() == 0) + if (resultSet.length() == 0) { - throw new EmailMessageException(ERR_UNKNOWN_SOURCE_ADDRESS, from); + if (unknownUser == null || unknownUser.length() == 0) + { + throw new EmailMessageException(ERR_UNKNOWN_SOURCE_ADDRESS, from); + } + else + { + userName = unknownUser; + } } else { - userName = unknownUser; + NodeRef userNode = resultSet.getNodeRef(0); + if (nodeService.exists(userNode)) + { + userName = DefaultTypeConverter.INSTANCE.convert( + String.class, + nodeService.getProperty(userNode, ContentModel.PROP_USERNAME)); + } + else + { + // The Lucene index returned a dead result + throw new EmailMessageException(ERR_UNKNOWN_SOURCE_ADDRESS, from); + } } } - else + finally { - NodeRef userNode = resultSet.getNodeRef(0); - if (nodeService.exists(userNode)) - { - userName = DefaultTypeConverter.INSTANCE.convert( - String.class, - nodeService.getProperty(userNode, ContentModel.PROP_USERNAME)); - } - else - { - // The Lucene index returned a dead result - throw new EmailMessageException(ERR_UNKNOWN_SOURCE_ADDRESS, from); - } + resultSet.close(); } // Ensure that the user is part of the Email Contributors group if (userName == null || !isEmailContributeUser(userName)) diff --git a/source/java/org/alfresco/email/server/handler/AbstractEmailMessageHandler.java b/source/java/org/alfresco/email/server/handler/AbstractEmailMessageHandler.java index b62cc5b86b..3fde32d02d 100644 --- a/source/java/org/alfresco/email/server/handler/AbstractEmailMessageHandler.java +++ b/source/java/org/alfresco/email/server/handler/AbstractEmailMessageHandler.java @@ -163,9 +163,16 @@ public abstract class AbstractEmailMessageHandler implements EmailMessageHandler StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"); String query = "@sys\\:node-dbid:" + parts[0]; ResultSet resultSet = searchService.query(storeRef, SearchService.LANGUAGE_LUCENE, query); - if (resultSet.length() == 1) + try { - return resultSet.getNodeRef(0); + if (resultSet.length() == 1) + { + return resultSet.getNodeRef(0); + } + } + finally + { + resultSet.close(); } return null; } diff --git a/source/java/org/alfresco/filesys/repo/ContentIOControlHandler.java b/source/java/org/alfresco/filesys/repo/ContentIOControlHandler.java index fa2037471e..917b478842 100644 --- a/source/java/org/alfresco/filesys/repo/ContentIOControlHandler.java +++ b/source/java/org/alfresco/filesys/repo/ContentIOControlHandler.java @@ -754,7 +754,7 @@ public class ContentIOControlHandler implements IOControlHandler { // Validate the existing ticket - getAuthenticationService().validate( cInfo.getAuthenticationTicket()); + getAuthenticationService().validate( cInfo.getAuthenticationTicket(), null); needTicket = false; } catch ( AuthenticationException ex) @@ -763,7 +763,7 @@ public class ContentIOControlHandler implements IOControlHandler try { - getAuthenticationService().invalidateTicket( cInfo.getAuthenticationTicket()); + getAuthenticationService().invalidateTicket( cInfo.getAuthenticationTicket(), null); cInfo.setAuthenticationTicket( null); } catch (Exception ex2) diff --git a/source/java/org/alfresco/jcr/session/SessionImpl.java b/source/java/org/alfresco/jcr/session/SessionImpl.java index 4b1d628da4..29a620ba9c 100644 --- a/source/java/org/alfresco/jcr/session/SessionImpl.java +++ b/source/java/org/alfresco/jcr/session/SessionImpl.java @@ -657,7 +657,7 @@ public class SessionImpl implements Session { try { - getRepositoryImpl().getServiceRegistry().getAuthenticationService().invalidateTicket(getTicket()); + getRepositoryImpl().getServiceRegistry().getAuthenticationService().invalidateTicket(getTicket(), null); } finally { diff --git a/source/java/org/alfresco/jcr/util/JCRProxyFactory.java b/source/java/org/alfresco/jcr/util/JCRProxyFactory.java index a14c9d8af7..1cf08a8ecd 100644 --- a/source/java/org/alfresco/jcr/util/JCRProxyFactory.java +++ b/source/java/org/alfresco/jcr/util/JCRProxyFactory.java @@ -130,7 +130,7 @@ public class JCRProxyFactory { if (username == null) { - authenticationService.validate(session.getTicket()); + authenticationService.validate(session.getTicket(), null); } } diff --git a/source/java/org/alfresco/repo/action/ActionServiceTransportImpl.java b/source/java/org/alfresco/repo/action/ActionServiceTransportImpl.java index 190ede86e8..9fa8e0cfd0 100644 --- a/source/java/org/alfresco/repo/action/ActionServiceTransportImpl.java +++ b/source/java/org/alfresco/repo/action/ActionServiceTransportImpl.java @@ -64,7 +64,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport */ public Action createAction(String ticket, String name) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.createAction(name); } @@ -74,7 +74,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport public Action createAction(String ticket, String name, Map params) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.createAction(name, params); } @@ -83,7 +83,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport */ public ActionCondition createActionCondition(String ticket, String name) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.createActionCondition(name); } @@ -93,7 +93,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport public ActionCondition createActionCondition(String ticket, String name, Map params) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.createActionCondition(name, params); } @@ -102,7 +102,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport */ public CompositeAction createCompositeAction(String ticket) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.createCompositeAction(); } @@ -112,7 +112,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport public boolean evaluateAction(String ticket, Action action, NodeRef actionedUponNodeRef) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.evaluateAction(action, actionedUponNodeRef); } @@ -122,7 +122,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport public boolean evaluateActionCondition(String ticket, ActionCondition condition, NodeRef actionedUponNodeRef) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.evaluateActionCondition(condition, actionedUponNodeRef); } @@ -132,7 +132,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport public void executeAction(String ticket, Action action, NodeRef actionedUponNodeRef) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); fActionService.executeAction(action, actionedUponNodeRef); } @@ -142,7 +142,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport public void executeAction(String ticket, Action action, NodeRef actionedUponNodeRef, boolean checkConditions) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); fActionService.executeAction(action, actionedUponNodeRef, checkConditions); } @@ -153,7 +153,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport NodeRef actionedUponNodeRef, boolean checkConditions, boolean executeAsynchronously) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); fActionService.executeAction(action, actionedUponNodeRef, checkConditions, executeAsynchronously); } @@ -162,7 +162,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport */ public Action getAction(String ticket, NodeRef nodeRef, String actionId) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.getAction(nodeRef, actionId); } @@ -172,7 +172,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport public ActionConditionDefinition getActionConditionDefinition( String ticket, String name) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.getActionConditionDefinition(name); } @@ -182,7 +182,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport public List getActionConditionDefinitions( String ticket) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.getActionConditionDefinitions(); } @@ -191,7 +191,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport */ public ActionDefinition getActionDefinition(String ticket, String name) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.getActionDefinition(name); } @@ -200,7 +200,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport */ public List getActionDefinitions(String ticket) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.getActionDefinitions(); } @@ -210,7 +210,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport public List getActionDefinitions(String ticket, NodeRef nodeRef) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.getActionDefinitions(nodeRef); } @@ -219,7 +219,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport */ public List getActions(String ticket, NodeRef nodeRef) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fActionService.getActions(nodeRef); } @@ -228,7 +228,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport */ public void removeAction(String ticket, NodeRef nodeRef, Action action) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); fActionService.removeAction(nodeRef, action); } @@ -237,7 +237,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport */ public void removeAllActions(String ticket, NodeRef nodeRef) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); fActionService.removeAllActions(nodeRef); } @@ -246,7 +246,7 @@ public class ActionServiceTransportImpl implements ActionServiceTransport */ public void saveAction(String ticket, NodeRef nodeRef, Action action) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); fActionService.saveAction(nodeRef, action); } } diff --git a/source/java/org/alfresco/repo/admin/patch/impl/AVMLockingPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/AVMLockingPatch.java index 9972a01769..3571a7d0f6 100644 --- a/source/java/org/alfresco/repo/admin/patch/impl/AVMLockingPatch.java +++ b/source/java/org/alfresco/repo/admin/patch/impl/AVMLockingPatch.java @@ -58,10 +58,17 @@ public class AVMLockingPatch extends AbstractPatch { ResultSet results = searchService.query(new StoreRef(STORE), "lucene", "TYPE:\"wca:webfolder\""); - for (NodeRef nodeRef : results.getNodeRefs()) + try { - String webProject = (String)nodeService.getProperty(nodeRef, WCMAppModel.PROP_AVMSTORE); - fLockingService.addWebProject(webProject); + for (NodeRef nodeRef : results.getNodeRefs()) + { + String webProject = (String)nodeService.getProperty(nodeRef, WCMAppModel.PROP_AVMSTORE); + fLockingService.addWebProject(webProject); + } + } + finally + { + results.close(); } return I18NUtil.getMessage(MSG_SUCCESS); } diff --git a/source/java/org/alfresco/repo/admin/patch/impl/ActionRuleDecouplingPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/ActionRuleDecouplingPatch.java index 2b105b091e..b7c25cc9eb 100644 --- a/source/java/org/alfresco/repo/admin/patch/impl/ActionRuleDecouplingPatch.java +++ b/source/java/org/alfresco/repo/admin/patch/impl/ActionRuleDecouplingPatch.java @@ -59,65 +59,72 @@ public class ActionRuleDecouplingPatch extends AbstractPatch // Get all the node's of type rule in the store int updateCount = 0; ResultSet resultSet = this.searchService.query(storeRef, "lucene", "TYPE:\"" + RuleModel.TYPE_RULE + "\""); - for (NodeRef origRuleNodeRef : resultSet.getNodeRefs()) + try { - // Check that this rule need updated - if (!this.nodeService.exists(origRuleNodeRef)) + for (NodeRef origRuleNodeRef : resultSet.getNodeRefs()) { - continue; - } - Map origProperties = this.nodeService.getProperties(origRuleNodeRef); - if (origProperties.containsKey(RuleModel.PROP_EXECUTE_ASYNC) == false) - { - // 1) Change the type of the rule to be a composite action - this.nodeService.setType(origRuleNodeRef, ActionModel.TYPE_COMPOSITE_ACTION); - - // 2) Create a new rule node - ChildAssociationRef parentRef = this.nodeService.getPrimaryParent(origRuleNodeRef); - NodeRef newRuleNodeRef = this.nodeService.createNode( - parentRef.getParentRef(), - parentRef.getTypeQName(), - parentRef.getQName(), - RuleModel.TYPE_RULE).getChildRef(); - - // 3) Move the origional rule under the new rule - this.nodeService.moveNode( - origRuleNodeRef, - newRuleNodeRef, - RuleModel.ASSOC_ACTION, - RuleModel.ASSOC_ACTION); - - // 4) Move the various properties from the origional, onto the new rule - Map newProperties = this.nodeService.getProperties(newRuleNodeRef); - - // Set the rule type, execute async and applyToChildren properties on the rule - Serializable ruleType = origProperties.get(RuleModel.PROP_RULE_TYPE); - origProperties.remove(RuleModel.PROP_RULE_TYPE); - newProperties.put(RuleModel.PROP_RULE_TYPE, ruleType); - Serializable executeAsync = origProperties.get(ActionModel.PROP_EXECUTE_ASYNCHRONOUSLY); - origProperties.remove(ActionModel.PROP_EXECUTE_ASYNCHRONOUSLY); - newProperties.put(RuleModel.PROP_EXECUTE_ASYNC, executeAsync); - Serializable applyToChildren = origProperties.get(RuleModel.PROP_APPLY_TO_CHILDREN); - origProperties.remove(RuleModel.PROP_APPLY_TO_CHILDREN); - newProperties.put(RuleModel.PROP_APPLY_TO_CHILDREN, applyToChildren); - origProperties.remove(QName.createQName(RuleModel.RULE_MODEL_URI, "owningNodeRef")); - - // Move the action and description values from the composite action onto the rule - Serializable title = origProperties.get(ActionModel.PROP_ACTION_TITLE); - origProperties.remove(ActionModel.PROP_ACTION_TITLE); - Serializable description = origProperties.get(ActionModel.PROP_ACTION_DESCRIPTION); - origProperties.remove(ActionModel.PROP_ACTION_DESCRIPTION); - newProperties.put(ContentModel.PROP_TITLE, title); - newProperties.put(ContentModel.PROP_DESCRIPTION, description); - - // Set the updated property values - this.nodeService.setProperties(origRuleNodeRef, origProperties); - this.nodeService.setProperties(newRuleNodeRef, newProperties); - - // Increment the update count - updateCount++; + // Check that this rule need updated + if (!this.nodeService.exists(origRuleNodeRef)) + { + continue; + } + Map origProperties = this.nodeService.getProperties(origRuleNodeRef); + if (origProperties.containsKey(RuleModel.PROP_EXECUTE_ASYNC) == false) + { + // 1) Change the type of the rule to be a composite action + this.nodeService.setType(origRuleNodeRef, ActionModel.TYPE_COMPOSITE_ACTION); + + // 2) Create a new rule node + ChildAssociationRef parentRef = this.nodeService.getPrimaryParent(origRuleNodeRef); + NodeRef newRuleNodeRef = this.nodeService.createNode( + parentRef.getParentRef(), + parentRef.getTypeQName(), + parentRef.getQName(), + RuleModel.TYPE_RULE).getChildRef(); + + // 3) Move the origional rule under the new rule + this.nodeService.moveNode( + origRuleNodeRef, + newRuleNodeRef, + RuleModel.ASSOC_ACTION, + RuleModel.ASSOC_ACTION); + + // 4) Move the various properties from the origional, onto the new rule + Map newProperties = this.nodeService.getProperties(newRuleNodeRef); + + // Set the rule type, execute async and applyToChildren properties on the rule + Serializable ruleType = origProperties.get(RuleModel.PROP_RULE_TYPE); + origProperties.remove(RuleModel.PROP_RULE_TYPE); + newProperties.put(RuleModel.PROP_RULE_TYPE, ruleType); + Serializable executeAsync = origProperties.get(ActionModel.PROP_EXECUTE_ASYNCHRONOUSLY); + origProperties.remove(ActionModel.PROP_EXECUTE_ASYNCHRONOUSLY); + newProperties.put(RuleModel.PROP_EXECUTE_ASYNC, executeAsync); + Serializable applyToChildren = origProperties.get(RuleModel.PROP_APPLY_TO_CHILDREN); + origProperties.remove(RuleModel.PROP_APPLY_TO_CHILDREN); + newProperties.put(RuleModel.PROP_APPLY_TO_CHILDREN, applyToChildren); + origProperties.remove(QName.createQName(RuleModel.RULE_MODEL_URI, "owningNodeRef")); + + // Move the action and description values from the composite action onto the rule + Serializable title = origProperties.get(ActionModel.PROP_ACTION_TITLE); + origProperties.remove(ActionModel.PROP_ACTION_TITLE); + Serializable description = origProperties.get(ActionModel.PROP_ACTION_DESCRIPTION); + origProperties.remove(ActionModel.PROP_ACTION_DESCRIPTION); + newProperties.put(ContentModel.PROP_TITLE, title); + newProperties.put(ContentModel.PROP_DESCRIPTION, description); + + // Set the updated property values + this.nodeService.setProperties(origRuleNodeRef, origProperties); + this.nodeService.setProperties(newRuleNodeRef, newProperties); + + // Increment the update count + updateCount++; + } } } + finally + { + resultSet.close(); + } // Done String msg = I18NUtil.getMessage(MSG_RESULT, updateCount); diff --git a/source/java/org/alfresco/repo/admin/patch/impl/AuthorityMigrationPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/AuthorityMigrationPatch.java index 559113e3ac..d9b3142544 100644 --- a/source/java/org/alfresco/repo/admin/patch/impl/AuthorityMigrationPatch.java +++ b/source/java/org/alfresco/repo/admin/patch/impl/AuthorityMigrationPatch.java @@ -24,31 +24,37 @@ */ package org.alfresco.repo.admin.patch.impl; +import java.sql.BatchUpdateException; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; +import java.util.Map.Entry; import org.springframework.extensions.surf.util.I18NUtil; import org.alfresco.model.ContentModel; import org.alfresco.repo.admin.patch.AbstractPatch; import org.alfresco.repo.admin.patch.PatchExecuter; +import org.alfresco.repo.batch.BatchProcessor; import org.alfresco.repo.importer.ImporterBootstrap; -import org.alfresco.repo.transaction.RetryingTransactionHelper; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; +import org.alfresco.repo.security.authority.UnknownAuthorityException; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; +import org.alfresco.service.cmr.rule.RuleService; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.ApplicationEventPublisherAware; /** * Migrates authority information previously stored in the user store to the spaces store, using the new structure used @@ -56,14 +62,13 @@ import org.apache.commons.logging.LogFactory; * * @author dward */ -public class AuthorityMigrationPatch extends AbstractPatch +public class AuthorityMigrationPatch extends AbstractPatch implements ApplicationEventPublisherAware { + /** The title we give to the batch process in progress messages / JMX. */ + private static final String MSG_PROCESS_NAME = "patch.authorityMigration.process.name"; - /** Progress message for authorities. */ - private static final String MSG_PROGRESS_AUTHORITY = "patch.authorityMigration.progress.authority"; - - /** Progress message for associations. */ - private static final String MSG_PROGRESS_ASSOC = "patch.authorityMigration.progress.assoc"; + /** The warning message when a 'dangling' assoc is found that can't be created */ + private static final String MSG_WARNING_INVALID_ASSOC = "patch.authorityMigration.warning.assoc"; /** Success message. */ private static final String MSG_SUCCESS = "patch.authorityMigration.result"; @@ -81,15 +86,18 @@ public class AuthorityMigrationPatch extends AbstractPatch /** The old authority members property. */ private static final QName PROP_MEMBERS = QName.createQName(ContentModel.USER_MODEL_URI, "members"); - /** The number of items to create in a transaction. */ - private static final int BATCH_SIZE = 10; - /** The authority service. */ private AuthorityService authorityService; + /** The rule service. */ + private RuleService ruleService; + /** The user bootstrap. */ private ImporterBootstrap userBootstrap; + /** The application event publisher. */ + private ApplicationEventPublisher applicationEventPublisher; + /** * Sets the authority service. * @@ -101,6 +109,17 @@ public class AuthorityMigrationPatch extends AbstractPatch this.authorityService = authorityService; } + /** + * Sets the rule service. + * + * @param ruleService + * the rule service + */ + public void setRuleService(RuleService ruleService) + { + this.ruleService = ruleService; + } + /** * Sets the user bootstrap. * @@ -112,6 +131,17 @@ public class AuthorityMigrationPatch extends AbstractPatch this.userBootstrap = userBootstrap; } + /** + * Sets the application event publisher. + * + * @param applicationEventPublisher + * the application event publisher + */ + public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) + { + this.applicationEventPublisher = applicationEventPublisher; + } + /** * Recursively retrieves the authorities under the given node and their associations. * @@ -122,14 +152,14 @@ public class AuthorityMigrationPatch extends AbstractPatch * the node to find authorities below * @param authoritiesToCreate * the authorities to create - * @param childAssocs - * the child associations + * @param parentAssocs + * the parent associations + * @return count of the number of parent associations */ - private void retrieveAuthorities(String parentAuthority, NodeRef nodeRef, Map authoritiesToCreate, - Map> childAssocs) + private int retrieveAuthorities(String parentAuthority, NodeRef nodeRef, Map authoritiesToCreate, + Map> parentAssocs) { - // If we have a parent authority, prepare a list for recording its children - Set children = parentAuthority == null ? null : childAssocs.get(parentAuthority); + int assocCount = 0; // Process all children List cars = this.nodeService.getChildAssocs(nodeRef); @@ -144,20 +174,20 @@ public class AuthorityMigrationPatch extends AbstractPatch authoritiesToCreate.put(authorityName, DefaultTypeConverter.INSTANCE.convert(String.class, this.nodeService .getProperty(current, AuthorityMigrationPatch.PROP_AUTHORITY_DISPLAY_NAME))); - // If we have a parent, remember the child association + // Record the parent association (or empty set if this is a root) + Set parents = parentAssocs.get(authorityName); + if (parents == null) + { + parents = new TreeSet(); + parentAssocs.put(authorityName, parents); + } if (parentAuthority != null) { - if (children == null) - { - children = new TreeSet(); - childAssocs.put(parentAuthority, children); - } - children.add(authorityName); + parents.add(parentAuthority); + assocCount++; } // loop over properties - Set propChildren = childAssocs.get(authorityName); - Collection members = DefaultTypeConverter.INSTANCE.getCollection(String.class, this.nodeService .getProperty(current, AuthorityMigrationPatch.PROP_MEMBERS)); if (members != null) @@ -167,119 +197,89 @@ public class AuthorityMigrationPatch extends AbstractPatch // Believe it or not, some old authorities have null members in them! if (user != null) { - if (propChildren == null) + Set propParents = parentAssocs.get(user); + if (propParents == null) { - propChildren = new TreeSet(); - childAssocs.put(authorityName, propChildren); + propParents = new TreeSet(); + parentAssocs.put(user, propParents); } - propChildren.add(user); + propParents.add(authorityName); + assocCount++; } } } - retrieveAuthorities(authorityName, current, authoritiesToCreate, childAssocs); + assocCount += retrieveAuthorities(authorityName, current, authoritiesToCreate, parentAssocs); } + return assocCount; } /** - * Migrates the authorities. + * Migrates the authorities and their associations. * * @param authoritiesToCreate * the authorities to create + * @param parentAssocs + * the parent associations to create (if they don't exist already) * @return the number of authorities migrated */ - private int migrateAuthorities(Map authoritiesToCreate) + private void migrateAuthorities(final Map authoritiesToCreate, Map> parentAssocs) { - int processedCount = 0; - final Iterator> i = authoritiesToCreate.entrySet().iterator(); - RetryingTransactionHelper retryingTransactionHelper = this.transactionService.getRetryingTransactionHelper(); - - // Process batches in separate transactions for maximum performance - while (i.hasNext()) + BatchProcessor.Worker>> worker = new BatchProcessor.Worker>>() { - processedCount += retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback() + + public String getIdentifier(Entry> entry) { - public Integer execute() throws Throwable - { - int processedCount = 0; - do - { - Map.Entry authority = i.next(); - String authorityName = authority.getKey(); - boolean existed = AuthorityMigrationPatch.this.authorityService.authorityExists(authorityName); - if (existed) - { - i.remove(); - } - else - { - AuthorityMigrationPatch.this.authorityService.createAuthority(AuthorityType - .getAuthorityType(authorityName), AuthorityMigrationPatch.this.authorityService - .getShortName(authorityName), authority.getValue(), null); - processedCount++; - } - } - while (processedCount < AuthorityMigrationPatch.BATCH_SIZE && i.hasNext()); - return processedCount; - } - }, false, true); + return entry.getKey(); + } - // Report progress - AuthorityMigrationPatch.progress_logger.info(I18NUtil.getMessage( - AuthorityMigrationPatch.MSG_PROGRESS_AUTHORITY, processedCount)); - } - return processedCount; - } - - /** - * Migrates the group associations. - * - * @param authoritiesCreated - * the authorities created - * @param childAssocs - * the child associations - * @return the number of associations migrated - */ - private int migrateAssocs(final Map authoritiesCreated, Map> childAssocs) - { - int processedCount = 0; - final Iterator>> j = childAssocs.entrySet().iterator(); - RetryingTransactionHelper retryingTransactionHelper = this.transactionService.getRetryingTransactionHelper(); - - // Process batches in separate transactions for maximum performance - while (j.hasNext()) - { - processedCount += retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback() + public void process(Entry> authority) throws Throwable { - public Integer execute() throws Throwable + String authorityName = authority.getKey(); + boolean existed = AuthorityMigrationPatch.this.authorityService.authorityExists(authorityName); + Set knownParents; + if (existed) { - int processedCount = 0; - do - { - Map.Entry> childAssoc = j.next(); - String parentAuthority = childAssoc.getKey(); - Set knownChildren = authoritiesCreated.containsKey(parentAuthority) ? Collections - . emptySet() : AuthorityMigrationPatch.this.authorityService - .getContainedAuthorities(AuthorityType.GROUP, parentAuthority, true); - for (String authorityName : childAssoc.getValue()) - { - if (!knownChildren.contains(authorityName)) - { - AuthorityMigrationPatch.this.authorityService.addAuthority(parentAuthority, - authorityName); - processedCount++; - } - } - } - while (processedCount < AuthorityMigrationPatch.BATCH_SIZE && j.hasNext()); - return processedCount; + knownParents = AuthorityMigrationPatch.this.authorityService.getContainingAuthorities( + AuthorityType.GROUP, authorityName, true); } - }, false, true); - - // Report progress - AuthorityMigrationPatch.progress_logger.info(I18NUtil.getMessage( - AuthorityMigrationPatch.MSG_PROGRESS_ASSOC, processedCount)); - } - return processedCount; + else + { + knownParents = Collections.emptySet(); + AuthorityType authorityType = AuthorityType.getAuthorityType(authorityName); + // We have associations to a non-existent authority. If it is a user, just skip it because it must + // have been a 'dangling' reference + if (authorityType == AuthorityType.USER) + { + AuthorityMigrationPatch.progress_logger.warn(I18NUtil.getMessage( + AuthorityMigrationPatch.MSG_WARNING_INVALID_ASSOC, authorityName)); + return; + } + AuthorityMigrationPatch.this.authorityService.createAuthority(authorityType, + AuthorityMigrationPatch.this.authorityService.getShortName(authorityName), + authoritiesToCreate.get(authorityName), null); + } + Set parentAssocsToCreate = authority.getValue(); + parentAssocsToCreate.removeAll(knownParents); + if (!parentAssocsToCreate.isEmpty()) + { + try + { + AuthorityMigrationPatch.this.authorityService.addAuthority(parentAssocsToCreate, authorityName); + } + catch (UnknownAuthorityException e) + { + // Let's force a transaction retry if a parent doesn't exist. It may be because we are waiting + // for another worker thread to create it + throw new BatchUpdateException().initCause(e); + } + } + } + }; + // Migrate using 2 threads, 20 authorities per transaction. Log every 100 entries. + new BatchProcessor>>(AuthorityMigrationPatch.progress_logger, + this.transactionService.getRetryingTransactionHelper(), this.ruleService, + this.applicationEventPublisher, parentAssocs.entrySet(), I18NUtil + .getMessage(AuthorityMigrationPatch.MSG_PROCESS_NAME), 100, 2, 20).process(worker, true); } /** @@ -323,18 +323,71 @@ public class AuthorityMigrationPatch extends AbstractPatch @Override protected String applyInternal() throws Exception { - int authorities = 0; - int assocs = 0; NodeRef authorityContainer = getAuthorityContainer(); + int authorities = 0, assocs = 0; if (authorityContainer != null) { + // Crawl the old tree of authorities Map authoritiesToCreate = new TreeMap(); - Map> childAssocs = new TreeMap>(); - retrieveAuthorities(null, authorityContainer, authoritiesToCreate, childAssocs); - authorities = migrateAuthorities(authoritiesToCreate); - assocs = migrateAssocs(authoritiesToCreate, childAssocs); + Map> parentAssocs = new TreeMap>(); + assocs = retrieveAuthorities(null, authorityContainer, authoritiesToCreate, parentAssocs); + + // Sort the group associations in parent-first order (root groups first) + Map> sortedParentAssocs = new LinkedHashMap>( + parentAssocs.size() * 2); + List authorityPath = new ArrayList(5); + for (String authority : parentAssocs.keySet()) + { + authorityPath.add(authority); + visitGroupAssociations(authorityPath, parentAssocs, sortedParentAssocs); + authorityPath.clear(); + } + + // Recreate the authorities and their associations in parent-first order + migrateAuthorities(authoritiesToCreate, sortedParentAssocs); + authorities = authoritiesToCreate.size(); } // build the result message return I18NUtil.getMessage(AuthorityMigrationPatch.MSG_SUCCESS, authorities, assocs); } + + /** + * Visits the last authority in the given list by recursively visiting its parents in associationsOld and then + * adding the authority to associationsNew. Used to sort associationsOld into 'parent-first' order. + * + * @param authorityPath + * The authority to visit, preceeded by all its descendants. Allows detection of cyclic child + * associations. + * @param associationsOld + * the association map to sort + * @param associationsNew + * the association map to add to in parent-first order + */ + private static void visitGroupAssociations(List authorityPath, Map> associationsOld, + Map> associationsNew) + { + String authorityName = authorityPath.get(authorityPath.size() - 1); + if (!associationsNew.containsKey(authorityName)) + { + Set associations = associationsOld.get(authorityName); + + if (!associations.isEmpty()) + { + int insertIndex = authorityPath.size(); + for (String parentAuthority : associations) + { + // Prevent cyclic paths + if (!authorityPath.contains(parentAuthority)) + { + authorityPath.add(parentAuthority); + visitGroupAssociations(authorityPath, associationsOld, associationsNew); + authorityPath.remove(insertIndex); + } + } + } + + associationsNew.put(authorityName, associations); + } + } + } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/admin/patch/impl/ContentFormTypePatch.java b/source/java/org/alfresco/repo/admin/patch/impl/ContentFormTypePatch.java index 27a9c14246..050c81153f 100644 --- a/source/java/org/alfresco/repo/admin/patch/impl/ContentFormTypePatch.java +++ b/source/java/org/alfresco/repo/admin/patch/impl/ContentFormTypePatch.java @@ -102,12 +102,19 @@ public class ContentFormTypePatch extends AbstractPatch sp.setLanguage(SearchService.LANGUAGE_LUCENE); sp.setQuery("ASPECT:\"" + WCMAppModel.ASPECT_FORM + "\""); ResultSet rs = this.searchService.query(sp); - Collection result = new ArrayList(rs.length()); - for (ResultSetRow row : rs) + try { - result.add(row.getNodeRef()); + Collection result = new ArrayList(rs.length()); + for (ResultSetRow row : rs) + { + result.add(row.getNodeRef()); + } + + return result; + } + finally + { + rs.close(); } - - return result; } } diff --git a/source/java/org/alfresco/repo/admin/patch/impl/FixNameCrcValuesPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/FixNameCrcValuesPatch.java index 6477da82b6..c71c96a06f 100644 --- a/source/java/org/alfresco/repo/admin/patch/impl/FixNameCrcValuesPatch.java +++ b/source/java/org/alfresco/repo/admin/patch/impl/FixNameCrcValuesPatch.java @@ -38,13 +38,13 @@ import java.util.zip.CRC32; import org.springframework.extensions.surf.util.I18NUtil; import org.alfresco.model.ContentModel; import org.alfresco.repo.admin.patch.AbstractPatch; +import org.alfresco.repo.batch.BatchProcessor; +import org.alfresco.repo.batch.BatchProcessor.Worker; import org.alfresco.repo.domain.ChildAssoc; import org.alfresco.repo.domain.Node; import org.alfresco.repo.domain.QNameDAO; import org.alfresco.repo.domain.hibernate.ChildAssocImpl; import org.alfresco.repo.node.db.NodeDaoService; -import org.alfresco.repo.security.sync.BatchProcessor; -import org.alfresco.repo.security.sync.BatchProcessor.Worker; import org.alfresco.service.cmr.admin.PatchException; import org.alfresco.service.cmr.rule.RuleService; import org.alfresco.service.namespace.QName; @@ -186,7 +186,7 @@ public class FixNameCrcValuesPatch extends AbstractPatch implements ApplicationE public String fixCrcValues() throws Exception { // get the association types to check - BatchProcessor batchProcessor = new BatchProcessor(transactionService + BatchProcessor batchProcessor = new BatchProcessor(logger, transactionService .getRetryingTransactionHelper(), ruleService, applicationEventPublisher, findMismatchedCrcs(), "FixNameCrcValuesPatch", 100, 2, 20); @@ -224,7 +224,8 @@ public class FixNameCrcValuesPatch extends AbstractPatch implements ApplicationE } // Update the CRCs long childCrc = getCrc(childName); - long qnameCrc = ChildAssocImpl.getCrc(assoc.getQName(qnameDAO)); + QName qname = assoc.getQName(qnameDAO); + long qnameCrc = ChildAssocImpl.getCrc(qname); // Update the assoc assoc.setChildNodeNameCrc(childCrc); @@ -237,7 +238,7 @@ public class FixNameCrcValuesPatch extends AbstractPatch implements ApplicationE catch (Throwable e) { String msg = I18NUtil.getMessage(MSG_UNABLE_TO_CHANGE, childNode.getId(), childName, oldChildCrc, - childCrc, oldQNameCrc, qnameCrc, e.getMessage()); + childCrc, qname, oldQNameCrc, qnameCrc, e.getMessage()); // We just log this and add details to the message file if (logger.isDebugEnabled()) { @@ -251,7 +252,8 @@ public class FixNameCrcValuesPatch extends AbstractPatch implements ApplicationE } getSession().clear(); // Record - writeLine(I18NUtil.getMessage(MSG_REWRITTEN, childNode.getId(), childName, oldChildCrc, childCrc, oldQNameCrc, qnameCrc)); + writeLine(I18NUtil.getMessage(MSG_REWRITTEN, childNode.getId(), childName, oldChildCrc, childCrc, + qname, oldQNameCrc, qnameCrc)); }}, true); diff --git a/source/java/org/alfresco/repo/attributes/AttributeServiceTransportService.java b/source/java/org/alfresco/repo/attributes/AttributeServiceTransportService.java index dd7b9d9d60..0b71401ba9 100644 --- a/source/java/org/alfresco/repo/attributes/AttributeServiceTransportService.java +++ b/source/java/org/alfresco/repo/attributes/AttributeServiceTransportService.java @@ -64,7 +64,7 @@ public class AttributeServiceTransportService implements */ public void addAttribute(String ticket, String path, Attribute value) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.addAttribute(path, value); } @@ -73,7 +73,7 @@ public class AttributeServiceTransportService implements */ public void addAttribute(String ticket, List keys, Attribute value) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.addAttribute(keys, value); } @@ -82,7 +82,7 @@ public class AttributeServiceTransportService implements */ public Attribute getAttribute(String ticket, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fService.getAttribute(path); } @@ -91,7 +91,7 @@ public class AttributeServiceTransportService implements */ public Attribute getAttribute(String ticket, List keys) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fService.getAttribute(keys); } @@ -100,7 +100,7 @@ public class AttributeServiceTransportService implements */ public List getKeys(String ticket, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fService.getKeys(path); } @@ -109,7 +109,7 @@ public class AttributeServiceTransportService implements */ public List getKeys(String ticket, List keys) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fService.getKeys(keys); } @@ -119,7 +119,7 @@ public class AttributeServiceTransportService implements public List> query(String ticket, String path, AttrQuery query) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fService.query(path, query); } @@ -129,7 +129,7 @@ public class AttributeServiceTransportService implements public List> query(String ticket, List keys, AttrQuery query) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fService.query(keys, query); } @@ -138,7 +138,7 @@ public class AttributeServiceTransportService implements */ public void removeAttribute(String ticket, String path, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.removeAttribute(path, name); } @@ -147,7 +147,7 @@ public class AttributeServiceTransportService implements */ public void removeAttribute(String ticket, List keys, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.removeAttribute(keys, name); } @@ -156,7 +156,7 @@ public class AttributeServiceTransportService implements */ public void removeAttribute(String ticket, String path, int index) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.removeAttribute(path, index); } @@ -165,7 +165,7 @@ public class AttributeServiceTransportService implements */ public void removeAttribute(String ticket, List keys, int index) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.removeAttribute(keys, index); } @@ -175,7 +175,7 @@ public class AttributeServiceTransportService implements public void setAttribute(String ticket, String path, String name, Attribute value) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.setAttribute(path, name, value); } @@ -185,7 +185,7 @@ public class AttributeServiceTransportService implements public void setAttribute(String ticket, List keys, String name, Attribute value) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.setAttribute(keys, name, value); } @@ -195,7 +195,7 @@ public class AttributeServiceTransportService implements public void setAttribute(String ticket, String path, int index, Attribute value) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.setAttribute(path, index, value); } @@ -205,7 +205,7 @@ public class AttributeServiceTransportService implements public void setAttribute(String ticket, List keys, int index, Attribute value) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.setAttribute(keys, index, value); } @@ -214,7 +214,7 @@ public class AttributeServiceTransportService implements */ public boolean exists(String ticket, List keys) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fService.exists(keys); } @@ -223,7 +223,7 @@ public class AttributeServiceTransportService implements */ public boolean exists(String ticket, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fService.exists(path); } @@ -232,7 +232,7 @@ public class AttributeServiceTransportService implements */ public int getCount(String ticket, List keys) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fService.getCount(keys); } @@ -241,7 +241,7 @@ public class AttributeServiceTransportService implements */ public int getCount(String ticket, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fService.getCount(path); } @@ -250,7 +250,7 @@ public class AttributeServiceTransportService implements */ public void addAttributes(String ticket, List keys, List values) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.addAttributes(keys, values); } @@ -259,7 +259,7 @@ public class AttributeServiceTransportService implements */ public void addAttributes(String ticket, String path, List values) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.addAttributes(path, values); } @@ -268,7 +268,7 @@ public class AttributeServiceTransportService implements */ public void setAttributes(String ticket, List keys, Map entries) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.setAttributes(keys, entries); } @@ -277,7 +277,7 @@ public class AttributeServiceTransportService implements */ public void setAttributes(String ticket, String path, Map entries) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.setAttributes(path, entries); } @@ -286,7 +286,7 @@ public class AttributeServiceTransportService implements */ public void removeEntries(String ticket, List keys, AttrQuery query) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.removeEntries(keys, query); } @@ -295,7 +295,7 @@ public class AttributeServiceTransportService implements */ public void removeEntries(String ticket, String path, AttrQuery query) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fService.removeEntries(path, query); } } diff --git a/source/java/org/alfresco/repo/avm/AVMExpiredContentProcessor.java b/source/java/org/alfresco/repo/avm/AVMExpiredContentProcessor.java index 41fb6f4088..26cdd0d380 100644 --- a/source/java/org/alfresco/repo/avm/AVMExpiredContentProcessor.java +++ b/source/java/org/alfresco/repo/avm/AVMExpiredContentProcessor.java @@ -248,21 +248,27 @@ public class AVMExpiredContentProcessor StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_AVM, storeName); ResultSet results = this.searchService.query(storeRef, SearchService.LANGUAGE_LUCENE, query.toString()); - - if (logger.isDebugEnabled()) - logger.debug("Found " + results.length() + " potential expired item(s) in store '" + storeName + "'"); - - if (results.length() > 0) + try { - for (NodeRef resultNode : results.getNodeRefs()) - { - // get the AVMNodeDescriptor object for each node found - Pair path = AVMNodeConverter.ToAVMVersionPath(resultNode); - AVMNodeDescriptor node = this.avmService.lookup(path.getFirst(), path.getSecond()); - - // process the node to see whether the date and time has passed - processNode(storeName, node); - } + if (logger.isDebugEnabled()) + logger.debug("Found " + results.length() + " potential expired item(s) in store '" + storeName + "'"); + + if (results.length() > 0) + { + for (NodeRef resultNode : results.getNodeRefs()) + { + // get the AVMNodeDescriptor object for each node found + Pair path = AVMNodeConverter.ToAVMVersionPath(resultNode); + AVMNodeDescriptor node = this.avmService.lookup(path.getFirst(), path.getSecond()); + + // process the node to see whether the date and time has passed + processNode(storeName, node); + } + } + } + finally + { + results.close(); } } else diff --git a/source/java/org/alfresco/repo/avm/AVMRemoteTransportService.java b/source/java/org/alfresco/repo/avm/AVMRemoteTransportService.java index d59e281d94..9e88cdf985 100644 --- a/source/java/org/alfresco/repo/avm/AVMRemoteTransportService.java +++ b/source/java/org/alfresco/repo/avm/AVMRemoteTransportService.java @@ -241,7 +241,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public String getInputHandle(String ticket, int version, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); InputStream in = fAVMService.getFileInputStream(version, path); String handle = GUID.generate(); synchronized (this) @@ -258,7 +258,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public String getInputHandle(String ticket, AVMNodeDescriptor desc) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); InputStream in = fAVMService.getFileInputStream(desc); String handle = GUID.generate(); synchronized (this) @@ -278,7 +278,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public byte [] readInput(String ticket, String handle, int count) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); InputStream in = null; synchronized (this) { @@ -331,7 +331,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public synchronized void closeInputHandle(String ticket, String handle) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); InputStream in = fInputStreams.get(handle); if (in != null) { @@ -356,7 +356,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public String getOutputHandle(String ticket, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); OutputStream out = fAVMService.getFileOutputStream(path); String handle = GUID.generate(); synchronized (this) @@ -378,7 +378,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void writeOutput(String ticket, String handle, byte [] buff, int count) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); OutputStream out = null; synchronized (this) { @@ -413,7 +413,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public synchronized void closeOutputHandle(String ticket, String handle) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); OutputStream out = fOutputStreams.get(handle); if (out != null) { @@ -440,7 +440,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable public SortedMap getDirectoryListingDirect(String ticket, int version, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getDirectoryListingDirect(version, path); } @@ -453,7 +453,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable public SortedMap getDirectoryListing(String ticket, int version, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getDirectoryListing(version, path); } @@ -465,7 +465,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable public SortedMap getDirectoryListing(String ticket, AVMNodeDescriptor dir) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getDirectoryListing(dir); } @@ -477,7 +477,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public List getDeleted(String ticket, int version, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getDeleted(version, path); } @@ -489,7 +489,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public String createFile(String ticket, String path, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); OutputStream out = fAVMService.createFile(path, name); String handle = GUID.generate(); synchronized (this) @@ -508,7 +508,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void createDirectory(String ticket, String path, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.createDirectory(path, name); } @@ -520,7 +520,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void createLayeredFile(String ticket, String targetPath, String parent, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.createLayeredFile(targetPath, parent, name); } @@ -532,7 +532,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void createLayeredDirectory(String ticket, String targetPath, String parent, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.createLayeredDirectory(targetPath, parent, name); } @@ -543,7 +543,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void retargetLayeredDirectory(String ticket, String path, String target) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.retargetLayeredDirectory(path, target); } @@ -553,7 +553,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void createStore(String ticket, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.createStore(name); } @@ -566,7 +566,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void createBranch(String ticket, int version, String srcPath, String dstPath, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.createBranch(version, srcPath, dstPath, name); } @@ -577,7 +577,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void removeNode(String ticket, String parent, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.removeNode(parent, name); } @@ -590,7 +590,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void rename(String ticket, String srcParent, String srcName, String dstParent, String dstName) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.rename(srcParent, srcName, dstParent, dstName); } @@ -601,7 +601,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void uncover(String ticket, String dirPath, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.uncover(dirPath, name); } @@ -612,7 +612,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public int getNextVersionID(String ticket, String storeName) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getNextVersionID(storeName); } @@ -633,7 +633,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public Map createSnapshot(String ticket, String store, String label, String comment) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.createSnapshot(store, label, comment); } @@ -644,7 +644,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public List getStoreVersions(String ticket, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getStoreVersions(name); } @@ -657,7 +657,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public List getStoreVersions(String ticket, String name, Date from, Date to) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getStoreVersions(name, from, to); } @@ -667,7 +667,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public List getStores(String ticket) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getStores(); } @@ -678,7 +678,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public AVMStoreDescriptor getStore(String ticket, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getStore(name); } @@ -690,7 +690,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public AVMNodeDescriptor getStoreRoot(String ticket, int version, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getStoreRoot(version, name); } @@ -702,7 +702,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public AVMNodeDescriptor lookup(String ticket, int version, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.lookup(version, path); } @@ -718,7 +718,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public AVMNodeDescriptor lookup(String ticket, int version, String path, boolean includeDeleted) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.lookup(version, path, includeDeleted); } @@ -731,7 +731,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public AVMNodeDescriptor lookup(String ticket, AVMNodeDescriptor dir, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.lookup(dir, name); } @@ -749,7 +749,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public AVMNodeDescriptor lookup(String ticket, AVMNodeDescriptor dir, String name, boolean includeDeleted) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.lookup(dir, name, includeDeleted); } @@ -762,7 +762,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public String getIndirectionPath(String ticket, int version, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getIndirectionPath(version, path); } @@ -772,7 +772,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void purgeStore(String ticket, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.purgeStore(name); } @@ -783,7 +783,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void purgeVersion(String ticket, int version, String name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.purgeVersion(version, name); } @@ -793,7 +793,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void makePrimary(String ticket, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.makePrimary(path); } @@ -805,7 +805,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public List getHistory(String ticket, AVMNodeDescriptor desc, int count) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getHistory(desc, count); } @@ -816,7 +816,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void setOpacity(String ticket, String path, boolean opacity) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.setOpacity(path, opacity); } @@ -828,7 +828,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public AVMNodeDescriptor getCommonAncestor(String ticket, AVMNodeDescriptor left, AVMNodeDescriptor right) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getCommonAncestor(left, right); } @@ -840,7 +840,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public LayeringDescriptor getLayeringInfo(String ticket, int version, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getLayeringInfo(version, path); } @@ -852,7 +852,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void setNodeProperty(String ticket, String path, QName name, PropertyValue value) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.setNodeProperty(path, name, value); } @@ -863,7 +863,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void setNodeProperties(String ticket, String path, Map properties) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.setNodeProperties(path, properties); } @@ -876,7 +876,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public PropertyValue getNodeProperty(String ticket, int version, String path, QName name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getNodeProperty(version, path, name); } @@ -888,7 +888,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public Map getNodeProperties(String ticket, int version, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getNodeProperties(version, path); } @@ -899,7 +899,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void deleteNodeProperty(String ticket, String path, QName name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.deleteNodeProperty(path, name); } @@ -909,7 +909,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void deleteNodeProperties(String ticket, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.deleteNodeProperties(path); } @@ -921,7 +921,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void setStoreProperty(String ticket, String store, QName name, PropertyValue value) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.setStoreProperty(store, name, value); } @@ -932,7 +932,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void setStoreProperties(String ticket, String store, Map props) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.setStoreProperties(store, props); } @@ -944,7 +944,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public PropertyValue getStoreProperty(String ticket, String store, QName name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getStoreProperty(store, name); } @@ -956,7 +956,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public Map queryStorePropertyKey(String ticket, String store, QName keyPattern) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.queryStorePropertyKey(store, keyPattern); } @@ -967,7 +967,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public Map> queryStoresPropertyKey(String ticket, QName keyPattern) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.queryStoresPropertyKeys(keyPattern); } @@ -978,7 +978,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public Map getStoreProperties(String ticket, String store) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getStoreProperties(store); } @@ -989,7 +989,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void deleteStoreProperty(String ticket, String store, QName name) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.deleteStoreProperty(store, name); } @@ -998,7 +998,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void renameStore(String ticket, String sourceName, String destName) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.renameStore(sourceName, destName); } @@ -1007,7 +1007,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void addAspect(String ticket, String path, QName aspectName) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.addAspect(path, aspectName); } @@ -1016,7 +1016,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public Set getAspects(String ticket, int version, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getAspects(version, path); } @@ -1025,7 +1025,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public boolean hasAspect(String ticket, int version, String path, QName aspectName) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.hasAspect(version, path, aspectName); } @@ -1034,7 +1034,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void removeAspect(String ticket, String path, QName aspectName) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.removeAspect(path, aspectName); } @@ -1043,7 +1043,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void revert(String ticket, String path, AVMNodeDescriptor toRevertTo) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.revert(path, toRevertTo); } @@ -1052,7 +1052,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public Pair getAPath(String ticket, AVMNodeDescriptor desc) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fAVMService.getAPath(desc); } @@ -1061,7 +1061,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void setGuid(String ticket, String path, String guid) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.setGuid(path, guid); } @@ -1070,7 +1070,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void setEncoding(String ticket, String path, String encoding) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.setEncoding(path, encoding); } @@ -1079,7 +1079,7 @@ public class AVMRemoteTransportService implements AVMRemoteTransport, Runnable */ public void setMimeType(String ticket, String path, String mimeType) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fAVMService.setMimeType(path, mimeType); } } diff --git a/source/java/org/alfresco/repo/avm/AVMSyncServiceTransportImpl.java b/source/java/org/alfresco/repo/avm/AVMSyncServiceTransportImpl.java index 1fd011ee93..6ffd1b6c46 100644 --- a/source/java/org/alfresco/repo/avm/AVMSyncServiceTransportImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMSyncServiceTransportImpl.java @@ -50,7 +50,7 @@ public class AVMSyncServiceTransportImpl implements AVMSyncServiceTransport public List compare(String ticket, int srcVersion, String srcPath, int dstVersion, String dstPath, NameMatcher excluder) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); return fSyncService.compare(srcVersion, srcPath, dstVersion, dstPath, excluder); } @@ -59,7 +59,7 @@ public class AVMSyncServiceTransportImpl implements AVMSyncServiceTransport */ public void flatten(String ticket, String layerPath, String underlyingPath) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); fSyncService.flatten(layerPath, underlyingPath); } @@ -68,7 +68,7 @@ public class AVMSyncServiceTransportImpl implements AVMSyncServiceTransport */ public void resetLayer(String ticket, String layerPath) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); fSyncService.resetLayer(layerPath); } @@ -80,7 +80,7 @@ public class AVMSyncServiceTransportImpl implements AVMSyncServiceTransport boolean overrideConflicts, boolean overrideOlder, String tag, String description) { - fAuthenticationService.validate(ticket); + fAuthenticationService.validate(ticket, null); fSyncService.update(diffList, excluder, ignoreConflicts, ignoreOlder, overrideConflicts, overrideOlder, tag, description); } } diff --git a/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceImpl.java b/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceImpl.java index 49d464a9b5..b48711afcf 100644 --- a/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceImpl.java +++ b/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceImpl.java @@ -578,11 +578,18 @@ public class AVMLockingServiceImpl implements AVMLockingService storeRef, SearchService.LANGUAGE_LUCENE, "@wca\\:avmstore:\"" + webProject + '"'); - if (results.getNodeRefs().size() == 1) + try { - return hasAccess(webProject, results.getNodeRefs().get(0), avmPath, user); + if (results.getNodeRefs().size() == 1) + { + return hasAccess(webProject, results.getNodeRefs().get(0), avmPath, user); + } + return false; + } + finally + { + results.close(); } - return false; } /* (non-Javadoc) @@ -652,7 +659,8 @@ public class AVMLockingServiceImpl implements AVMLockingService new StoreRef(this.webProjectStore), SearchService.LANGUAGE_LUCENE, query.toString()); - List nodes = resultSet.getNodeRefs(); + List nodes = resultSet.getNodeRefs(); + resultSet.close(); if (nodes.size() == 1) { diff --git a/source/java/org/alfresco/repo/security/sync/BatchMonitor.java b/source/java/org/alfresco/repo/batch/BatchMonitor.java similarity index 95% rename from source/java/org/alfresco/repo/security/sync/BatchMonitor.java rename to source/java/org/alfresco/repo/batch/BatchMonitor.java index 45c648c965..586ed90c98 100644 --- a/source/java/org/alfresco/repo/security/sync/BatchMonitor.java +++ b/source/java/org/alfresco/repo/batch/BatchMonitor.java @@ -22,7 +22,7 @@ * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ -package org.alfresco.repo.security.sync; +package org.alfresco.repo.batch; import java.util.Date; diff --git a/source/java/org/alfresco/repo/security/sync/BatchMonitorEvent.java b/source/java/org/alfresco/repo/batch/BatchMonitorEvent.java similarity index 94% rename from source/java/org/alfresco/repo/security/sync/BatchMonitorEvent.java rename to source/java/org/alfresco/repo/batch/BatchMonitorEvent.java index 56ae1844ec..3963f6fd1f 100644 --- a/source/java/org/alfresco/repo/security/sync/BatchMonitorEvent.java +++ b/source/java/org/alfresco/repo/batch/BatchMonitorEvent.java @@ -22,7 +22,7 @@ * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ -package org.alfresco.repo.security.sync; +package org.alfresco.repo.batch; import org.springframework.context.ApplicationEvent; diff --git a/source/java/org/alfresco/repo/security/sync/BatchProcessor.java b/source/java/org/alfresco/repo/batch/BatchProcessor.java similarity index 89% rename from source/java/org/alfresco/repo/security/sync/BatchProcessor.java rename to source/java/org/alfresco/repo/batch/BatchProcessor.java index 316040c8a9..88727586bd 100644 --- a/source/java/org/alfresco/repo/security/sync/BatchProcessor.java +++ b/source/java/org/alfresco/repo/batch/BatchProcessor.java @@ -22,7 +22,7 @@ * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ -package org.alfresco.repo.security.sync; +package org.alfresco.repo.batch; import java.io.PrintWriter; import java.io.StringWriter; @@ -43,7 +43,6 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.rule.RuleService; import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.springframework.context.ApplicationEventPublisher; /** @@ -60,26 +59,26 @@ import org.springframework.context.ApplicationEventPublisher; */ public class BatchProcessor implements BatchMonitor { - /** Let's share the logger of ChainingUserRegistrySynchronizer. */ - private static final Log logger = LogFactory.getLog(ChainingUserRegistrySynchronizer.class); + /** The logger to use. */ + private final Log logger; /** The retrying transaction helper. */ - private RetryingTransactionHelper retryingTransactionHelper; + private final RetryingTransactionHelper retryingTransactionHelper; /** The rule service. */ - private RuleService ruleService; + private final RuleService ruleService; /** The collection. */ - private Collection collection; + private final Collection collection; /** The process name. */ - private String processName; + private final String processName; /** The number of entries to process before reporting progress. */ - private int loggingInterval; + private final int loggingInterval; /** The number of worker threads. */ - private int workerThreads; + private final int workerThreads; /** The number of entries we process at a time in a transaction *. */ private final int batchSize; @@ -108,6 +107,8 @@ public class BatchProcessor implements BatchMonitor /** * Instantiates a new batch processor. * + * @param logger + * the logger to use * @param retryingTransactionHelper * the retrying transaction helper * @param ruleService @@ -125,10 +126,11 @@ public class BatchProcessor implements BatchMonitor * @param batchSize * the number of entries we process at a time in a transaction */ - public BatchProcessor(RetryingTransactionHelper retryingTransactionHelper, RuleService ruleService, + public BatchProcessor(Log logger, RetryingTransactionHelper retryingTransactionHelper, RuleService ruleService, ApplicationEventPublisher applicationEventPublisher, Collection collection, String processName, int loggingInterval, int workerThreads, int batchSize) { + this.logger = logger; this.retryingTransactionHelper = retryingTransactionHelper; this.ruleService = ruleService; this.collection = collection; @@ -262,15 +264,15 @@ public class BatchProcessor implements BatchMonitor synchronized (this) { this.startTime = new Date(); - if (BatchProcessor.logger.isInfoEnabled()) + if (this.logger.isInfoEnabled()) { if (count >= 0) { - BatchProcessor.logger.info(getProcessName() + ": Commencing batch of " + count + " entries"); + this.logger.info(getProcessName() + ": Commencing batch of " + count + " entries"); } else { - BatchProcessor.logger.info(getProcessName() + ": Commencing batch"); + this.logger.info(getProcessName() + ": Commencing batch"); } } @@ -279,7 +281,7 @@ public class BatchProcessor implements BatchMonitor // Create a thread pool executor with the specified number of threads and a finite blocking queue of jobs ExecutorService executorService = splitTxns && this.workerThreads > 1 ? new ThreadPoolExecutor( this.workerThreads, this.workerThreads, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue( - this.workerThreads * batchSize * 10) + this.workerThreads * this.batchSize * 10) { // Add blocking behaviour to work queue @Override @@ -341,21 +343,21 @@ public class BatchProcessor implements BatchMonitor { reportProgress(true); this.endTime = new Date(); - if (BatchProcessor.logger.isInfoEnabled()) + if (this.logger.isInfoEnabled()) { if (count >= 0) { - BatchProcessor.logger.info(getProcessName() + ": Completed batch of " + count + " entries"); + this.logger.info(getProcessName() + ": Completed batch of " + count + " entries"); } else { - BatchProcessor.logger.info(getProcessName() + ": Completed batch"); + this.logger.info(getProcessName() + ": Completed batch"); } } - if (this.totalErrors > 0 && BatchProcessor.logger.isErrorEnabled()) + if (this.totalErrors > 0 && this.logger.isErrorEnabled()) { - BatchProcessor.logger.error(getProcessName() + ": " + this.totalErrors + this.logger.error(getProcessName() + ": " + this.totalErrors + " error(s) detected. Last error from entry \"" + this.lastErrorEntryId + "\"", this.lastError); } @@ -391,7 +393,7 @@ public class BatchProcessor implements BatchMonitor message.append(". Rate: ").append(processed * 1000L / duration).append(" per second"); } message.append(". " + this.totalErrors + " failures detected."); - BatchProcessor.logger.info(message); + this.logger.info(message); } } @@ -467,7 +469,7 @@ public class BatchProcessor implements BatchMonitor /** The last error entry id. */ private String txnLastErrorEntryId; - + /* * (non-Javadoc) * @see org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback#execute () @@ -491,9 +493,9 @@ public class BatchProcessor implements BatchMonitor { if (RetryingTransactionHelper.extractRetryCause(t) == null) { - if (BatchProcessor.logger.isWarnEnabled()) + if (BatchProcessor.this.logger.isWarnEnabled()) { - BatchProcessor.logger.warn(getProcessName() + ": Failed to process entry \"" + BatchProcessor.this.logger.warn(getProcessName() + ": Failed to process entry \"" + this.txnEntryId + "\".", t); } this.txnLastError = t; @@ -529,9 +531,9 @@ public class BatchProcessor implements BatchMonitor this.txnLastError = t; this.txnLastErrorEntryId = this.txnEntryId; this.txnErrors++; - if (BatchProcessor.logger.isWarnEnabled()) + if (BatchProcessor.this.logger.isWarnEnabled()) { - BatchProcessor.logger.warn(getProcessName() + ": Failed to process entry \"" + BatchProcessor.this.logger.warn(getProcessName() + ": Failed to process entry \"" + BatchProcessor.this.currentEntryId + "\".", t); } } @@ -621,7 +623,7 @@ public class BatchProcessor implements BatchMonitor BatchProcessor.this.lastError = this.txnLastError; BatchProcessor.this.lastErrorEntryId = this.txnLastErrorEntryId; } - + reset(); } } diff --git a/source/java/org/alfresco/repo/blog/BlogIntegrationServiceSystemTest.java b/source/java/org/alfresco/repo/blog/BlogIntegrationServiceSystemTest.java index b9473a9420..2cb97e362c 100644 --- a/source/java/org/alfresco/repo/blog/BlogIntegrationServiceSystemTest.java +++ b/source/java/org/alfresco/repo/blog/BlogIntegrationServiceSystemTest.java @@ -114,6 +114,7 @@ public class BlogIntegrationServiceSystemTest extends BaseAlfrescoSpringTest imp SearchService.LANGUAGE_XPATH, "app:company_home"); NodeRef companyHome = results1.getNodeRefs().get(0); + results1.close(); // Create the blog details node this.blogDetailsNodeRef = this.nodeService.createNode( diff --git a/source/java/org/alfresco/repo/coci/WorkingCopyAspect.java b/source/java/org/alfresco/repo/coci/WorkingCopyAspect.java index d89eb4726d..1715c7145f 100644 --- a/source/java/org/alfresco/repo/coci/WorkingCopyAspect.java +++ b/source/java/org/alfresco/repo/coci/WorkingCopyAspect.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2009 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 @@ -18,7 +18,7 @@ * 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 + * FLOSS exception. You should have received a copy of the text describing * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ @@ -42,6 +42,7 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; +import org.alfresco.util.GUID; public class WorkingCopyAspect implements CopyServicePolicies.OnCopyNodePolicy { @@ -60,6 +61,11 @@ public class WorkingCopyAspect implements CopyServicePolicies.OnCopyNodePolicy */ private LockService lockService; + /** + * The working copy aspect copy behaviour callback. + * */ + private WorkingCopyAspectCopyBehaviourCallback workingCopyAspectCopyBehaviourCallback = new WorkingCopyAspectCopyBehaviourCallback(); + /** * Sets the policy component * @@ -142,7 +148,7 @@ public class WorkingCopyAspect implements CopyServicePolicies.OnCopyNodePolicy */ public CopyBehaviourCallback getCopyCallback(QName classRef, CopyDetails copyDetails) { - return WorkingCopyAspectCopyBehaviourCallback.instance; + return this.workingCopyAspectCopyBehaviourCallback; } /** @@ -153,10 +159,8 @@ public class WorkingCopyAspect implements CopyServicePolicies.OnCopyNodePolicy * @author Derek Hulley * @since 3.2 */ - private static class WorkingCopyAspectCopyBehaviourCallback extends DefaultCopyBehaviourCallback + private class WorkingCopyAspectCopyBehaviourCallback extends DefaultCopyBehaviourCallback { - private static WorkingCopyAspectCopyBehaviourCallback instance = new WorkingCopyAspectCopyBehaviourCallback(); - /** * Disallows copying of the {@link ContentModel#ASPECT_WORKING_COPY cm:workingCopy} aspect. */ @@ -177,8 +181,8 @@ public class WorkingCopyAspect implements CopyServicePolicies.OnCopyNodePolicy * Prevents copying off the {@link ContentModel#PROP_NAME cm:name} property. */ @Override - public Map getCopyProperties( - QName classQName, CopyDetails copyDetails, Map properties) + public Map getCopyProperties(QName classQName, CopyDetails copyDetails, + Map properties) { if (classQName.equals(ContentModel.ASPECT_WORKING_COPY)) { @@ -186,7 +190,32 @@ public class WorkingCopyAspect implements CopyServicePolicies.OnCopyNodePolicy } else if (copyDetails.getSourceNodeAspectQNames().contains(ContentModel.ASPECT_WORKING_COPY)) { - properties.remove(ContentModel.PROP_NAME); + // Generate a new name for a new copy of a working copy + String newName = null; + + // This is a copy of a working copy to a new node (not a check in). Try to derive a new name from the + // node it is checked out from + if (copyDetails.isTargetNodeIsNew() && copyDetails.getSourceNodeAspectQNames().contains(ContentModel.ASPECT_COPIEDFROM)) + { + NodeRef checkedOutFrom = (NodeRef) copyDetails.getSourceNodeProperties().get( + ContentModel.PROP_COPY_REFERENCE); + if (nodeService.exists(checkedOutFrom)) + { + String oldName = (String) nodeService.getProperty(checkedOutFrom, ContentModel.PROP_NAME); + int extIndex = oldName.lastIndexOf('.'); + newName = extIndex == -1 ? oldName + "_" + GUID.generate() : oldName.substring(0, extIndex) + + "_" + GUID.generate() + oldName.substring(extIndex); + } + } + + if (newName == null) + { + properties.remove(ContentModel.PROP_NAME); + } + else + { + properties.put(ContentModel.PROP_NAME, newName); + } return properties; } else diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryModelType.java b/source/java/org/alfresco/repo/dictionary/DictionaryModelType.java index d9952e66a6..6087ce3085 100644 --- a/source/java/org/alfresco/repo/dictionary/DictionaryModelType.java +++ b/source/java/org/alfresco/repo/dictionary/DictionaryModelType.java @@ -666,9 +666,16 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda // search for TYPE or ASPECT - TODO - alternative would be to extract QName and search by namespace ... ResultSet rs = searchService.query(store, SearchService.LANGUAGE_LUCENE, classType+":\""+className+"\""); - if (rs.length() > 0) + try { - throw new AlfrescoRuntimeException("Failed to validate model delete" + tenantDomain + " - found " + rs.length() + " nodes in store " + store + " with " + classType + " '" + className + "'" ); + if (rs.length() > 0) + { + throw new AlfrescoRuntimeException("Failed to validate model delete" + tenantDomain + " - found " + rs.length() + " nodes in store " + store + " with " + classType + " '" + className + "'" ); + } + } + finally + { + rs.close(); } } @@ -691,16 +698,23 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda ArrayList nodeRefs = new ArrayList(); ResultSet rs = searchService.query(storeRef, SearchService.LANGUAGE_LUCENE, "TYPE:\""+ContentModel.TYPE_DICTIONARY_MODEL+"\""); - if (rs.length() > 0) + try { - for (NodeRef modelNodeRef : rs.getNodeRefs()) - { - QName name = (QName)nodeService.getProperty(modelNodeRef, ContentModel.PROP_MODEL_NAME); - if ((name != null) && (name.equals(modelName))) - { - nodeRefs.add(modelNodeRef); - } - } + if (rs.length() > 0) + { + for (NodeRef modelNodeRef : rs.getNodeRefs()) + { + QName name = (QName)nodeService.getProperty(modelNodeRef, ContentModel.PROP_MODEL_NAME); + if ((name != null) && (name.equals(modelName))) + { + nodeRefs.add(modelNodeRef); + } + } + } + } + finally + { + rs.close(); } return nodeRefs; } diff --git a/source/java/org/alfresco/repo/imap/AbstractMimeMessage.java b/source/java/org/alfresco/repo/imap/AbstractMimeMessage.java index 65a68a9686..ee22497576 100755 --- a/source/java/org/alfresco/repo/imap/AbstractMimeMessage.java +++ b/source/java/org/alfresco/repo/imap/AbstractMimeMessage.java @@ -343,6 +343,7 @@ public abstract class AbstractMimeMessage extends MimeMessage return result; } result = resultSet.getNodeRef(0).toString(); + resultSet.close(); return result; } diff --git a/source/java/org/alfresco/repo/imap/ImapServiceImplTest.java b/source/java/org/alfresco/repo/imap/ImapServiceImplTest.java index d0aa030e2e..f8bba23935 100755 --- a/source/java/org/alfresco/repo/imap/ImapServiceImplTest.java +++ b/source/java/org/alfresco/repo/imap/ImapServiceImplTest.java @@ -227,7 +227,7 @@ public class ImapServiceImplTest extends TestCase private void reauthenticate(String name, String password) { - authenticationService.invalidateTicket(authenticationService.getCurrentTicket()); + authenticationService.invalidateTicket(authenticationService.getCurrentTicket(), null); authenticationService.clearCurrentSecurityContext(); authenticationService.authenticate(name, password.toCharArray()); } diff --git a/source/java/org/alfresco/repo/imap/LoadTester.java b/source/java/org/alfresco/repo/imap/LoadTester.java index 274da79da4..0999ab6dcf 100755 --- a/source/java/org/alfresco/repo/imap/LoadTester.java +++ b/source/java/org/alfresco/repo/imap/LoadTester.java @@ -193,7 +193,7 @@ public class LoadTester extends TestCase private void reauthenticate(String name, String password) { - authenticationService.invalidateTicket(authenticationService.getCurrentTicket()); + authenticationService.invalidateTicket(authenticationService.getCurrentTicket(), null); authenticationService.clearCurrentSecurityContext(); authenticationService.authenticate(name, password.toCharArray()); } diff --git a/source/java/org/alfresco/repo/invitation/InvitationServiceImpl.java b/source/java/org/alfresco/repo/invitation/InvitationServiceImpl.java index aa34f82cd7..e8e85785eb 100644 --- a/source/java/org/alfresco/repo/invitation/InvitationServiceImpl.java +++ b/source/java/org/alfresco/repo/invitation/InvitationServiceImpl.java @@ -1286,13 +1286,20 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli // is created, otherwise if a user account already exists for invitee // user name, then local reference to invitee password will be "null" // - String inviteePassword = null; - if (!this.authenticationService.authenticationExists(inviteeUserName)) { - if (logger.isDebugEnabled()) - logger - .debug("Invitee user account does not exist, creating disabled account."); - inviteePassword = createInviteeDisabledAccount(inviteeUserName); - } + final String initeeUserNameFinal = inviteeUserName; + String inviteePassword = AuthenticationUtil.runAs(new RunAsWork() + { + public String doWork() + { + if (!InvitationServiceImpl.this.authenticationService.authenticationExists(initeeUserNameFinal)) + { + if (logger.isDebugEnabled()) + logger.debug("Invitee user account does not exist, creating disabled account."); + return createInviteeDisabledAccount(initeeUserNameFinal); + } + return null; + } + }, AuthenticationUtil.getSystemUserName()); // create a ticket for the invite - this is used String inviteTicket = GUID.generate(); diff --git a/source/java/org/alfresco/repo/node/archive/NodeArchiveServiceImpl.java b/source/java/org/alfresco/repo/node/archive/NodeArchiveServiceImpl.java index 8ea3149066..0b11d6f739 100644 --- a/source/java/org/alfresco/repo/node/archive/NodeArchiveServiceImpl.java +++ b/source/java/org/alfresco/repo/node/archive/NodeArchiveServiceImpl.java @@ -254,20 +254,27 @@ public class NodeArchiveServiceImpl implements NodeArchiveService { // get all archived children using a search ResultSet rs = getArchivedNodes(originalStoreRef); - // loop through the resultset and attempt to restore all the nodes - List results = new ArrayList(1000); - for (ResultSetRow row : rs) + try { - NodeRef archivedNodeRef = row.getNodeRef(); - RestoreNodeReport result = restoreArchivedNode(archivedNodeRef, destinationNodeRef, assocTypeQName, assocQName); - results.add(result); + // loop through the resultset and attempt to restore all the nodes + List results = new ArrayList(1000); + for (ResultSetRow row : rs) + { + NodeRef archivedNodeRef = row.getNodeRef(); + RestoreNodeReport result = restoreArchivedNode(archivedNodeRef, destinationNodeRef, assocTypeQName, assocQName); + results.add(result); + } + // done + if (logger.isDebugEnabled()) + { + logger.debug("Restored " + results.size() + " nodes into store " + originalStoreRef); + } + return results; } - // done - if (logger.isDebugEnabled()) + finally { - logger.debug("Restored " + results.size() + " nodes into store " + originalStoreRef); + rs.close(); } - return results; } /** @@ -311,17 +318,24 @@ public class NodeArchiveServiceImpl implements NodeArchiveService { // get all archived children using a search ResultSet rs = getArchivedNodes(originalStoreRef); - // loop through the resultset and attempt to restore all the nodes - List results = new ArrayList(1000); - for (ResultSetRow row : rs) + try { - NodeRef archivedNodeRef = row.getNodeRef(); - purgeArchivedNode(archivedNodeRef); + // loop through the resultset and attempt to restore all the nodes + List results = new ArrayList(1000); + for (ResultSetRow row : rs) + { + NodeRef archivedNodeRef = row.getNodeRef(); + purgeArchivedNode(archivedNodeRef); + } + // done + if (logger.isDebugEnabled()) + { + logger.debug("Deleted " + results.size() + " nodes originally in store " + originalStoreRef); + } } - // done - if (logger.isDebugEnabled()) + finally { - logger.debug("Deleted " + results.size() + " nodes originally in store " + originalStoreRef); + rs.close(); } } diff --git a/source/java/org/alfresco/repo/remote/FileFolderRemoteServer.java b/source/java/org/alfresco/repo/remote/FileFolderRemoteServer.java index b1eeaa0ee8..baff7540ec 100644 --- a/source/java/org/alfresco/repo/remote/FileFolderRemoteServer.java +++ b/source/java/org/alfresco/repo/remote/FileFolderRemoteServer.java @@ -103,7 +103,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback> callback = new RetryingTransactionCallback>() { @@ -128,7 +128,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback> callback = new RetryingTransactionCallback>() { @@ -153,7 +153,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback> callback = new RetryingTransactionCallback>() { @@ -178,7 +178,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -207,7 +207,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback> callback = new RetryingTransactionCallback>() { @@ -238,7 +238,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback> callback = new RetryingTransactionCallback>() { @@ -263,7 +263,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -289,7 +289,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -315,7 +315,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -340,7 +340,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -365,7 +365,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -395,7 +395,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -421,7 +421,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -448,7 +448,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -473,7 +473,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback> callback = new RetryingTransactionCallback>() { @@ -498,7 +498,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -523,7 +523,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -552,7 +552,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -601,7 +601,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -653,7 +653,7 @@ public class FileFolderRemoteServer implements FileFolderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { diff --git a/source/java/org/alfresco/repo/remote/LoaderRemoteServer.java b/source/java/org/alfresco/repo/remote/LoaderRemoteServer.java index 57c1f4858f..9767da0e33 100644 --- a/source/java/org/alfresco/repo/remote/LoaderRemoteServer.java +++ b/source/java/org/alfresco/repo/remote/LoaderRemoteServer.java @@ -167,7 +167,7 @@ public class LoaderRemoteServer implements LoaderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() { @@ -252,7 +252,7 @@ public class LoaderRemoteServer implements LoaderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); // Make the call RetryingTransactionCallback callback = new RetryingTransactionCallback() @@ -333,7 +333,7 @@ public class LoaderRemoteServer implements LoaderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); RetryingTransactionCallback callback = new RetryingTransactionCallback() { public NodeRef execute() throws Throwable @@ -360,7 +360,7 @@ public class LoaderRemoteServer implements LoaderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); RetryingTransactionCallback callback = new RetryingTransactionCallback() { public FileInfo[] execute() throws Throwable @@ -396,7 +396,7 @@ public class LoaderRemoteServer implements LoaderRemote AuthenticationUtil.pushAuthentication(); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); RetryingTransactionCallback callback = new RetryingTransactionCallback() { public NodeRef execute() throws Throwable @@ -423,7 +423,7 @@ public class LoaderRemoteServer implements LoaderRemote try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); RetryingTransactionCallback callback = new RetryingTransactionCallback() { public NodeRef [] execute() throws Throwable diff --git a/source/java/org/alfresco/repo/remote/RepoRemoteTransportService.java b/source/java/org/alfresco/repo/remote/RepoRemoteTransportService.java index 73535fb915..0f87497ee4 100644 --- a/source/java/org/alfresco/repo/remote/RepoRemoteTransportService.java +++ b/source/java/org/alfresco/repo/remote/RepoRemoteTransportService.java @@ -229,7 +229,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public synchronized void closeInputHandle(String ticket, String handle) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); InputStream in = fInputStreams.get(handle); if (in != null) { @@ -252,7 +252,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public synchronized void closeOutputHandle(String ticket, String handle) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); OutputStream out = fOutputStreams.get(handle); if (out != null) { @@ -275,7 +275,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public NodeRef createDirectory(String ticket, NodeRef base, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fRepoRemote.createDirectory(base, path); } @@ -284,7 +284,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public String createFile(String ticket, NodeRef base, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); OutputStream out = fRepoRemote.createFile(base, path); return getOutputHandle(out); } @@ -294,7 +294,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public Map> getListing(String ticket, NodeRef dir) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fRepoRemote.getListing(dir); } @@ -303,7 +303,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public NodeRef getRoot(String ticket) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fRepoRemote.getRoot(); } @@ -312,7 +312,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public Pair lookup(String ticket, NodeRef base, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); return fRepoRemote.lookup(base, path); } @@ -321,7 +321,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public String readFile(String ticket, NodeRef base, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); InputStream in = fRepoRemote.readFile(base, path); return getInputHandle(in); } @@ -331,7 +331,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public String readFile(String ticket, NodeRef fileRef) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); InputStream in = fRepoRemote.readFile(fileRef); return getInputHandle(in); } @@ -341,7 +341,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public byte[] readInput(String ticket, String handle, int count) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); InputStream in = null; synchronized (this) { @@ -390,7 +390,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public void removeNode(String ticket, NodeRef base, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fRepoRemote.removeNode(base, path); } @@ -399,7 +399,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public void removeNode(String ticket, NodeRef toRemove) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fRepoRemote.removeNode(toRemove); } @@ -408,7 +408,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public void rename(String ticket, NodeRef base, String src, String dst) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); fRepoRemote.rename(base, src, dst); } @@ -417,7 +417,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public String writeFile(String ticket, NodeRef base, String path) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); OutputStream out = fRepoRemote.writeFile(base, path); return getOutputHandle(out); } @@ -427,7 +427,7 @@ public class RepoRemoteTransportService implements RepoRemoteTransport, */ public void writeOutput(String ticket, String handle, byte[] buff, int count) { - fAuthService.validate(ticket); + fAuthService.validate(ticket, null); OutputStream out = null; synchronized (this) { diff --git a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneCategoryTest.java b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneCategoryTest.java index 9b3f85cf21..573ec2491c 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneCategoryTest.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneCategoryTest.java @@ -805,9 +805,9 @@ public class ADMLuceneCategoryTest extends TestCase tx = transactionService.getUserTransaction(); tx.begin(); start = System.nanoTime(); - @SuppressWarnings("unused") ResultSet set = searcher.query(serviceRegistry.getPersonService().getPeopleContainer().getStoreRef(), "lucene", "@"+LuceneQueryParser.escape(ContentModel.ASPECT_GEN_CLASSIFIABLE.toString())+":second*"); System.out.println("Query complete in "+(System.nanoTime()-start)/1e9f); + set.close(); tx.commit(); } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneTest.java b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneTest.java index 7e9f0d90ad..3bc3975355 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneTest.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneTest.java @@ -748,6 +748,7 @@ public class ADMLuceneTest extends TestCase assertEquals("Skip = " + skip + " max = " + max + " actual = " + actualPosition, expected.get(actualPosition), nodeRef); actualPosition++; } + results.close(); } public void testNonPublicSearchServicePaging() throws InterruptedException @@ -808,6 +809,7 @@ public class ADMLuceneTest extends TestCase assertEquals("Skip = " + skip + " max = " + max + " actual = " + actualPosition, expected.get(actualPosition), nodeRef); actualPosition++; } + results.close(); } public void testAlfrescoSql() throws InterruptedException diff --git a/source/java/org/alfresco/repo/security/authentication/AbstractAuthenticationService.java b/source/java/org/alfresco/repo/security/authentication/AbstractAuthenticationService.java index 5eddc4a099..4fe5f74c48 100644 --- a/source/java/org/alfresco/repo/security/authentication/AbstractAuthenticationService.java +++ b/source/java/org/alfresco/repo/security/authentication/AbstractAuthenticationService.java @@ -73,6 +73,11 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer { return sysAdminParams.getMaxUsers(); } + + public String getCurrentTicket() + { + return getCurrentTicket(null); + } public abstract Set getUsersWithTickets(boolean nonExpiredOnly); diff --git a/source/java/org/alfresco/repo/security/authentication/AbstractChainingAuthenticationService.java b/source/java/org/alfresco/repo/security/authentication/AbstractChainingAuthenticationService.java index 87be816923..25b2ebeee0 100644 --- a/source/java/org/alfresco/repo/security/authentication/AbstractChainingAuthenticationService.java +++ b/source/java/org/alfresco/repo/security/authentication/AbstractChainingAuthenticationService.java @@ -38,7 +38,8 @@ import org.alfresco.service.cmr.security.MutableAuthenticationService; * * @author dward */ -public abstract class AbstractChainingAuthenticationService extends AbstractAuthenticationService implements MutableAuthenticationService +public abstract class AbstractChainingAuthenticationService extends AbstractAuthenticationService implements + MutableAuthenticationService { /** * Instantiates a new abstract chaining authentication service. @@ -62,7 +63,8 @@ public abstract class AbstractChainingAuthenticationService extends AbstractAuth */ protected abstract List getUsableAuthenticationServices(); - /* (non-Javadoc) + /* + * (non-Javadoc) * @see org.alfresco.service.cmr.security.AuthenticationService#createAuthentication(java.lang.String, char[]) */ public void createAuthentication(String userName, char[] password) throws AuthenticationException @@ -75,8 +77,10 @@ public abstract class AbstractChainingAuthenticationService extends AbstractAuth getMutableAuthenticationService().createAuthentication(userName, password); } - /* (non-Javadoc) - * @see org.alfresco.service.cmr.security.AuthenticationService#updateAuthentication(java.lang.String, char[], char[]) + /* + * (non-Javadoc) + * @see org.alfresco.service.cmr.security.AuthenticationService#updateAuthentication(java.lang.String, char[], + * char[]) */ public void updateAuthentication(String userName, char[] oldPassword, char[] newPassword) throws AuthenticationException @@ -140,6 +144,17 @@ public abstract class AbstractChainingAuthenticationService extends AbstractAuth .isAuthenticationMutable(userName); } + + /** + * {@inheritDoc} + */ + public boolean isAuthenticationCreationAllowed() + { + MutableAuthenticationService mutableAuthenticationService = getMutableAuthenticationService(); + return mutableAuthenticationService == null ? false : mutableAuthenticationService + .isAuthenticationCreationAllowed(); + } + /** * {@inheritDoc} */ @@ -159,7 +174,7 @@ public abstract class AbstractChainingAuthenticationService extends AbstractAuth // Ignore and chain } } - return true; + return false; } /** @@ -236,7 +251,7 @@ public abstract class AbstractChainingAuthenticationService extends AbstractAuth // it doesn't exist in any of the authentication components return false; } - + /** * {@inheritDoc} */ @@ -280,13 +295,13 @@ public abstract class AbstractChainingAuthenticationService extends AbstractAuth /** * {@inheritDoc} */ - public void invalidateTicket(String ticket) throws AuthenticationException + public void invalidateTicket(String ticket, String sessionId) throws AuthenticationException { for (AuthenticationService authService : getUsableAuthenticationServices()) { try { - authService.invalidateTicket(ticket); + authService.invalidateTicket(ticket, sessionId); return; } catch (AuthenticationException e) @@ -301,13 +316,13 @@ public abstract class AbstractChainingAuthenticationService extends AbstractAuth /** * {@inheritDoc} */ - public void validate(String ticket) throws AuthenticationException + public void validate(String ticket, String sessionId) throws AuthenticationException { for (AuthenticationService authService : getUsableAuthenticationServices()) { try { - authService.validate(ticket); + authService.validate(ticket, sessionId); return; } catch (AuthenticationException e) @@ -322,13 +337,13 @@ public abstract class AbstractChainingAuthenticationService extends AbstractAuth /** * {@inheritDoc} */ - public String getCurrentTicket() + public String getCurrentTicket(String sessionId) { for (AuthenticationService authService : getUsableAuthenticationServices()) { try { - return authService.getCurrentTicket(); + return authService.getCurrentTicket(sessionId); } catch (AuthenticationException e) { @@ -341,13 +356,13 @@ public abstract class AbstractChainingAuthenticationService extends AbstractAuth /** * {@inheritDoc} */ - public String getNewTicket() + public String getNewTicket(String sessionId) { for (AuthenticationService authService : getUsableAuthenticationServices()) { try { - return authService.getNewTicket(); + return authService.getNewTicket(sessionId); } catch (AuthenticationException e) { @@ -539,7 +554,5 @@ public abstract class AbstractChainingAuthenticationService extends AbstractAuth } return defaultGuestUserNames; } - - } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/security/authentication/AuthenticationServiceImpl.java b/source/java/org/alfresco/repo/security/authentication/AuthenticationServiceImpl.java index e3aaf81c3d..3dcb7a224b 100644 --- a/source/java/org/alfresco/repo/security/authentication/AuthenticationServiceImpl.java +++ b/source/java/org/alfresco/repo/security/authentication/AuthenticationServiceImpl.java @@ -86,7 +86,7 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService imp } ticketComponent.clearCurrentTicket(); - ticketComponent.getCurrentTicket(userName); // to ensure new ticket is created (even if client does not explicitly call getCurrentTicket) + ticketComponent.getCurrentTicket(userName, null, true); // to ensure new ticket is created (even if client does not explicitly call getCurrentTicket) } public String getCurrentUserName() throws AuthenticationException @@ -104,9 +104,9 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService imp return ticketComponent.getUsersWithTickets(nonExpiredOnly); } - public void invalidateTicket(String ticket) throws AuthenticationException + public void invalidateTicket(String ticket, String sessionId) throws AuthenticationException { - ticketComponent.invalidateTicketById(ticket); + ticketComponent.invalidateTicketById(ticket, sessionId); } public int countTickets(boolean nonExpiredOnly) @@ -120,7 +120,7 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService imp } - public void validate(String ticket) throws AuthenticationException + public void validate(String ticket, String sessionId) throws AuthenticationException { String currentUser = null; try @@ -128,7 +128,7 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService imp // clear context - to avoid MT concurrency issue (causing domain mismatch) - see also 'authenticate' above clearCurrentSecurityContext(); - currentUser = ticketComponent.validateTicket(ticket); + currentUser = ticketComponent.validateTicket(ticket, sessionId); authenticationComponent.setCurrentUser(currentUser, UserNameValidationMode.CHECK); } catch (AuthenticationException ae) @@ -138,14 +138,43 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService imp } } - public String getCurrentTicket() + public String getCurrentTicket(String sessionId) throws AuthenticationException { - return ticketComponent.getCurrentTicket(getCurrentUserName()); + String userName = getCurrentUserName(); + // So that preAuthenticationCheck can constrain the creation of new tickets, we first ask for the current ticket + // without auto-creation + String ticket = ticketComponent.getCurrentTicket(userName, sessionId, false); + if (ticket == null) + { + try + { + preAuthenticationCheck(userName); + } + catch (AuthenticationException e) + { + clearCurrentSecurityContext(); + throw e; + } + // If we get through the authentication check then it's safe to issue a new ticket (e.g. for + // SSO/external-based login) + return ticketComponent.getCurrentTicket(userName, sessionId, true); + } + return ticket; } - public String getNewTicket() + public String getNewTicket(String sessionId) { - return ticketComponent.getNewTicket(getCurrentUserName()); + String userName = getCurrentUserName(); + try + { + preAuthenticationCheck(userName); + } + catch (AuthenticationException e) + { + clearCurrentSecurityContext(); + throw e; + } + return ticketComponent.getNewTicket(userName, sessionId); } public void clearCurrentSecurityContext() @@ -165,7 +194,7 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService imp authenticationComponent.setGuestUserAsCurrentUser(); String guestUser = authenticationComponent.getCurrentUserName(); ticketComponent.clearCurrentTicket(); - ticketComponent.getCurrentTicket(guestUser); // to ensure new ticket is created (even if client does not explicitly call getCurrentTicket) + ticketComponent.getCurrentTicket(guestUser, null, true); // to ensure new ticket is created (even if client does not explicitly call getCurrentTicket) } public boolean guestUserAuthenticationAllowed() diff --git a/source/java/org/alfresco/repo/security/authentication/AuthenticationTest.java b/source/java/org/alfresco/repo/security/authentication/AuthenticationTest.java index 798947ad12..8541df44d1 100644 --- a/source/java/org/alfresco/repo/security/authentication/AuthenticationTest.java +++ b/source/java/org/alfresco/repo/security/authentication/AuthenticationTest.java @@ -274,11 +274,11 @@ public class AuthenticationTest extends TestCase //userTransaction = transactionService.getUserTransaction(); //userTransaction.begin(); - pubAuthenticationService.validate(ticket); + pubAuthenticationService.validate(ticket, null); userName = pubAuthenticationService.getCurrentUserName(); assertEquals("andy", userName); - pubAuthenticationService.validate(newticket); + pubAuthenticationService.validate(newticket, null); userName = pubAuthenticationService.getCurrentUserName(); assertEquals("andy", userName); @@ -629,14 +629,14 @@ public class AuthenticationTest extends TestCase Authentication result = authenticationManager.authenticate(token); result.setAuthenticated(true); - String ticket = ticketComponent.getNewTicket(getUserName(result)); - String user = ticketComponent.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); + String ticket = ticketComponent.getNewTicket(getUserName(result), null); + String user = ticketComponent.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); user = null; try { - user = ticketComponent.validateTicket("INVALID"); + user = ticketComponent.validateTicket("INVALID", null); assertNotNull(null); } catch (AuthenticationException e) @@ -644,11 +644,11 @@ public class AuthenticationTest extends TestCase assertNull(user); } - ticketComponent.invalidateTicketById(ticket); + ticketComponent.invalidateTicketById(ticket, null); try { - user = ticketComponent.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); + user = ticketComponent.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); assertNotNull(null); } catch (AuthenticationException e) @@ -677,11 +677,11 @@ public class AuthenticationTest extends TestCase Authentication result = authenticationManager.authenticate(token); result.setAuthenticated(true); - String ticket = tc.getNewTicket(getUserName(result)); - tc.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); - tc.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); + String ticket = tc.getNewTicket(getUserName(result), null); + tc.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); + tc.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); dao.deleteUser("Andy"); // assertNull(dao.getUserOrNull("Andy")); @@ -703,12 +703,12 @@ public class AuthenticationTest extends TestCase Authentication result = authenticationManager.authenticate(token); result.setAuthenticated(true); - String ticket = tc.getNewTicket(getUserName(result)); - tc.validateTicket(ticket); - assertTrue(!ticketComponent.getCurrentTicket("Andy").equals(ticket)); + String ticket = tc.getNewTicket(getUserName(result), null); + tc.validateTicket(ticket, null); + assertTrue(!ticketComponent.getCurrentTicket("Andy", null, true).equals(ticket)); try { - tc.validateTicket(ticket); + tc.validateTicket(ticket, null); assertNotNull(null); } catch (AuthenticationException e) @@ -737,13 +737,13 @@ public class AuthenticationTest extends TestCase Authentication result = authenticationManager.authenticate(token); result.setAuthenticated(true); - String ticket = tc.getNewTicket(getUserName(result)); - tc.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); - tc.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); - tc.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); + String ticket = tc.getNewTicket(getUserName(result), null); + tc.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); + tc.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); + tc.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); synchronized (this) { @@ -759,7 +759,7 @@ public class AuthenticationTest extends TestCase } try { - tc.validateTicket(ticket); + tc.validateTicket(ticket, null); assertNotNull(null); } catch (AuthenticationException e) @@ -769,7 +769,7 @@ public class AuthenticationTest extends TestCase try { - tc.validateTicket(ticket); + tc.validateTicket(ticket, null); assertNotNull(null); } catch (AuthenticationException e) @@ -779,7 +779,7 @@ public class AuthenticationTest extends TestCase try { - tc.validateTicket(ticket); + tc.validateTicket(ticket, null); assertNotNull(null); } catch (AuthenticationException e) @@ -802,7 +802,7 @@ public class AuthenticationTest extends TestCase try { - tc.validateTicket(ticket); + tc.validateTicket(ticket, null); assertNotNull(null); } catch (AuthenticationException e) @@ -811,7 +811,7 @@ public class AuthenticationTest extends TestCase } tc.setExpiryMode(ExpiryMode.AFTER_INACTIVITY.toString()); - ticket = tc.getNewTicket(getUserName(result)); + ticket = tc.getNewTicket(getUserName(result), null); for (int i = 0; i < 50; i++) { @@ -828,7 +828,7 @@ public class AuthenticationTest extends TestCase e.printStackTrace(); } - tc.validateTicket(ticket); + tc.validateTicket(ticket, null); } } @@ -848,7 +848,7 @@ public class AuthenticationTest extends TestCase try { - tc.validateTicket(ticket); + tc.validateTicket(ticket, null); assertNotNull(null); } catch (AuthenticationException e) @@ -877,13 +877,13 @@ public class AuthenticationTest extends TestCase Authentication result = authenticationManager.authenticate(token); result.setAuthenticated(true); - String ticket = tc.getNewTicket(getUserName(result)); - tc.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); - tc.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); - tc.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); + String ticket = tc.getNewTicket(getUserName(result), null); + tc.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); + tc.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); + tc.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); synchronized (this) { @@ -899,7 +899,7 @@ public class AuthenticationTest extends TestCase } try { - tc.validateTicket(ticket); + tc.validateTicket(ticket, null); assertNotNull(null); } catch (AuthenticationException e) @@ -909,7 +909,7 @@ public class AuthenticationTest extends TestCase try { - tc.validateTicket(ticket); + tc.validateTicket(ticket, null); assertNotNull(null); } catch (AuthenticationException e) @@ -919,7 +919,7 @@ public class AuthenticationTest extends TestCase try { - tc.validateTicket(ticket); + tc.validateTicket(ticket, null); assertNotNull(null); } catch (AuthenticationException e) @@ -942,7 +942,7 @@ public class AuthenticationTest extends TestCase try { - tc.validateTicket(ticket); + tc.validateTicket(ticket, null); assertNotNull(null); } catch (AuthenticationException e) @@ -970,13 +970,13 @@ public class AuthenticationTest extends TestCase Authentication result = authenticationManager.authenticate(token); result.setAuthenticated(true); - String ticket = tc.getNewTicket(getUserName(result)); - tc.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); - tc.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); - tc.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); + String ticket = tc.getNewTicket(getUserName(result), null); + tc.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); + tc.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); + tc.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); synchronized (this) { try @@ -990,8 +990,8 @@ public class AuthenticationTest extends TestCase } } - tc.validateTicket(ticket); - assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket); + tc.validateTicket(ticket, null); + assertEquals(ticketComponent.getCurrentTicket("Andy", null, true), ticket); dao.deleteUser("Andy"); // assertNull(dao.getUserOrNull("Andy")); @@ -1126,14 +1126,14 @@ public class AuthenticationTest extends TestCase // instance String ticket = authenticationService.getCurrentTicket(); // validate our ticket is still valid - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); assertEquals(ticket, authenticationService.getCurrentTicket()); // destroy the ticket instance - authenticationService.invalidateTicket(ticket); + authenticationService.invalidateTicket(ticket, null); try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); fail("Invalid taicket should have been rejected"); } catch (AuthenticationException e) @@ -1175,11 +1175,11 @@ public class AuthenticationTest extends TestCase // validate our ticket is still valid authenticationService.clearCurrentSecurityContext(); - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); assertEquals(ticket, authenticationService.getCurrentTicket()); // destroy the ticket instance - authenticationService.invalidateTicket(ticket); + authenticationService.invalidateTicket(ticket, null); Authentication current = authenticationComponent.getCurrentAuthentication(); if (current != null) @@ -1190,7 +1190,7 @@ public class AuthenticationTest extends TestCase try { - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); fail("Invalid ticket should have been rejected"); } catch (AuthenticationException e) @@ -1234,11 +1234,11 @@ public class AuthenticationTest extends TestCase // instance String ticket = authenticationService.getCurrentTicket(); // validate our ticket is still valid - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); assertEquals(ticket, authenticationService.getCurrentTicket()); // destroy the ticket instance - authenticationService.invalidateTicket(ticket); + authenticationService.invalidateTicket(ticket, null); Authentication current = authenticationComponent.getCurrentAuthentication(); if (current != null) @@ -1294,11 +1294,11 @@ public class AuthenticationTest extends TestCase // instance String ticket = authenticationService.getCurrentTicket(); // validate our ticket is still valid - authenticationService.validate(ticket); + authenticationService.validate(ticket, null); assertEquals(ticket, authenticationService.getCurrentTicket()); // destroy the ticket instance - authenticationService.invalidateTicket(ticket); + authenticationService.invalidateTicket(ticket, null); Authentication current = authenticationComponent.getCurrentAuthentication(); if (current != null) @@ -1316,6 +1316,48 @@ public class AuthenticationTest extends TestCase // assertNull(dao.getUserOrNull("Andy")); } + public void testAuthenticationServiceSessionIds() + { + // create an authentication object e.g. the user + authenticationService.createAuthentication("Andy", "auth1".toCharArray()); + + // authenticate with this user details + authenticationService.authenticate("Andy", "auth1".toCharArray()); + + // assert the user is authenticated + assertEquals("Andy", authenticationService.getCurrentUserName()); + + // Get the user's ticket and associate it with "AndySessionId" + String andyTicket = authenticationService.getCurrentTicket("AndySessionId"); + + // Now validate the ticket in another session + authenticationService.validate(andyTicket, "DaveSessionId"); + + assertEquals(andyTicket, authenticationService.getCurrentTicket()); + + // Invalidate it in that session + authenticationService.invalidateTicket(andyTicket, "DaveSessionId"); + + // Make sure we don't get that ticket again in the same session + assertNotSame(andyTicket, authenticationService.getCurrentTicket("DaveSessionId")); + + // The ticket should still validate in the other session + authenticationService.validate(andyTicket, "AndySessionId"); + + // When we invalidate it in the other session, the ticket should be invalidated globally + authenticationService.invalidateTicket(andyTicket, "AndySessionId"); + + try + { + authenticationService.validate(andyTicket, null); + fail("Invalid ticket should have been rejected"); + } + catch (AuthenticationException e) + { + // Expected + } + } + public void testPubAuthenticationService1() { authenticationComponent.setSystemUserAsCurrentUser(); @@ -1456,14 +1498,14 @@ public class AuthenticationTest extends TestCase assertNull(authenticationComponent.getCurrentAuthentication()); // validate our ticket is still valid - pubAuthenticationService.validate(ticket); + pubAuthenticationService.validate(ticket, null); assertEquals(ticket, authenticationService.getCurrentTicket()); // destroy the ticket instance - pubAuthenticationService.invalidateTicket(ticket); + pubAuthenticationService.invalidateTicket(ticket, null); try { - pubAuthenticationService.validate(ticket); + pubAuthenticationService.validate(ticket, null); fail("Ticket should not validate"); } catch (AuthenticationException e) @@ -1525,11 +1567,11 @@ public class AuthenticationTest extends TestCase // instance String ticket = pubAuthenticationService.getCurrentTicket(); // validate our ticket is still valid - pubAuthenticationService.validate(ticket); + pubAuthenticationService.validate(ticket, null); assertEquals(ticket, authenticationService.getCurrentTicket()); // destroy the ticket instance - pubAuthenticationService.invalidateTicket(ticket); + pubAuthenticationService.invalidateTicket(ticket, null); } @@ -1586,11 +1628,11 @@ public class AuthenticationTest extends TestCase // instance String ticket = pubAuthenticationService.getCurrentTicket(); // validate our ticket is still valid - pubAuthenticationService.validate(ticket); + pubAuthenticationService.validate(ticket, null); assertEquals(ticket, authenticationService.getCurrentTicket()); // destroy the ticket instance - pubAuthenticationService.invalidateTicket(ticket); + pubAuthenticationService.invalidateTicket(ticket, null); authenticationComponent.clearCurrentSecurityContext(); diff --git a/source/java/org/alfresco/repo/security/authentication/ChainingAuthenticationServiceTest.java b/source/java/org/alfresco/repo/security/authentication/ChainingAuthenticationServiceTest.java index 0880066ef5..6d9b7e0193 100644 --- a/source/java/org/alfresco/repo/security/authentication/ChainingAuthenticationServiceTest.java +++ b/source/java/org/alfresco/repo/security/authentication/ChainingAuthenticationServiceTest.java @@ -305,11 +305,11 @@ public class ChainingAuthenticationServiceTest extends TestCase String ticket = as.getCurrentTicket(); assertTrue(ticket == as.getCurrentTicket()); - as.validate(ticket); - as.invalidateTicket(ticket); + as.validate(ticket, null); + as.invalidateTicket(ticket, null); try { - as.validate(ticket); + as.validate(ticket, null); fail(); } catch (AuthenticationException e) @@ -318,11 +318,11 @@ public class ChainingAuthenticationServiceTest extends TestCase } ticket = as.getCurrentTicket(); - as.validate(ticket); + as.validate(ticket, null); as.invalidateUserSession("andy"); try { - as.validate(ticket); + as.validate(ticket, null); fail(); } catch (AuthenticationException e) @@ -638,11 +638,11 @@ public class ChainingAuthenticationServiceTest extends TestCase String ticket = as.getCurrentTicket(); assertTrue(ticket == as.getCurrentTicket()); - as.validate(ticket); - as.invalidateTicket(ticket); + as.validate(ticket, null); + as.invalidateTicket(ticket, null); try { - as.validate(ticket); + as.validate(ticket, null); fail(); } catch (AuthenticationException e) @@ -651,11 +651,11 @@ public class ChainingAuthenticationServiceTest extends TestCase } ticket = as.getCurrentTicket(); - as.validate(ticket); + as.validate(ticket, null); as.invalidateUserSession("andy"); try { - as.validate(ticket); + as.validate(ticket, null); fail(); } catch (AuthenticationException e) diff --git a/source/java/org/alfresco/repo/security/authentication/InMemoryTicketComponentImpl.java b/source/java/org/alfresco/repo/security/authentication/InMemoryTicketComponentImpl.java index 53e6e2fc97..453c5ede4a 100644 --- a/source/java/org/alfresco/repo/security/authentication/InMemoryTicketComponentImpl.java +++ b/source/java/org/alfresco/repo/security/authentication/InMemoryTicketComponentImpl.java @@ -27,6 +27,7 @@ package org.alfresco.repo.security.authentication; import java.io.Serializable; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Set; @@ -83,23 +84,25 @@ public class InMemoryTicketComponentImpl implements TicketComponent this.ticketsCache = ticketsCache; } - public String getNewTicket(String userName) throws AuthenticationException + public String getNewTicket(String userName, String sessionId) throws AuthenticationException { Date expiryDate = null; if (ticketsExpire) { expiryDate = Duration.add(new Date(), validDuration); } - Ticket ticket = new Ticket(ticketsExpire ? expiryMode : ExpiryMode.DO_NOT_EXPIRE, expiryDate, userName, validDuration); + Ticket ticket = new Ticket(ticketsExpire ? expiryMode : ExpiryMode.DO_NOT_EXPIRE, expiryDate, userName, + validDuration, sessionId == null ? Collections. emptySet() : Collections.singleton(sessionId)); ticketsCache.put(ticket.getTicketId(), ticket); String ticketString = GRANTED_AUTHORITY_TICKET_PREFIX + ticket.getTicketId(); currentTicket.set(ticketString); return ticketString; } - public String validateTicket(String ticketString) throws AuthenticationException + public String validateTicket(String ticketString, String sessionId) throws AuthenticationException { - Ticket ticket = getTicketByTicketString(ticketString); + String ticketKey = getTicketKey(ticketString); + Ticket ticket = this.ticketsCache.get(ticketKey); if (ticket == null) { throw new AuthenticationException("Missing ticket for " + ticketString); @@ -112,7 +115,17 @@ public class InMemoryTicketComponentImpl implements TicketComponent // TODO: Strengthen ticket as GUID is predicatble if (oneOff) { - ticketsCache.remove(getTicketKey(ticketString)); + ticketsCache.remove(ticketKey); + } + // Make sure the association with the session is recorded + else if (sessionId != null) + { + Ticket newTicket = ticket.addSessionId(sessionId); + if (newTicket != ticket) + { + ticketsCache.put(ticketKey, newTicket); + ticket = newTicket; + } } currentTicket.set(ticketString); return ticket.getUserName(); @@ -146,10 +159,28 @@ public class InMemoryTicketComponentImpl implements TicketComponent return key; } - public void invalidateTicketById(String ticketString) + public void invalidateTicketById(String ticketString, String sessionId) { - String key = ticketString.substring(GRANTED_AUTHORITY_TICKET_PREFIX.length()); - ticketsCache.remove(key); + String ticketKey = getTicketKey(ticketString); + // If we are dissassociating the ticket from an app server session, it may still not be time to expire it, as it + // may be in use by other sessions + if (sessionId != null) + { + Ticket ticketObj = ticketsCache.get(ticketKey); + ticketObj = ticketObj.removeSessionId(sessionId); + if (ticketObj == null) + { + ticketsCache.remove(ticketKey); + } + else + { + ticketsCache.put(ticketKey, ticketObj); + } + } + else + { + ticketsCache.remove(ticketKey); + } } /* @@ -297,13 +328,27 @@ public class InMemoryTicketComponentImpl implements TicketComponent private String guid; private Duration validDuration; + + private Set sessionIds; - Ticket(ExpiryMode expires, Date expiryDate, String userName, Duration validDuration) + private Ticket(Ticket copy, Set sessionIds) + { + this.expires = copy.expires; + this.expiryDate = copy.expiryDate; + this.userName = copy.userName; + this.validDuration = copy.validDuration; + this.guid = copy.guid; + this.ticketId = copy.ticketId; + this.sessionIds = sessionIds; + } + + Ticket(ExpiryMode expires, Date expiryDate, String userName, Duration validDuration, Set sessionIds) { this.expires = expires; this.expiryDate = expiryDate; this.userName = userName; this.validDuration = validDuration; + this.sessionIds = sessionIds; this.guid = UUIDGenerator.getInstance().generateRandomBasedUUID().toString(); String encode = (expires.toString()) + ((expiryDate == null) ? new Date().toString() : expiryDate.toString()) + userName + guid; @@ -338,6 +383,35 @@ public class InMemoryTicketComponentImpl implements TicketComponent } } + public Ticket addSessionId(String sessionId) + { + if (this.sessionIds.contains(sessionId)) + { + return this; + } + Set newSessionIds = new HashSet(this.sessionIds.size() * 2 + 2); + newSessionIds.addAll(this.sessionIds); + newSessionIds.add(sessionId); + return new Ticket(this, newSessionIds); + } + + public Ticket removeSessionId(String sessionId) + { + if (this.sessionIds.contains(sessionId)) + { + Set newSessionIds; + if (this.sessionIds.size() > 1) + { + newSessionIds = new HashSet(this.sessionIds.size() * 2 - 2); + newSessionIds.addAll(this.sessionIds); + newSessionIds.remove(sessionId); + return new Ticket(this, newSessionIds); + } + return null; + } + return this; + } + /** * Has the ticket expired * @@ -414,6 +488,10 @@ public class InMemoryTicketComponentImpl implements TicketComponent return userName; } + protected Set getSessionIds() + { + return sessionIds; + } } /** @@ -466,21 +544,35 @@ public class InMemoryTicketComponentImpl implements TicketComponent return ticket.getUserName(); } - public String getCurrentTicket(String userName) + public String getCurrentTicket(String userName, String sessionId, boolean autoCreate) { - String ticket = currentTicket.get(); - if (ticket == null) + String ticketString = currentTicket.get(); + if (ticketString == null) { - return getNewTicket(userName); + return autoCreate ? getNewTicket(userName, sessionId) : null; } - String ticketUser = getAuthorityForTicket(ticket); - if (userName.equals(ticketUser)) + String ticketKey = getTicketKey(ticketString); + Ticket ticketObj = this.ticketsCache.get(ticketKey); + if (ticketObj != null && userName.equals(ticketObj.getUserName())) { - return ticket; + if (sessionId != null) + { + // A current, as yet unclaimed valid ticket. Make the association with the session now + if (ticketObj.getSessionIds().isEmpty()) + { + this.ticketsCache.put(ticketKey, ticketObj.addSessionId(sessionId)); + } + // The ticket is already claimed by at least one other session, so start a new one + else + { + return autoCreate ? getNewTicket(userName, sessionId) : null; + } + } + return ticketString; } else { - return getNewTicket(userName); + return autoCreate ? getNewTicket(userName, sessionId) : null; } } diff --git a/source/java/org/alfresco/repo/security/authentication/MutableAuthenticationServiceImpl.java b/source/java/org/alfresco/repo/security/authentication/MutableAuthenticationServiceImpl.java index 140964d350..74786d8983 100644 --- a/source/java/org/alfresco/repo/security/authentication/MutableAuthenticationServiceImpl.java +++ b/source/java/org/alfresco/repo/security/authentication/MutableAuthenticationServiceImpl.java @@ -137,4 +137,11 @@ public class MutableAuthenticationServiceImpl extends AuthenticationServiceImpl return authenticationExists(userName); } + /* (non-Javadoc) + * @see org.alfresco.service.cmr.security.MutableAuthenticationService#isAuthenticationCreationAllowed() + */ + public boolean isAuthenticationCreationAllowed() + { + return true; + } } diff --git a/source/java/org/alfresco/repo/security/authentication/TestAuthenticationServiceImpl.java b/source/java/org/alfresco/repo/security/authentication/TestAuthenticationServiceImpl.java index d3298b9f06..03f7ab1824 100644 --- a/source/java/org/alfresco/repo/security/authentication/TestAuthenticationServiceImpl.java +++ b/source/java/org/alfresco/repo/security/authentication/TestAuthenticationServiceImpl.java @@ -251,6 +251,11 @@ public class TestAuthenticationServiceImpl implements MutableAuthenticationServi { return authenticationExists(userName); } + + public boolean isAuthenticationCreationAllowed() + { + return allowCreate; + } public String getCurrentUserName() throws AuthenticationException { @@ -279,7 +284,7 @@ public class TestAuthenticationServiceImpl implements MutableAuthenticationServi userToTicket.remove(userName); } - public void invalidateTicket(String ticket) throws AuthenticationException + public void invalidateTicket(String ticket, String sessionId) throws AuthenticationException { String userToRemove = null; for (String user : userToTicket.keySet()) @@ -297,7 +302,7 @@ public class TestAuthenticationServiceImpl implements MutableAuthenticationServi } - public void validate(String ticket) throws AuthenticationException + public void validate(String ticket, String sessionId) throws AuthenticationException { String userToSet = null; for (String user : userToTicket.keySet()) @@ -319,8 +324,13 @@ public class TestAuthenticationServiceImpl implements MutableAuthenticationServi } - // TODO: Fix this up public String getCurrentTicket() + { + return getCurrentTicket(null); + } + + // TODO: Fix this up + public String getCurrentTicket(String sessionId) { String currentUser = getCurrentUserName(); String ticket = userToTicket.get(currentUser); @@ -332,7 +342,7 @@ public class TestAuthenticationServiceImpl implements MutableAuthenticationServi return ticket; } - public String getNewTicket() + public String getNewTicket(String sessionId) { String currentUser = getCurrentUserName(); String ticket = userToTicket.get(currentUser); diff --git a/source/java/org/alfresco/repo/security/authentication/TicketComponent.java b/source/java/org/alfresco/repo/security/authentication/TicketComponent.java index 7e694e2746..e5b8e283ab 100644 --- a/source/java/org/alfresco/repo/security/authentication/TicketComponent.java +++ b/source/java/org/alfresco/repo/security/authentication/TicketComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2009 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 @@ -18,7 +18,7 @@ * 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 + * FLOSS exception. You should have received a copy of the text describing * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ @@ -36,54 +36,68 @@ import java.util.Set; public interface TicketComponent { /** - * Register a new ticket + * Register a new ticket. If a session ID is given, an association with that session ID will be recorded for the + * returned ticket. * * @param userName + * @param sessionId + * the app server session ID (e.g. HttpSession ID) or null if not applicable. * @return - the ticket * @throws AuthenticationException */ - public String getNewTicket(String userName) throws AuthenticationException; + public String getNewTicket(String userName, String sessionId) throws AuthenticationException; /** - * Get the current ticket + * Gets the current ticket. If a session ID is given, an association with that session ID will be recorded for the + * returned ticket. * * @param userName + * @param sessionId + * the app server session ID (e.g. HttpSession ID) or null if not applicable. + * @param autoCreate + * should we create one automatically if there isn't one? * @return - the ticket - */ - - public String getCurrentTicket(String userName); + */ + public String getCurrentTicket(String userName, String sessionId, boolean autoCreate); /** - * Check that a certificate is valid and can be used in place of a login. - * - * Tickets may be rejected because: + * Check that a certificate is valid and can be used in place of a login. Optionally records an association between + * the ticket and a given app server session Id. This is so that we don't expire tickets prematurely referenced by + * more than one application server session. Tickets may be rejected because: *
    - *
  1. The certificate does not exists - *
  2. The status of the user has changed + *
  3. The certificate does not exists + *
  4. The status of the user has changed *
      - *
    1. The user is locked - *
    2. The account has expired - *
    3. The credentials have expired - *
    4. The account is disabled + *
    5. The user is locked + *
    6. The account has expired + *
    7. The credentials have expired + *
    8. The account is disabled *
    - *
  5. The ticket may have expired + *
  6. The ticket may have expired *
      - *
    1. The ticked my be invalid by timed expiry - *
    2. An attemp to reuse a once only ticket + *
    3. The ticked my be invalid by timed expiry + *
    4. An attemp to reuse a once only ticket *
    *
* * @param ticket + * @param sessionId + * the app server session ID (e.g. HttpSession ID) or null if not applicable. * @return - the user name * @throws AuthenticationException */ - public String validateTicket(String ticket) throws AuthenticationException; + public String validateTicket(String ticket, String sessionId) throws AuthenticationException; /** - * Invalidate the tickets by id + * Invalidates a ticket, or disassociates it from an app server session. Once it has been disassociated from all + * sessions, the ticket will be invalidated globally. + * * @param ticket + * @param sessionId + * the app server session ID (e.g. HttpSession ID) or null if the ticket should be + * invalidated globally. */ - public void invalidateTicketById(String ticket); + public void invalidateTicketById(String ticket, String sessionId); /** * Invalidate all user tickets diff --git a/source/java/org/alfresco/repo/security/authentication/ldap/LDAPAuthenticationComponentImpl.java b/source/java/org/alfresco/repo/security/authentication/ldap/LDAPAuthenticationComponentImpl.java index ff849d29f0..5c2b30cae8 100644 --- a/source/java/org/alfresco/repo/security/authentication/ldap/LDAPAuthenticationComponentImpl.java +++ b/source/java/org/alfresco/repo/security/authentication/ldap/LDAPAuthenticationComponentImpl.java @@ -176,31 +176,6 @@ public class LDAPAuthenticationComponentImpl extends AbstractAuthenticationCompo @Override protected boolean implementationAllowsGuestLogin() { - InitialDirContext ctx = null; - try - { - ctx = ldapInitialContextFactory.getDefaultIntialDirContext(); - return true; - - } - catch (Exception e) - { - return false; - } - finally - { - if (ctx != null) - { - try - { - ctx.close(); - } - catch (NamingException e) - { - throw new AuthenticationException("Failed to close connection", e); - } - } - } + return true; } - } diff --git a/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java b/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java index 0784856449..27c5bee1d7 100644 --- a/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java +++ b/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java @@ -663,8 +663,13 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per { throw new AlfrescoRuntimeException("Attempt to create person for an authority which is not a user"); } - + tenantService.checkDomainUser(userName); + + if (personExists(userName)) + { + throw new AlfrescoRuntimeException("Person '" + userName + "' already exists."); + } properties.put(ContentModel.PROP_USERNAME, userName); properties.put(ContentModel.PROP_SIZE_CURRENT, 0L); diff --git a/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java b/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java index 13e2ca076b..145388b7a9 100644 --- a/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java +++ b/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java @@ -42,6 +42,8 @@ import org.alfresco.model.ContentModel; import org.alfresco.repo.attributes.Attribute; import org.alfresco.repo.attributes.LongAttributeValue; import org.alfresco.repo.attributes.MapAttributeValue; +import org.alfresco.repo.batch.BatchProcessor; +import org.alfresco.repo.batch.BatchProcessor.Worker; import org.alfresco.repo.lock.JobLockService; import org.alfresco.repo.lock.LockAcquisitionException; import org.alfresco.repo.management.subsystems.ActivateableBean; @@ -137,7 +139,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl /** The transaction service. */ private TransactionService transactionService; - + /** The retrying transaction helper. */ private RetryingTransactionHelper retryingTransactionHelper; @@ -542,9 +544,9 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl // First, analyze the group structure. Create maps of authorities to their parents for associations to create // and delete. Also deal with 'overlaps' with other zones in the authentication chain. final BatchProcessor groupProcessor = new BatchProcessor( - this.retryingTransactionHelper, this.ruleService, this.applicationEventPublisher, userRegistry - .getGroups(lastModified), zone + " Group Analysis", this.loggingInterval, this.workerThreads, - 20); + ChainingUserRegistrySynchronizer.logger, this.retryingTransactionHelper, this.ruleService, + this.applicationEventPublisher, userRegistry.getGroups(lastModified), zone + " Group Analysis", + this.loggingInterval, this.workerThreads, 20); class Analyzer implements Worker { private final Set allZoneAuthorities = new TreeSet(); @@ -776,9 +778,9 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl // Add the groups and their parent associations in depth-first order final Set groupsToCreate = groupAnalyzer.getGroupsToCreate(); BatchProcessor>> groupCreator = new BatchProcessor>>( - this.retryingTransactionHelper, this.ruleService, this.applicationEventPublisher, - sortedGroupAssociations.entrySet(), zone + " Group Creation and Association", - this.loggingInterval, this.workerThreads, 20); + ChainingUserRegistrySynchronizer.logger, this.retryingTransactionHelper, this.ruleService, + this.applicationEventPublisher, sortedGroupAssociations.entrySet(), zone + + " Group Creation and Association", this.loggingInterval, this.workerThreads, 20); groupCreator.process(new Worker>>() { @@ -870,9 +872,9 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl } } final BatchProcessor personProcessor = new BatchProcessor( - this.retryingTransactionHelper, this.ruleService, this.applicationEventPublisher, userRegistry - .getPersons(lastModified), zone + " User Creation and Association", this.loggingInterval, - this.workerThreads, 10); + ChainingUserRegistrySynchronizer.logger, this.retryingTransactionHelper, this.ruleService, + this.applicationEventPublisher, userRegistry.getPersons(lastModified), zone + + " User Creation and Association", this.loggingInterval, this.workerThreads, 10); class PersonWorker implements Worker { private long latestTime; @@ -1029,8 +1031,9 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl if (allowDeletions) { BatchProcessor authorityDeletionProcessor = new BatchProcessor( - this.retryingTransactionHelper, this.ruleService, this.applicationEventPublisher, - deletionCandidates, zone + " Authority Deletion", this.loggingInterval, this.workerThreads, 10); + ChainingUserRegistrySynchronizer.logger, this.retryingTransactionHelper, this.ruleService, + this.applicationEventPublisher, deletionCandidates, zone + " Authority Deletion", + this.loggingInterval, this.workerThreads, 10); class AuthorityDeleter implements Worker { private int personProcessedCount; diff --git a/source/java/org/alfresco/repo/site/SiteServiceImpl.java b/source/java/org/alfresco/repo/site/SiteServiceImpl.java index f425908279..1710c3dab2 100644 --- a/source/java/org/alfresco/repo/site/SiteServiceImpl.java +++ b/source/java/org/alfresco/repo/site/SiteServiceImpl.java @@ -621,11 +621,10 @@ public class SiteServiceImpl implements SiteService, SiteModel siteRoot.getStoreRef(), SearchService.LANGUAGE_LUCENE, query.toString(), - params); - - result = new ArrayList(results.length()); + params); try { + result = new ArrayList(results.length()); for (NodeRef site : results.getNodeRefs()) { // Ignore any node type that is not a "site" diff --git a/source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java b/source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java index cd10e51672..4592c82f52 100644 --- a/source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java +++ b/source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java @@ -334,6 +334,7 @@ public class TaggingServiceImpl implements TaggingService, { tagNodeRef = resultSet.getNodeRef(0); } + resultSet.close(); return tagNodeRef; } @@ -621,7 +622,9 @@ public class TaggingServiceImpl implements TaggingService, storeRef, SearchService.LANGUAGE_LUCENE, "+PATH:\"/cm:taggable/cm:" + ISO9075.encode(tag) + "/member\""); - return resultSet.getNodeRefs(); + List nodeRefs = resultSet.getNodeRefs(); + resultSet.close(); + return nodeRefs; } /** @@ -641,7 +644,9 @@ public class TaggingServiceImpl implements TaggingService, storeRef, SearchService.LANGUAGE_LUCENE, "+PATH:\"" + pathString + "//*\" +PATH:\"/cm:taggable/cm:" + ISO9075.encode(tag) + "/member\""); - return resultSet.getNodeRefs(); + List nodeRefs = resultSet.getNodeRefs(); + resultSet.close(); + return nodeRefs; } /** diff --git a/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java b/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java index 67ece06469..60192f6075 100644 --- a/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java +++ b/source/java/org/alfresco/repo/tenant/MultiTDemoTest.java @@ -558,14 +558,17 @@ public class MultiTDemoTest extends TestCase cnt = cnt + 1; } + resultSet.close(); // Find all root categories resultSet = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, query); assertEquals(cnt, resultSet.length()); + resultSet.close(); String queryMembers = "PATH:\"/cm:generalclassifiable//cm:catA/member\""; resultSet = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, queryMembers); assertEquals(0, resultSet.length()); + resultSet.close(); NodeRef homeSpaceRef = getHomeSpaceFolderNode(AuthenticationUtil.getRunAsUser()); NodeRef contentRef = addContent(homeSpaceRef, "tqbfjotld.txt", "The quick brown fox jumps over the lazy dog (tenant " + tenantDomain + ")", MimetypeMap.MIMETYPE_TEXT_PLAIN); @@ -592,6 +595,7 @@ public class MultiTDemoTest extends TestCase queryMembers = "PATH:\"/cm:generalclassifiable//cm:CatA/member\""; resultSet = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, queryMembers); assertEquals(1, resultSet.length()); + resultSet.close(); } public void testCreateFolders() @@ -774,6 +778,7 @@ public class MultiTDemoTest extends TestCase assertEquals(1, resultSet.length()); NodeRef nodeRef = resultSet.getNodeRef(0); + resultSet.close(); // checkout, update and checkin @@ -792,10 +797,12 @@ public class MultiTDemoTest extends TestCase query = "+PATH:\"/app:company_home/app:dictionary/app:email_templates/app:invite_email_templates/*\" +TEXT:\""+origText+"\""; resultSet = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, query); assertEquals(0, resultSet.length()); + resultSet.close(); query = "+PATH:\"/app:company_home/app:dictionary/app:email_templates/app:invite_email_templates/*\" +TEXT:\""+updateText+"\""; resultSet = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, query); assertEquals(1, resultSet.length()); + resultSet.close(); return null; } @@ -1043,6 +1050,7 @@ public class MultiTDemoTest extends TestCase { folderNodeRef = rs.getNodeRef(0); } + rs.close(); return folderNodeRef; } diff --git a/source/java/org/alfresco/service/cmr/security/AuthenticationService.java b/source/java/org/alfresco/service/cmr/security/AuthenticationService.java index a1c7129277..c6d620db49 100644 --- a/source/java/org/alfresco/service/cmr/security/AuthenticationService.java +++ b/source/java/org/alfresco/service/cmr/security/AuthenticationService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2009 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 @@ -103,37 +103,58 @@ public interface AuthenticationService @Auditable(parameters = {"userName"}) public void invalidateUserSession(String userName) throws AuthenticationException; - /** - * Invalidate a single ticket by ID - * - * @param ticket - * @throws AuthenticationException - */ - @Auditable(parameters = {"ticket"}, recordable = {false}) - public void invalidateTicket(String ticket) throws AuthenticationException; - - /** - * Validate a ticket. Set the current user name accordingly. - * - * @param ticket - * @throws AuthenticationException - */ - @Auditable(parameters = {"ticket"}, recordable = {false}) - public void validate(String ticket) throws AuthenticationException; + /** + * Invalidate a single ticket by ID or remove its association with a given session ID. + * + * @param ticket + * @param sessionId + * the app server session ID (e.g. HttpSession ID) or null if not applicable. + * @throws AuthenticationException + */ + @Auditable(parameters = {"ticket", "sessionId"}, recordable = {false, false}) + public void invalidateTicket(String ticket, String sessionId) throws AuthenticationException; /** - * Get the current ticket as a string - * @return + * Validate a ticket and associate it with a given app server session ID. Set the current user name accordingly. + * + * @param ticket + * @param sessionId + * the app server session ID (e.g. HttpSession ID) or null if not applicable. + * @throws AuthenticationException + */ + @Auditable(parameters = {"ticket", "sessionId"}, recordable = {false, false}) + public void validate(String ticket, String sessionId) throws AuthenticationException; + + /** + * Gets the current ticket as a string. If there isn't an appropriate current ticket, a new ticket will be made the + * current ticket. + * + * @param sessionId + * the app server session ID (e.g. HttpSession ID) or null if not applicable. If non-null, + * the ticket returned is either a new one or one previously associated with the same sessionId by + * {@link #validate(String, String)} or {@link #getCurrentTicket(String)}. + * @return the current ticket as a string + */ + @Auditable(parameters = {"sessionId"}, recordable = {false}) + public String getCurrentTicket(String sessionId); + + /** + * Gets the current ticket as a string. If there isn't an appropriate current ticket, a new ticket will be made the + * current ticket. + * + * @return the current ticket as a string */ @Auditable public String getCurrentTicket(); - + /** - * Get the current ticket as a string + * Get a new ticket as a string + * @param sessionId + * the app server session ID (e.g. HttpSession ID) or null if not applicable. * @return */ - @Auditable - public String getNewTicket(); + @Auditable(parameters = {"sessionId"}, recordable = {false}) + public String getNewTicket(String sessionId); /** * Remove the current security information diff --git a/source/java/org/alfresco/service/cmr/security/MutableAuthenticationService.java b/source/java/org/alfresco/service/cmr/security/MutableAuthenticationService.java index 16f1aa7dca..a41be76188 100644 --- a/source/java/org/alfresco/service/cmr/security/MutableAuthenticationService.java +++ b/source/java/org/alfresco/service/cmr/security/MutableAuthenticationService.java @@ -43,6 +43,14 @@ public interface MutableAuthenticationService extends AuthenticationService @Auditable(parameters = {"userName"}, recordable = {true}) public boolean isAuthenticationMutable(String userName); + /** + * Determines whether authentication creation is allowed. + * + * @return true if authentication creation is allowed + */ + @Auditable + public boolean isAuthenticationCreationAllowed(); + /** * Create an authentication for the given user. * diff --git a/source/java/org/alfresco/util/RuntimeSystemPropertiesSetter.java b/source/java/org/alfresco/util/RuntimeSystemPropertiesSetter.java index ea006d65e4..e1026e32cc 100644 --- a/source/java/org/alfresco/util/RuntimeSystemPropertiesSetter.java +++ b/source/java/org/alfresco/util/RuntimeSystemPropertiesSetter.java @@ -24,6 +24,7 @@ *----------------------------------------------------------------------------*/ package org.alfresco.util; +import java.io.File; import java.util.HashMap; import java.util.Map; @@ -32,7 +33,10 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; import org.springframework.core.Ordered; +import org.springframework.core.io.support.ResourcePatternResolver; /** * Sets runtime JVM system properties for Spring Framework. @@ -46,13 +50,15 @@ import org.springframework.core.Ordered; * @author Jon Cox * @see #setProperties(Map) */ -public class RuntimeSystemPropertiesSetter implements BeanFactoryPostProcessor, Ordered +public class RuntimeSystemPropertiesSetter implements BeanFactoryPostProcessor, ApplicationContextAware, Ordered { private static Log logger = LogFactory.getLog(RuntimeSystemPropertiesSetter.class ); /** default: just before PropertyPlaceholderConfigurer */ private int order = Integer.MAX_VALUE - 1; + private ResourcePatternResolver resolver; + /** * @see #setProperties(Map) */ @@ -75,6 +81,12 @@ public class RuntimeSystemPropertiesSetter implements BeanFactoryPostProcessor, this.jvmProperties = jvmProperties; } + + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException + { + this.resolver = applicationContext; + } + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // Push any mapped properties into the JVM @@ -94,8 +106,7 @@ public class RuntimeSystemPropertiesSetter implements BeanFactoryPostProcessor, } } - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - String path=null; + File path=null; try { // Typically, the value of 'path' will be something like: @@ -109,9 +120,8 @@ public class RuntimeSystemPropertiesSetter implements BeanFactoryPostProcessor, // will be disabled later when org.alfresco.mbeans.VirtServerRegistry // refuses to bring up the serverConnector bean. - path = loader.getResource("alfresco/alfresco-jmxrmi.password").toURI().getPath(); + path = this.resolver.getResource("classpath:alfresco/alfresco-jmxrmi.password").getFile().getCanonicalFile(); } - catch (java.net.URISyntaxException e ) { e.printStackTrace(); } catch (Exception e ) { if ( logger.isWarnEnabled() ) @@ -121,8 +131,7 @@ public class RuntimeSystemPropertiesSetter implements BeanFactoryPostProcessor, if ( path == null ) { System.setProperty("alfresco.jmx.dir", ""); } else { - String alfresco_jmx_dir = - path.substring(0,path.lastIndexOf("/alfresco-jmxrmi.password")); + String alfresco_jmx_dir = path.getParent(); // The value of 'alfresco.jmx.dir' will be something like: // $TOMCAT_HOME/webapps/alfresco/WEB-INF/classes/alfresco