diff --git a/source/java/org/alfresco/repo/security/authority/AuthorityDAO.java b/source/java/org/alfresco/repo/security/authority/AuthorityDAO.java index 46f9390c17..8102782664 100644 --- a/source/java/org/alfresco/repo/security/authority/AuthorityDAO.java +++ b/source/java/org/alfresco/repo/security/authority/AuthorityDAO.java @@ -145,9 +145,10 @@ public interface AuthorityDAO * * @param type * @param namePattern + * @param zones - may be null to indicate all zones * @return */ - public Set findAuthorities(AuthorityType type, String namePattern); + public Set findAuthorities(AuthorityType type, String namePattern, Set zones); /** * Gets or creates an authority zone node with the specified name diff --git a/source/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java b/source/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java index 56ef3aaa1d..a818e2b8fa 100644 --- a/source/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java +++ b/source/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java @@ -183,10 +183,10 @@ public class AuthorityDAOImpl implements AuthorityDAO public Set getAllAuthorities(AuthorityType type) { - return findAuthorities(type, null); + return findAuthorities(type, null, null); } - public Set findAuthorities(AuthorityType type, String namePattern) + public Set findAuthorities(AuthorityType type, String namePattern, Set zones) { Pattern pattern = null; if (namePattern != null) @@ -209,12 +209,32 @@ public class AuthorityDAOImpl implements AuthorityDAO // For other types, we just look directly under the authority container if (type == null || !type.equals(AuthorityType.USER)) { - NodeRef container = getAuthorityContainer(); - if (container != null) + if (zones == null) { - for (ChildAssociationRef childRef : nodeService.getChildAssocs(container)) + NodeRef container = getAuthorityContainer(); + if (container != null) { - addAuthorityNameIfMatches(authorities, childRef.getQName().getLocalName(), type, pattern); + for (ChildAssociationRef childRef : nodeService.getChildAssocs(container)) + { + addAuthorityNameIfMatches(authorities, childRef.getQName().getLocalName(), type, pattern); + } + } + } + else + { + for (String zone : zones) + { + NodeRef container = getOrCreateZone(zone); + if (container != null) + { + if (container != null) + { + for (ChildAssociationRef childRef : nodeService.getChildAssocs(container)) + { + addAuthorityNameIfMatches(authorities, childRef.getQName().getLocalName(), type, pattern); + } + } + } } } } diff --git a/source/java/org/alfresco/repo/security/authority/AuthorityServiceImpl.java b/source/java/org/alfresco/repo/security/authority/AuthorityServiceImpl.java index c9e6007144..a85c3d850b 100644 --- a/source/java/org/alfresco/repo/security/authority/AuthorityServiceImpl.java +++ b/source/java/org/alfresco/repo/security/authority/AuthorityServiceImpl.java @@ -244,25 +244,7 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean public Set findAuthorities(AuthorityType type, String namePattern) { - Set authorities = new HashSet(); - switch (type) - { - case ADMIN: - case EVERYONE: - case GUEST: - throw new UnsupportedOperationException(); - case GROUP: - authorities.addAll(authorityDAO.findAuthorities(type, namePattern)); - break; - case OWNER: - case ROLE: - throw new UnsupportedOperationException(); - case USER: - throw new UnsupportedOperationException(); - default: - break; - } - return authorities; + return findAuthoritiesInZone(type, namePattern, null); } @@ -441,4 +423,38 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean { return authorityDAO.getAllRootAuthoritiesInZone(zoneName, type); } + + public Set findAuthoritiesByShortNameInZone(AuthorityType type, String shortNamePattern, String zone) + { + String fullNamePattern = getName(type, shortNamePattern); + return findAuthoritiesInZone(type, fullNamePattern, zone); + } + + public Set findAuthoritiesInZone(AuthorityType type, String namePattern, String zone) + { + Set authorities = new HashSet(); + switch (type) + { + case ADMIN: + case EVERYONE: + case GUEST: + throw new UnsupportedOperationException(); + case GROUP: + Set zones = null; + if(zone != null) + { + zones = Collections.singleton(zone); + } + authorities.addAll(authorityDAO.findAuthorities(type, namePattern, zones)); + break; + case OWNER: + case ROLE: + throw new UnsupportedOperationException(); + case USER: + throw new UnsupportedOperationException(); + default: + break; + } + return authorities; + } } diff --git a/source/java/org/alfresco/repo/security/authority/AuthorityServiceTest.java b/source/java/org/alfresco/repo/security/authority/AuthorityServiceTest.java index 538dc23fac..ce80cc6dc1 100644 --- a/source/java/org/alfresco/repo/security/authority/AuthorityServiceTest.java +++ b/source/java/org/alfresco/repo/security/authority/AuthorityServiceTest.java @@ -25,6 +25,7 @@ package org.alfresco.repo.security.authority; import java.io.Serializable; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -160,16 +161,15 @@ public class AuthorityServiceTest extends TestCase super.tearDown(); } - public void testZones() - { + { assertNull(pubAuthorityService.getAuthorityZones("GROUP_DEFAULT")); assertNull(pubAuthorityService.getAuthorityZones("GROUP_NULL")); assertNull(pubAuthorityService.getAuthorityZones("GROUP_EMPTY")); assertNull(pubAuthorityService.getAuthorityZones("GROUP_1")); assertNull(pubAuthorityService.getAuthorityZones("GROUP_2")); assertNull(pubAuthorityService.getAuthorityZones("GROUP_3")); - + pubAuthorityService.createAuthority(AuthorityType.GROUP, "DEFAULT"); Set zones = pubAuthorityService.getAuthorityZones("GROUP_DEFAULT"); assertEquals(2, zones.size()); @@ -177,47 +177,47 @@ public class AuthorityServiceTest extends TestCase assertEquals(0, pubAuthorityService.getAuthorityZones("GROUP_DEFAULT").size()); pubAuthorityService.addAuthorityToZones("GROUP_DEFAULT", zones); assertEquals(2, pubAuthorityService.getAuthorityZones("GROUP_DEFAULT").size()); - + HashSet newZones = null; pubAuthorityService.createAuthority(AuthorityType.GROUP, "NULL", "NULL", newZones); assertEquals(0, pubAuthorityService.getAuthorityZones("GROUP_NULL").size()); - + newZones = new HashSet(); pubAuthorityService.createAuthority(AuthorityType.GROUP, "EMPTY", "EMPTY", newZones); assertEquals(0, pubAuthorityService.getAuthorityZones("GROUP_EMPTY").size()); - + newZones.add("One"); pubAuthorityService.createAuthority(AuthorityType.GROUP, "1", "1", newZones); assertEquals(1, pubAuthorityService.getAuthorityZones("GROUP_1").size()); - + newZones.add("Two"); pubAuthorityService.createAuthority(AuthorityType.GROUP, "2", "2", newZones); assertEquals(2, pubAuthorityService.getAuthorityZones("GROUP_2").size()); - + newZones.add("Three"); pubAuthorityService.createAuthority(AuthorityType.GROUP, "3", "3", newZones); assertEquals(3, pubAuthorityService.getAuthorityZones("GROUP_3").size()); - + HashSet toRemove = null; pubAuthorityService.removeAuthorityFromZones("GROUP_3", toRemove); assertEquals(3, pubAuthorityService.getAuthorityZones("GROUP_3").size()); - + toRemove = new HashSet(); pubAuthorityService.removeAuthorityFromZones("GROUP_3", toRemove); assertEquals(3, pubAuthorityService.getAuthorityZones("GROUP_3").size()); - + toRemove.add("Three"); pubAuthorityService.removeAuthorityFromZones("GROUP_3", toRemove); assertEquals(2, pubAuthorityService.getAuthorityZones("GROUP_3").size()); - + toRemove.add("Two"); pubAuthorityService.removeAuthorityFromZones("GROUP_3", toRemove); assertEquals(1, pubAuthorityService.getAuthorityZones("GROUP_3").size()); - + toRemove.add("One"); pubAuthorityService.removeAuthorityFromZones("GROUP_3", toRemove); assertEquals(0, pubAuthorityService.getAuthorityZones("GROUP_3").size()); - + pubAuthorityService.addAuthorityToZones("GROUP_3", newZones); assertEquals(3, pubAuthorityService.getAuthorityZones("GROUP_3").size()); assertEquals(3, pubAuthorityService.getAllAuthoritiesInZone("One", null).size()); @@ -226,19 +226,19 @@ public class AuthorityServiceTest extends TestCase assertEquals(3, pubAuthorityService.getAllAuthoritiesInZone("One", AuthorityType.GROUP).size()); assertEquals(2, pubAuthorityService.getAllAuthoritiesInZone("Two", AuthorityType.GROUP).size()); assertEquals(1, pubAuthorityService.getAllAuthoritiesInZone("Three", AuthorityType.GROUP).size()); - + assertEquals(3, pubAuthorityService.getAllRootAuthoritiesInZone("One", null).size()); assertEquals(2, pubAuthorityService.getAllRootAuthoritiesInZone("Two", null).size()); assertEquals(1, pubAuthorityService.getAllRootAuthoritiesInZone("Three", null).size()); assertEquals(3, pubAuthorityService.getAllRootAuthoritiesInZone("One", AuthorityType.GROUP).size()); assertEquals(2, pubAuthorityService.getAllRootAuthoritiesInZone("Two", AuthorityType.GROUP).size()); assertEquals(1, pubAuthorityService.getAllRootAuthoritiesInZone("Three", AuthorityType.GROUP).size()); - + // I am not convinced of the definition of root within zone ... - + pubAuthorityService.addAuthority("GROUP_1", "GROUP_2"); pubAuthorityService.addAuthority("GROUP_1", "GROUP_3"); - + assertEquals(1, pubAuthorityService.getAllRootAuthoritiesInZone("One", null).size()); assertEquals(0, pubAuthorityService.getAllRootAuthoritiesInZone("Two", null).size()); assertEquals(0, pubAuthorityService.getAllRootAuthoritiesInZone("Three", null).size()); @@ -246,48 +246,91 @@ public class AuthorityServiceTest extends TestCase assertEquals(0, pubAuthorityService.getAllRootAuthoritiesInZone("Two", AuthorityType.GROUP).size()); assertEquals(0, pubAuthorityService.getAllRootAuthoritiesInZone("Three", AuthorityType.GROUP).size()); } - + public void testGroupWildcards() { long before, after; char end = 'd'; - for (char i = 'a'; i <= end; i++) + String[] zones = new String[] { null, "ONE", "TWO", "THREE" }; + for (String zone : zones) { - for (char j = 'a'; j <= end; j++) + for (char i = 'a'; i <= end; i++) { - for (char k = 'a'; k <= end; k++) + for (char j = 'a'; j <= end; j++) { - StringBuilder name = new StringBuilder(); - name.append("__").append(i).append(j).append(k); - pubAuthorityService.createAuthority(AuthorityType.GROUP, name.toString()); + for (char k = 'a'; k <= end; k++) + { + StringBuilder name = new StringBuilder(); + name.append("__").append(zone).append("__").append(i).append(j).append(k); + if (zone == null) + { + pubAuthorityService.createAuthority(AuthorityType.GROUP, name.toString()); + } + else + { + pubAuthorityService.createAuthority(AuthorityType.GROUP, name.toString(), name.toString(), Collections.singleton(zone)); + } + } } } } int size = end - 'a' + 1; before = System.nanoTime(); - Set matches = pubAuthorityService.findAuthorities(AuthorityType.GROUP, "GROUP___a*"); + Set matches = pubAuthorityService.findAuthorities(AuthorityType.GROUP, "GROUP___*__a*"); after = System.nanoTime(); - System.out.println("GROUP___a* in "+((after-before)/1000000000.0f)); - assertEquals(size*size, matches.size()); - + System.out.println("GROUP___a* in " + ((after - before) / 1000000000.0f)); + assertEquals(size * size * zones.length, matches.size()); + before = System.nanoTime(); - matches = pubAuthorityService.findAuthorities(AuthorityType.GROUP, "GROUP___aa*"); + matches = pubAuthorityService.findAuthorities(AuthorityType.GROUP, "GROUP___*__aa*"); after = System.nanoTime(); - System.out.println("GROUP___aa* in "+((after-before)/1000000000.0f)); - assertEquals(size, matches.size()); - + System.out.println("GROUP___aa* in " + ((after - before) / 1000000000.0f)); + assertEquals(size * zones.length, matches.size()); + before = System.nanoTime(); - matches = pubAuthorityService.findAuthorities(AuthorityType.GROUP, "GROUP___*aa"); + matches = pubAuthorityService.findAuthorities(AuthorityType.GROUP, "GROUP___*__*aa"); after = System.nanoTime(); - System.out.println("GROUP___*aa in "+((after-before)/1000000000.0f)); - assertEquals(size, matches.size()); + System.out.println("GROUP___*aa in " + ((after - before) / 1000000000.0f)); + assertEquals(size * zones.length, matches.size()); before = System.nanoTime(); - - matches = pubAuthorityService.findAuthorities(AuthorityType.GROUP, "GROUP___*a"); + + matches = pubAuthorityService.findAuthorities(AuthorityType.GROUP, "GROUP___*__*a"); after = System.nanoTime(); - System.out.println("GROUP___*a in "+((after-before)/1000000000.0f)); - assertEquals(size*size, matches.size()); - + System.out.println("GROUP___*a in " + ((after - before) / 1000000000.0f)); + assertEquals(size * size * zones.length, matches.size()); + + // Zone specific + + for (String zone : zones) + { + if (zone != null) + { + before = System.nanoTime(); + matches = pubAuthorityService.findAuthoritiesInZone(AuthorityType.GROUP, "GROUP___*__a*", zone); + after = System.nanoTime(); + System.out.println("GROUP___a* in " + ((after - before) / 1000000000.0f)); + assertEquals(size * size, matches.size()); + + before = System.nanoTime(); + matches = pubAuthorityService.findAuthoritiesInZone(AuthorityType.GROUP, "GROUP___*__aa*", zone); + after = System.nanoTime(); + System.out.println("GROUP___aa* in " + ((after - before) / 1000000000.0f)); + assertEquals(size, matches.size()); + + before = System.nanoTime(); + matches = pubAuthorityService.findAuthoritiesInZone(AuthorityType.GROUP, "GROUP___*__*aa", zone); + after = System.nanoTime(); + System.out.println("GROUP___*aa in " + ((after - before) / 1000000000.0f)); + assertEquals(size, matches.size()); + before = System.nanoTime(); + + matches = pubAuthorityService.findAuthoritiesInZone(AuthorityType.GROUP, "GROUP___*__*a", zone); + after = System.nanoTime(); + System.out.println("GROUP___*a in " + ((after - before) / 1000000000.0f)); + assertEquals(size * size, matches.size()); + } + } + } public void testNonAdminUser() @@ -702,7 +745,7 @@ public class AuthorityServiceTest extends TestCase pubAuthorityService.addAuthority(auth3, auth2); assertEquals(7, pubAuthorityService.getAllAuthorities(AuthorityType.GROUP).size()); - + // Number of root authorities has been reduced since auth2 is no longer an orphan assertEquals(3, pubAuthorityService.getAllRootAuthorities(AuthorityType.GROUP).size()); // The next call looks for people not users :-) diff --git a/source/java/org/alfresco/repo/security/authority/SimpleAuthorityServiceImpl.java b/source/java/org/alfresco/repo/security/authority/SimpleAuthorityServiceImpl.java index a1d5f122a7..6359065836 100644 --- a/source/java/org/alfresco/repo/security/authority/SimpleAuthorityServiceImpl.java +++ b/source/java/org/alfresco/repo/security/authority/SimpleAuthorityServiceImpl.java @@ -330,4 +330,14 @@ public class SimpleAuthorityServiceImpl implements AuthorityService { } + + public Set findAuthoritiesByShortNameInZone(AuthorityType type, String shortNamePattern, String zone) + { + return Collections.emptySet(); + } + + public Set findAuthoritiesInZone(AuthorityType type, String namePattern, String zone) + { + return Collections.emptySet(); + } } diff --git a/source/java/org/alfresco/service/cmr/security/AuthorityService.java b/source/java/org/alfresco/service/cmr/security/AuthorityService.java index acda9dd928..9e9d058948 100644 --- a/source/java/org/alfresco/service/cmr/security/AuthorityService.java +++ b/source/java/org/alfresco/service/cmr/security/AuthorityService.java @@ -379,4 +379,25 @@ public interface AuthorityService */ @NotAuditable public Set getDefaultZones(); + + + /** + * Find authorities by pattern matching (* and ?) against the full authority name in a particular zone + * @param type - the authority type + * @param namePattern - the pattern which will be matched against the full authority name. + * @param zone - the zone + * @return the names of the authorities matching the pattern and type. + */ + @Auditable(parameters = {"type"}) + public Set findAuthoritiesInZone(AuthorityType type, String namePattern, String zone); + + /** + * Find authorities by pattern matching (* and ?) against the authority name. + * @param type - the authority type + * @param shortNamePattern - the pattern which will be matched against the shortName. + * @param zone + * @return the names of the authorities matching the pattern and type. + */ + @Auditable(parameters = {"type"}) + public Set findAuthoritiesByShortNameInZone(AuthorityType type, String shortNamePattern, String zone); }