You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by js...@apache.org on 2017/03/24 13:09:04 UTC

svn commit: r1788436 - in /sling/trunk/bundles/jcr/base/src: main/java/org/apache/sling/jcr/base/internal/ test/java/org/apache/sling/jcr/base/internal/

Author: jsedding
Date: Fri Mar 24 13:09:04 2017
New Revision: 1788436

URL: http://svn.apache.org/viewvc?rev=1788436&view=rev
Log:
SLING-6707 - LoginAdminWhitelist.fragment metatype descriptor not as intended

- add description for whitelist.bundles.regexp
- remove whitelist.bundles.default and whitelist.bundles.additional from metatype
  and handle them separately
- refactor handling of backwards compatibility for above properties

Modified:
    sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelist.java
    sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistConfiguration.java
    sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/WhitelistFragment.java
    sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistTest.java

Modified: sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelist.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelist.java?rev=1788436&r1=1788435&r2=1788436&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelist.java (original)
+++ sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelist.java Fri Mar 24 13:09:04 2017
@@ -19,6 +19,8 @@
 package org.apache.sling.jcr.base.internal;
 
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.regex.Pattern;
 
@@ -36,6 +38,8 @@ import org.osgi.service.metatype.annotat
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.sling.commons.osgi.PropertiesUtil.toStringArray;
+
 /**
  * Whitelist that defines which bundles can use the
  * {@link SlingRepository#loginAdministrative} method.
@@ -59,13 +63,15 @@ public class LoginAdminWhitelist {
 
     private volatile ConfigurationState config;
 
-    // for backwards compatibility only
-    private volatile WhitelistFragment defaultFragment;
+    private final List<WhitelistFragment> whitelistFragments = new CopyOnWriteArrayList<WhitelistFragment>();
+
+    // for backwards compatibility only (read properties directly to prevent them from appearing in the metatype)
+    private static final String PROP_WHITELIST_BUNDLES_DEFAULT = "whitelist.bundles.default";
 
-    // for backwards compatibility only
-    private volatile WhitelistFragment additionalFragment;
+    private static final String PROP_WHITELIST_BUNDLES_ADDITIONAL = "whitelist.bundles.additional";
 
-    private final List<WhitelistFragment> whitelistFragments = new CopyOnWriteArrayList<>();
+    private final Map<String, WhitelistFragment> backwardsCompatibleFragments =
+            new ConcurrentHashMap<String, WhitelistFragment>();
 
     @Reference(
             cardinality = ReferenceCardinality.MULTIPLE,
@@ -84,9 +90,10 @@ public class LoginAdminWhitelist {
     }
 
     @Activate @Modified @SuppressWarnings("unused")
-    void configure(LoginAdminWhitelistConfiguration configuration) {
+    void configure(LoginAdminWhitelistConfiguration configuration, Map<String, Object> properties) {
         this.config = new ConfigurationState(configuration);
-        backwardsCompatibility(configuration);
+        ensureBackwardsCompatibility(properties, PROP_WHITELIST_BUNDLES_DEFAULT);
+        ensureBackwardsCompatibility(properties, PROP_WHITELIST_BUNDLES_ADDITIONAL);
     }
 
     public boolean allowLoginAdministrative(Bundle b) {
@@ -130,7 +137,7 @@ public class LoginAdminWhitelist {
             final String regexp = config.whitelist_bundles_regexp();
             if(regexp.trim().length() > 0) {
                 whitelistRegexp = Pattern.compile(regexp);
-                LOG.warn("A whitelist.bundles.regexp is configured, this is NOT RECOMMENDED for production: {}",
+                LOG.warn("A 'whitelist.bundles.regexp' is configured, this is NOT RECOMMENDED for production: {}",
                         whitelistRegexp);
             } else {
                 whitelistRegexp = null;
@@ -139,7 +146,7 @@ public class LoginAdminWhitelist {
             bypassWhitelist = config.whitelist_bypass();
             if(bypassWhitelist) {
                 LOG.info("bypassWhitelist=true, whitelisted BSNs=<ALL>");
-                LOG.warn("All bundles are allowed to use loginAdministrative due to the 'bypass whitelist' " +
+                LOG.warn("All bundles are allowed to use loginAdministrative due to the 'whitelist.bypass' " +
                         "configuration of this service. This is NOT RECOMMENDED, for security reasons."
                 );
             }
@@ -147,25 +154,19 @@ public class LoginAdminWhitelist {
     }
 
     @SuppressWarnings("deprecated")
-    private void backwardsCompatibility(final LoginAdminWhitelistConfiguration configuration) {
-        if (defaultFragment != null) {
-            unbindWhitelistFragment(defaultFragment);
-        }
-        if (additionalFragment != null) {
-            unbindWhitelistFragment(additionalFragment);
-        }
-        final String[] defaultBsns = configuration.whitelist_bundles_default();
-        if (defaultBsns != null && defaultBsns.length != 0) {
-            LOG.warn("Using deprecated configuration property 'whitelist.bundles.default'");
-            defaultFragment = new WhitelistFragment("deprecated-whitelist.bundles.default", defaultBsns);
-            bindWhitelistFragment(defaultFragment);
-        }
-
-        final String[] additionalBsns = configuration.whitelist_bundles_additional();
-        if (additionalBsns != null && additionalBsns.length != 0) {
-            LOG.warn("Using deprecated configuration property 'whitelist.bundles.additional'");
-            additionalFragment = new WhitelistFragment("deprecated-whitelist.bundles.additional", additionalBsns);
-            bindWhitelistFragment(additionalFragment);
+    private void ensureBackwardsCompatibility(final Map<String, Object> properties, final String propertyName) {
+        final WhitelistFragment oldFragment = backwardsCompatibleFragments.remove(propertyName);
+        
+        final String[] bsns = toStringArray(properties.get(propertyName), new String[0]);
+        if (bsns.length != 0) {
+            LOG.warn("Using deprecated configuration property '{}'", propertyName);
+            final WhitelistFragment fragment = new WhitelistFragment("deprecated-" + propertyName, bsns);
+            bindWhitelistFragment(fragment);
+            backwardsCompatibleFragments.put(propertyName, fragment);
+        }
+        
+        if (oldFragment != null) {
+            unbindWhitelistFragment(oldFragment);
         }
     }
 }

Modified: sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistConfiguration.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistConfiguration.java?rev=1788436&r1=1788435&r2=1788436&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistConfiguration.java (original)
+++ sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistConfiguration.java Fri Mar 24 13:09:04 2017
@@ -53,23 +53,11 @@ import org.osgi.service.metatype.annotat
      *
      * @return The configured regular exression.
      */
