https://issues.apache.org/jira/browse/AMQ-5644 - authorization map for wildcard subscriptions

This commit is contained in:
Dejan Bosanac 2015-03-10 11:24:16 +01:00
parent a99bd09303
commit 3b39d2cc2a
4 changed files with 137 additions and 9 deletions

View File

@ -19,15 +19,13 @@ package org.apache.activemq.security;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.security.Principal;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.*;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.filter.DestinationMap;
import org.apache.activemq.filter.DestinationMapEntry;
import org.apache.activemq.filter.DestinationMapNode;
import org.apache.activemq.filter.DestinationNode;
/**
* Represents a destination based configuration of policies so that individual
@ -170,7 +168,8 @@ public class DefaultAuthorizationMap extends DestinationMap implements Authoriza
}
return answer;
}
return findWildcardMatches(key);
return findWildcardMatches(key, false);
}

View File

@ -162,9 +162,14 @@ public class DestinationMap {
@SuppressWarnings({"rawtypes", "unchecked"})
protected Set findWildcardMatches(ActiveMQDestination key) {
return findWildcardMatches(key, true);
}
@SuppressWarnings({"rawtypes", "unchecked"})
protected Set findWildcardMatches(ActiveMQDestination key, boolean deep) {
String[] paths = key.getDestinationPaths();
Set answer = new HashSet();
getRootNode(key).appendMatchingValues(answer, paths, 0);
getRootNode(key).appendMatchingValues(answer, paths, 0, deep);
return answer;
}

View File

@ -224,13 +224,18 @@ public class DestinationMapNode implements DestinationNode {
}
}
public void appendMatchingValues(Set<DestinationNode> answer, String[] paths, int startIndex) {
@SuppressWarnings({"rawtypes", "unchecked"})
public void appendMatchingValues(Set answer, String[] paths, int idx) {
appendMatchingValues(answer, paths, idx, true);
}
public void appendMatchingValues(Set<DestinationNode> answer, String[] paths, int startIndex, boolean deep) {
DestinationNode node = this;
boolean couldMatchAny = true;
int size = paths.length;
for (int i = startIndex; i < size && node != null; i++) {
String path = paths[i];
if (path.equals(ANY_DESCENDENT)) {
if (deep && path.equals(ANY_DESCENDENT)) {
answer.addAll(node.getDesendentValues());
couldMatchAny = false;
break;

View File

@ -89,6 +89,104 @@ public class AuthorizationMapTest extends TestCase {
assertTrue("Contains users group", tempAdminACLs.contains(TEMP_DESTINATION_ADMINS));
}
public void testWildcardSubscriptions() {
final GroupPrincipal USERSA = new GroupPrincipal("usersA");
DefaultAuthorizationMap map = new DefaultAuthorizationMap();
List<DestinationMapEntry> entries = new ArrayList<>();
entries.add(createEntry("A", "usersA", null, null));
map.setAuthorizationEntries(entries);
Set<?> readACLs = map.getReadACLs(new ActiveMQQueue(">"));
assertEquals("set size: " + readACLs, 0, readACLs.size());
readACLs = map.getReadACLs(new ActiveMQQueue("A"));
assertEquals("set size: " + readACLs, 1, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERSA));
entries.add(createEntry("USERS.>", "users", null, null));
map.setAuthorizationEntries(entries);
readACLs = map.getReadACLs(new ActiveMQQueue(">"));
assertEquals("set size: " + readACLs, 0, readACLs.size());
readACLs = map.getReadACLs(new ActiveMQQueue("A"));
assertEquals("set size: " + readACLs, 1, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERSA));
readACLs = map.getReadACLs(new ActiveMQQueue("USERS.>"));
assertEquals("set size: " + readACLs, 1, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERS));
readACLs = map.getReadACLs(new ActiveMQQueue("USERS.FOO.>"));
assertEquals("set size: " + readACLs, 1, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERS));
readACLs = map.getReadACLs(new ActiveMQQueue("USERS.TEST"));
assertEquals("set size: " + readACLs, 1, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERS));
entries.add(createEntry("USERS.A.>", "usersA", null, null));
map.setAuthorizationEntries(entries);
readACLs = map.getReadACLs(new ActiveMQQueue(">"));
assertEquals("set size: " + readACLs, 0, readACLs.size());
readACLs = map.getReadACLs(new ActiveMQQueue("A"));
assertEquals("set size: " + readACLs, 1, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERSA));
readACLs = map.getReadACLs(new ActiveMQQueue("USERS.>"));
assertEquals("set size: " + readACLs, 1, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERS));
readACLs = map.getReadACLs(new ActiveMQQueue("USERS.FOO.>"));
assertEquals("set size: " + readACLs, 1, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERS));
readACLs = map.getReadACLs(new ActiveMQQueue("USERS.TEST"));
assertEquals("set size: " + readACLs, 1, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERS));
readACLs = map.getReadACLs(new ActiveMQQueue("USERS.A.>"));
assertEquals("set size: " + readACLs, 2, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERS));
assertTrue("Contains users group", readACLs.contains(USERSA));
entries.add(createEntry(">", "admins", null, null));
map.setAuthorizationEntries(entries);
readACLs = map.getReadACLs(new ActiveMQQueue(">"));
assertEquals("set size: " + readACLs, 1, readACLs.size());
assertTrue("Contains admins group", readACLs.contains(ADMINS));
readACLs = map.getReadACLs(new ActiveMQQueue("A"));
assertEquals("set size: " + readACLs, 2, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERSA));
assertTrue("Contains admins group", readACLs.contains(ADMINS));
readACLs = map.getReadACLs(new ActiveMQQueue("USERS.>"));
assertEquals("set size: " + readACLs, 2, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERS));
assertTrue("Contains admins group", readACLs.contains(ADMINS));
readACLs = map.getReadACLs(new ActiveMQQueue("USERS.FOO.>"));
assertEquals("set size: " + readACLs, 2, readACLs.size());
assertTrue("Contains admins group", readACLs.contains(ADMINS));
assertTrue("Contains users group", readACLs.contains(USERS));
readACLs = map.getReadACLs(new ActiveMQQueue("USERS.TEST"));
assertEquals("set size: " + readACLs, 2, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERS));
assertTrue("Contains admins group", readACLs.contains(ADMINS));
readACLs = map.getReadACLs(new ActiveMQQueue("USERS.A.>"));
assertEquals("set size: " + readACLs, 3, readACLs.size());
assertTrue("Contains users group", readACLs.contains(USERS));
assertTrue("Contains users group", readACLs.contains(USERSA));
assertTrue("Contains admins group", readACLs.contains(ADMINS));
}
protected AuthorizationMap createWildcardAuthorizationMap() {
DefaultAuthorizationMap answer = new DefaultAuthorizationMap();
@ -191,4 +289,25 @@ public class AuthorizationMapTest extends TestCase {
return answer;
}
protected AuthorizationEntry createEntry(String queue, String read, String write, String admin) {
AuthorizationEntry entry = new AuthorizationEntry();
if (queue != null) {
entry.setQueue(queue);
}
try {
if (read != null) {
entry.setRead(read);
}
if (write != null) {
entry.setWrite(write);
}
if (admin != null) {
entry.setAdmin(admin);
}
} catch (Exception e) {
fail(e.toString());
}
return entry;
}
}