Merged V2.1 to HEAD

6466: Xml metadata.  Support for pulling collections of values from XML
   6470: Fix for AWC-1321 - Using zero as items per page gives error for Alfresco repos in OpenSearch
   6471: Fix for AWC-1496 - OpenSearch dashlet can get in a state where search queries are not executed
   6472: Fix for AWC-1495. Searching additional attributes now working correctly for folders.
   6473: Fix for AR-1251 (Version error when saving new content via CIFS)
   6474: Updated bundles and installers - added missing files back into Linux bundle
   6475: LDAP and chainging authentication
          Resolved conflicted state of 'root\projects\repository\source\java\org\alfresco\repo\security\authentication\AuthenticationUtil.java'
   6477: XForms WCM-696.
   6478: Fix for WCM-567 (IndexOutOfBoundsException when stepping through wizard rapidly)
   6480: Fix to issue when removing locks on directories.
   6481: Updated installer and config wizard to fix download option and config behaviour when called from installer.
   6482: Fix for WCM-1229 (properties sheet does not refresh)
   6483: Fix for AR-1511
   6484: Fix for AR-1351
   6485: Missed a unit test update


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6737 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2007-09-10 22:57:18 +00:00
parent 1f3aabc6a0
commit bcfd0ae519
31 changed files with 1179 additions and 487 deletions

View File

@@ -76,7 +76,7 @@ public class TestData
public Object execute() throws Exception
{
// Bootstrap Users
MutableAuthenticationDao authDAO = (MutableAuthenticationDao) applicationContext.getBean("alfDaoImpl");
MutableAuthenticationDao authDAO = (MutableAuthenticationDao) applicationContext.getBean("authenticationDao");
if (authDAO.userExists("superuser") == false)
{
authDAO.createUser("superuser", "".toCharArray());

View File

@@ -120,7 +120,7 @@ public class AuditServiceTest extends BaseSpringTest
authorityService = (AuthorityService) applicationContext.getBean("authorityService");
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("alfDaoImpl");
authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("authenticationDao");
auditService = (AuditService) applicationContext.getBean("AuditService");
auditEntry = (AuditEntry) applicationContext.getBean("auditModel");

View File

@@ -177,7 +177,7 @@ public class AVMSubmitPackageHandler
Map<String, AVMNodeDescriptor> list = fAVMService.getDirectoryListing(desc, true);
for (AVMNodeDescriptor child : list.values())
{
recursivelyRemoveLocks(webProject, child.getVersionID(), child.getPath());
recursivelyRemoveLocks(webProject, version, child.getPath());
}
}
}

View File

@@ -57,6 +57,8 @@ import org.alfresco.util.PropertyCheck;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* An extracter that pulls values from XML documents using configurable XPath
@@ -248,7 +250,30 @@ public class XPathMetadataExtracter extends AbstractMappingMetadataExtracter imp
String documentProperty = element.getKey();
XPathExpression xpathExpression = element.getValue();
// Execute it
String value = (String) xpathExpression.evaluate(document, XPathConstants.STRING);
NodeList nodeList = (NodeList) xpathExpression.evaluate(document, XPathConstants.NODESET);
// Convert the value
Serializable value = null;
int nodeCount = nodeList.getLength();
if (nodeCount == 0)
{
// No result
}
else if (nodeCount == 1)
{
Node node = nodeList.item(0);
// Get the string value
value = node.getTextContent();
}
else
{
// Make a collection of the values
ArrayList<String> stringValues = new ArrayList<String>(5);
for (int i = 0; i < nodeCount; i++)
{
stringValues.add(nodeList.item(i).getTextContent());
}
value = stringValues;
}
// Put the value
rawProperties.put(documentProperty, value);
}
@@ -305,7 +330,7 @@ public class XPathMetadataExtracter extends AbstractMappingMetadataExtracter imp
xpathExpressionMapping.put(documentProperty, xpathExpression);
if (logger.isDebugEnabled())
{
logger.debug("Added mapping from " + documentProperty + " to " + xpathExpression);
logger.debug("Added mapping from " + documentProperty + " to " + xpathStr);
}
}
// Done

View File