+    @AttributeDefinition(
+            name = "Whitelist regexp",
+            description = "Regular expression for bundle symbolic names for which loginAdministrative() " +
+                    "is allowed. NOT recommended for production use, but useful for testing with " +
+                    "generated bundles."
+    )
     String whitelist_bundles_regexp() default "";
-
-    /**
-     * Default list of bundle symbolic names for which loginAdministrative() is allowed.
-     *
-     * @return The default whitelisted BSNs
-     * @deprecated use {@link WhitelistFragment} configurations instead
-     */
-    @Deprecated
-    String[] whitelist_bundles_default() default {};
-
-    /**
-     * Additional list of bundle symbolic names for which loginAdministrative() is allowed.
-     *
-     * @return Additional whitelisted BSNs
-     * @deprecated use {@link WhitelistFragment} configurations instead
-     */
-    @Deprecated
-    String[] whitelist_bundles_additional() default {};
 }

Modified: sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/WhitelistFragment.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/WhitelistFragment.java?rev=1788436&r1=1788435&r2=1788436&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/WhitelistFragment.java (original)
+++ sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/WhitelistFragment.java Fri Mar 24 13:09:04 2017
@@ -25,7 +25,9 @@ import org.osgi.service.metatype.annotat
 import org.osgi.service.metatype.annotations.Designate;
 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
 
-import java.util.List;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
 
 import static java.util.Arrays.asList;
 
@@ -62,23 +64,24 @@ public class WhitelistFragment {
 
     private String name;
 
-    private List<String> bundles;
+    private Set<String> bundles;
 
     @SuppressWarnings("unused")
     public WhitelistFragment() {
         // default constructor for SCR
     }
 
+    // constructor for tests and for backwards compatible deprecated fragments
     WhitelistFragment(String name, String[] bundles) {
         this.name = name;
-        this.bundles = asList(bundles);
+        this.bundles = asSet(bundles);
     }
 
     @Activate
     @SuppressWarnings("unused")
     void activate(Configuration config) {
         name = config.whitelist_name();
-        bundles = asList(config.whitelist_bundles() == null ? new String[0] : config.whitelist_bundles());
+        bundles = asSet(config.whitelist_bundles());
     }
 
     boolean allows(String bsn) {
@@ -89,4 +92,28 @@ public class WhitelistFragment {
     public String toString() {
         return name + ": " + bundles + "";
     }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof WhitelistFragment)) {
+            return false;
+        }
+        final WhitelistFragment that = (WhitelistFragment) o;
+        return name.equals(that.name)
+                && bundles.equals(that.bundles);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name.hashCode();
+        result = 31 * result + bundles.hashCode();
+        return result;
+    }
+
+    private Set<String> asSet(final String[] values) {
+        return Collections.unmodifiableSet(new HashSet<String>(asList(values)));
+    }
 }

