Merged V1.3 to HEAD (3218:3225)

svn merge svn://www.alfresco.org:3691/alfresco/BRANCHES/V1.3@3218 svn://www.alfresco.org:3691/alfresco/BRANCHES/V1.3@3225 .


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3408 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley 2006-07-26 11:03:16 +00:00
parent f4e00169ab
commit 4e18df8f63
7 changed files with 127 additions and 53 deletions

View File

@ -64,6 +64,9 @@
</property> </property>
<property name="accessCache"> <property name="accessCache">
<ref bean="permissionsAccessCache" /> <ref bean="permissionsAccessCache" />
</property>
<property name="policyComponent">
<ref bean="policyComponent" />
</property> </property>
<!-- Dynamic authorites are evaluated in the context of a store/node etc --> <!-- Dynamic authorites are evaluated in the context of a store/node etc -->
<!-- as opposed to being fixed like user name and groups. --> <!-- as opposed to being fixed like user name and groups. -->

View File

@ -91,7 +91,7 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
if ( client.isGuest()) if ( client.isGuest())
m_authComponent.setGuestUserAsCurrentUser(); m_authComponent.setGuestUserAsCurrentUser();
else else
m_authComponent.setCurrentUser(client.getUserName()); m_authComponent.setCurrentUser(mapUserNameToPerson(client.getUserName()));
// Debug // Debug
@ -229,7 +229,7 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
// Set the current user to be authenticated, save the authentication token // Set the current user to be authenticated, save the authentication token
client.setAuthenticationToken( m_authComponent.setCurrentUser(client.getUserName())); client.setAuthenticationToken( m_authComponent.setCurrentUser(mapUserNameToPerson(client.getUserName())));
// Get the users home folder node, if available // Get the users home folder node, if available

View File

@ -890,4 +890,50 @@ public abstract class CifsAuthenticator
} }
} }
/**
* Map the case insensitive logon name to the internal person object user name
*
* @param userName String
* @return String
*/
protected final String mapUserNameToPerson(String userName)
{
// Get the home folder for the user
UserTransaction tx = m_transactionService.getUserTransaction();
String personName = null;
try
{
tx.begin();
personName = m_personService.getUserIdentifier( userName);
tx.commit();
}
catch (Throwable ex)
{
try
{
tx.rollback();
}
catch (Throwable ex2)
{
logger.error("Failed to rollback transaction", ex2);
}
// Re-throw the exception
if (ex instanceof RuntimeException)
{
throw (RuntimeException) ex;
}
else
{
throw new RuntimeException("Error during execution of transaction.", ex);
}
}
// Return the person name
return personName;
}
} }

View File

@ -1106,7 +1106,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Setup the Acegi authenticated user // Setup the Acegi authenticated user
m_authComponent.setCurrentUser( krbDetails.getUserName()); m_authComponent.setCurrentUser( mapUserNameToPerson(krbDetails.getUserName()));
// Store the full user name in the client information, indicate that this is not a guest logon // Store the full user name in the client information, indicate that this is not a guest logon
@ -1236,7 +1236,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Setup the Acegi authenticated user // Setup the Acegi authenticated user
m_authComponent.setCurrentUser( userName); m_authComponent.setCurrentUser( mapUserNameToPerson(userName));
// Store the full user name in the client information, indicate that this is not a guest logon // Store the full user name in the client information, indicate that this is not a guest logon
@ -1368,7 +1368,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Setup the Acegi authenticated user // Setup the Acegi authenticated user
m_authComponent.setCurrentUser( client.getUserName()); m_authComponent.setCurrentUser( mapUserNameToPerson( client.getUserName()));
// Store the full user name in the client information, indicate that this is not a guest logon // Store the full user name in the client information, indicate that this is not a guest logon
@ -1479,7 +1479,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Setup the Acegi authenticated user // Setup the Acegi authenticated user
m_authComponent.setCurrentUser( userName); m_authComponent.setCurrentUser( mapUserNameToPerson( userName));
// Store the full user name in the client information, indicate that this is not a guest logon // Store the full user name in the client information, indicate that this is not a guest logon
@ -1602,7 +1602,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Setup the Acegi authenticated user // Setup the Acegi authenticated user
m_authComponent.setCurrentUser( client.getUserName()); m_authComponent.setCurrentUser( mapUserNameToPerson( client.getUserName()));
// Store the full user name in the client information, indicate that this is not a guest logon // Store the full user name in the client information, indicate that this is not a guest logon
@ -1765,7 +1765,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Setup the Acegi authenticated user // Setup the Acegi authenticated user
m_authComponent.setCurrentUser( userName); m_authComponent.setCurrentUser( mapUserNameToPerson( userName));
// Store the full user name in the client information, indicate that this is not a guest logon // Store the full user name in the client information, indicate that this is not a guest logon