@@ -26,49 +26,65 @@ package org.alfresco.repo.ownable.impl;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.OwnableService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper;
import org.springframework.beans.factory.InitializingBean;
/**
* Ownership service support. Use in permissions framework as dynamic authority.
* Ownership service support. Use in permissions framework as dynamic authority.
*
* @author Andy Hind
*/
public class OwnableServiceImpl implements OwnableService, InitializingBean
public class OwnableServiceImpl implements OwnableService, InitializingBean, NodeServicePolicies.OnAddAspectPolicy, NodeServicePolicies.OnUpdatePropertiesPolicy,
NodeServicePolicies.OnRemoveAspectPolicy, NodeServicePolicies.OnDeleteNodePolicy
{
private NodeService nodeService;
private AuthenticationService authenticationService;
private SimpleCache<NodeRef, String> nodeOwnerCache;
private PolicyComponent policyComponent;
public OwnableServiceImpl()
{
super();
}
// IOC
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = authenticationService;
}
public void setPolicyComponent(PolicyComponent policyComponent)
{
this.policyComponent = policyComponent;
}
/**
* @param ownerCache a transactionally-safe cache of node owners
* @param ownerCache
* a transactionally-safe cache of node owners
*/
public void setNodeOwnerCache(SimpleCache<NodeRef, String> ownerCache)
{
@@ -89,14 +105,31 @@ public class OwnableServiceImpl implements OwnableService, InitializingBean
{
throw new IllegalArgumentException("Property 'nodeOwnerCache' has not been set");
}
if (policyComponent == null)
{
throw new IllegalArgumentException("Property 'policyComponent' has not been set");
}
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onAddAspect"), ContentModel.ASPECT_OWNABLE, new JavaBehaviour(this, "onAddAspect"));
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"), ContentModel.ASPECT_OWNABLE, new JavaBehaviour(this, "onUpdateProperties"));
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onRemoveAspect"), ContentModel.ASPECT_OWNABLE, new JavaBehaviour(this,
"onRemoveAspect"));
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"), ContentModel.ASPECT_OWNABLE, new JavaBehaviour(this, "onDeleteNode"));
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onAddAspect"), ContentModel.ASPECT_AUDITABLE, new JavaBehaviour(this, "onAddAspect"));
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"), ContentModel.ASPECT_AUDITABLE, new JavaBehaviour(this, "onUpdateProperties"));
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onRemoveAspect"), ContentModel.ASPECT_AUDITABLE, new JavaBehaviour(this,
"onRemoveAspect"));
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"), ContentModel.ASPECT_AUDITABLE, new JavaBehaviour(this, "onDeleteNode"));
}
// OwnableService implmentation
public String getOwner(NodeRef nodeRef)
{
String userName = nodeOwnerCache.get(nodeRef);
if (userName == null)
{
// If ownership is not explicitly set then we fall back to the creator
@@ -104,13 +137,13 @@ public class OwnableServiceImpl implements OwnableService, InitializingBean
{
userName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_OWNER));
}
else if(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_AUDITABLE))
else if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_AUDITABLE))
{
userName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_CREATOR));
}
nodeOwnerCache.put(nodeRef, userName);
}
return userName;
}
@@ -138,4 +171,41 @@ public class OwnableServiceImpl implements OwnableService, InitializingBean
{
return getOwner(nodeRef) != null;
}
public void onAddAspect(NodeRef nodeRef, QName aspectTypeQName)
{
nodeOwnerCache.remove(nodeRef);
}
public void onRemoveAspect(NodeRef nodeRef, QName aspectTypeQName)
{
nodeOwnerCache.remove(nodeRef);
}
public void onDeleteNode(ChildAssociationRef childAssocRef, boolean isNodeArchived)
{
nodeOwnerCache.remove(childAssocRef.getChildRef());
}
public void onUpdateProperties(NodeRef nodeRef, Map<QName, Serializable> before, Map<QName, Serializable> after)
{
Serializable pb = before.get(ContentModel.PROP_OWNER);
Serializable pa = after.get(ContentModel.PROP_OWNER);
if (!EqualsHelper.nullSafeEquals(pb, pa))
{
nodeOwnerCache.remove(nodeRef);
return;
}
pb = before.get(ContentModel.PROP_CREATOR);
pa = after.get(ContentModel.PROP_CREATOR);
if (!EqualsHelper.nullSafeEquals(pb, pa))
{
nodeOwnerCache.remove(nodeRef);
return;
}
}
}

View File