Modified: sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistTest.java?rev=1788436&r1=1788435&r2=1788436&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistTest.java (original)
+++ sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistTest.java Fri Mar 24 13:09:04 2017
@@ -59,7 +59,7 @@ public class LoginAdminWhitelistTest {
 
     @Test
     public void testBypassWhitelist() throws ConfigurationException {
-        whitelist.configure(config(true, null, null, null));
+        configure(whitelist, true, null, null, null);
         
         for(String bsn : randomBsn()) {
             assertAdminLogin(bsn, true);
@@ -71,7 +71,7 @@ public class LoginAdminWhitelistTest {
         final String [] allowed = {
                 "bundle1", "bundle2"
         };
-        whitelist.configure(config(null, null, allowed, null));
+        configure(whitelist, null, null, allowed, null);
 
         assertAdminLogin("foo.1.bar", false);
 
@@ -89,8 +89,7 @@ public class LoginAdminWhitelistTest {
         final String [] allowed = {
                 "bundle5", "bundle6"
         };
-        final LoginAdminWhitelistConfiguration config = config(null, null, null, allowed);
-        whitelist.configure(config);
+        configure(whitelist, null, null, null, allowed);
 
         assertAdminLogin("foo.1.bar", false);
 
@@ -105,7 +104,7 @@ public class LoginAdminWhitelistTest {
     
     @Test
     public void testDefaultAndAdditionalConfig() throws ConfigurationException {
-        whitelist.configure(config(null, null, new String [] { "defB"}, new String [] { "addB"}));
+        configure(whitelist, null, null, new String [] { "defB"}, new String [] { "addB"});
         
         assertAdminLogin("defB", true);
         assertAdminLogin("addB", true);
@@ -121,7 +120,7 @@ public class LoginAdminWhitelistTest {
         final String [] allowed = {
                 "bundle3", "bundle4"
         };
-        whitelist.configure(config(null, "foo.*bar", allowed, null));
+        configure(whitelist, null, "foo.*bar", allowed, null);
 
         assertAdminLogin("foo.2.bar", true);
         assertAdminLogin("foo.somethingElse.bar", true);
@@ -144,7 +143,7 @@ public class LoginAdminWhitelistTest {
         final WhitelistFragment testFragment1 = new WhitelistFragment("test1", allowed1);
         final WhitelistFragment testFragment2 = new WhitelistFragment("test2", allowed2);
 
-        whitelist.configure(config(null, null, null, null));
+        configure(whitelist, null, null, null, null);
         whitelist.bindWhitelistFragment(testFragment1);
         whitelist.bindWhitelistFragment(testFragment2);
 
@@ -171,8 +170,7 @@ public class LoginAdminWhitelistTest {
         }
     }
 
-
-    private LoginAdminWhitelistConfiguration config(final Boolean bypass, final String regexp, final String[] defaultBSNs, final String[] additionalBSNs) throws ConfigurationException {
+    private void configure(final LoginAdminWhitelist whitelist, final Boolean bypass, final String regexp, final String[] defaultBSNs, final String[] additionalBSNs) throws ConfigurationException {
         final Hashtable<String, Object> props = new Hashtable<>();
         if (bypass != null) {
             props.put("whitelist.bypass", bypass);
@@ -186,6 +184,8 @@ public class LoginAdminWhitelistTest {
         if (additionalBSNs != null) {
             props.put("whitelist.bundles.additional", additionalBSNs);
         }
-        return ConfigAnnotationUtil.fromDictionary(LoginAdminWhitelistConfiguration.class, props);
+        LoginAdminWhitelistConfiguration configuration =
+                ConfigAnnotationUtil.fromDictionary(LoginAdminWhitelistConfiguration.class, props);
+        whitelist.configure(configuration, props);
     }
 }
\ No newline at end of file