diff --git a/config/alfresco/avm-services-context.xml b/config/alfresco/avm-services-context.xml index a2661bf497..3a53a08fbd 100644 --- a/config/alfresco/avm-services-context.xml +++ b/config/alfresco/avm-services-context.xml @@ -322,6 +322,12 @@ + + + + + + diff --git a/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceImpl.java b/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceImpl.java index 5eef20f6ba..907b0c0b47 100644 --- a/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceImpl.java +++ b/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceImpl.java @@ -28,6 +28,7 @@ package org.alfresco.repo.avm.locking; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Set; import org.alfresco.repo.attributes.Attribute; import org.alfresco.repo.attributes.ListAttributeValue; @@ -41,6 +42,9 @@ import org.alfresco.service.cmr.avm.AVMExistsException; import org.alfresco.service.cmr.avm.AVMNotFoundException; import org.alfresco.service.cmr.avm.locking.AVMLock; import org.alfresco.service.cmr.avm.locking.AVMLockingService; +import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.service.cmr.security.AuthorityType; +import org.alfresco.service.cmr.security.PersonService; import org.alfresco.util.MD5; import org.alfresco.util.Pair; @@ -60,6 +64,16 @@ public class AVMLockingServiceImpl implements AVMLockingService */ private AttributeService fAttributeService; + /** + * AuthorityService reference. + */ + private AuthorityService fAuthorityService; + + /** + * PersonService reference. + */ + private PersonService fPersonService; + /** * Transaction Helper reference. */ @@ -78,6 +92,24 @@ public class AVMLockingServiceImpl implements AVMLockingService fAttributeService = service; } + /** + * Set the authority service reference. + * @param service + */ + public void setAuthorityService(AuthorityService service) + { + fAuthorityService = service; + } + + /** + * Set the person service reference. + * @param service + */ + public void setPersonService(PersonService service) + { + fPersonService = service; + } + /** * Setter for RetryingTransactionHelper reference. * @param helper @@ -175,6 +207,14 @@ public class AVMLockingServiceImpl implements AVMLockingService */ public void lockPath(AVMLock lock) { + for (String authority : lock.getOwners()) + { + if (fPersonService.getPerson(authority) == null && + !fAuthorityService.authorityExists(authority)) + { + throw new AVMBadArgumentException("Not an Authority: " + authority); + } + } List keys = new ArrayList(); Attribute lockData = lock.getAttribute(); keys.add(LOCK_TABLE); @@ -426,6 +466,11 @@ public class AVMLockingServiceImpl implements AVMLockingService { for (String user : usersToAdd) { + if (fPersonService.getPerson(user) == null && + !fAuthorityService.authorityExists(user)) + { + throw new AVMBadArgumentException("Not an authority: " + user); + } if (lock.getOwners().contains(user)) { continue; @@ -458,16 +503,22 @@ public class AVMLockingServiceImpl implements AVMLockingService } /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.locking.AVMLockingService#motherMayI(java.lang.String, java.lang.String) + * @see org.alfresco.service.cmr.avm.locking.AVMLockingService#hasAccess(java.lang.String, java.lang.String) */ - public boolean motherMayI(String webProject, String avmPath, String user) + public boolean hasAccess(String webProject, String avmPath, String user) { + if (fPersonService.getPerson(user) == null && + !fAuthorityService.authorityExists(user)) + { + return false; + } String[] storePath = avmPath.split(":"); if (storePath.length != 2) { throw new AVMBadArgumentException("Malformed AVM Path : " + avmPath); } - AVMLock lock = getLock(webProject, storePath[1]); + String path = normalizePath(storePath[1]); + AVMLock lock = getLock(webProject, path); if (lock == null) { return true; @@ -476,14 +527,46 @@ public class AVMLockingServiceImpl implements AVMLockingService { return false; } - List owners = lock.getOwners(); - if (owners.contains(user)) + // TODO is this meaningful? I don't think so. + if (AuthorityType.getAuthorityType(user) == AuthorityType.ADMIN) { return true; } - // TODO Figure out how the users, groups, roles mess works and give an answer - // based on that. Our entire access control and user, group, role approach - // is apalling and needs to be replaced. + List owners = lock.getOwners(); + for (String owner : owners) + { + if (AuthorityType.getAuthorityType(owner) == AuthorityType.EVERYONE) + { + return true; + } + if (checkAgainstAuthority(user, owner)) + { + return true; + } + } + return false; + } + + /** + * Helper function that checks the transitive closure of authorities for user. + * @param user + * @param authority + * @return + */ + private boolean checkAgainstAuthority(String user, String authority) + { + if (user.equalsIgnoreCase(authority)) + { + return true; + } + Set containing = fAuthorityService.getContainingAuthorities(null, user, false); + for (String parent : containing) + { + if (parent.equalsIgnoreCase(authority)) + { + return true; + } + } return false; } } diff --git a/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceTest.java b/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceTest.java index 13cc8e37bf..3036d09554 100644 --- a/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceTest.java +++ b/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceTest.java @@ -25,12 +25,24 @@ package org.alfresco.repo.avm.locking; +import java.io.Serializable; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Set; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.security.authentication.AuthenticationComponent; +import org.alfresco.repo.security.authentication.AuthenticationComponentImpl; import org.alfresco.service.cmr.attributes.AttributeService; import org.alfresco.service.cmr.avm.locking.AVMLock; import org.alfresco.service.cmr.avm.locking.AVMLockingService; +import org.alfresco.service.cmr.security.AuthenticationService; +import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.service.cmr.security.AuthorityType; +import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.service.namespace.QName; import org.springframework.context.support.FileSystemXmlApplicationContext; import junit.framework.TestCase; @@ -47,6 +59,14 @@ public class AVMLockingServiceTest extends TestCase private static AttributeService fAttributeService; + private static PersonService fPersonService; + + private static AuthorityService fAuthorityService; + + private static AuthenticationService fAuthenticationService; + + private static AuthenticationComponent fAuthenticationComponent; + /* (non-Javadoc) * @see junit.framework.TestCase#setUp() */ @@ -58,7 +78,32 @@ public class AVMLockingServiceTest extends TestCase fContext = new FileSystemXmlApplicationContext("config/alfresco/application-context.xml"); fService = (AVMLockingService)fContext.getBean("AVMLockingService"); fAttributeService = (AttributeService)fContext.getBean("AttributeService"); + fPersonService = (PersonService)fContext.getBean("PersonService"); + fAuthorityService = (AuthorityService)fContext.getBean("AuthorityService"); + fAuthenticationService = (AuthenticationService)fContext.getBean("AuthenticationService"); + fAuthenticationComponent = (AuthenticationComponent)fContext.getBean("AuthenticationComponent"); + fAuthenticationComponent.setSystemUserAsCurrentUser(); } + // Set up sample users groups and roles. + fAuthenticationService.createAuthentication("Buffy", "Buffy".toCharArray()); + fPersonService.getPerson("Buffy"); + fAuthorityService.createAuthority(AuthorityType.GROUP, null, "Scoobies"); + fAuthorityService.addAuthority("GROUP_Scoobies", "Buffy"); + fAuthorityService.createAuthority(AuthorityType.ROLE, null, "SUPER_POWERED"); + fAuthorityService.addAuthority("ROLE_SUPER_POWERED", "Buffy"); + fAuthenticationService.createAuthentication("Willow", "Willow".toCharArray()); + fPersonService.getPerson("Willow"); + fAuthorityService.addAuthority("GROUP_Scoobies", "Willow"); + fAuthenticationService.createAuthentication("Xander", "Xander".toCharArray()); + fPersonService.getPerson("Xander"); + fAuthorityService.addAuthority("GROUP_Scoobies", "Xander"); + fAuthenticationService.createAuthentication("Tara", "Tara".toCharArray()); + fPersonService.getPerson("Tara"); + fAuthenticationService.createAuthentication("Spike", "Spike".toCharArray()); + fPersonService.getPerson("Spike"); + fAuthorityService.addAuthority("ROLE_SUPER_POWERED", "Spike"); + fAuthorityService.createAuthority(AuthorityType.GROUP, null, "vampires"); + fAuthorityService.addAuthority("GROUP_vampires", "Spike"); } /* (non-Javadoc) @@ -72,6 +117,19 @@ public class AVMLockingServiceTest extends TestCase { fAttributeService.removeAttribute("", key); } + fAuthenticationService.deleteAuthentication("Buffy"); + fAuthenticationService.deleteAuthentication("Willow"); + fAuthenticationService.deleteAuthentication("Xander"); + fAuthenticationService.deleteAuthentication("Tara"); + fAuthenticationService.deleteAuthentication("Spike"); + fPersonService.deletePerson("Buffy"); + fPersonService.deletePerson("Willow"); + fPersonService.deletePerson("Tara"); + fPersonService.deletePerson("Xander"); + fPersonService.deletePerson("Spike"); + fAuthorityService.deleteAuthority("GROUP_Scoobies"); + fAuthorityService.deleteAuthority("ROLE_SUPER_POWERED"); + fAuthorityService.deleteAuthority("GROUP_vampires"); } public void testAll() diff --git a/source/java/org/alfresco/service/cmr/avm/locking/AVMLockingService.java b/source/java/org/alfresco/service/cmr/avm/locking/AVMLockingService.java index 203b66d537..6661a16de2 100644 --- a/source/java/org/alfresco/service/cmr/avm/locking/AVMLockingService.java +++ b/source/java/org/alfresco/service/cmr/avm/locking/AVMLockingService.java @@ -119,7 +119,7 @@ public interface AVMLockingService * @param webProject The name of the web project that this path is being checked in. * @param avmPath A full avmPath * @param user The name of the user, group, role to check on. - * @return Mother's verdict. + * @return Whether the user has access. */ - public boolean motherMayI(String webProject, String avmPath, String user); + public boolean hasAccess(String webProject, String avmPath, String user); }