Repository: karaf
Updated Branches:
  refs/heads/karaf-3.0.x fb62c4e2b -> be9a38265


[KARAF-4348] Correct ordering of wildcard PID for RBAC

(cherry picked from commit 3e83c1d45a6dc9c4a06ba4efed47e2de2ec36cd2)


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/be9a3826
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/be9a3826
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/be9a3826

Branch: refs/heads/karaf-3.0.x
Commit: be9a382659072a9473de24b91167864a8813810f
Parents: fb62c4e
Author: Grzegorz Grzybek <[email protected]>
Authored: Thu Feb 18 18:28:29 2016 +0100
Committer: Grzegorz Grzybek <[email protected]>
Committed: Thu Feb 18 18:31:24 2016 +0100

----------------------------------------------------------------------
 .../karaf/management/KarafMBeanServerGuard.java | 63 +++++++++++++++-
 .../management/KarafMBeanServerGuardTest.java   | 77 ++++++++++++++++++++
 2 files changed, 136 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/be9a3826/management/server/src/main/java/org/apache/karaf/management/KarafMBeanServerGuard.java
----------------------------------------------------------------------
diff --git 
a/management/server/src/main/java/org/apache/karaf/management/KarafMBeanServerGuard.java
 
b/management/server/src/main/java/org/apache/karaf/management/KarafMBeanServerGuard.java
index 4c94370..448dab2 100644
--- 
a/management/server/src/main/java/org/apache/karaf/management/KarafMBeanServerGuard.java
+++ 
b/management/server/src/main/java/org/apache/karaf/management/KarafMBeanServerGuard.java
@@ -31,9 +31,14 @@ import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.Principal;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.Enumeration;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
 import java.util.regex.Pattern;
 
 import org.slf4j.Logger;