@@ -24,6 +24,9 @@
*/
package org.alfresco.repo.ownable.impl;
import java.io.Serializable;
import java.util.HashMap;
import javax.transaction.UserTransaction;
import junit.framework.TestCase;
@@ -40,6 +43,7 @@ import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.OwnableService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.springframework.context.ApplicationContext;
@@ -85,7 +89,7 @@ public class OwnableServiceTest extends TestCase
permissionService = (PermissionService) ctx.getBean("permissionService");
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("authenticationDao");
TransactionService transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE.getLocalName());
@@ -147,6 +151,14 @@ public class OwnableServiceTest extends TestCase
assertFalse(nodeService.hasAspect(testNode, ContentModel.ASPECT_OWNABLE));
assertTrue(dynamicAuthority.hasAuthority(testNode, "andy"));
assertEquals("andy", ownableService.getOwner(testNode));
nodeService.setProperty(testNode, ContentModel.PROP_CREATOR, "woof");
assertEquals("woof", ownableService.getOwner(testNode));
nodeService.setProperty(testNode, ContentModel.PROP_CREATOR, "andy");
assertEquals("andy", ownableService.getOwner(testNode));
permissionService.setInheritParentPermissions(testNode, false);
@@ -189,6 +201,16 @@ public class OwnableServiceTest extends TestCase
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.TAKE_OWNERSHIP));
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.SET_OWNER));
nodeService.setProperty(testNode, ContentModel.PROP_OWNER, "muppet");
assertEquals("muppet", ownableService.getOwner(testNode));
nodeService.removeAspect(testNode, ContentModel.ASPECT_OWNABLE);
assertEquals("andy", ownableService.getOwner(testNode));
HashMap<QName, Serializable> aspectProperties = new HashMap<QName, Serializable>();
aspectProperties.put(ContentModel.PROP_OWNER, "muppet");
nodeService.addAspect(testNode, ContentModel.ASPECT_OWNABLE, aspectProperties);
assertEquals("muppet", ownableService.getOwner(testNode));
}

View File

@@ -26,9 +26,12 @@ package org.alfresco.repo.rule.ruletrigger;
import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.ContentServicePolicies;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -87,9 +90,24 @@ public class OnContentUpdateRuleTrigger extends RuleTriggerAbstractBase
*/
public void onContentUpdate(NodeRef nodeRef, boolean newContent)
{
if (newContent == this.onNewContent)
// Check the new content and make sure that we do indeed want to trigger the rule
boolean fail = false;
if (newContent == true)
{
ContentReader contentReader = this.contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
if (contentReader == null ||
contentReader.exists() == false ||
isZeroLengthOfficeDoc(contentReader) == true)
{
fail = true;
}
}
// Trigger the rules in the appropriate way
if (fail == false && newContent == this.onNewContent)
{
if (triggerParentRules == true)
if (triggerParentRules == true)
{
if (logger.isDebugEnabled() == true)
{
@@ -108,5 +126,24 @@ public class OnContentUpdateRuleTrigger extends RuleTriggerAbstractBase
}
}
}
/**
* Indicates whether we are dealing with a zero length office document or not
*
* @param contentReader the content reader
* @return boolean true if zero length office document, false otherwise
*/
private boolean isZeroLengthOfficeDoc(ContentReader contentReader)
{
boolean result = false;
if (contentReader.getSize() == 0 &&
(MimetypeMap.MIMETYPE_WORD.equals(contentReader.getMimetype()) == true ||
MimetypeMap.MIMETYPE_EXCEL.equals(contentReader.getMimetype()) == true ||
MimetypeMap.MIMETYPE_PPT.equals(contentReader.getMimetype()) == true))
{
result = true;
}
return result;
}
}

View File