View File

@ -125,7 +125,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
{ {
// Use the existing authentication token // Use the existing authentication token
m_authComponent.setCurrentUser(client.getUserName()); m_authComponent.setCurrentUser( mapUserNameToPerson( client.getUserName()));
// Debug // Debug
@ -220,40 +220,28 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
// Map the passthru username to an Alfresco person // Map the passthru username to an Alfresco person
String username = client.getUserName(); String username = client.getUserName();
NodeRef userNode = m_personService.getPerson( username); String personName = m_personService.getUserIdentifier( username);
if ( userNode != null) if ( personName != null)
{ {
// Get the person name and use that as the current user to line up with permission checks // Use the person name as the current user
String personName = (String) m_nodeService.getProperty(userNode, ContentModel.PROP_USERNAME);
m_authComponent.setCurrentUser(personName); m_authComponent.setCurrentUser(personName);
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled())
logger.debug("Setting current user using person " + personName + " (username " + username + ")"); logger.debug("Setting current user using person " + personName + " (username " + username + ")");
// Allow the user full access to the server
authSts = CifsAuthenticator.AUTH_ALLOW;
// Debug
if (logger.isDebugEnabled())
logger.debug("Passthru authenticate user=" + client.getUserName() + ", FULL");
} }
else
{
// Set using the user name
m_authComponent.setCurrentUser( username);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Setting current user using username " + username);
}
// Allow the user full access to the server
authSts = CifsAuthenticator.AUTH_ALLOW;
// Debug
if (logger.isDebugEnabled())
logger.debug("Passthru authenticate user=" + client.getUserName() + ", FULL");
} }
finally finally
{ {

View File

@ -61,7 +61,7 @@ public class AuthorityDAOImpl implements AuthorityDAO
private DictionaryService dictionaryService; private DictionaryService dictionaryService;
private SimpleCache<String, ArrayList<NodeRef>> userToAuthorityCache; private SimpleCache<String, HashSet<String>> userToAuthorityCache;
public AuthorityDAOImpl() public AuthorityDAOImpl()
{ {
@ -90,7 +90,7 @@ public class AuthorityDAOImpl implements AuthorityDAO
this.searchService = searchService; this.searchService = searchService;
} }
public void setUserToAuthorityCache(SimpleCache<String, ArrayList<NodeRef>> userToAuthorityCache) public void setUserToAuthorityCache(SimpleCache<String, HashSet<String>> userToAuthorityCache)
{ {
this.userToAuthorityCache = userToAuthorityCache; this.userToAuthorityCache = userToAuthorityCache;
} }
@ -127,6 +127,7 @@ public class AuthorityDAOImpl implements AuthorityDAO
} }
nodeService.addChild(parentRef, childRef, ContentModel.ASSOC_MEMBER, QName.createQName("usr", childName, nodeService.addChild(parentRef, childRef, ContentModel.ASSOC_MEMBER, QName.createQName("usr", childName,
namespacePrefixResolver)); namespacePrefixResolver));
userToAuthorityCache.clear();
} }
else else
{ {
@ -165,7 +166,7 @@ public class AuthorityDAOImpl implements AuthorityDAO
throw new UnknownAuthorityException("An authority was not found for " + name); throw new UnknownAuthorityException("An authority was not found for " + name);
} }
nodeService.deleteNode(nodeRef); nodeService.deleteNode(nodeRef);
userToAuthorityCache.clear();
} }
public Set<String> getAllRootAuthorities(AuthorityType type) public Set<String> getAllRootAuthorities(AuthorityType type)
@ -234,15 +235,31 @@ public class AuthorityDAOImpl implements AuthorityDAO
throw new UnknownAuthorityException("An authority was not found for " + childName); throw new UnknownAuthorityException("An authority was not found for " + childName);
} }
nodeService.removeChild(parentRef, childRef); nodeService.removeChild(parentRef, childRef);
userToAuthorityCache.clear();
} }
} }
public Set<String> getContainingAuthorities(AuthorityType type, String name, boolean immediate) public Set<String> getContainingAuthorities(AuthorityType type, String name, boolean immediate)
{ {
HashSet<String> authorities = new HashSet<String>(); if (AuthorityType.getAuthorityType(name).equals(AuthorityType.USER) && ! immediate && (type == null))
findAuthorities(type, name, authorities, true, !immediate); {
return authorities; // Cache user to authority look ups
HashSet<String> authorities = userToAuthorityCache.get(name);
if(authorities == null)
{
authorities = new HashSet<String>();
findAuthorities(type, name, authorities, true, !immediate);
userToAuthorityCache.put(name, authorities);
}
return authorities;
}
else
{
HashSet<String> authorities = new HashSet<String>();
findAuthorities(type, name, authorities, true, !immediate);
return authorities;
}
} }
private void findAuthorities(AuthorityType type, String name, Set<String> authorities, boolean parents, private void findAuthorities(AuthorityType type, String name, Set<String> authorities, boolean parents,
@ -276,12 +293,7 @@ public class AuthorityDAOImpl implements AuthorityDAO
private ArrayList<NodeRef> getUserContainers(String name) private ArrayList<NodeRef> getUserContainers(String name)
{ {
ArrayList<NodeRef> containers = userToAuthorityCache.get(name); ArrayList<NodeRef> containers = findUserContainers(name);
if (containers == null)
{
containers = findUserContainers(name);
userToAuthorityCache.put(name, containers);
}
return containers; return containers;
} }

View File

@ -26,7 +26,10 @@ import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.GrantedAuthority; import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.providers.dao.User; import net.sf.acegisecurity.providers.dao.User;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cache.SimpleCache; import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.permissions.DynamicAuthority; import org.alfresco.repo.security.permissions.DynamicAuthority;
import org.alfresco.repo.security.permissions.NodePermissionEntry; import org.alfresco.repo.security.permissions.NodePermissionEntry;
@ -43,6 +46,7 @@ import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper; import org.alfresco.util.EqualsHelper;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -102,6 +106,8 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
*/ */
private List<DynamicAuthority> dynamicAuthorities; private List<DynamicAuthority> dynamicAuthorities;
private PolicyComponent policyComponent;
/* /*
* Standard spring construction. * Standard spring construction.
*/ */
@ -152,13 +158,24 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
/** /**
* Set the permissions access cache. * Set the permissions access cache.
* *
* @param accessCache a transactionally safe cache * @param accessCache
* a transactionally safe cache
*/ */
public void setAccessCache(SimpleCache<Serializable, AccessStatus> accessCache) public void setAccessCache(SimpleCache<Serializable, AccessStatus> accessCache)
{ {
this.accessCache = accessCache; this.accessCache = accessCache;
} }
public void setPolicyComponent(PolicyComponent policyComponent)
{
this.policyComponent = policyComponent;
}
public void onMoveNode(ChildAssociationRef oldChildAssocRef, ChildAssociationRef newChildAssocRef)
{
accessCache.clear();
}
public void afterPropertiesSet() throws Exception public void afterPropertiesSet() throws Exception
{ {
if (dictionaryService == null) if (dictionaryService == null)
@ -189,6 +206,13 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
{ {
throw new IllegalArgumentException("Property 'accessCache' has not been set"); throw new IllegalArgumentException("Property 'accessCache' has not been set");
} }
if (policyComponent == null)
{
throw new IllegalArgumentException("Property 'policyComponent' has not been set");
}
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onMoveNode"), ContentModel.ASPECT_AUDITABLE, new JavaBehaviour(this, "onMoveNode"));
} }
// //
@ -372,7 +396,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
Set<String> authorisations = getAuthorisations(auth, nodeRef); Set<String> authorisations = getAuthorisations(auth, nodeRef);
Serializable key = generateKey( Serializable key = generateKey(
authorisations, authorisations,
nodeService.getPath(nodeRef), nodeRef,
perm); perm);
AccessStatus status = accessCache.get(key); AccessStatus status = accessCache.get(key);
if (status != null) if (status != null)
@ -423,16 +447,17 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
} }
/** /**
* Key for a cache object is built from all the known Authorities (which can change * Key for a cache object is built from all the known Authorities (which can
* dynamically so they must all be used) the NodeRef ID and the permission reference itself. * change dynamically so they must all be used) the NodeRef ID and the
* This gives a unique key for each permission test. * permission reference itself. This gives a unique key for each permission
* test.
*/ */
static Serializable generateKey(Set<String> auths, Path path, PermissionReference perm) static Serializable generateKey(Set<String> auths, NodeRef nodeRef, PermissionReference perm)
{ {
LinkedHashSet<Serializable> key = new LinkedHashSet<Serializable>(); LinkedHashSet<Serializable> key = new LinkedHashSet<Serializable>();
key.add(perm.toString()); key.add(perm.toString());
key.addAll(auths); key.addAll(auths);
key.add(path); key.add(nodeRef);
return key; return key;
} }