mirror of https://github.com/apache/activemq.git
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@1486063 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
75245da626
commit
02a58c2a34
|
@ -16,37 +16,57 @@
|
|||
*/
|
||||
package org.apache.activemq.security;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.naming.Binding;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import javax.naming.event.EventDirContext;
|
||||
import javax.naming.event.NamespaceChangeListener;
|
||||
import javax.naming.event.NamingEvent;
|
||||
import javax.naming.event.NamingExceptionEvent;
|
||||
import javax.naming.event.ObjectChangeListener;
|
||||
import javax.naming.ldap.LdapName;
|
||||
import javax.naming.ldap.Rdn;
|
||||
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ActiveMQTopic;
|
||||
import org.apache.activemq.filter.DestinationMapEntry;
|
||||
import org.apache.activemq.jaas.GroupPrincipal;
|
||||
import org.apache.activemq.jaas.UserPrincipal;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.event.*;
|
||||
import javax.naming.ldap.LdapName;
|
||||
import javax.naming.ldap.Rdn;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
||||
public class SimpleCachedLDAPAuthorizationMap implements AuthorizationMap {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SimpleCachedLDAPAuthorizationMap.class);
|
||||
|
||||
// Configuration Options
|
||||
private String initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
|
||||
private final String initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
|
||||
private String connectionURL = "ldap://localhost:1024";
|
||||
private String connectionUsername = "uid=admin,ou=system";
|
||||
private String connectionPassword = "secret";
|
||||
private String connectionProtocol = "s";
|
||||
private String authentication = "simple";
|
||||
|
||||
|
||||
private int queuePrefixLength = 4;
|
||||
private int topicPrefixLength = 4;
|
||||
private int tempPrefixLength = 4;
|
||||
|
@ -55,7 +75,6 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
private String topicSearchBase = "ou=Topic,ou=Destination,ou=ActiveMQ,ou=system";
|
||||
private String tempSearchBase = "ou=Temp,ou=Destination,ou=ActiveMQ,ou=system";
|
||||
|
||||
|
||||
private String permissionGroupMemberAttribute = "member";
|
||||
|
||||
private String adminPermissionGroupSearchFilter = "(cn=Admin)";
|
||||
|
@ -68,7 +87,6 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
private String groupNameAttribute = "cn";
|
||||
private String userNameAttribute = "uid";
|
||||
|
||||
|
||||
private int refreshInterval = -1;
|
||||
private boolean refreshDisabled = false;
|
||||
|
||||
|
@ -80,8 +98,27 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
protected DirContext context;
|
||||
private EventDirContext eventContext;
|
||||
|
||||
protected HashMap<ActiveMQDestination, AuthorizationEntry> entries =
|
||||
new HashMap<ActiveMQDestination, AuthorizationEntry>();
|
||||
private final AtomicReference<DefaultAuthorizationMap> map =
|
||||
new AtomicReference<DefaultAuthorizationMap>(new DefaultAuthorizationMap());
|
||||
private final ThreadPoolExecutor updaterService;
|
||||
|
||||
protected Map<ActiveMQDestination, AuthorizationEntry> entries =
|
||||
new ConcurrentHashMap<ActiveMQDestination, AuthorizationEntry>();
|
||||
|
||||
public SimpleCachedLDAPAuthorizationMap() {
|
||||
// Allow for only a couple outstanding update requests, they can be slow so we
|
||||
// don't want a bunch to pile up for no reason.
|
||||
updaterService = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<Runnable>(2),
|
||||
new ThreadFactory() {
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
return new Thread(r, "SimpleCachedLDAPAuthorizationMap update thread");
|
||||
}
|
||||
});
|
||||
updaterService.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
|
||||
}
|
||||
|
||||
protected DirContext createContext() throws NamingException {
|
||||
Hashtable<String, String> env = new Hashtable<String, String>();
|
||||
|
@ -104,19 +141,20 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
try {
|
||||
context.getAttributes("");
|
||||
alive = true;
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
return alive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the existing open context or creates a new one and registers listeners for
|
||||
* push notifications if such an update style is enabled. This implementation should not
|
||||
* be invoked concurrently.
|
||||
* Returns the existing open context or creates a new one and registers listeners for push notifications if such an
|
||||
* update style is enabled. This implementation should not be invoked concurrently.
|
||||
*
|
||||
* @return the current context
|
||||
*
|
||||
* @throws NamingException if there is an error setting things up
|
||||
* @throws NamingException
|
||||
* if there is an error setting things up
|
||||
*/
|
||||
protected DirContext open() throws NamingException {
|
||||
if (isContextAlive()) {
|
||||
|
@ -139,8 +177,8 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
this.new CachedLDAPAuthorizationMapNamespaceChangeListener(DestinationType.QUEUE, permissionType));
|
||||
}
|
||||
// Listener for changes to the destination pattern entry itself and not a permission entry.
|
||||
eventContext.addNamingListener(queueSearchBase, "cn=*", new SearchControls(),
|
||||
this.new CachedLDAPAuthorizationMapNamespaceChangeListener(DestinationType.QUEUE, null));
|
||||
eventContext.addNamingListener(queueSearchBase, "cn=*", new SearchControls(), this.new CachedLDAPAuthorizationMapNamespaceChangeListener(
|
||||
DestinationType.QUEUE, null));
|
||||
|
||||
// Listeners for Topic policy //
|
||||
|
||||
|
@ -150,8 +188,8 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
this.new CachedLDAPAuthorizationMapNamespaceChangeListener(DestinationType.TOPIC, permissionType));
|
||||
}
|
||||
// Listener for changes to the destination pattern entry itself and not a permission entry.
|
||||
eventContext.addNamingListener(topicSearchBase, "cn=*", new SearchControls(),
|
||||
this.new CachedLDAPAuthorizationMapNamespaceChangeListener(DestinationType.TOPIC, null));
|
||||
eventContext.addNamingListener(topicSearchBase, "cn=*", new SearchControls(), this.new CachedLDAPAuthorizationMapNamespaceChangeListener(
|
||||
DestinationType.TOPIC, null));
|
||||
|
||||
// Listeners for Temp policy //
|
||||
|
||||
|
@ -171,10 +209,11 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
}
|
||||
|
||||
/**
|
||||
* Queries the directory and initializes the policy based on the data in the directory.
|
||||
* This implementation should not be invoked concurrently.
|
||||
* Queries the directory and initializes the policy based on the data in the directory. This implementation should
|
||||
* not be invoked concurrently.
|
||||
*
|
||||
* @throws Exception if there is an unrecoverable error processing the directory contents
|
||||
* @throws Exception
|
||||
* if there is an unrecoverable error processing the directory contents
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
protected void query() throws Exception {
|
||||
|
@ -183,65 +222,72 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
final SearchControls constraints = new SearchControls();
|
||||
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
|
||||
DefaultAuthorizationMap newMap = new DefaultAuthorizationMap();
|
||||
for (PermissionType permissionType : PermissionType.values()) {
|
||||
try {
|
||||
processQueryResults(
|
||||
currentContext.search(queueSearchBase, getFilterForPermissionType(permissionType), constraints),
|
||||
DestinationType.QUEUE, permissionType);
|
||||
processQueryResults(newMap,
|
||||
currentContext.search(queueSearchBase, getFilterForPermissionType(permissionType),
|
||||
constraints), DestinationType.QUEUE, permissionType);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Policy not applied!. Error processing policy under '" + queueSearchBase + "' with filter '"
|
||||
+ getFilterForPermissionType(permissionType) + "'", e);
|
||||
LOG.error("Policy not applied!. Error processing policy under '" + queueSearchBase +
|
||||
"' with filter '" + getFilterForPermissionType(permissionType) + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
for (PermissionType permissionType : PermissionType.values()) {
|
||||
try {
|
||||
processQueryResults(
|
||||
currentContext.search(topicSearchBase, getFilterForPermissionType(permissionType), constraints),
|
||||
DestinationType.TOPIC, permissionType);
|
||||
processQueryResults(newMap,
|
||||
currentContext.search(topicSearchBase, getFilterForPermissionType(permissionType),
|
||||
constraints), DestinationType.TOPIC, permissionType);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Policy not applied!. Error processing policy under '" + topicSearchBase + "' with filter '"
|
||||
+ getFilterForPermissionType(permissionType) + "'", e);
|
||||
LOG.error("Policy not applied!. Error processing policy under '" + topicSearchBase +
|
||||
"' with filter '" + getFilterForPermissionType(permissionType) + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
for (PermissionType permissionType : PermissionType.values()) {
|
||||
try {
|
||||
processQueryResults(
|
||||
currentContext.search(tempSearchBase, getFilterForPermissionType(permissionType), constraints),
|
||||
DestinationType.TEMP, permissionType);
|
||||
processQueryResults(newMap,
|
||||
currentContext.search(tempSearchBase, getFilterForPermissionType(permissionType),
|
||||
constraints), DestinationType.TEMP, permissionType);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Policy not applied!. Error processing policy under '" + tempSearchBase + "' with filter '"
|
||||
+ getFilterForPermissionType(permissionType) + "'", e);
|
||||
LOG.error("Policy not applied!. Error processing policy under '" + tempSearchBase +
|
||||
"' with filter '" + getFilterForPermissionType(permissionType) + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
setEntries(new ArrayList<DestinationMapEntry>(entries.values()));
|
||||
// Create and swap in the new instance with updated LDAP data.
|
||||
newMap.setAuthorizationEntries(new ArrayList<DestinationMapEntry>(entries.values()));
|
||||
this.map.set(newMap);
|
||||
|
||||
updated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes results from a directory query in the context of a given destination type and permission type.
|
||||
* This implementation should not be invoked concurrently.
|
||||
* Processes results from a directory query in the context of a given destination type and permission type. This
|
||||
* implementation should not be invoked concurrently.
|
||||
*
|
||||
* @param results the results to process
|
||||
* @param destinationType the type of the destination for which the directory results apply
|
||||
* @param permissionType the type of the permission for which the directory results apply
|
||||
* @param results
|
||||
* the results to process
|
||||
* @param destinationType
|
||||
* the type of the destination for which the directory results apply
|
||||
* @param permissionType
|
||||
* the type of the permission for which the directory results apply
|
||||
*
|
||||
* @throws Exception if there is an error processing the results
|
||||
* @throws Exception
|
||||
* if there is an error processing the results
|
||||
*/
|
||||
protected void processQueryResults(NamingEnumeration<SearchResult> results,
|
||||
DestinationType destinationType, PermissionType permissionType) throws Exception {
|
||||
protected void processQueryResults(DefaultAuthorizationMap map, NamingEnumeration<SearchResult> results, DestinationType destinationType, PermissionType permissionType)
|
||||
throws Exception {
|
||||
|
||||
while (results.hasMore()) {
|
||||
SearchResult result = results.next();
|
||||
AuthorizationEntry entry = null;
|
||||
|
||||
try {
|
||||
entry = getEntry(new LdapName(result.getNameInNamespace()), destinationType);
|
||||
entry = getEntry(map, new LdapName(result.getNameInNamespace()), destinationType);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Policy not applied! Error parsing authorization policy entry under "
|
||||
+ result.getNameInNamespace(), e);
|
||||
LOG.error("Policy not applied! Error parsing authorization policy entry under " + result.getNameInNamespace(), e);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -250,20 +296,23 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
}
|
||||
|
||||
/**
|
||||
* Marks the time at which the authorization state was last refreshed. Relevant for synchronous policy updates.
|
||||
* This implementation should not be invoked concurrently.
|
||||
* Marks the time at which the authorization state was last refreshed. Relevant for synchronous
|
||||
* policy updates. This implementation should not be invoked concurrently.
|
||||
*/
|
||||
protected void updated() {
|
||||
lastUpdated = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves or creates the {@link AuthorizationEntry} that corresponds to
|
||||
* the DN in {@code dn}. This implementation should not be invoked concurrently.
|
||||
* Retrieves or creates the {@link AuthorizationEntry} that corresponds to the DN in {@code dn}. This implementation
|
||||
* should not be invoked concurrently.
|
||||
*
|
||||
* @param map
|
||||
* the DefaultAuthorizationMap to operate on.
|
||||
* @param dn
|
||||
* the DN representing the policy entry in the directory
|
||||
* @param destinationType the type of the destination to get/create the entry for
|
||||
* @param destinationType
|
||||
* the type of the destination to get/create the entry for
|
||||
*
|
||||
* @return the corresponding authorization entry for the DN
|
||||
*
|
||||
|
@ -271,7 +320,7 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
* if destination type is not one of {@link DestinationType#QUEUE}, {@link DestinationType#TOPIC},
|
||||
* {@link DestinationType#TEMP} or if the policy entry DN is malformed
|
||||
*/
|
||||
protected AuthorizationEntry getEntry(LdapName dn, DestinationType destinationType) {
|
||||
protected AuthorizationEntry getEntry(DefaultAuthorizationMap map, LdapName dn, DestinationType destinationType) {
|
||||
AuthorizationEntry entry = null;
|
||||
switch (destinationType) {
|
||||
case TEMP:
|
||||
|
@ -279,13 +328,12 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
if (dn.size() != getPrefixLengthForDestinationType(destinationType) + 1) {
|
||||
// handle unknown entry
|
||||
throw new IllegalArgumentException("Malformed policy structure for a temporary destination "
|
||||
+ "policy entry. The permission group entries should be immediately below the "
|
||||
+ "temporary policy base DN.");
|
||||
+ "policy entry. The permission group entries should be immediately below the " + "temporary policy base DN.");
|
||||
}
|
||||
entry = getTempDestinationAuthorizationEntry();
|
||||
entry = map.getTempDestinationAuthorizationEntry();
|
||||
if (entry == null) {
|
||||
entry = new TempDestinationAuthorizationEntry();
|
||||
setTempDestinationAuthorizationEntry((TempDestinationAuthorizationEntry) entry);
|
||||
map.setTempDestinationAuthorizationEntry((TempDestinationAuthorizationEntry) entry);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -295,8 +343,7 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
// handle regular destinations
|
||||
if (dn.size() != getPrefixLengthForDestinationType(destinationType) + 2) {
|
||||
throw new IllegalArgumentException("Malformed policy structure for a queue or topic destination "
|
||||
+ "policy entry. The destination pattern and permission group entries should be "
|
||||
+ "nested below the queue or topic policy base DN.");
|
||||
+ "policy entry. The destination pattern and permission group entries should be " + "nested below the queue or topic policy base DN.");
|
||||
}
|
||||
|
||||
ActiveMQDestination dest = formatDestination(dn, destinationType);
|
||||
|
@ -320,17 +367,19 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
}
|
||||
|
||||
/**
|
||||
* Applies the policy from the directory to the given entry within the context of the provided
|
||||
* permission type.
|
||||
* Applies the policy from the directory to the given entry within the context of the provided permission type.
|
||||
*
|
||||
* @param entry the policy entry to apply the policy to
|
||||
* @param result the results from the directory to apply to the policy entry
|
||||
* @param permissionType the permission type of the data in the directory
|
||||
* @param entry
|
||||
* the policy entry to apply the policy to
|
||||
* @param result
|
||||
* the results from the directory to apply to the policy entry
|
||||
* @param permissionType
|
||||
* the permission type of the data in the directory
|
||||
*
|
||||
* @throws NamingException if there is an error applying the ACL
|
||||
* @throws NamingException
|
||||
* if there is an error applying the ACL
|
||||
*/
|
||||
protected void applyACL(AuthorizationEntry entry, SearchResult result,
|
||||
PermissionType permissionType) throws NamingException {
|
||||
protected void applyACL(AuthorizationEntry entry, SearchResult result, PermissionType permissionType) throws NamingException {
|
||||
|
||||
// Find members
|
||||
Attribute memberAttribute = result.getAttributes().get(permissionGroupMemberAttribute);
|
||||
|
@ -348,13 +397,9 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
// Lookup of member to determine principal type (group or user) and name.
|
||||
Attributes memberAttributes;
|
||||
try {
|
||||
memberAttributes = context.getAttributes(memberDn,
|
||||
new String[] {"objectClass", groupNameAttribute, userNameAttribute});
|
||||
memberAttributes = context.getAttributes(memberDn, new String[] { "objectClass", groupNameAttribute, userNameAttribute });
|
||||
} catch (NamingException e) {
|
||||
LOG.error(
|
||||
"Policy not applied! Unknown member " + memberDn
|
||||
+ " in policy entry "
|
||||
+ result.getNameInNamespace(), e);
|
||||
LOG.error("Policy not applied! Unknown member " + memberDn + " in policy entry " + result.getNameInNamespace(), e);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -368,10 +413,8 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
group = true;
|
||||
Attribute name = memberAttributes.get(groupNameAttribute);
|
||||
if (name == null) {
|
||||
LOG.error("Policy not applied! Group "
|
||||
+ memberDn
|
||||
+ "does not have name attribute "
|
||||
+ groupNameAttribute + " under entry " + result.getNameInNamespace());
|
||||
LOG.error("Policy not applied! Group " + memberDn + "does not have name attribute " + groupNameAttribute + " under entry "
|
||||
+ result.getNameInNamespace());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -382,9 +425,8 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
user = true;
|
||||
Attribute name = memberAttributes.get(userNameAttribute);
|
||||
if (name == null) {
|
||||
LOG.error("Policy not applied! User "
|
||||
+ memberDn + " does not have name attribute "
|
||||
+ userNameAttribute + " under entry " + result.getNameInNamespace());
|
||||
LOG.error("Policy not applied! User " + memberDn + " does not have name attribute " + userNameAttribute + " under entry "
|
||||
+ result.getNameInNamespace());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -398,14 +440,15 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
}
|
||||
|
||||
if ((!group && !user) || (group && user)) {
|
||||
LOG.error("Policy not applied! Can't determine type of member "
|
||||
+ memberDn + " under entry " + result.getNameInNamespace());
|
||||
LOG.error("Policy not applied! Can't determine type of member " + memberDn + " under entry " + result.getNameInNamespace());
|
||||
} else if (principalName != null) {
|
||||
DefaultAuthorizationMap map = this.map.get();
|
||||
if (group && !user) {
|
||||
try {
|
||||
members.add(createGroupPrincipal(principalName, getGroupClass()));
|
||||
members.add(DefaultAuthorizationMap.createGroupPrincipal(principalName, map.getGroupClass()));
|
||||
} catch (Exception e) {
|
||||
NamingException ne = new NamingException("Can't create a group " + principalName + " of class " + getGroupClass());
|
||||
NamingException ne = new NamingException(
|
||||
"Can't create a group " + principalName + " of class " + map.getGroupClass());
|
||||
ne.initCause(e);
|
||||
throw ne;
|
||||
}
|
||||
|
@ -418,18 +461,19 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
try {
|
||||
applyAcl(entry, permissionType, members);
|
||||
} catch (Exception e) {
|
||||
LOG.error(
|
||||
"Policy not applied! Error adding principals to ACL under "
|
||||
+ result.getNameInNamespace(), e);
|
||||
LOG.error("Policy not applied! Error adding principals to ACL under " + result.getNameInNamespace(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies policy to the entry given the actual principals that will be applied to the policy entry.
|
||||
*
|
||||
* @param entry the policy entry to which the policy should be applied
|
||||
* @param permissionType the type of the permission that the policy will be applied to
|
||||
* @param acls the principals that represent the actual policy
|
||||
* @param entry
|
||||
* the policy entry to which the policy should be applied
|
||||
* @param permissionType
|
||||
* the type of the permission that the policy will be applied to
|
||||
* @param acls
|
||||
* the principals that represent the actual policy
|
||||
*
|
||||
* @throw IllegalArgumentException if {@code permissionType} is unsupported
|
||||
*/
|
||||
|
@ -451,18 +495,20 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
}
|
||||
|
||||
/**
|
||||
* Parses a DN into the equivalent {@link ActiveMQDestination}. The default implementation
|
||||
* expects a format of cn=<PERMISSION_NAME>,ou=<DESTINATION_PATTERN>,.... or
|
||||
* ou=<DESTINATION_PATTERN>,.... for permission and destination entries, respectively.
|
||||
* For example {@code cn=admin,ou=$,ou=...} or {@code ou=$,ou=...}.
|
||||
* Parses a DN into the equivalent {@link ActiveMQDestination}. The default implementation expects a format of
|
||||
* cn=<PERMISSION_NAME>,ou=<DESTINATION_PATTERN>,.... or ou=<DESTINATION_PATTERN>,.... for permission and
|
||||
* destination entries, respectively. For example {@code cn=admin,ou=$,ou=...} or {@code ou=$,ou=...}.
|
||||
*
|
||||
* @param dn the DN to parse
|
||||
* @param destinationType the type of the destination that we are parsing
|
||||
* @param dn
|
||||
* the DN to parse
|
||||
* @param destinationType
|
||||
* the type of the destination that we are parsing
|
||||
*
|
||||
* @return the destination that the DN represents
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code destinationType} is {@link DestinationType#TEMP} or
|
||||
* if the format of {@code dn} is incorrect for for a topic or queue
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code destinationType} is {@link DestinationType#TEMP} or if the format of {@code dn} is
|
||||
* incorrect for for a topic or queue
|
||||
*
|
||||
* @see #formatDestination(Rdn, DestinationType)
|
||||
*/
|
||||
|
@ -480,21 +526,19 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
} else if (dn.size() == (getPrefixLengthForDestinationType(destinationType) + 1)) {
|
||||
destination = formatDestination(dn.getRdn(dn.size() - 1), destinationType);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Malformed DN for representing a permission or destination entry.");
|
||||
throw new IllegalArgumentException("Malformed DN for representing a permission or destination entry.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot format destination for destination type " + destinationType);
|
||||
throw new IllegalArgumentException("Cannot format destination for destination type " + destinationType);
|
||||
}
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses RDN values representing the destination name/pattern and
|
||||
* destination type into the equivalent {@link ActiveMQDestination}.
|
||||
* Parses RDN values representing the destination name/pattern and destination type into the equivalent
|
||||
* {@link ActiveMQDestination}.
|
||||
*
|
||||
* @param destinationName
|
||||
* the RDN representing the name or pattern for the destination
|
||||
|
@ -521,19 +565,18 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
dest = new ActiveMQTopic(formatDestinationName(destinationName));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown destination type: "
|
||||
+ destinationType);
|
||||
throw new IllegalArgumentException("Unknown destination type: " + destinationType);
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the RDN representing a destination name/pattern into the standard string representation
|
||||
* of the name/pattern. This implementation does not care about the type of the RDN such that the RDN could
|
||||
* be a CN or OU.
|
||||
* Parses the RDN representing a destination name/pattern into the standard string representation of the
|
||||
* name/pattern. This implementation does not care about the type of the RDN such that the RDN could be a CN or OU.
|
||||
*
|
||||
* @param destinationName the RDN representing the name or pattern for the destination
|
||||
* @param destinationName
|
||||
* the RDN representing the name or pattern for the destination
|
||||
*
|
||||
* @see #formatDestination(Rdn, Rdn)
|
||||
*/
|
||||
|
@ -542,14 +585,13 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
}
|
||||
|
||||
/**
|
||||
* Transcribes an existing set into a new set. Used to make defensive copies
|
||||
* for concurrent access.
|
||||
* Transcribes an existing set into a new set. Used to make defensive copies for concurrent access.
|
||||
*
|
||||
* @param source
|
||||
* the source set or {@code null}
|
||||
*
|
||||
* @return a new set containing the same elements as {@code source} or
|
||||
* {@code null} if {@code source} is {@code null}
|
||||
* @return a new set containing the same elements as {@code source} or {@code null} if {@code source} is
|
||||
* {@code null}
|
||||
*/
|
||||
protected <T> Set<T> transcribeSet(Set<T> source) {
|
||||
if (source != null) {
|
||||
|
@ -562,7 +604,8 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
/**
|
||||
* Returns the filter string for the given permission type.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code permissionType} is not supported
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code permissionType} is not supported
|
||||
*
|
||||
* @see #setAdminPermissionGroupSearchFilter(String)
|
||||
* @see #setReadPermissionGroupSearchFilter(String)
|
||||
|
@ -591,7 +634,8 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
/**
|
||||
* Returns the DN prefix size based on the given destination type.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code destinationType} is not supported
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code destinationType} is not supported
|
||||
*
|
||||
* @see #setQueueSearchBase(String)
|
||||
* @see #setTopicSearchBase(String)
|
||||
|
@ -618,11 +662,24 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
}
|
||||
|
||||
/**
|
||||
* Performs a check for updates from the server in the event that synchronous updates are enabled
|
||||
* and are the refresh interval has elapsed.
|
||||
* Performs a check for updates from the server in the event that synchronous updates are enabled and are the
|
||||
* refresh interval has elapsed.
|
||||
*/
|
||||
protected void checkForUpdates() {
|
||||
|
||||
if (context != null && refreshDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (context == null || (!refreshDisabled && (refreshInterval != -1 && System.currentTimeMillis() >= lastUpdated + refreshInterval))) {
|
||||
this.updaterService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
// Check again in case of stacked update request.
|
||||
if (context == null || (!refreshDisabled &&
|
||||
(refreshInterval != -1 && System.currentTimeMillis() >= lastUpdated + refreshInterval))) {
|
||||
|
||||
if (!isContextAlive()) {
|
||||
try {
|
||||
context = createContext();
|
||||
|
@ -631,159 +688,160 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
return;
|
||||
}
|
||||
}
|
||||
reset();
|
||||
setTempDestinationAuthorizationEntry(null);
|
||||
|
||||
entries.clear();
|
||||
|
||||
LOG.debug("Updating authorization map!");
|
||||
try {
|
||||
query();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error updating authorization map. Partial policy "
|
||||
+ "may be applied until the next successful update.", e);
|
||||
LOG.error("Error updating authorization map. Partial policy " +
|
||||
"may be applied until the next successful update.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Authorization Map
|
||||
|
||||
/**
|
||||
* Provides synchronous refresh capabilities if so configured before delegating to the super implementation,
|
||||
* and otherwise simply delegates to the super implementation.
|
||||
* Provides synchronized and defensive access to the admin ACLs for temp destinations as the super implementation
|
||||
* returns live copies of the ACLs and {@link AuthorizationEntry} is not setup for concurrent access.
|
||||
*/
|
||||
@Override
|
||||
protected synchronized Set<AuthorizationEntry> getAllEntries(ActiveMQDestination destination) {
|
||||
public Set<Object> getTempDestinationAdminACLs() {
|
||||
checkForUpdates();
|
||||
return super.getAllEntries(destination);
|
||||
DefaultAuthorizationMap map = this.map.get();
|
||||
return transcribeSet(map.getTempDestinationAdminACLs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides synchronized and defensive access to the admin ACLs for temp destinations as the super
|
||||
* implementation returns live copies of the ACLs and {@link AuthorizationEntry} is not
|
||||
* setup for concurrent access.
|
||||
* Provides synchronized and defensive access to the read ACLs for temp destinations as the super implementation
|
||||
* returns live copies of the ACLs and {@link AuthorizationEntry} is not setup for concurrent access.
|
||||
*/
|
||||
@Override
|
||||
public synchronized Set<Object> getTempDestinationAdminACLs() {
|
||||
public Set<Object> getTempDestinationReadACLs() {
|
||||
checkForUpdates();
|
||||
return transcribeSet(super.getTempDestinationAdminACLs());
|
||||
DefaultAuthorizationMap map = this.map.get();
|
||||
return transcribeSet(map.getTempDestinationReadACLs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides synchronized and defensive access to the read ACLs for temp destinations as the super
|
||||
* implementation returns live copies of the ACLs and {@link AuthorizationEntry} is not
|
||||
* setup for concurrent access.
|
||||
* Provides synchronized and defensive access to the write ACLs for temp destinations as the super implementation
|
||||
* returns live copies of the ACLs and {@link AuthorizationEntry} is not setup for concurrent access.
|
||||
*/
|
||||
public synchronized Set<Object> getTempDestinationReadACLs() {
|
||||
@Override
|
||||
public Set<Object> getTempDestinationWriteACLs() {
|
||||
checkForUpdates();
|
||||
return transcribeSet(super.getTempDestinationReadACLs());
|
||||
DefaultAuthorizationMap map = this.map.get();
|
||||
return transcribeSet(map.getTempDestinationWriteACLs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides synchronized and defensive access to the write ACLs for temp destinations as the super
|
||||
* implementation returns live copies of the ACLs and {@link AuthorizationEntry} is not
|
||||
* setup for concurrent access.
|
||||
* Provides synchronized access to the admin ACLs for the destinations as {@link AuthorizationEntry}
|
||||
* is not setup for concurrent access.
|
||||
*/
|
||||
public synchronized Set<Object> getTempDestinationWriteACLs() {
|
||||
@Override
|
||||
public Set<Object> getAdminACLs(ActiveMQDestination destination) {
|
||||
checkForUpdates();
|
||||
return transcribeSet(super.getTempDestinationWriteACLs());
|
||||
DefaultAuthorizationMap map = this.map.get();
|
||||
return map.getAdminACLs(destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides synchronized access to the admin ACLs for the destinations as
|
||||
* {@link AuthorizationEntry} is not setup for concurrent access.
|
||||
* Provides synchronized access to the read ACLs for the destinations as {@link AuthorizationEntry} is not setup for
|
||||
* concurrent access.
|
||||
*/
|
||||
public synchronized Set<Object> getAdminACLs(ActiveMQDestination destination) {
|
||||
return super.getAdminACLs(destination);
|
||||
@Override
|
||||
public Set<Object> getReadACLs(ActiveMQDestination destination) {
|
||||
checkForUpdates();
|
||||
DefaultAuthorizationMap map = this.map.get();
|
||||
return map.getReadACLs(destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides synchronized access to the read ACLs for the destinations as
|
||||
* {@link AuthorizationEntry} is not setup for concurrent access.
|
||||
* Provides synchronized access to the write ACLs for the destinations as {@link AuthorizationEntry} is not setup
|
||||
* for concurrent access.
|
||||
*/
|
||||
public synchronized Set<Object> getReadACLs(ActiveMQDestination destination) {
|
||||
@Override
|
||||
public Set<Object> getWriteACLs(ActiveMQDestination destination) {
|
||||
checkForUpdates();
|
||||
return super.getReadACLs(destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides synchronized access to the write ACLs for the destinations as
|
||||
* {@link AuthorizationEntry} is not setup for concurrent access.
|
||||
*/
|
||||
public synchronized Set<Object> getWriteACLs(ActiveMQDestination destination) {
|
||||
checkForUpdates();
|
||||
return super.getWriteACLs(destination);
|
||||
DefaultAuthorizationMap map = this.map.get();
|
||||
return map.getWriteACLs(destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for new policy entries in the directory.
|
||||
*
|
||||
* @param namingEvent the new entry event that occurred
|
||||
* @param destinationType the type of the destination to which the event applies
|
||||
* @param permissionType the permission type to which the event applies
|
||||
* @param namingEvent
|
||||
* the new entry event that occurred
|
||||
* @param destinationType
|
||||
* the type of the destination to which the event applies
|
||||
* @param permissionType
|
||||
* the permission type to which the event applies
|
||||
*/
|
||||
public synchronized void objectAdded(NamingEvent namingEvent, DestinationType destinationType,
|
||||
PermissionType permissionType) {
|
||||
public void objectAdded(NamingEvent namingEvent, DestinationType destinationType, PermissionType permissionType) {
|
||||
LOG.debug("Adding object: " + namingEvent.getNewBinding());
|
||||
SearchResult result = (SearchResult) namingEvent.getNewBinding();
|
||||
|
||||
try {
|
||||
DefaultAuthorizationMap map = this.map.get();
|
||||
LdapName name = new LdapName(result.getName());
|
||||
|
||||
AuthorizationEntry entry = getEntry(name, destinationType);
|
||||
AuthorizationEntry entry = getEntry(map, name, destinationType);
|
||||
|
||||
applyACL(entry, result, permissionType);
|
||||
if (!(entry instanceof TempDestinationAuthorizationEntry)) {
|
||||
put(entry.getDestination(), entry);
|
||||
map.put(entry.getDestination(), entry);
|
||||
}
|
||||
|
||||
} catch (InvalidNameException e) {
|
||||
LOG.error("Policy not applied! Error parsing DN for addition of "
|
||||
+ result.getName(), e);
|
||||
LOG.error("Policy not applied! Error parsing DN for addition of " + result.getName(), e);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Policy not applied! Error processing object addition for addition of "
|
||||
+ result.getName(), e);
|
||||
LOG.error("Policy not applied! Error processing object addition for addition of " + result.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for removed policy entries in the directory.
|
||||
*
|
||||
* @param namingEvent the removed entry event that occurred
|
||||
* @param destinationType the type of the destination to which the event applies
|
||||
* @param permissionType the permission type to which the event applies
|
||||
* @param namingEvent
|
||||
* the removed entry event that occurred
|
||||
* @param destinationType
|
||||
* the type of the destination to which the event applies
|
||||
* @param permissionType
|
||||
* the permission type to which the event applies
|
||||
*/
|
||||
public synchronized void objectRemoved(NamingEvent namingEvent, DestinationType destinationType,
|
||||
PermissionType permissionType) {
|
||||
public void objectRemoved(NamingEvent namingEvent, DestinationType destinationType, PermissionType permissionType) {
|
||||
LOG.debug("Removing object: " + namingEvent.getOldBinding());
|
||||
Binding result = namingEvent.getOldBinding();
|
||||
|
||||
try {
|
||||
DefaultAuthorizationMap map = this.map.get();
|
||||
LdapName name = new LdapName(result.getName());
|
||||
|
||||
AuthorizationEntry entry = getEntry(name, destinationType);
|
||||
|
||||
AuthorizationEntry entry = getEntry(map, name, destinationType);
|
||||
applyAcl(entry, permissionType, new HashSet<Object>());
|
||||
} catch (InvalidNameException e) {
|
||||
LOG.error("Policy not applied! Error parsing DN for object removal for removal of "
|
||||
+ result.getName(), e);
|
||||
LOG.error("Policy not applied! Error parsing DN for object removal for removal of " + result.getName(), e);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Policy not applied! Error processing object removal for removal of "
|
||||
+ result.getName(), e);
|
||||
LOG.error("Policy not applied! Error processing object removal for removal of " + result.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for renamed policy entries in the directory. This handler deals with the renaming
|
||||
* of destination entries as well as permission entries. If the permission type is not null, it is
|
||||
* assumed that we are dealing with the renaming of a permission entry. Otherwise, it is assumed
|
||||
* that we are dealing with the renaming of a destination entry.
|
||||
* Handler for renamed policy entries in the directory. This handler deals with the renaming of destination entries
|
||||
* as well as permission entries. If the permission type is not null, it is assumed that we are dealing with the
|
||||
* renaming of a permission entry. Otherwise, it is assumed that we are dealing with the renaming of a destination
|
||||
* entry.
|
||||
*
|
||||
* @param namingEvent the renaming entry event that occurred
|
||||
* @param destinationType the type of the destination to which the event applies
|
||||
* @param permissionType the permission type to which the event applies
|
||||
* @param namingEvent
|
||||
* the renaming entry event that occurred
|
||||
* @param destinationType
|
||||
* the type of the destination to which the event applies
|
||||
* @param permissionType
|
||||
* the permission type to which the event applies
|
||||
*/
|
||||
public synchronized void objectRenamed(NamingEvent namingEvent, DestinationType destinationType,
|
||||
PermissionType permissionType) {
|
||||
public void objectRenamed(NamingEvent namingEvent, DestinationType destinationType, PermissionType permissionType) {
|
||||
Binding oldBinding = namingEvent.getOldBinding();
|
||||
Binding newBinding = namingEvent.getNewBinding();
|
||||
LOG.debug("Renaming object: " + oldBinding + " to " + newBinding);
|
||||
|
@ -805,9 +863,7 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
boolean matchedToType = false;
|
||||
|
||||
for (PermissionType newPermissionType : PermissionType.values()) {
|
||||
NamingEnumeration<SearchResult> results = context.search(
|
||||
newName,
|
||||
getFilterForPermissionType(newPermissionType), controls);
|
||||
NamingEnumeration<SearchResult> results = context.search(newName, getFilterForPermissionType(newPermissionType), controls);
|
||||
|
||||
if (results.hasMore()) {
|
||||
objectAdded(namingEvent, destinationType, newPermissionType);
|
||||
|
@ -817,19 +873,18 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
}
|
||||
|
||||
if (!matchedToType) {
|
||||
LOG.error("Policy not applied! Error processing object rename for rename of "
|
||||
+ oldBinding.getName() + " to " + newBinding.getName()
|
||||
LOG.error("Policy not applied! Error processing object rename for rename of " + oldBinding.getName() + " to " + newBinding.getName()
|
||||
+ ". Could not determine permission type of new object.");
|
||||
}
|
||||
|
||||
} else {
|
||||
// Handle the case where a destination entry is being renamed.
|
||||
if (oldDest != null && newDest != null) {
|
||||
AuthorizationEntry entry = entries.remove(oldDest);
|
||||
if (entry != null) {
|
||||
entry.setDestination(newDest);
|
||||
put(newDest, entry);
|
||||
remove(oldDest, entry);
|
||||
DefaultAuthorizationMap map = this.map.get();
|
||||
map.put(newDest, entry);
|
||||
map.remove(oldDest, entry);
|
||||
entries.put(newDest, entry);
|
||||
} else {
|
||||
LOG.warn("No authorization entry for " + oldDest);
|
||||
|
@ -837,23 +892,23 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
}
|
||||
}
|
||||
} catch (InvalidNameException e) {
|
||||
LOG.error("Policy not applied! Error parsing DN for object rename for rename of "
|
||||
+ oldBinding.getName() + " to " + newBinding.getName(), e);
|
||||
LOG.error("Policy not applied! Error parsing DN for object rename for rename of " + oldBinding.getName() + " to " + newBinding.getName(), e);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Policy not applied! Error processing object rename for rename of "
|
||||
+ oldBinding.getName() + " to " + newBinding.getName(), e);
|
||||
LOG.error("Policy not applied! Error processing object rename for rename of " + oldBinding.getName() + " to " + newBinding.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for changed policy entries in the directory.
|
||||
*
|
||||
* @param namingEvent the changed entry event that occurred
|
||||
* @param destinationType the type of the destination to which the event applies
|
||||
* @param permissionType the permission type to which the event applies
|
||||
* @param namingEvent
|
||||
* the changed entry event that occurred
|
||||
* @param destinationType
|
||||
* the type of the destination to which the event applies
|
||||
* @param permissionType
|
||||
* the permission type to which the event applies
|
||||
*/
|
||||
public synchronized void objectChanged(NamingEvent namingEvent,
|
||||
DestinationType destinationType, PermissionType permissionType) {
|
||||
public void objectChanged(NamingEvent namingEvent, DestinationType destinationType, PermissionType permissionType) {
|
||||
LOG.debug("Changing object " + namingEvent.getOldBinding() + " to " + namingEvent.getNewBinding());
|
||||
objectRemoved(namingEvent, destinationType, permissionType);
|
||||
objectAdded(namingEvent, destinationType, permissionType);
|
||||
|
@ -862,7 +917,8 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
/**
|
||||
* Handler for exception events from the registry.
|
||||
*
|
||||
* @param namingExceptionEvent the exception event
|
||||
* @param namingExceptionEvent
|
||||
* the exception event
|
||||
*/
|
||||
public void namingExceptionThrown(NamingExceptionEvent namingExceptionEvent) {
|
||||
context = null;
|
||||
|
@ -974,8 +1030,7 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
return permissionGroupMemberAttribute;
|
||||
}
|
||||
|
||||
public void setPermissionGroupMemberAttribute(
|
||||
String permissionGroupMemberAttribute) {
|
||||
public void setPermissionGroupMemberAttribute(String permissionGroupMemberAttribute) {
|
||||
this.permissionGroupMemberAttribute = permissionGroupMemberAttribute;
|
||||
}
|
||||
|
||||
|
@ -983,8 +1038,7 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
return adminPermissionGroupSearchFilter;
|
||||
}
|
||||
|
||||
public void setAdminPermissionGroupSearchFilter(
|
||||
String adminPermissionGroupSearchFilter) {
|
||||
public void setAdminPermissionGroupSearchFilter(String adminPermissionGroupSearchFilter) {
|
||||
this.adminPermissionGroupSearchFilter = adminPermissionGroupSearchFilter;
|
||||
}
|
||||
|
||||
|
@ -992,8 +1046,7 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
return readPermissionGroupSearchFilter;
|
||||
}
|
||||
|
||||
public void setReadPermissionGroupSearchFilter(
|
||||
String readPermissionGroupSearchFilter) {
|
||||
public void setReadPermissionGroupSearchFilter(String readPermissionGroupSearchFilter) {
|
||||
this.readPermissionGroupSearchFilter = readPermissionGroupSearchFilter;
|
||||
}
|
||||
|
||||
|
@ -1001,8 +1054,7 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
return writePermissionGroupSearchFilter;
|
||||
}
|
||||
|
||||
public void setWritePermissionGroupSearchFilter(
|
||||
String writePermissionGroupSearchFilter) {
|
||||
public void setWritePermissionGroupSearchFilter(String writePermissionGroupSearchFilter) {
|
||||
this.writePermissionGroupSearchFilter = writePermissionGroupSearchFilter;
|
||||
}
|
||||
|
||||
|
@ -1063,38 +1115,32 @@ public class SimpleCachedLDAPAuthorizationMap extends DefaultAuthorizationMap {
|
|||
}
|
||||
|
||||
protected static enum DestinationType {
|
||||
QUEUE,
|
||||
TOPIC,
|
||||
TEMP;
|
||||
QUEUE, TOPIC, TEMP;
|
||||
}
|
||||
|
||||
protected static enum PermissionType {
|
||||
READ,
|
||||
WRITE,
|
||||
ADMIN;
|
||||
READ, WRITE, ADMIN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener implementation for directory changes that maps change events to
|
||||
* destination types.
|
||||
* Listener implementation for directory changes that maps change events to destination types.
|
||||
*/
|
||||
protected class CachedLDAPAuthorizationMapNamespaceChangeListener implements
|
||||
NamespaceChangeListener, ObjectChangeListener {
|
||||
protected class CachedLDAPAuthorizationMapNamespaceChangeListener implements NamespaceChangeListener, ObjectChangeListener {
|
||||
|
||||
private final DestinationType destinationType;
|
||||
private final PermissionType permissionType;
|
||||
|
||||
/**
|
||||
* Creates a new listener. If {@code permissionType} is {@code null}, add
|
||||
* and remove events are ignored as they do not directly affect policy state.
|
||||
* This configuration is used when listening for changes on entries that represent
|
||||
* destination patterns and not for entries that represent permissions.
|
||||
* Creates a new listener. If {@code permissionType} is {@code null}, add and remove events are ignored as they
|
||||
* do not directly affect policy state. This configuration is used when listening for changes on entries that
|
||||
* represent destination patterns and not for entries that represent permissions.
|
||||
*
|
||||
* @param destinationType the type of the destination being listened for
|
||||
* @param permissionType the optional permission type being listened for
|
||||
* @param destinationType
|
||||
* the type of the destination being listened for
|
||||
* @param permissionType
|
||||
* the optional permission type being listened for
|
||||
*/
|
||||
public CachedLDAPAuthorizationMapNamespaceChangeListener(
|
||||
DestinationType destinationType, PermissionType permissionType) {
|
||||
public CachedLDAPAuthorizationMapNamespaceChangeListener(DestinationType destinationType, PermissionType permissionType) {
|
||||
this.destinationType = destinationType;
|
||||
this.permissionType = permissionType;
|
||||
}
|
||||
|
|
|
@ -112,8 +112,13 @@ public abstract class AbstractCachedLDAPAuthorizationMapLegacyTest extends Abstr
|
|||
|
||||
reader.close();
|
||||
|
||||
failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
|
||||
assertEquals("set size: " + failedACLs, 0, failedACLs.size());
|
||||
assertTrue("did not get expected size. ", Wait.waitFor(new Wait.Condition() {
|
||||
|
||||
@Override
|
||||
public boolean isSatisified() throws Exception {
|
||||
return map.getReadACLs(new ActiveMQQueue("TEST.FOO")).size() == 0;
|
||||
}
|
||||
}));
|
||||
|
||||
assertNull(map.getTempDestinationReadACLs());
|
||||
assertNull(map.getTempDestinationWriteACLs());
|
||||
|
@ -335,10 +340,14 @@ public abstract class AbstractCachedLDAPAuthorizationMapLegacyTest extends Abstr
|
|||
}
|
||||
|
||||
reader.close();
|
||||
Thread.sleep(2000);
|
||||
|
||||
failedACLs = map.getReadACLs(new ActiveMQQueue("FAILED"));
|
||||
assertEquals("set size: " + failedACLs, 2, failedACLs.size());
|
||||
assertTrue("did not get expected size. ", Wait.waitFor(new Wait.Condition() {
|
||||
|
||||
@Override
|
||||
public boolean isSatisified() throws Exception {
|
||||
return map.getReadACLs(new ActiveMQQueue("FAILED")).size() == 2;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
protected SimpleCachedLDAPAuthorizationMap createMap() {
|
||||
|
|
Loading…
Reference in New Issue