@@ -30,12 +30,13 @@ import java.util.Set;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.rule.RuleType;
/**
* Rule trigger abstract base
* Rule trigger abstract base
*
* @author Roy Wetherall
*/
@@ -55,6 +56,11 @@ public abstract class RuleTriggerAbstractBase implements RuleTrigger
* The node service
*/
protected NodeService nodeService;
/**
* The content service
*/
protected ContentService contentService;
/**
* The authentication Component
@@ -91,6 +97,16 @@ public abstract class RuleTriggerAbstractBase implements RuleTrigger
{
this.nodeService = nodeService;
}
/**
* Set the content service
*
* @param contentService the content service
*/
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
/**
* Set the authenticationComponent
@@ -123,6 +139,7 @@ public abstract class RuleTriggerAbstractBase implements RuleTrigger
/**
* Registration of an interested rule type
*
*/
public void registerRuleType(RuleType ruleType)
{
@@ -131,7 +148,7 @@ public abstract class RuleTriggerAbstractBase implements RuleTrigger
/**
* Trigger the rules that relate to any interested rule types for the node
* references passed.
* references passed.
*
* @param nodeRef
* the node reference who rules are to be triggered

View File

@@ -98,7 +98,7 @@ public class SearchServiceTest extends TestCase
nodeService = (NodeService) ctx.getBean("dbNodeService");
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
authenticationService = (AuthenticationService) ctx.getBean("authenticationService");
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("authenticationDao");
pubSearchService = (SearchService) ctx.getBean("SearchService");
pubPermissionService = (PermissionService) ctx.getBean("PermissionService");

View File

@@ -28,10 +28,6 @@ import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.context.Context;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import net.sf.acegisecurity.providers.dao.User;
@@ -46,11 +42,9 @@ import org.alfresco.service.cmr.security.PermissionService;
*/
public abstract class AbstractAuthenticationComponent implements AuthenticationComponent
{
// Name of the system user
static final String SYSTEM_USER_NAME = "System";
/**
* The abstract class keeps track of support for guest login
*/
private Boolean allowGuestLogin = null;
public AbstractAuthenticationComponent()
@@ -58,6 +52,11 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
super();
}
/**
* Set if guest login is supported.
*
* @param allowGuestLogin
*/
public void setAllowGuestLogin(Boolean allowGuestLogin)
{
this.allowGuestLogin = allowGuestLogin;
@@ -65,6 +64,7 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
public void authenticate(String userName, char[] password) throws AuthenticationException
{
// Support guest login from the login screen
if ((userName != null) && (userName.equalsIgnoreCase(PermissionService.GUEST_AUTHORITY)))
{
setGuestUserAsCurrentUser();
@@ -75,6 +75,14 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
}
}
/**
* Default unsupported authentication implementation
* - as of 2.1 this is the best way to implement your own authentication component as it will support guest login
* - prior to this direct over ride for authenticate(String , char[]) was used. This will still work.
*
* @param userName
* @param password
*/
protected void authenticateImpl(String userName, char[] password)
{
throw new UnsupportedOperationException();
@@ -97,11 +105,11 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
try
{
UserDetails ud = null;
if (userName.equals(SYSTEM_USER_NAME))
if (userName.equals(AuthenticationUtil.SYSTEM_USER_NAME))
{
GrantedAuthority[] gas = new GrantedAuthority[1];
gas[0] = new GrantedAuthorityImpl("ROLE_SYSTEM");
ud = new User(SYSTEM_USER_NAME, "", true, true, true, true, gas);
ud = new User(AuthenticationUtil.SYSTEM_USER_NAME, "", true, true, true, true, gas);
}
else if (userName.equalsIgnoreCase(PermissionService.GUEST_AUTHORITY))
{
@@ -173,28 +181,6 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
return AuthenticationUtil.getCurrentUserName();
}
/**
* Get the current user name
*
* @param authentication
* Authentication
* @return String
*/
private String getUserName(Authentication authentication)
{
String username;
if (authentication.getPrincipal() instanceof UserDetails)
{
username = ((UserDetails) authentication.getPrincipal()).getUsername();
}
else
{
username = authentication.getPrincipal().toString();
}
return username;
}
/**
* Set the system user as the current user.
*
@@ -202,7 +188,7 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
*/
public Authentication setSystemUserAsCurrentUser()
{
return setCurrentUser(SYSTEM_USER_NAME);
return setCurrentUser(AuthenticationUtil.SYSTEM_USER_NAME);
}
/**
@@ -212,7 +198,7 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
*/
public String getSystemUserName()
{
return SYSTEM_USER_NAME;
return AuthenticationUtil.SYSTEM_USER_NAME;
}
/**

View File

@@ -135,7 +135,7 @@ public class AuthenticationTest extends TestCase
// ctx.getBean("permissionService");
ticketsCache = (SimpleCache<String, Ticket>) ctx.getBean("ticketsCache");
dao = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
dao = (MutableAuthenticationDao) ctx.getBean("authenticationDao");
authenticationManager = (AuthenticationManager) ctx.getBean("authenticationManager");
saltSource = (SaltSource) ctx.getBean("saltSource");

View File

@@ -231,7 +231,6 @@ public abstract class AuthenticationUtil
private static String getUserName(Authentication authentication)
{
String username;
if (authentication.getPrincipal() instanceof UserDetails)
{
username = ((UserDetails) authentication.getPrincipal()).getUsername();

View File

@@ -0,0 +1,400 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.security.authentication;
import java.util.ArrayList;
import java.util.List;
import net.sf.acegisecurity.Authentication;
import org.alfresco.service.cmr.security.PermissionService;
/**
* A chaining authentication component is required for all the beans that qire up an authentication component and not an
* authentication service. It supports chaining in much the same way and wires up components in the same way asthe
* chaining authentication service wires up services.
*
* @author andyh
*/
public class ChainingAuthenticationComponentImpl implements AuthenticationComponent
{
/**
* NLTM authentication mode - if unset - finds the first component that supports NTLM - if set - finds the first
* component that supports the specified mode.
*/
private NTLMMode ntlmMode = null;
/**
* The authentication components
*/
private List<AuthenticationComponent> authenticationComponents;
/**
* An authentication service that supports change (as wired in to the authentication service). It is never used for
* change it is to ensure it is at the top of the list (as required by the chaining authentication service)
*/
private AuthenticationComponent mutableAuthenticationComponent;
/**
* Get the authentication components
*
* @return - a list of authentication components
*/
public List<AuthenticationComponent> getAuthenticationComponents()
{
return authenticationComponents;
}
/**
* Set a list of authentication components
*
* @param authenticationComponents
*/
public void setAuthenticationComponents(List<AuthenticationComponent> authenticationComponents)
{
this.authenticationComponents = authenticationComponents;
}
/**
* Get the authentication service thta must be at the top of the list (this may be null)
*
* @return
*/
public AuthenticationComponent getMutableAuthenticationComponent()
{
return mutableAuthenticationComponent;
}
/**
* Set the authentication component at the top of the list.
*
* @param mutableAuthenticationComponent
*/
public void setMutableAuthenticationComponent(AuthenticationComponent mutableAuthenticationComponent)
{
this.mutableAuthenticationComponent = mutableAuthenticationComponent;
}
public void setNtlmMode(NTLMMode ntlmMode)
{
this.ntlmMode = ntlmMode;
}
/**
* Chain authentication with user name and password - tries all in order until one works, or fails.
*/
public void authenticate(String userName, char[] password) throws AuthenticationException
{
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
{
try
{
authComponent.authenticate(userName, password);
return;
}
catch (AuthenticationException e)
{
// Ignore and chain
}
}
throw new AuthenticationException("Failed to authenticate");
}
/**
* NTLM passthrough authentication - if a mode is defined - the first PASS_THROUGH provider is used - if not, the
* first component that supports NTLM is used if it supports PASS_THROUGH
*/
public Authentication authenticate(Authentication token) throws AuthenticationException
{
if (ntlmMode != null)
{
switch (ntlmMode)
{
case NONE:
throw new AuthenticationException("NTLM is not supported");
case MD4_PROVIDER:
throw new AuthenticationException("NTLM passthrough is not supported then configured for MD4 hashing");
case PASS_THROUGH:
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
{
if (authComponent.getNTLMMode() == NTLMMode.PASS_THROUGH)
{
return authComponent.authenticate(token);
}
}
throw new AuthenticationException("No NTLM passthrough authentication to use");
default:
throw new AuthenticationException("No NTLM passthrough authentication to use");
}
}
else
{
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
{
if (authComponent.getNTLMMode() != NTLMMode.NONE)
{
if (authComponent.getNTLMMode() == NTLMMode.PASS_THROUGH)
{
return authComponent.authenticate(token);
}
else
{
throw new AuthenticationException("The first authentication component to support NTLM supports MD4 hashing");
}
}
}
throw new AuthenticationException("No NTLM passthrough authentication to use");
}
}
/**
* Clear the security context
*/
public void clearCurrentSecurityContext()
{
AuthenticationUtil.clearCurrentSecurityContext();
}
/**
* Get the current authentication
*/
public Authentication getCurrentAuthentication() throws AuthenticationException
{
return AuthenticationUtil.getCurrentAuthentication();
}
/**
* Get the current user name
*/
public String getCurrentUserName() throws AuthenticationException
{
return AuthenticationUtil.getCurrentUserName();
}
/**
* Get the guest user name
*/
public String getGuestUserName()
{
return PermissionService.GUEST_AUTHORITY.toLowerCase();
}
/**
* Get the MD4 password hash
*/
public String getMD4HashedPassword(String userName)
{
if (ntlmMode != null)
{
switch (ntlmMode)
{
case NONE:
throw new AuthenticationException("NTLM is not supported");
case PASS_THROUGH:
throw new AuthenticationException("NTLM passthrough is not supported then configured for MD4 hashing");
case MD4_PROVIDER:
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
{
if (authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
{
return authComponent.getMD4HashedPassword(userName);
}
}
throw new AuthenticationException("No MD4 provider available");
default:
throw new AuthenticationException("No MD4 provider available");
}
}
else
{
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
{
if (authComponent.getNTLMMode() != NTLMMode.NONE)
{
if (authComponent.getNTLMMode() == NTLMMode.PASS_THROUGH)
{
throw new AuthenticationException("The first authentication component to support NTLM supports passthrough");
}
else
{
return authComponent.getMD4HashedPassword(userName);
}
}
}
throw new AuthenticationException("No MD4 provider available");
}
}
/**
* Get the NTLM mode - this is only what is set if one of the implementations provides support for that mode.
*/
public NTLMMode getNTLMMode()
{
if (ntlmMode != null)
{
switch (ntlmMode)
{
case NONE:
return NTLMMode.NONE;
case PASS_THROUGH:
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
{
if (authComponent.getNTLMMode() == NTLMMode.PASS_THROUGH)
{
return NTLMMode.PASS_THROUGH;
}
}
return NTLMMode.NONE;
case MD4_PROVIDER:
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
{
if (authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
{
return NTLMMode.MD4_PROVIDER;
}
}
return NTLMMode.NONE;
default:
return NTLMMode.NONE;
}
}
else
{
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
{
if (authComponent.getNTLMMode() != NTLMMode.NONE)
{
return authComponent.getNTLMMode();
}
}
return NTLMMode.NONE;
}
}
/**
* Get the system user name
*/
public String getSystemUserName()
{
return AuthenticationUtil.SYSTEM_USER_NAME;
}
/**
* If any implementation supoprts guest then huest is allowed
*/
public boolean guestUserAuthenticationAllowed()
{
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
{
if (authComponent.guestUserAuthenticationAllowed())
{
return true;
}
}
return false;
}
/**
* Ste the current authentication
*/
public Authentication setCurrentAuthentication(Authentication authentication)
{
return AuthenticationUtil.setCurrentAuthentication(authentication);
}
/**
* Set the current user - try all implementations - as some may check the user exists
*/
public Authentication setCurrentUser(String userName)
{
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
{
try
{
return authComponent.setCurrentUser(userName);
}
catch (AuthenticationException e)
{
// Ignore and chain
}
}
throw new AuthenticationException("Failed to set current user " + userName);
}
/**
* Authenticate as guest - try all in the cahin
*/
public Authentication setGuestUserAsCurrentUser()
{
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
{
try
{
return authComponent.setGuestUserAsCurrentUser();
}
catch (AuthenticationException e)
{
// Ignore and chain
}
}
throw new AuthenticationException("Guest authentication is not allowed");
}
/**
* Set the system user
*/
public Authentication setSystemUserAsCurrentUser()
{
return setCurrentUser(getSystemUserName());
}
/**
* Helper to get authentication components
*
* @return
*/
private List<AuthenticationComponent> getUsableAuthenticationComponents()
{
if (mutableAuthenticationComponent == null)
{
return authenticationComponents;
}
else
{
ArrayList<AuthenticationComponent> services = new ArrayList<AuthenticationComponent>(authenticationComponents == null ? 1 : (authenticationComponents.size() + 1));
services.add(mutableAuthenticationComponent);
if (authenticationComponents != null)
{
services.addAll(authenticationComponents);
}
return services;
}
}
}

View File

@@ -72,7 +72,7 @@ public class SimpleAuthorityServiceTest extends TestCase
authorityService = (AuthorityService) ctx.getBean("authorityService");
pubAuthorityService = (AuthorityService) ctx.getBean("AuthorityService");
personService = (PersonService) ctx.getBean("personService");
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("authenticationDao");
this.authenticationComponent.setSystemUserAsCurrentUser();

View File

@@ -90,7 +90,7 @@ public class LockOwnerDynamicAuthorityTest extends TestCase
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
lockService = (LockService) ctx.getBean("lockService");
permissionService = (PermissionService) ctx.getBean("permissionService");
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("authenticationDao");
checkOutCheckInService = (CheckOutCheckInService) ctx.getBean("checkOutCheckInService");
ownableService = (OwnableService) ctx.getBean("ownableService");

View File

@@ -102,7 +102,7 @@ public class AbstractPermissionTest extends BaseSpringTest
authorityService = (AuthorityService) applicationContext.getBean("authorityService");
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("alfDaoImpl");
authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("authenticationDao");
StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.nanoTime());

View File

@@ -70,8 +70,8 @@ import org.springframework.beans.factory.InitializingBean;
public class PermissionServiceImpl implements PermissionServiceSPI, InitializingBean
{
static SimplePermissionReference OLD_ALL_PERMISSIONS_REFERENCE = new SimplePermissionReference(QName.createQName(
"", PermissionService.ALL_PERMISSIONS), PermissionService.ALL_PERMISSIONS);
static SimplePermissionReference OLD_ALL_PERMISSIONS_REFERENCE = new SimplePermissionReference(QName.createQName("", PermissionService.ALL_PERMISSIONS),
PermissionService.ALL_PERMISSIONS);
private static Log log = LogFactory.getLog(PermissionServiceImpl.class);
@@ -228,8 +228,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
throw new IllegalArgumentException("Property 'policyComponent' has not been set");
}
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onMoveNode"),
ContentModel.TYPE_BASE, new JavaBehaviour(this, "onMoveNode"));
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onMoveNode"), ContentModel.TYPE_BASE, new JavaBehaviour(this, "onMoveNode"));
}
@@ -263,8 +262,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
NodePermissionEntry nodePremissionEntry = getSetPermissions(nodeRef);
for (PermissionEntry pe : nodePremissionEntry.getPermissionEntries())
{
accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe
.getAccessStatus(), pe.getAuthority()));
accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe.getAccessStatus(), pe.getAuthority()));
}
return accessPermissions;
}
@@ -390,8 +388,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
if (log.isDebugEnabled())
{
log.debug("Permission <"
+ perm + "> is " + (result ? "allowed" : "denied") + " for "
+ authenticationComponent.getCurrentUserName() + " on node " + nodeService.getPath(nodeRef));
+ perm + "> is " + (result ? "allowed" : "denied") + " for " + authenticationComponent.getCurrentUserName() + " on node " + nodeService.getPath(nodeRef));
}
status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED;
@@ -649,21 +646,16 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
// Set the required node permissions
if (required.equals(getPermissionReference(ALL_PERMISSIONS)))
{
nodeRequirements = modelDAO.getRequiredPermissions(
getPermissionReference(PermissionService.FULL_CONTROL), typeQName, aspectQNames,
RequiredPermission.On.NODE);
nodeRequirements = modelDAO.getRequiredPermissions(getPermissionReference(PermissionService.FULL_CONTROL), typeQName, aspectQNames, RequiredPermission.On.NODE);
}
else
{
nodeRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames,
RequiredPermission.On.NODE);
nodeRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.NODE);
}
parentRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames,
RequiredPermission.On.PARENT);
parentRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.PARENT);
childrenRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames,
RequiredPermission.On.CHILDREN);
childrenRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.CHILDREN);
// Find all the permissions that grant the allowed permission
// All permissions are treated specially.
@@ -695,8 +687,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
* @param recursiveIn
* @return
*/
boolean evaluate(Set<String> authorisations, NodeRef nodeRef, Set<Pair<String, PermissionReference>> denied,
MutableBoolean recursiveIn)
boolean evaluate(Set<String> authorisations, NodeRef nodeRef, Set<Pair<String, PermissionReference>> denied, MutableBoolean recursiveIn)
{
// Do we defer our required test to a parent (yes if not null)
MutableBoolean recursiveOut = null;
@@ -771,8 +762,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
if (pr.equals(required))
{
// Recursive permission
success &= this.evaluate(authorisations, car.getParentRef(), locallyDenied,
recursiveOut);
success &= this.evaluate(authorisations, car.getParentRef(), locallyDenied, recursiveOut);
if ((recursiveOut != null) && recursiveOut.getValue())
{
if (recursiveIn != null)
@@ -848,8 +838,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
}
public boolean hasSinglePermission(Set<String> authorisations, NodeRef nodeRef,
Set<Pair<String, PermissionReference>> denied)
public boolean hasSinglePermission(Set<String> authorisations, NodeRef nodeRef, Set<Pair<String, PermissionReference>> denied)
{
nodeRef = tenantService.getName(nodeRef);
@@ -974,8 +963,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
// All the sets that grant this permission must be
// denied
// Note that granters includes the orginal permission
Set<PermissionReference> granters = modelDAO
.getGrantingPermissions(pe.getPermissionReference());
Set<PermissionReference> granters = modelDAO.getGrantingPermissions(pe.getPermissionReference());
for (PermissionReference granter : granters)
{
deniedSet.add(new Pair<String, PermissionReference>(pe.getAuthority(), granter));
@@ -991,8 +979,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
// All permission excludes all permissions available for
// the node.
if (pe.getPermissionReference().equals(getAllPermissionReference())
|| pe.getPermissionReference().equals(OLD_ALL_PERMISSIONS_REFERENCE))
if (pe.getPermissionReference().equals(getAllPermissionReference()) || pe.getPermissionReference().equals(OLD_ALL_PERMISSIONS_REFERENCE))
{
for (PermissionReference deny : modelDAO.getAllPermissions(nodeRef))
{
@@ -1048,8 +1035,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
* the set of denied permissions/authority pais
* @return
*/
private boolean isGranted(PermissionEntry pe, Set<String> authorisations,
Set<Pair<String, PermissionReference>> denied)
private boolean isGranted(PermissionEntry pe, Set<String> authorisations, Set<Pair<String, PermissionReference>> denied)
{
// If the permission entry denies then we just deny
if (pe.isDenied())
@@ -1059,16 +1045,41 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
// The permission is allowed but we deny it as it is in the denied
// set
if (denied != null)
{
Pair<String, PermissionReference> specific = new Pair<String, PermissionReference>(pe.getAuthority(),
required);
Pair<String, PermissionReference> specific = new Pair<String, PermissionReference>(pe.getAuthority(), required);
if (denied.contains(specific))
{
return false;
}
}
// any deny denies
if (false)
{
if (denied != null)
{
for (String auth : authorisations)
{
Pair<String, PermissionReference> specific = new Pair<String, PermissionReference>(auth, required);
if (denied.contains(specific))
{
return false;
}
for (PermissionReference perm : granters)
{
specific = new Pair<String, PermissionReference>(auth, perm);
if (denied.contains(specific))
{
return false;
}
}
}
}
}
// If the permission has a match in both the authorities and
// granters list it is allowed
// It applies to the current user and it is granted
@@ -1124,8 +1135,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return false;
}
Pair other = (Pair) o;
return EqualsHelper.nullSafeEquals(this.getA(), other.getA())
&& EqualsHelper.nullSafeEquals(this.getB(), other.getB());
return EqualsHelper.nullSafeEquals(this.getA(), other.getA()) && EqualsHelper.nullSafeEquals(this.getB(), other.getB());
}
@Override
@@ -1167,15 +1177,13 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return permissionsDaoComponent.getAllSetPermissions(authority);
}
public Set<NodeRef> findNodesByAssignedPermissionForCurrentUser(String permission, boolean allow, boolean includeContainingAuthorities,
boolean exactPermissionMatch)
public Set<NodeRef> findNodesByAssignedPermissionForCurrentUser(String permission, boolean allow, boolean includeContainingAuthorities, boolean exactPermissionMatch)
{
String currentUser = authenticationComponent.getCurrentUserName();
return findNodesByAssignedPermission(currentUser, permission, allow, includeContainingAuthorities, exactPermissionMatch);
}
public Set<NodeRef> findNodesByAssignedPermission(String authority, String permission, boolean allow,
boolean includeContainingAuthorities, boolean includeContainingPermissions)
public Set<NodeRef> findNodesByAssignedPermission(String authority, String permission, boolean allow, boolean includeContainingAuthorities, boolean includeContainingPermissions)
{
// TODO: owned nodes and add owner rights ??
// Does not include dynamic permissions (they would have to be done by query - e.g. owership and OWNER rights)

View File

@@ -149,7 +149,7 @@ public abstract class BaseVersionStoreTest extends BaseSpringTest
this.authenticationService = (AuthenticationService)applicationContext.getBean("authenticationService");
this.transactionService = (TransactionService)this.applicationContext.getBean("transactionComponent");
this.txnHelper = (RetryingTransactionHelper) applicationContext.getBean("retryingTransactionHelper");
this.authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("alfDaoImpl");
this.authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("authenticationDao");
this.nodeArchiveService = (NodeArchiveService) applicationContext.getBean("nodeArchiveService");
this.nodeService = (NodeService)applicationContext.getBean("nodeService");