Merge pull request #11 from apache/issues/SLING-11741
Issues/sling 11741
diff --git a/pom.xml b/pom.xml
index d4708af..237db2b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.apache.sling</groupId>
<artifactId>sling-bundle-parent</artifactId>
- <version>49</version>
+ <version>52</version>
<relativePath />
</parent>
@@ -83,15 +83,15 @@
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.jcr.api</artifactId>
- <version>2.4.0</version>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.util.converter</artifactId>
+ <version>1.0.9</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.osgi</artifactId>
- <version>2.4.2</version>
+ <artifactId>org.apache.sling.jcr.api</artifactId>
+ <version>2.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -146,26 +146,32 @@
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.testing.osgi-mock</artifactId>
- <version>3.3.6</version>
+ <artifactId>org.apache.sling.testing.osgi-mock.junit4</artifactId>
+ <version>3.3.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.testing.sling-mock</artifactId>
- <version>3.4.4</version>
+ <artifactId>org.apache.sling.testing.sling-mock.junit4</artifactId>
+ <version>3.4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.jcr-mock</artifactId>
- <version>1.6.6</version>
+ <version>1.6.10</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.osgi</artifactId>
+ <version>2.4.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <version>1.9.5</version>
+ <artifactId>mockito-core</artifactId>
+ <version>5.4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java b/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java
index 9082158..c91f7e0 100644
--- a/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java
+++ b/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java
@@ -441,12 +441,12 @@
*/
@Override
public final Session loginAdministrative(final String workspace) throws RepositoryException {
- final boolean whitelisted = getSlingRepositoryManager().allowLoginAdministrativeForBundle(usingBundle);
+ final boolean allowed = getSlingRepositoryManager().allowLoginAdministrativeForBundle(usingBundle);
- if(!whitelisted) {
+ if(!allowed) {
final String symbolicName = usingBundle.getSymbolicName();
- logger.error("Bundle {} is NOT whitelisted to use SlingRepository.loginAdministrative", symbolicName);
- throw new LoginException("Bundle " + symbolicName +" is NOT whitelisted");
+ logger.error("Bundle {} is NOT allow listed to use SlingRepository.loginAdministrative", symbolicName);
+ throw new LoginException("Bundle " + symbolicName +" is NOT allow listed");
} else if (this.getSlingRepositoryManager().isDisableLoginAdministrative()) {
logger.error("SlingRepository.loginAdministrative is disabled. Please use SlingRepository.loginService.");
throw new LoginException("SlingRepository.loginAdministrative is disabled.");
diff --git a/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java b/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java
index e19ba44..1ea27a8 100644
--- a/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java
+++ b/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java
@@ -33,7 +33,7 @@
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.api.SlingRepositoryInitializer;
import org.apache.sling.jcr.base.internal.loader.Loader;
-import org.apache.sling.jcr.base.internal.LoginAdminWhitelist;
+import org.apache.sling.jcr.base.internal.LoginAdminAllowList;
import org.apache.sling.jcr.base.internal.mount.ProxyJackrabbitRepository;
import org.apache.sling.jcr.base.internal.mount.ProxyRepository;
import org.apache.sling.jcr.base.spi.RepositoryMount;
@@ -120,7 +120,7 @@
private volatile Loader loader;
- private volatile ServiceTracker<LoginAdminWhitelist, LoginAdminWhitelist> whitelistTracker;
+ private volatile ServiceTracker<LoginAdminAllowList, LoginAdminAllowList> allowListTracker;
private final Object repoInitLock = new Object();
@@ -181,7 +181,7 @@
* to use {@code loginAdministrative}.
*/
protected boolean allowLoginAdministrativeForBundle(final Bundle bundle) {
- return whitelistTracker.getService().allowLoginAdministrative(bundle);
+ return allowListTracker.getService().allowLoginAdministrative(bundle);
}
/**
@@ -514,36 +514,36 @@
this.repoInitializerTracker.open();
// If allowLoginAdministrativeForBundle is overridden we assume we don't need
- // a LoginAdminWhitelist service - that's the case if the derived class
- // implements its own strategy and the LoginAdminWhitelist interface is
+ // a LoginAdminAllowList service - that's the case if the derived class
+ // implements its own strategy and the LoginAdminAllowList interface is
// not exported by this bundle anyway, so cannot be implemented differently.
- boolean enableWhitelist = !isAllowLoginAdministrativeForBundleOverridden();
- final CountDownLatch waitForWhitelist = new CountDownLatch(enableWhitelist ? 1 : 0);
- if (enableWhitelist) {
- whitelistTracker = new ServiceTracker<LoginAdminWhitelist, LoginAdminWhitelist>(bundleContext, LoginAdminWhitelist.class, null) {
+ boolean enableAllowlist = !isAllowLoginAdministrativeForBundleOverridden();
+ final CountDownLatch waitForAllowList = new CountDownLatch(enableAllowlist ? 1 : 0);
+ if (enableAllowlist) {
+ allowListTracker = new ServiceTracker<LoginAdminAllowList, LoginAdminAllowList>(bundleContext, LoginAdminAllowList.class, null) {
@Override
- public LoginAdminWhitelist addingService(final ServiceReference<LoginAdminWhitelist> reference) {
+ public LoginAdminAllowList addingService(final ServiceReference<LoginAdminAllowList> reference) {
try {
return super.addingService(reference);
} finally {
- waitForWhitelist.countDown();
+ waitForAllowList.countDown();
}
}
};
- whitelistTracker.open();
+ allowListTracker.open();
}
- // start repository asynchronously to allow LoginAdminWhitelist to become available
- // NOTE: making this conditional allows tests to register a mock whitelist before
+ // start repository asynchronously to allow LoginAdminAllowList to become available
+ // NOTE: making this conditional allows tests to register a mock allow list before
// activating the RepositoryManager, so they don't need to deal with async startup
startupThread = new Thread("Apache Sling Repository Startup Thread #" + startupCounter.incrementAndGet()) {
@Override
public void run() {
try {
- waitForWhitelist.await();
+ waitForAllowList.await();
initializeAndRegisterRepositoryService();
} catch (InterruptedException e) {
- log.warn("Interrupted while waiting for the {} service, cancelling repository initialisation. {}", LoginAdminWhitelist.class.getSimpleName(), INTERRUPTED_EXCEPTION_NOTE, e);
+ log.warn("Interrupted while waiting for the {} service, cancelling repository initialisation. {}", LoginAdminAllowList.class.getSimpleName(), INTERRUPTED_EXCEPTION_NOTE, e);
Thread.currentThread().interrupt();
}
}
@@ -686,9 +686,9 @@
repoInitializerTracker = null;
}
- if (whitelistTracker != null) {
- whitelistTracker.close();
- whitelistTracker = null;
+ if (allowListTracker != null) {
+ allowListTracker.close();
+ allowListTracker = null;
}
this.repositoryService = null;
diff --git a/src/main/java/org/apache/sling/jcr/base/internal/WhitelistFragment.java b/src/main/java/org/apache/sling/jcr/base/internal/AllowListFragment.java
similarity index 65%
rename from src/main/java/org/apache/sling/jcr/base/internal/WhitelistFragment.java
rename to src/main/java/org/apache/sling/jcr/base/internal/AllowListFragment.java
index 81184a4..2c00dde 100644
--- a/src/main/java/org/apache/sling/jcr/base/internal/WhitelistFragment.java
+++ b/src/main/java/org/apache/sling/jcr/base/internal/AllowListFragment.java
@@ -32,9 +32,9 @@
import static java.util.Arrays.asList;
@ObjectClassDefinition(
- name = "Apache Sling Login Admin Whitelist Configuration Fragment",
- description = "Whitelist configuration fragments contribute a list of whitelisted bundle symbolic " +
- "names to the Login Admin Whitelist. This allows for modularisation of the whitelist."
+ name = "Apache Sling Login Admin Allow List Configuration Fragment",
+ description = "This list of Bundle Symbolic Names is added to the list of bundles which are allowed " +
+ "to use Administrative Login. The full list is built in a modular way out of all such configuration fragments."
)
@interface Configuration {
@@ -42,55 +42,55 @@
name = "Name",
description = "Optional name to disambiguate configurations."
)
- String whitelist_name() default "[unnamed]";
+ String allowlist_name() default "[unnamed]";
@AttributeDefinition(
- name = "Whitelisted BSNs",
+ name = "Allow listed BSNs",
description = "A list of bundle symbolic names allowed to use loginAdministrative()."
)
- String[] whitelist_bundles();
+ String[] allowlist_bundles();
- @SuppressWarnings("unused")
- String webconsole_configurationFactory_nameHint() default "{whitelist.name}: [{whitelist.bundles}]";
+ @SuppressWarnings({"unused", "java:S100"})
+ String webconsole_configurationFactory_nameHint() default "{allowlist.name}: [{allowlist.bundles}]";
}
@Component(
- configurationPid = "org.apache.sling.jcr.base.internal.LoginAdminWhitelist.fragment",
+ configurationPid = AllowListFragment.FACTORY_PID,
configurationPolicy = ConfigurationPolicy.REQUIRE,
- service = WhitelistFragment.class
+ service = AllowListFragment.class
)
@Designate(ocd = Configuration.class, factory = true)
-public class WhitelistFragment {
+public class AllowListFragment {
- private String name;
+ public static final String FACTORY_PID = "org.apache.sling.jcr.base.LoginAdminAllowList.fragment";
- private Set<String> bundles;
+ final String name;
- @SuppressWarnings("unused")
- public WhitelistFragment() {
- // default constructor for SCR
+ final Set<String> bundles;
+
+ /**
+ * Constructor for SCR
+ * @param config Configuration
+ */
+ @Activate
+ public AllowListFragment(final Configuration config) {
+ this.name = config.allowlist_name();
+ this.bundles = asSet(config.allowlist_bundles());
}
// constructor for tests and for backwards compatible deprecated fragments
- WhitelistFragment(String name, String[] bundles) {
+ AllowListFragment(String name, String[] bundles) {
this.name = name;
this.bundles = asSet(bundles);
}
- @Activate
- @SuppressWarnings("unused")
- void activate(Configuration config) {
- name = config.whitelist_name();
- bundles = asSet(config.whitelist_bundles());
- }
-
- boolean allows(String bsn) {
+ boolean allows(final String bsn) {
return bundles.contains(bsn);
}
@Override
public String toString() {
- return name + ": " + bundles + "";
+ return name + ": " + bundles;
}
@Override
@@ -98,10 +98,10 @@
if (this == o) {
return true;
}
- if (!(o instanceof WhitelistFragment)) {
+ if (!(o instanceof AllowListFragment)) {
return false;
}
- final WhitelistFragment that = (WhitelistFragment) o;
+ final AllowListFragment that = (AllowListFragment) o;
return name.equals(that.name)
&& bundles.equals(that.bundles);
}
@@ -114,6 +114,6 @@
}
private Set<String> asSet(final String[] values) {
- return Collections.unmodifiableSet(new HashSet<String>(asList(values)));
+ return Collections.unmodifiableSet(new HashSet<>(asList(values)));
}
}
diff --git a/src/main/java/org/apache/sling/jcr/base/internal/LegacyFragment.java b/src/main/java/org/apache/sling/jcr/base/internal/LegacyFragment.java
new file mode 100644
index 0000000..eae6249
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/base/internal/LegacyFragment.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jcr.base.internal;
+
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+
+/**
+ * Legacy fragment configuration. Use {@link AllowListFragment} instead.
+ */
+@Component(
+ configurationPid = LegacyFragment.LEGACY_FACTORY_PID,
+ configurationPolicy = ConfigurationPolicy.REQUIRE,
+ service = AllowListFragment.class
+)
+public class LegacyFragment extends AllowListFragment {
+
+ public static final String LEGACY_FACTORY_PID = "org.apache.sling.jcr.base.internal.LoginAdminWhitelist.fragment";
+
+ public @interface Configuration {
+ @SuppressWarnings("java:S100")
+ String whitelist_name() default "[unnamed]";
+
+ @SuppressWarnings("java:S100")
+ String[] whitelist_bundles();
+ }
+
+
+ @Activate
+ public LegacyFragment(Configuration configuration) {
+ super(configuration.whitelist_name(), configuration.whitelist_bundles());
+ LoginAdminAllowList.LOG.warn("Using deprecated factory configuration '{}' with whitelist.name='{}'. " +
+ "Update your configuration to use configuration '{}' instead.",
+ LEGACY_FACTORY_PID, configuration.whitelist_name(), AllowListFragment.FACTORY_PID);
+ }
+}
diff --git a/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminAllowList.java b/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminAllowList.java
new file mode 100644
index 0000000..ef85849
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminAllowList.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+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;
+
+import org.apache.sling.jcr.api.SlingRepository;
+import org.osgi.framework.Bundle;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Modified;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
+import org.osgi.util.converter.Converters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Allow list that defines which bundles can use the
+ * {@link SlingRepository#loginAdministrative} method.
+ *
+ * The default configuration lets a few trusted Sling bundles
+ * use the loginAdministrative method.
+ */
+@Component(service = LoginAdminAllowList.class,
+ configurationPid = {LoginAdminAllowList.PID, LoginAdminAllowList.LEGACY_PID}
+)
+public class LoginAdminAllowList {
+
+ public static final String PID = "org.apache.sling.jcr.base.LoginAdminAllowList";
+
+ public static final String LEGACY_PID = "org.apache.sling.jcr.base.internal.LoginAdminWhitelist";
+
+ static final Logger LOG = LoggerFactory.getLogger(LoginAdminAllowList.class);
+
+ // for backwards compatibility only (read properties directly to prevent them from appearing in the metatype)
+ private static final String LEGACY_BYPASS_PROPERTY = "whitelist.bypass";
+
+ private static final String LEGACY_BUNDLES_PROPERTY = "whitelist.bundles.regexp";
+
+ private static final String PROP_LEGACY_BUNDLES_DEFAULT = "whitelist.bundles.default";
+
+ private static final String PROP_LEGACY_BUNDLES_ADDITIONAL = "whitelist.bundles.additional";
+
+ @SuppressWarnings("java:S3077")
+ // java:S3077 - the field is updated and read atomically, and the object is
+ // immutable, hence the use of "volatile" is adequate
+ private volatile ConfigurationState config;
+
+ private final List<AllowListFragment> allowListFragments = new CopyOnWriteArrayList<>();
+
+ private final Map<String, AllowListFragment> backwardsCompatibleFragments = new ConcurrentHashMap<>();
+
+ @Reference(
+ cardinality = ReferenceCardinality.MULTIPLE,
+ policy = ReferencePolicy.DYNAMIC,
+ policyOption = ReferencePolicyOption.GREEDY
+ )
+ void bindAllowListFragment(AllowListFragment fragment) {
+ allowListFragments.add(fragment);
+ LOG.info("AllowListFragment added '{}'", fragment);
+ }
+
+ void unbindAllowListFragment(AllowListFragment fragment) {
+ allowListFragments.remove(fragment);
+ LOG.info("AllowListFragment removed '{}'", fragment);
+ }
+
+ @Activate @Modified
+ void configure(final LoginAdminAllowListConfiguration configuration, final Map<String, Object> properties) {
+ this.config = new ConfigurationState(configuration, properties);
+ ensureBackwardsCompatibility(properties, PROP_LEGACY_BUNDLES_DEFAULT);
+ ensureBackwardsCompatibility(properties, PROP_LEGACY_BUNDLES_ADDITIONAL);
+ }
+
+ public boolean allowLoginAdministrative(Bundle b) {
+ // create local copy of ConfigurationState to avoid reading mixed configurations during an configure
+ final ConfigurationState localConfig = this.config;
+ if (localConfig == null) {
+ throw new IllegalStateException("LoginAdminAllowList has no configuration.");
+ }
+
+ if(localConfig.bypassAllowList) {
+ LOG.debug("Allow list is bypassed, all bundles allowed to use loginAdministrative");
+ return true;
+ }
+
+ final String bsn = b.getSymbolicName();
+
+ if(localConfig.allowListRegexp != null && localConfig.allowListRegexp.matcher(bsn).matches()) {
+ LOG.debug("{} is allow listed to use loginAdministrative, by regexp", bsn);
+ return true;
+ }
+
+ for (final AllowListFragment fragment : allowListFragments) {
+ if (fragment.allows(bsn)) {
+ LOG.debug("{} is allow listed to use loginAdministrative, by allow list fragment '{}'",
+ bsn, fragment);
+ return true;
+ }
+ }
+
+ LOG.debug("{} is not allow listed to use loginAdministrative", bsn);
+ return false;
+ }
+
+ // encapsulate configuration state for atomic configuration updates
+ static class ConfigurationState {
+
+ public final boolean bypassAllowList;
+
+ public final Pattern allowListRegexp;
+
+ ConfigurationState(final LoginAdminAllowListConfiguration config, final Map<String, Object> properties) {
+ // first check for legacy properties
+ boolean bypass = config.allowlist_bypass();
+ final Object legacyBypassObject = properties.get(LEGACY_BYPASS_PROPERTY);
+ if (legacyBypassObject != null) {
+ LOG.warn("Using deprecated configuration property '{}' from configuration '{}'. " +
+ "Update your configuration to use configuration '{}' and property '{}' instead.",
+ LEGACY_BYPASS_PROPERTY, LEGACY_PID, PID, "allowlist.bypass");
+ bypass = Converters.standardConverter().convert(legacyBypassObject).defaultValue(false).to(Boolean.class);
+ }
+ String legacyRegexp = null;
+ final Object legacyBundlesObject = properties.get(LEGACY_BUNDLES_PROPERTY);
+ if (legacyBypassObject != null) {
+ LOG.warn("Using deprecated configuration property '{}' from configuration '{}'. " +
+ "Update your configuration to use configuration '{}' and property '{}' instead.",
+ LEGACY_BUNDLES_PROPERTY, LEGACY_PID, PID, "allowlist.bundles.regexp");
+ legacyRegexp = Converters.standardConverter().convert(legacyBundlesObject).to(String.class);
+ }
+
+ final String regexp = config.allowlist_bundles_regexp();
+ if (regexp.trim().length() > 0) {
+ if (legacyRegexp != null) {
+ LOG.warn("Both deprecated configuration property '{}' and non-deprecated configuration property '{}' are set. " +
+ "The deprecated property '{}' is ignored.",
+ LEGACY_BUNDLES_PROPERTY, "allowlist.bundles.regexp", LEGACY_BUNDLES_PROPERTY);
+ }
+ this.allowListRegexp = Pattern.compile(regexp);
+ } else {
+ this.allowListRegexp = legacyRegexp != null ? Pattern.compile(legacyRegexp) : null;
+ }
+ if (this.allowListRegexp != null) {
+ LOG.warn("A 'allowlist.bundles.regexp' is configured, this is NOT RECOMMENDED for production: {}", allowListRegexp);
+ }
+ this.bypassAllowList = bypass;
+ if (this.bypassAllowList) {
+ LOG.info("allowlist.bypass=true, allowed BSNs=<ALL>");
+ LOG.warn("All bundles are allowed to use loginAdministrative due to the 'allowlist.bypass' " +
+ "configuration of this service. This is NOT RECOMMENDED, for security reasons."
+ );
+ }
+ }
+ }
+
+ private void ensureBackwardsCompatibility(final Map<String, Object> properties, final String propertyName) {
+ final AllowListFragment oldFragment = backwardsCompatibleFragments.remove(propertyName);
+
+ final String[] bsns = Converters.standardConverter().convert(properties.get(propertyName)).to(String[].class);
+ if (bsns != null && bsns.length != 0) {
+ LOG.warn("Using deprecated configuration property '{}'", propertyName);
+ final AllowListFragment fragment = new AllowListFragment("deprecated-" + propertyName, bsns);
+ bindAllowListFragment(fragment);
+ backwardsCompatibleFragments.put(propertyName, fragment);
+ }
+
+ if (oldFragment != null) {
+ unbindAllowListFragment(oldFragment);
+ }
+ }
+}
diff --git a/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistConfiguration.java b/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminAllowListConfiguration.java
similarity index 86%
rename from src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistConfiguration.java
rename to src/main/java/org/apache/sling/jcr/base/internal/LoginAdminAllowListConfiguration.java
index 62df245..a3e625e 100644
--- a/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistConfiguration.java
+++ b/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminAllowListConfiguration.java
@@ -22,24 +22,25 @@
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@ObjectClassDefinition(
- name = "Apache Sling Login Admin Whitelist",
+ pid = LoginAdminAllowList.PID,
+ name = "Apache Sling Login Admin Allowlist",
description = "Defines which bundles can use SlingRepository.loginAdministrative()"
)
-@interface LoginAdminWhitelistConfiguration {
+@interface LoginAdminAllowListConfiguration {
/**
- * Need to allow for bypassing the whitelist, for backwards
+ * Need to allow for bypassing the allowlist, for backwards
* compatibility with previous Sling versions which didn't
* implement it. Setting this to true is not recommended
* and logged as a warning.
*/
@AttributeDefinition(
- name = "Bypass the whitelist",
+ name = "Bypass the allowlist",
description = "Allow all bundles to use loginAdministrative(). Should ONLY be used " +
"for backwards compatibility reasons and if you are aware of " +
"the related security risks."
)
- boolean whitelist_bypass() default false;
+ boolean allowlist_bypass() default false;
/**
* Regular expression for bundle symbolic names for which loginAdministrative()
@@ -54,10 +55,10 @@
* @return The configured regular exression.
*/
@AttributeDefinition(
- name = "Whitelist regexp",
+ name = "Allowlist 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 "";
+ String allowlist_bundles_regexp() default "";
}
diff --git a/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelist.java b/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelist.java
deleted file mode 100644
index 5bd5d38..0000000
--- a/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelist.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-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;
-
-import org.apache.sling.jcr.api.SlingRepository;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Modified;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferenceCardinality;
-import org.osgi.service.component.annotations.ReferencePolicy;
-import org.osgi.service.component.annotations.ReferencePolicyOption;
-import org.osgi.service.metatype.annotations.Designate;
-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.
- *
- * The default configuration lets a few trusted Sling bundles
- * use the loginAdministrative method.
- */
-@Component(
- service = LoginAdminWhitelist.class,
- property = {
- Constants.SERVICE_DESCRIPTION + "=Apache Sling Login Admin Whitelist",
- Constants.SERVICE_VENDOR + "=The Apache Software Foundation"
- }
-)
-@Designate(
- ocd = LoginAdminWhitelistConfiguration.class
-)
-public class LoginAdminWhitelist {
-
- private static final Logger LOG = LoggerFactory.getLogger(LoginAdminWhitelist.class);
-
- private volatile ConfigurationState config;
-
- 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";
-
- private static final String PROP_WHITELIST_BUNDLES_ADDITIONAL = "whitelist.bundles.additional";
-
- private final Map<String, WhitelistFragment> backwardsCompatibleFragments =
- new ConcurrentHashMap<String, WhitelistFragment>();
-
- @Reference(
- cardinality = ReferenceCardinality.MULTIPLE,
- policy = ReferencePolicy.DYNAMIC,
- policyOption = ReferencePolicyOption.GREEDY
- ) @SuppressWarnings("unused")
- void bindWhitelistFragment(WhitelistFragment fragment) {
- whitelistFragments.add(fragment);
- LOG.info("WhitelistFragment added '{}'", fragment);
- }
-
- @SuppressWarnings("unused")
- void unbindWhitelistFragment(WhitelistFragment fragment) {
- whitelistFragments.remove(fragment);
- LOG.info("WhitelistFragment removed '{}'", fragment);
- }
-
- @Activate @Modified @SuppressWarnings("unused")
- void configure(LoginAdminWhitelistConfiguration configuration, Map<String, Object> properties) {
- this.config = new ConfigurationState(configuration);
- ensureBackwardsCompatibility(properties, PROP_WHITELIST_BUNDLES_DEFAULT);
- ensureBackwardsCompatibility(properties, PROP_WHITELIST_BUNDLES_ADDITIONAL);
- }
-
- public boolean allowLoginAdministrative(Bundle b) {
- if (config == null) {
- throw new IllegalStateException("LoginAdminWhitelist has no configuration.");
- }
- // create local copy of ConfigurationState to avoid reading mixed configurations during an configure
- final ConfigurationState localConfig = this.config;
- if(localConfig.bypassWhitelist) {
- LOG.debug("Whitelist is bypassed, all bundles allowed to use loginAdministrative");
- return true;
- }
-
- final String bsn = b.getSymbolicName();
-
- if(localConfig.whitelistRegexp != null && localConfig.whitelistRegexp.matcher(bsn).matches()) {
- LOG.debug("{} is whitelisted to use loginAdministrative, by regexp", bsn);
- return true;
- }
-
- for (final WhitelistFragment fragment : whitelistFragments) {
- if (fragment.allows(bsn)) {
- LOG.debug("{} is whitelisted to use loginAdministrative, by whitelist fragment '{}'",
- bsn, fragment);
- return true;
- }
- }
-
- LOG.debug("{} is not whitelisted to use loginAdministrative", bsn);
- return false;
- }
-
- // encapsulate configuration state for atomic configuration updates
- private static class ConfigurationState {
-
- private final boolean bypassWhitelist;
-
- private final Pattern whitelistRegexp;
-
- private ConfigurationState(final LoginAdminWhitelistConfiguration config) {
- 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: {}",
- whitelistRegexp);
- } else {
- whitelistRegexp = null;
- }
-
- 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 'whitelist.bypass' " +
- "configuration of this service. This is NOT RECOMMENDED, for security reasons."
- );
- }
- }
- }
-
- @SuppressWarnings("deprecated")
- 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);
- }
- }
-}
diff --git a/src/main/java/org/apache/sling/jcr/base/internal/mount/ProxyJackrabbitSession.java b/src/main/java/org/apache/sling/jcr/base/internal/mount/ProxyJackrabbitSession.java
index 97ee586..ba529e7 100644
--- a/src/main/java/org/apache/sling/jcr/base/internal/mount/ProxyJackrabbitSession.java
+++ b/src/main/java/org/apache/sling/jcr/base/internal/mount/ProxyJackrabbitSession.java
@@ -18,7 +18,6 @@
*/
package org.apache.sling.jcr.base.internal.mount;
-import java.util.HashSet;
import java.util.Set;
import javax.jcr.AccessDeniedException;
import javax.jcr.Item;
diff --git a/src/test/java/org/apache/sling/jcr/base/MockSlingRepositoryManager.java b/src/test/java/org/apache/sling/jcr/base/MockSlingRepositoryManager.java
index cecb298..c3de220 100644
--- a/src/test/java/org/apache/sling/jcr/base/MockSlingRepositoryManager.java
+++ b/src/test/java/org/apache/sling/jcr/base/MockSlingRepositoryManager.java
@@ -36,25 +36,25 @@
/** Minimal AbstractSlingRepositoryManager used for testing */
public class MockSlingRepositoryManager extends AbstractSlingRepositoryManager {
- public static final String WHITELIST_ALL = "*";
+ public static final String ALLOWLIST_ALL = "*";
- public static final String WHITELIST_NONE = "";
+ public static final String ALLOWLIST_NONE = "";
private final Repository repository;
private boolean loginAdminDisabled;
- private Set<String> loginAdminWhitelist;
+ private Set<String> loginAdminAllowList;
public MockSlingRepositoryManager(Repository repository) {
- this(repository, false, WHITELIST_ALL);
+ this(repository, false, ALLOWLIST_ALL);
}
- public MockSlingRepositoryManager(Repository repository, boolean loginAdminDisabled, String... loginAdminWhitelist) {
+ public MockSlingRepositoryManager(Repository repository, boolean loginAdminDisabled, String... loginAdminAllowList) {
this.repository = repository;
this.loginAdminDisabled = loginAdminDisabled;
- this.loginAdminWhitelist = new HashSet<>(Arrays.asList(loginAdminWhitelist));
- this.loginAdminWhitelist.remove(WHITELIST_NONE);
+ this.loginAdminAllowList = new HashSet<>(Arrays.asList(loginAdminAllowList));
+ this.loginAdminAllowList.remove(ALLOWLIST_NONE);
}
@Override
@@ -94,7 +94,7 @@
@Override
protected boolean allowLoginAdministrativeForBundle(final Bundle bundle) {
- return loginAdminWhitelist.contains("*") || loginAdminWhitelist.contains(bundle.getSymbolicName());
+ return loginAdminAllowList.contains("*") || loginAdminAllowList.contains(bundle.getSymbolicName());
}
public void activate(BundleContext context) {
diff --git a/src/test/java/org/apache/sling/jcr/base/RepositoryInitializersTest.java b/src/test/java/org/apache/sling/jcr/base/RepositoryInitializersTest.java
index 16832f0..d6f0b8b 100644
--- a/src/test/java/org/apache/sling/jcr/base/RepositoryInitializersTest.java
+++ b/src/test/java/org/apache/sling/jcr/base/RepositoryInitializersTest.java
@@ -83,7 +83,7 @@
private void registerInitializer(String id, int serviceRanking) {
final SlingRepositoryInitializer init = new TestInitializer(id);
final Hashtable<String, Object> props = new Hashtable<String, Object>();
- props.put(Constants.SERVICE_RANKING, new Integer(serviceRanking));
+ props.put(Constants.SERVICE_RANKING, serviceRanking);
context.bundleContext().registerService(SlingRepositoryInitializer.class.getName(), init, props);
}
diff --git a/src/test/java/org/apache/sling/jcr/base/internal/WhitelistWiringTest.java b/src/test/java/org/apache/sling/jcr/base/internal/AllowListWiringTest.java
similarity index 87%
rename from src/test/java/org/apache/sling/jcr/base/internal/WhitelistWiringTest.java
rename to src/test/java/org/apache/sling/jcr/base/internal/AllowListWiringTest.java
index ef14d62..e02b476 100644
--- a/src/test/java/org/apache/sling/jcr/base/internal/WhitelistWiringTest.java
+++ b/src/test/java/org/apache/sling/jcr/base/internal/AllowListWiringTest.java
@@ -18,8 +18,8 @@
*/
package org.apache.sling.jcr.base.internal;
-import static org.apache.sling.jcr.base.MockSlingRepositoryManager.WHITELIST_ALL;
-import static org.apache.sling.jcr.base.MockSlingRepositoryManager.WHITELIST_NONE;
+import static org.apache.sling.jcr.base.MockSlingRepositoryManager.ALLOWLIST_ALL;
+import static org.apache.sling.jcr.base.MockSlingRepositoryManager.ALLOWLIST_NONE;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
@@ -44,19 +44,19 @@
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
-/** Verify that the AbstractSlingRepository2 uses the login admin whitelist,
+/** Verify that the AbstractSlingRepository2 uses the login admin allow list,
* as well as its combination with the global "disable login admin" flag
*/
@RunWith(Parameterized.class)
-public class WhitelistWiringTest {
+public class AllowListWiringTest {
private SlingRepository repository;
private final boolean managerAllowsLoginAdmin;
- private final boolean whitelistAllowsLoginAdmin;
+ private final boolean allowListAllowsLoginAdmin;
private final boolean loginAdminExpected;
- @Parameters(name="manager {0}, whitelist {1} -> {2}")
+ @Parameters(name="manager {0}, allow list {1} -> {2}")
public static Collection<Object[]> data() {
final List<Object[]> result = new ArrayList<Object[]>();
result.add(new Object[] { false, false, false });
@@ -66,9 +66,9 @@
return result;
}
- public WhitelistWiringTest(boolean managerAllowsLoginAdmin, boolean whitelistAllowsLoginAdmin, boolean loginAdminExpected) {
+ public AllowListWiringTest(boolean managerAllowsLoginAdmin, boolean allowListAllowsLoginAdmin, boolean loginAdminExpected) {
this.managerAllowsLoginAdmin = managerAllowsLoginAdmin;
- this.whitelistAllowsLoginAdmin = whitelistAllowsLoginAdmin;
+ this.allowListAllowsLoginAdmin = allowListAllowsLoginAdmin;
this.loginAdminExpected = loginAdminExpected;
}
@@ -77,10 +77,10 @@
BundleContext bundleContext = MockOsgi.newBundleContext();
Bundle bundle = bundleContext.getBundle();
- String whitelist = whitelistAllowsLoginAdmin ? WHITELIST_ALL : WHITELIST_NONE;
+ String allowList = allowListAllowsLoginAdmin ? ALLOWLIST_ALL : ALLOWLIST_NONE;
final MockSlingRepositoryManager repoMgr =
- new MockSlingRepositoryManager(MockJcr.newRepository(), !managerAllowsLoginAdmin, whitelist);
+ new MockSlingRepositoryManager(MockJcr.newRepository(), !managerAllowsLoginAdmin, allowList);
repoMgr.activate(bundleContext);
diff --git a/src/test/java/org/apache/sling/jcr/base/internal/LegacyFragmentTest.java b/src/test/java/org/apache/sling/jcr/base/internal/LegacyFragmentTest.java
new file mode 100644
index 0000000..62556cb
--- /dev/null
+++ b/src/test/java/org/apache/sling/jcr/base/internal/LegacyFragmentTest.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jcr.base.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+import org.osgi.util.converter.Converters;
+
+public class LegacyFragmentTest {
+
+ private final LegacyFragment.Configuration configuration;
+ {
+ final Map<String, Object> props = new HashMap<>();
+ props.put("whitelist.name", "test");
+ props.put("whitelist.bundles", new String[] { "org.apache.sling.test" });
+ configuration = Converters.standardConverter()
+ .convert(props)
+ .to(LegacyFragment.Configuration.class);
+ }
+
+ @Test
+ public void testFragmentBinding() {
+ final AllowListFragment fragment = new LegacyFragment(configuration);
+ assertEquals("test", fragment.name);
+ assertTrue(fragment.allows("org.apache.sling.test"));
+ assertFalse(fragment.allows("org.apache.sling.test.not.allowed"));
+ assertEquals(1, fragment.bundles.size());
+ }
+
+ @Test
+ public void testEquality() {
+ final LegacyFragment legacyFragment = new LegacyFragment(configuration);
+ final AllowListFragment fragment = new AllowListFragment(configuration.whitelist_name(), configuration.whitelist_bundles());
+
+ assertEquals(fragment, legacyFragment);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistTest.java b/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminAllowListTest.java
similarity index 62%
rename from src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistTest.java
rename to src/test/java/org/apache/sling/jcr/base/internal/LoginAdminAllowListTest.java
index bf08545..7c2724f 100644
--- a/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistTest.java
+++ b/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminAllowListTest.java
@@ -19,6 +19,8 @@
package org.apache.sling.jcr.base.internal;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
@@ -33,19 +35,19 @@
import org.osgi.framework.Bundle;
import org.osgi.service.cm.ConfigurationException;
-public class LoginAdminWhitelistTest {
+public class LoginAdminAllowListTest {
- private LoginAdminWhitelist whitelist;
+ private LoginAdminAllowList allowList;
@Before
public void setup() {
- whitelist = new LoginAdminWhitelist();
+ allowList = new LoginAdminAllowList();
}
private void assertAdminLogin(final String bundleSymbolicName, boolean expected) {
final Bundle b = Mockito.mock(Bundle.class);
when(b.getSymbolicName()).thenReturn(bundleSymbolicName);
- final boolean actual = whitelist.allowLoginAdministrative(b);
+ final boolean actual = allowList.allowLoginAdministrative(b);
assertEquals("For bundle " + bundleSymbolicName + ", expected admin login=" + expected, expected, actual);
}
@@ -58,8 +60,8 @@
}
@Test
- public void testBypassWhitelist() throws ConfigurationException {
- configure(whitelist, true, null, null, null);
+ public void testBypassAllowList() throws ConfigurationException {
+ configure(allowList, true, null, null, null);
for(String bsn : randomBsn()) {
assertAdminLogin(bsn, true);
@@ -71,7 +73,7 @@
final String [] allowed = {
"bundle1", "bundle2"
};
- configure(whitelist, null, null, allowed, null);
+ configure(allowList, null, null, allowed, null);
assertAdminLogin("foo.1.bar", false);
@@ -89,7 +91,7 @@
final String [] allowed = {
"bundle5", "bundle6"
};
- configure(whitelist, null, null, null, allowed);
+ configure(allowList, null, null, null, allowed);
assertAdminLogin("foo.1.bar", false);
@@ -104,7 +106,7 @@
@Test
public void testDefaultAndAdditionalConfig() throws ConfigurationException {
- configure(whitelist, null, null, new String [] { "defB"}, new String [] { "addB"});
+ configure(allowList, null, null, new String [] { "defB"}, new String [] { "addB"});
assertAdminLogin("defB", true);
assertAdminLogin("addB", true);
@@ -116,11 +118,11 @@
}
@Test
- public void testRegexpWhitelist() throws ConfigurationException {
+ public void testRegexpAllowList() throws ConfigurationException {
final String [] allowed = {
"bundle3", "bundle4"
};
- configure(whitelist, null, "foo.*bar", allowed, null);
+ configure(allowList, null, "foo.*bar", allowed, null);
assertAdminLogin("foo.2.bar", true);
assertAdminLogin("foo.somethingElse.bar", true);
@@ -136,16 +138,16 @@
@Test
- public void testWhitelistFragment() throws ConfigurationException {
+ public void testAllowListFragment() throws ConfigurationException {
final String [] allowed1 = randomBsn().toArray(new String[0]);
final String [] allowed2 = randomBsn().toArray(new String[0]);
- final WhitelistFragment testFragment1 = new WhitelistFragment("test1", allowed1);
- final WhitelistFragment testFragment2 = new WhitelistFragment("test2", allowed2);
+ final AllowListFragment testFragment1 = new AllowListFragment("test1", allowed1);
+ final AllowListFragment testFragment2 = new AllowListFragment("test2", allowed2);
- configure(whitelist, null, null, null, null);
- whitelist.bindWhitelistFragment(testFragment1);
- whitelist.bindWhitelistFragment(testFragment2);
+ configure(allowList, null, null, null, null);
+ allowList.bindAllowListFragment(testFragment1);
+ allowList.bindAllowListFragment(testFragment2);
for(String bsn : allowed1) {
assertAdminLogin(bsn, true);
@@ -159,7 +161,7 @@
assertAdminLogin(bsn, false);
}
- whitelist.unbindWhitelistFragment(testFragment1);
+ allowList.unbindAllowListFragment(testFragment1);
for(String bsn : allowed1) {
assertAdminLogin(bsn, false);
@@ -170,13 +172,13 @@
}
}
- private void configure(final LoginAdminWhitelist whitelist, final Boolean bypass, final String regexp, final String[] defaultBSNs, final String[] additionalBSNs) throws ConfigurationException {
+ private void configure(final LoginAdminAllowList allowList, 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);
+ props.put("allowlist.bypass", bypass);
}
if (regexp != null) {
- props.put("whitelist.bundles.regexp", regexp);
+ props.put("allowlist.bundles.regexp", regexp);
}
if (defaultBSNs != null) {
props.put("whitelist.bundles.default", defaultBSNs);
@@ -184,8 +186,34 @@
if (additionalBSNs != null) {
props.put("whitelist.bundles.additional", additionalBSNs);
}
- LoginAdminWhitelistConfiguration configuration =
- ConfigAnnotationUtil.fromDictionary(LoginAdminWhitelistConfiguration.class, props);
- whitelist.configure(configuration, props);
+ LoginAdminAllowListConfiguration configuration =
+ ConfigAnnotationUtil.fromDictionary(LoginAdminAllowListConfiguration.class, props);
+ allowList.configure(configuration, props);
+ }
+
+ @Test
+ public void testLegacyConfigurationOnly() {
+ final LoginAdminAllowListConfiguration cfg = Mockito.mock(LoginAdminAllowListConfiguration.class);
+ when(cfg.allowlist_bypass()).thenReturn(false);
+ when(cfg.allowlist_bundles_regexp()).thenReturn("");
+ final Hashtable<String, Object> props = new Hashtable<>();
+ props.put("whitelist.bypass", true);
+ props.put("whitelist.bundles.regexp", "foo.*bar");
+ final LoginAdminAllowList.ConfigurationState state = new LoginAdminAllowList.ConfigurationState(cfg, props);
+ assertTrue(state.bypassAllowList);
+ assertEquals("foo.*bar", state.allowListRegexp.pattern());
+ }
+
+ @Test
+ public void testLegacyAndConfiguration() {
+ final LoginAdminAllowListConfiguration cfg = Mockito.mock(LoginAdminAllowListConfiguration.class);
+ when(cfg.allowlist_bypass()).thenReturn(true);
+ when(cfg.allowlist_bundles_regexp()).thenReturn("bar.foo*");
+ final Hashtable<String, Object> props = new Hashtable<>();
+ props.put("whitelist.bypass", false);
+ props.put("whitelist.bundles.regexp", "foo.*bar");
+ final LoginAdminAllowList.ConfigurationState state = new LoginAdminAllowList.ConfigurationState(cfg, props);
+ assertFalse(state.bypassAllowList);
+ assertEquals("bar.foo*", state.allowListRegexp.pattern());
}
}
\ No newline at end of file