@@ -50,6 +55,8 @@ public class KarafMBeanServerGuard implements 
InvocationHandler {
 
     private static final String JMX_OBJECTNAME_PROPERTY_WILDCARD = "_";
 
+    private static final Comparator<String[]> WILDCARD_PID_COMPARATOR = new 
WildcardPidComparator();
+
     private ConfigurationAdmin configAdmin;
 
     public ConfigurationAdmin getConfigAdmin() {
@@ -316,6 +323,7 @@ public class KarafMBeanServerGuard implements 
InvocationHandler {
     private String getGeneralPid(List<String> allPids, String pid) {
         String ret = "";
         String[] pidStrArray = pid.split(Pattern.quote("."));
+        Set<String[]> rets = new TreeSet<String[]>(WILDCARD_PID_COMPARATOR);
         for (String id : allPids) {
             String[] idStrArray = id.split(Pattern.quote("."));
             if (idStrArray.length == pidStrArray.length) {
@@ -330,13 +338,24 @@ public class KarafMBeanServerGuard implements 
InvocationHandler {
                     }
                 }
                 if (match) {
-                    ret = id;
-                    return ret;
+                    rets.add(idStrArray);
                 }
             }
         }
-        
-        return ret;
+
+        Iterator<String[]> it = rets.iterator();
+        if (!it.hasNext()) {
+            return "";
+        } else {
+            StringBuilder buffer = new StringBuilder();
+            for (String segment : it.next()) {
+                if (buffer.length() > 0) {
+                    buffer.append(".");
+                }
+                buffer.append(segment);
+            }
+            return buffer.toString();
+        }
     }
 
     private List<String> getNameSegments(ObjectName objectName) {
@@ -423,4 +442,40 @@ public class KarafMBeanServerGuard implements 
InvocationHandler {
         return false;
     }
 
+    /**
+     * <code>nulls</code>-last comparator of PIDs split to segments. {@link 
#JMX_OBJECTNAME_PROPERTY_WILDCARD}
+     * in a segment makes the PID more generic, thus - with lower prioroty.
+     */
+    private static class WildcardPidComparator implements Comparator<String[]> 
{
+        @Override
+        public int compare(String[] o1, String[] o2) {
+            if (o1 == null && o2 == null) {
+                return 0;
+            }
+            if (o1 == null) {
+                return 1;
+            }
+            if (o2 == null) {
+                return -1;
+            }
+            if (o1.length != o2.length) {
+                // not necessary - not called with PIDs of different segment 
count
+                return o1.length - o2.length;
+            }
+            for (int n = 0; n < o1.length; n++) {
+                if (o1[n].equals(o2[n])) {
+                    continue;
+                }
+                if (o1[n].equals(JMX_OBJECTNAME_PROPERTY_WILDCARD)) {
+                    return 1;
+                }
+                if (o2[n].equals(JMX_OBJECTNAME_PROPERTY_WILDCARD)) {
+                    return -1;
+                }
+                return o1[n].compareTo(o2[n]);
+            }
+            return 0;
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/be9a3826/management/server/src/test/java/org/apache/karaf/management/KarafMBeanServerGuardTest.java
----------------------------------------------------------------------
diff --git 
a/management/server/src/test/java/org/apache/karaf/management/KarafMBeanServerGuardTest.java
 
b/management/server/src/test/java/org/apache/karaf/management/KarafMBeanServerGuardTest.java
index b0b37be..c7ae4c0 100644
--- 
a/management/server/src/test/java/org/apache/karaf/management/KarafMBeanServerGuardTest.java
+++ 
b/management/server/src/test/java/org/apache/karaf/management/KarafMBeanServerGuardTest.java
@@ -275,6 +275,83 @@ public class KarafMBeanServerGuardTest extends TestCase {
                 guard.getRequiredRoles(on, "zar", new Object[]{}, new 
String[]{}));
     }
 
+    @SuppressWarnings("unchecked")
+    public void testRequiredRolesHierarchyWildcard1() throws Exception {
+        Dictionary<String, Object> conf1 = new Hashtable<String, Object>();
+        conf1.put("foo", "viewer");
+        conf1.put(Constants.SERVICE_PID, "jmx.acl._.bar.Test");
+        Dictionary<String, Object> conf2 = new Hashtable<String, Object>();
+        conf2.put("foo", "editor");
+        conf2.put(Constants.SERVICE_PID, "jmx.acl.foo.bar.Test");
+
+        ConfigurationAdmin ca = getMockConfigAdmin2(conf1, conf2);
+        assertEquals("Precondition", 2, 
ca.listConfigurations("(service.pid=jmx.acl*)").length);
+
+        KarafMBeanServerGuard guard = new KarafMBeanServerGuard();
+        guard.setConfigAdmin(ca);
+
+        ObjectName on1 = ObjectName.getInstance("foo.bar:type=Test");
+        assertEquals("Should only return the most specific definition",
+                Collections.singletonList("editor"),
+                guard.getRequiredRoles(on1, "foo", new Object[]{}, new 
String[]{}));
+        ObjectName on2 = ObjectName.getInstance("tar.bar:type=Test");
+        assertEquals("Should return definition from wildcard PID",
+                Collections.singletonList("viewer"),
+                guard.getRequiredRoles(on2, "foo", new Object[]{}, new 
String[]{}));
+    }
+
+    @SuppressWarnings("unchecked")
+    public void testRequiredRolesHierarchyWildcard2() throws Exception {
+        Dictionary<String, Object> conf1 = new Hashtable<String, Object>();
+        conf1.put("foo", "viewer");
+        conf1.put(Constants.SERVICE_PID, "jmx.acl.foo.bar.Test");
+        Dictionary<String, Object> conf2 = new Hashtable<String, Object>();
+        conf2.put("foo", "editor");
+        conf2.put(Constants.SERVICE_PID, "jmx.acl._.bar.Test");
+
+        ConfigurationAdmin ca = getMockConfigAdmin2(conf1, conf2);
+        assertEquals("Precondition", 2, 
ca.listConfigurations("(service.pid=jmx.acl*)").length);
+
+        KarafMBeanServerGuard guard = new KarafMBeanServerGuard();
+        guard.setConfigAdmin(ca);
+
+        ObjectName on1 = ObjectName.getInstance("foo.bar:type=Test");
+        assertEquals("Should only return the most specific definition",
+                Collections.singletonList("viewer"),
+                guard.getRequiredRoles(on1, "foo", new Object[]{}, new 
String[]{}));
+        ObjectName on2 = ObjectName.getInstance("tar.bar:type=Test");
+        assertEquals("Should return definition from wildcard PID",
+                Collections.singletonList("editor"),
+                guard.getRequiredRoles(on2, "foo", new Object[]{}, new 
String[]{}));
+    }
+
+    @SuppressWarnings("unchecked")
+    public void testRequiredRolesHierarchyWildcard3() throws Exception {
+        Dictionary<String, Object> conf1 = new Hashtable<String, Object>();
+        conf1.put("foo", "viewer");
+        conf1.put(Constants.SERVICE_PID, "jmx.acl._.bar.Test");
+        Dictionary<String, Object> conf2 = new Hashtable<String, Object>();
+        conf2.put("foo", "editor");
+        conf2.put(Constants.SERVICE_PID, "jmx.acl.foo._.Test");
+
+        ConfigurationAdmin ca = getMockConfigAdmin2(conf1, conf2);
+        assertEquals("Precondition", 2, 
ca.listConfigurations("(service.pid=jmx.acl*)").length);
+
+        KarafMBeanServerGuard guard = new KarafMBeanServerGuard();
+        guard.setConfigAdmin(ca);
+
+        ObjectName on1 = ObjectName.getInstance("foo.bar:type=Test");
+        assertEquals("Should only return the most specific definition",
+                Collections.singletonList("editor"),
+                guard.getRequiredRoles(on1, "foo", new Object[]{}, new 
String[]{}));
+        ObjectName on2 = ObjectName.getInstance("foo.tar:type=Test");
+        assertEquals(Collections.singletonList("editor"),
+                guard.getRequiredRoles(on2, "foo", new Object[]{}, new 
String[]{}));
+        ObjectName on3 = ObjectName.getInstance("boo.bar:type=Test");
+        assertEquals(Collections.singletonList("viewer"),
+                guard.getRequiredRoles(on3, "foo", new Object[]{}, new 
String[]{}));
+    }
+
     public void testRequiredRolesMethodNameWildcard() throws Exception {
         Dictionary<String, Object> configuration = new Hashtable<String, 
Object>();
         configuration.put("getFoo", "viewer");

Reply via email to