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 2016/11/16 11:56:47 UTC
svn commit: r1769962 - in /sling/trunk/bundles/jcr:
base/src/main/java/org/apache/sling/jcr/base/
base/src/main/java/org/apache/sling/jcr/base/internal/
base/src/test/java/org/apache/sling/jcr/base/internal/
base/src/test/java/org/apache/sling/jcr/base...
Author: jsedding
Date: Wed Nov 16 11:56:46 2016
New Revision: 1769962
URL: http://svn.apache.org/viewvc?rev=1769962&view=rev
Log:
SLING-6285 - Implement LoginAdminWhitelist in JCR Base
- move implementation from o.a.s.jcr.oak.server to o.a.s.jcr.base
- move and refactor tests to work with moved implementation
- support @Modified callback on LoginAdminWhitelist to avoid restarting repositories on configuratin change
- improved error handling, i.e. set a message for LoginExceptions
Added:
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelist.java
- copied, changed from r1769656, sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/LoginAdminWhitelist.java
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistConfiguration.java
- copied, changed from r1769656, sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/LoginAdminWhitelistConfiguration.java
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistTest.java
- copied, changed from r1769656, sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/internal/LoginAdminWhitelistTest.java
sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/util/ConfigAnnotationUtil.java (with props)
Removed:
sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/LoginAdminWhitelist.java
sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/LoginAdminWhitelistConfiguration.java
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/internal/LoginAdminWhitelistTest.java
Modified:
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java
sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/package-info.java
sling/trunk/bundles/jcr/oak-server/pom.xml
sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/OakSlingRepositoryManager.java
sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/OakServerTestSupport.java
Modified: sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java?rev=1769962&r1=1769961&r2=1769962&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java (original)
+++ sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java Wed Nov 16 11:56:46 2016
@@ -373,11 +373,12 @@ public abstract class AbstractSlingRepos
final boolean whitelisted = getSlingRepositoryManager().allowLoginAdministrativeForBundle(usingBundle);
if(!whitelisted) {
- logger.error("Bundle {} is NOT whitelisted to use SlingRepository.loginAdministrative", usingBundle.getSymbolicName());
- throw new LoginException();
+ final String symbolicName = usingBundle.getSymbolicName();
+ logger.error("Bundle {} is NOT whitelisted to use SlingRepository.loginAdministrative", symbolicName);
+ throw new LoginException("Bundle " + symbolicName +" is NOT whitelisted");
} else if (this.getSlingRepositoryManager().isDisableLoginAdministrative()) {
logger.error("SlingRepository.loginAdministrative is disabled. Please use SlingRepository.loginService.");
- throw new LoginException();
+ throw new LoginException("SlingRepository.loginAdministrative is disabled.");
}
logger.debug("SlingRepository.loginAdministrative is deprecated. Please use SlingRepository.loginService.");
Modified: sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java?rev=1769962&r1=1769961&r2=1769962&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java (original)
+++ sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java Wed Nov 16 11:56:46 2016
@@ -18,6 +18,7 @@
*/
package org.apache.sling.jcr.base;
+import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Dictionary;
@@ -26,6 +27,7 @@ import javax.jcr.Repository;
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.serviceusermapping.ServiceUserMapper;
import org.osgi.annotation.versioning.ProviderType;
import org.osgi.framework.Bundle;
@@ -101,6 +103,10 @@ public abstract class AbstractSlingRepos
private volatile Loader loader;
+ private volatile ServiceReference<LoginAdminWhitelist> whitelistRef;
+
+ private volatile LoginAdminWhitelist whitelist;
+
private final Object repoInitLock = new Object();
/**
@@ -151,7 +157,9 @@ public abstract class AbstractSlingRepos
* @return A boolean value indicating whether or not the bundle is allowed
* to use {@code loginAdministrative}.
*/
- protected abstract boolean allowLoginAdministrativeForBundle(final Bundle bundle);
+ protected boolean allowLoginAdministrativeForBundle(final Bundle bundle) {
+ return whitelist.allowLoginAdministrative(bundle);
+ }
/**
* Creates the backing JCR repository instances. It is expected for this
@@ -322,6 +330,15 @@ public abstract class AbstractSlingRepos
this.defaultWorkspace = defaultWorkspace;
this.disableLoginAdministrative = disableLoginAdministrative;
+ boolean enableWhitelist = !isAllowLoginAdministrativeForBundleOverridden();
+ if (enableWhitelist) {
+ this.whitelistRef = bundleContext.getServiceReference(LoginAdminWhitelist.class);
+ if (whitelistRef == null) {
+ throw new IllegalStateException("Whitelist must not be null");
+ }
+ this.whitelist = bundleContext.getService(whitelistRef);
+ }
+
this.repoInitializerTracker = new ServiceTracker<SlingRepositoryInitializer, SlingRepositoryInitializerInfo>(bundleContext, SlingRepositoryInitializer.class,
new ServiceTrackerCustomizer<SlingRepositoryInitializer, SlingRepositoryInitializerInfo>() {
@@ -407,6 +424,23 @@ public abstract class AbstractSlingRepos
return false;
}
+ // find out whether allowLoginAdministrativeForBundle is overridden
+ private boolean isAllowLoginAdministrativeForBundleOverridden() {
+ Class<?> clazz = getClass();
+ while (clazz != AbstractSlingRepositoryManager.class) {
+ final Method[] declaredMethods = clazz.getDeclaredMethods();
+ for (final Method method : declaredMethods) {
+ if (method.getName().equals("allowLoginAdministrativeForBundle")
+ && method.getParameterTypes().length == 1
+ && method.getParameterTypes()[0] == Bundle.class) {
+ return true;
+ }
+ }
+ clazz = clazz.getSuperclass();
+ }
+ return false;
+ }
+
private void executeRepositoryInitializers(final SlingRepository repo) throws Exception {
final SlingRepositoryInitializerInfo [] infos = repoInitializerTracker.getServices(new SlingRepositoryInitializerInfo[0]);
if (infos == null || infos.length == 0) {
@@ -424,6 +458,12 @@ public abstract class AbstractSlingRepos
* This method must be called if overwritten by implementations !!
*/
protected final void stop() {
+ if (whitelistRef != null) {
+ whitelist = null;
+ bundleContext.ungetService(whitelistRef);
+ whitelistRef = null;
+ }
+
if(repoInitializerTracker != null) {
repoInitializerTracker.close();
repoInitializerTracker = null;
Copied: sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelist.java (from r1769656, sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/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?p2=sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelist.java&p1=sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/LoginAdminWhitelist.java&r1=1769656&r2=1769962&rev=1769962&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/LoginAdminWhitelist.java (original)
+++ sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelist.java Wed Nov 16 11:56:46 2016
@@ -16,10 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.sling.jcr.oak.server.internal;
+package org.apache.sling.jcr.base.internal;
import java.util.Arrays;
-import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Pattern;
@@ -28,6 +27,7 @@ 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.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,60 +51,70 @@ import org.slf4j.LoggerFactory;
)
public class LoginAdminWhitelist {
- private final Logger log = LoggerFactory.getLogger(getClass());
+ private static final Logger LOG = LoggerFactory.getLogger(LoginAdminWhitelist.class);
- private boolean bypassWhitelist;
+ private volatile ConfigurationState config;
- private Pattern whitelistRegexp;
-
- private Set<String> whitelistedBsn;
-
- @Activate
- void activate(LoginAdminWhitelistConfiguration config) {
- whitelistedBsn = new TreeSet<String>();
-
- if (config.whitelist_bundles_default() != null) {
- whitelistedBsn.addAll(Arrays.asList(config.whitelist_bundles_default()));
- }
- if (config.whitelist_bundles_additional() != null) { // null check due to FELIX-5404
- whitelistedBsn.addAll(Arrays.asList(config.whitelist_bundles_additional()));
- }
-
- 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 'bypass whitelist' configuration"
- + " of this service. This is NOT RECOMMENDED, for security reasons."
- );
- } else {
- log.info("bypassWhitelist=false, whitelisted BSNs({})={}", whitelistedBsn.size(), whitelistedBsn);
- }
+ @Activate @Modified
+ void configure(LoginAdminWhitelistConfiguration configuration) {
+ this.config = new ConfigurationState(configuration);
}
- boolean allowLoginAdministrative(Bundle b) {
- if(bypassWhitelist) {
- log.debug("Whitelist is bypassed, all bundles allowed to use loginAdministrative");
+ 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(whitelistRegexp != null && whitelistRegexp.matcher(bsn).matches()) {
- log.debug("{} is whitelisted to use loginAdministrative, by regexp", bsn);
+ if(localConfig.whitelistRegexp != null && localConfig.whitelistRegexp.matcher(bsn).matches()) {
+ LOG.debug("{} is whitelisted to use loginAdministrative, by regexp", bsn);
return true;
- } else if(whitelistedBsn.contains(bsn)) {
- log.debug("{} is whitelisted to use loginAdministrative, by explicit whitelist", bsn);
+ } else if(localConfig.whitelistedBsn.contains(bsn)) {
+ LOG.debug("{} is whitelisted to use loginAdministrative, by explicit whitelist", bsn);
return true;
}
- log.debug("{} is not whitelisted to use loginAdministrative", bsn);
+ LOG.debug("{} is not whitelisted to use loginAdministrative", bsn);
return false;
}
+
+ // encapsulate configuration state for atomic configuration updates
+ private static class ConfigurationState {
+ private final TreeSet<String> whitelistedBsn;
+ private final Pattern whitelistRegexp;
+ private final boolean bypassWhitelist;
+
+ private ConfigurationState(final LoginAdminWhitelistConfiguration config) {
+ whitelistedBsn = new TreeSet<String>();
+ if (config.whitelist_bundles_default() != null) { // null check due to FELIX-5404
+ whitelistedBsn.addAll(Arrays.asList(config.whitelist_bundles_default()));
+ }
+ if (config.whitelist_bundles_additional() != null) {
+ whitelistedBsn.addAll(Arrays.asList(config.whitelist_bundles_additional()));
+ }
+
+ 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 'bypass whitelist' " +
+ "configuration of this service. This is NOT RECOMMENDED, for security reasons."
+ );
+ } else {
+ LOG.info("bypassWhitelist=false, whitelisted BSNs({})={}", whitelistedBsn.size(), whitelistedBsn);
+ }
+ }
+ }
}
Copied: sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistConfiguration.java (from r1769656, sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/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?p2=sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistConfiguration.java&p1=sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/LoginAdminWhitelistConfiguration.java&r1=1769656&r2=1769962&rev=1769962&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/LoginAdminWhitelistConfiguration.java (original)
+++ sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistConfiguration.java Wed Nov 16 11:56:46 2016
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.sling.jcr.oak.server.internal;
+package org.apache.sling.jcr.base.internal;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
Modified: sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/package-info.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/package-info.java?rev=1769962&r1=1769961&r2=1769962&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/package-info.java (original)
+++ sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/package-info.java Wed Nov 16 11:56:46 2016
@@ -25,7 +25,7 @@
* {@link org.apache.sling.jcr.base.AbstractSlingRepository2} being the
* basis for the repository service instance handed to using bundles.
*/
-@org.osgi.annotation.versioning.Version("3.1.0")
+@org.osgi.annotation.versioning.Version("3.2.0")
package org.apache.sling.jcr.base;
Copied: sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistTest.java (from r1769656, sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/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?p2=sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistTest.java&p1=sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/internal/LoginAdminWhitelistTest.java&r1=1769656&r2=1769962&rev=1769962&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/internal/LoginAdminWhitelistTest.java (original)
+++ sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/internal/LoginAdminWhitelistTest.java Wed Nov 16 11:56:46 2016
@@ -16,20 +16,22 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.sling.jcr.oak.server.internal;
+package org.apache.sling.jcr.base.internal;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
-import java.lang.annotation.Annotation;
import java.util.ArrayList;
+import java.util.Hashtable;
import java.util.List;
import java.util.UUID;
+import org.apache.sling.jcr.base.util.ConfigAnnotationUtil;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.osgi.framework.Bundle;
+import org.osgi.service.cm.ConfigurationException;
public class LoginAdminWhitelistTest {
@@ -58,9 +60,9 @@ public class LoginAdminWhitelistTest {
}
@Test
- public void testDefaultConfig() {
+ public void testDefaultConfig() throws ConfigurationException {
final LoginAdminWhitelistConfiguration config = config(null, null, null, null);
- whitelist.activate(config);
+ whitelist.configure(config);
for(String bsn : config.whitelist_bundles_default()) {
assertAdminLogin(bsn, true);
@@ -74,8 +76,8 @@ public class LoginAdminWhitelistTest {
}
@Test
- public void testBypassWhitelist() {
- whitelist.activate(config(true, null, null, null));
+ public void testBypassWhitelist() throws ConfigurationException {
+ whitelist.configure(config(true, null, null, null));
for(String bsn : randomBsn()) {
assertAdminLogin(bsn, true);
@@ -83,11 +85,11 @@ public class LoginAdminWhitelistTest {
}
@Test
- public void testDefaultConfigOnly() {
+ public void testDefaultConfigOnly() throws ConfigurationException {
final String [] allowed = {
"bundle1", "bundle2"
};
- whitelist.activate(config(null, null, allowed, null));
+ whitelist.configure(config(null, null, allowed, null));
assertAdminLogin("bundle1", true);
assertAdminLogin("bundle2", true);
@@ -100,18 +102,18 @@ public class LoginAdminWhitelistTest {
}
@Test
- public void testAdditionalConfigOnly() {
+ public void testAdditionalConfigOnly() throws ConfigurationException {
final String [] allowed = {
"bundle5", "bundle6"
};
final LoginAdminWhitelistConfiguration config = config(null, null, null, allowed);
- whitelist.activate(config);
+ whitelist.configure(config);
assertAdminLogin("bundle5", true);
assertAdminLogin("bundle6", true);
assertAdminLogin("foo.1.bar", false);
assertAdminLogin(TYPICAL_DEFAULT_ALLOWED_BSN, true);
-
+
for(String bsn : config.whitelist_bundles_default()) {
assertAdminLogin(bsn, true);
}
@@ -122,8 +124,8 @@ public class LoginAdminWhitelistTest {
}
@Test
- public void testDefaultAndAdditionalConfig() {
- whitelist.activate(config(null, null, new String [] { "defB"}, new String [] { "addB"}));
+ public void testDefaultAndAdditionalConfig() throws ConfigurationException {
+ whitelist.configure(config(null, null, new String [] { "defB"}, new String [] { "addB"}));
assertAdminLogin("defB", true);
assertAdminLogin("addB", true);
@@ -136,11 +138,11 @@ public class LoginAdminWhitelistTest {
}
@Test
- public void testRegexpWhitelist() {
+ public void testRegexpWhitelist() throws ConfigurationException {
final String [] allowed = {
"bundle3", "bundle4"
};
- whitelist.activate(config(null, "foo.*bar", allowed, null));
+ whitelist.configure(config(null, "foo.*bar", allowed, null));
assertAdminLogin("bundle3", true);
assertAdminLogin("bundle4", true);
@@ -153,44 +155,20 @@ public class LoginAdminWhitelistTest {
}
}
-
- private LoginAdminWhitelistConfiguration config(final Boolean bypass, final String regexp, final String[] defaultBSNs, final String[] additionalBSNs) {
- return new LoginAdminWhitelistConfiguration() {
- @Override
- public boolean whitelist_bypass() {
- return defaultIfNull(bypass, "whitelist_bypass");
- }
-
- @Override
- public String whitelist_bundles_regexp() {
- return defaultIfNull(regexp, "whitelist_bundles_regexp");
- }
-
- @Override
- public String[] whitelist_bundles_default() {
- return defaultIfNull(defaultBSNs, "whitelist_bundles_default");
- }
-
- @Override
- public String[] whitelist_bundles_additional() {
- return defaultIfNull(additionalBSNs, "whitelist_bundles_additional");
- }
-
- @Override
- public Class<? extends Annotation> annotationType() {
- return LoginAdminWhitelistConfiguration.class;
- }
-
- private <T> T defaultIfNull(final T value, final String methodName) {
- if (value != null) {
- return value;
- }
- try {
- return (T)this.annotationType().getMethod(methodName).getDefaultValue();
- } catch (NoSuchMethodException e) {
- return null;
- }
- }
- };
+ private LoginAdminWhitelistConfiguration config(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);
+ }
+ if (regexp != null) {
+ props.put("whitelist.bundles.regexp", regexp);
+ }
+ if (defaultBSNs != null) {
+ props.put("whitelist.bundles.default", defaultBSNs);
+ }
+ if (additionalBSNs != null) {
+ props.put("whitelist.bundles.additional", additionalBSNs);
+ }
+ return ConfigAnnotationUtil.fromDictionary(LoginAdminWhitelistConfiguration.class, props);
}
}
\ No newline at end of file
Added: sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/util/ConfigAnnotationUtil.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/util/ConfigAnnotationUtil.java?rev=1769962&view=auto
==============================================================================
--- sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/util/ConfigAnnotationUtil.java (added)
+++ sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/util/ConfigAnnotationUtil.java Wed Nov 16 11:56:46 2016
@@ -0,0 +1,146 @@
+/*
+ * 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.util;
+
+import org.osgi.service.cm.ConfigurationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+public class ConfigAnnotationUtil {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ConfigAnnotationUtil.class);
+
+ @SuppressWarnings("unchecked")
+ public static <T> T fromDictionary(final Class<T> clazz, final Dictionary<String, ?> properties)
+ throws ConfigurationException {
+ return (T)Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{ clazz },
+ new Handler(copyAndVerify(properties, clazz)));
+ }
+
+ private static class Handler implements InvocationHandler {
+
+ private Dictionary<String, ?> properties;
+
+ private Handler(final Dictionary<String, ?> properties) {
+ this.properties = properties;
+ }
+
+ @Override
+ public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+ final String methodName = method.getName();
+ if ("toString".equals(methodName)) {
+ return proxy.getClass().getName() + "[" + properties.toString() + "]";
+ }
+
+ final String propertyName = toPropertyName(methodName);
+ Object value;
+ if (properties != null && (value = properties.get(propertyName)) != null) {
+ return value;
+ } else {
+ return method.getDefaultValue();
+ }
+ }
+ }
+
+ private static String toPropertyName(final String methodName) {
+ return methodName.replace('_', '.');
+ }
+
+ private static String toMethodName(final String propertyName) {
+ return propertyName.replace('.', '_');
+ }
+
+ private static <T> Dictionary<String, ?> copyAndVerify(final Dictionary<String, ?> properties, final Class<T> clazz)
+ throws ConfigurationException {
+ if (properties == null) {
+ return null;
+ }
+
+ final Hashtable<String, Object> copy = new Hashtable<>();
+ final Enumeration<String> keys = properties.keys();
+ while (keys.hasMoreElements()) {
+ final String propertyName = keys.nextElement();
+ final Object value = properties.get(propertyName);
+ verifyValueType(clazz, propertyName, value);
+ copy.put(propertyName, value);
+ }
+ return copy;
+ }
+
+ private static <T> void verifyValueType(final Class<T> clazz, final String propertyName, final Object value)
+ throws ConfigurationException {
+ final Method method = getDeclaredMethodByName(clazz, toMethodName(propertyName));
+ if (method != null) {
+ final Class<?> returnType = method.getReturnType();
+ final Class<?> valueClass = value.getClass();
+ if (!isAssignable(returnType, valueClass)) {
+ LOG.error("Invalid value type for {} ({} instead of {})", propertyName, valueClass, returnType);
+ throw new ConfigurationException(propertyName,
+ "Value of incorrect type " + valueClass.getName() + " instead of " + returnType.getName());
+ }
+ }
+ }
+
+ private static boolean isAssignable(final Class<?> type, final Class<?> superType) {
+ final Class<?> wrappedType = primitiveToWrapper(type);
+ final Class<?> wrappedSuperType = primitiveToWrapper(superType);
+ return wrappedType.isAssignableFrom(wrappedSuperType);
+ }
+
+ private static Method getDeclaredMethodByName(final Class<?> clazz, final String methodName) {
+ final Method[] declaredMethods = clazz.getDeclaredMethods();
+ Method method = null;
+ for (final Method declaredMethod : declaredMethods) {
+ if (declaredMethod.getName().equals(methodName)) {
+ method = declaredMethod;
+ break;
+ }
+ }
+ return method;
+ }
+
+ private static Class<?> primitiveToWrapper(Class<?> clazz) {
+ if (primitiveToWrapper.containsKey(clazz)) {
+ return primitiveToWrapper.get(clazz);
+ } else {
+ return clazz;
+ }
+ }
+
+ private static final Map<Class<?>, Class<?>> primitiveToWrapper = new HashMap<Class<?>, Class<?>>();
+ static {
+ primitiveToWrapper.put(Boolean.TYPE, Boolean.class);
+ primitiveToWrapper.put(Byte.TYPE, Byte.class);
+ primitiveToWrapper.put(Character.TYPE, Character.class);
+ primitiveToWrapper.put(Short.TYPE, Short.class);
+ primitiveToWrapper.put(Integer.TYPE, Integer.class);
+ primitiveToWrapper.put(Long.TYPE, Long.class);
+ primitiveToWrapper.put(Double.TYPE, Double.class);
+ primitiveToWrapper.put(Float.TYPE, Float.class);
+ }
+}
Propchange: sling/trunk/bundles/jcr/base/src/test/java/org/apache/sling/jcr/base/util/ConfigAnnotationUtil.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: sling/trunk/bundles/jcr/oak-server/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/oak-server/pom.xml?rev=1769962&r1=1769961&r2=1769962&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/oak-server/pom.xml (original)
+++ sling/trunk/bundles/jcr/oak-server/pom.xml Wed Nov 16 11:56:46 2016
@@ -177,7 +177,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.jcr.base</artifactId>
- <version>2.4.2</version>
+ <version>2.4.3-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
Modified: sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/OakSlingRepositoryManager.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/OakSlingRepositoryManager.java?rev=1769962&r1=1769961&r2=1769962&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/OakSlingRepositoryManager.java (original)
+++ sling/trunk/bundles/jcr/oak-server/src/main/java/org/apache/sling/jcr/oak/server/internal/OakSlingRepositoryManager.java Wed Nov 16 11:56:46 2016
@@ -99,9 +99,6 @@ public class OakSlingRepositoryManager e
@Reference
private ThreadPoolManager threadPoolManager = null;
- @Reference
- private LoginAdminWhitelist loginAdminWhitelist;
-
private ThreadPool threadPool;
private ServiceRegistration oakExecutorServiceReference;
@@ -122,9 +119,6 @@ public class OakSlingRepositoryManager e
private ServiceRegistration nodeAggregatorRegistration;
- public OakSlingRepositoryManager() {
- }
-
@Override
protected ServiceUserMapper getServiceUserMapper() {
return this.serviceUserMapper;
@@ -203,11 +197,6 @@ public class OakSlingRepositoryManager e
((JackrabbitRepository) repository).shutdown();
}
- @Override
- protected boolean allowLoginAdministrativeForBundle(final Bundle bundle) {
- return loginAdminWhitelist.allowLoginAdministrative(bundle);
- }
-
@Activate
private void activate(final OakSlingRepositoryManagerConfiguration configuration, final ComponentContext componentContext) {
this.configuration = configuration;
Modified: sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/OakServerTestSupport.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/OakServerTestSupport.java?rev=1769962&r1=1769961&r2=1769962&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/OakServerTestSupport.java (original)
+++ sling/trunk/bundles/jcr/oak-server/src/test/java/org/apache/sling/jcr/oak/server/it/OakServerTestSupport.java Wed Nov 16 11:56:46 2016
@@ -202,7 +202,7 @@ public abstract class OakServerTestSuppo
}
protected Option getWhitelistRegexpOption() {
- return newConfiguration("org.apache.sling.jcr.oak.server.internal.LoginAdminWhitelist")
+ return newConfiguration("org.apache.sling.jcr.base.internal.LoginAdminWhitelist")
.put("whitelist.bundles.regexp", "PAXEXAM-PROBE-.*")
.asOption();
}