You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by pa...@apache.org on 2021/01/28 13:29:15 UTC
[sling-org-apache-sling-serviceusermapper] branch
issues/SLING-10099 updated: SLING-10099 : Validators should all agree for a
service user to be valid and should be configurable
This is an automated email from the ASF dual-hosted git repository.
pauls pushed a commit to branch issues/SLING-10099
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-serviceusermapper.git
The following commit(s) were added to refs/heads/issues/SLING-10099 by this push:
new 14dbc32 SLING-10099 : Validators should all agree for a service user to be valid and should be configurable
14dbc32 is described below
commit 14dbc3248c4f3795d25d62dfc7b32d265d2514d1
Author: Karl Pauls <ka...@gmail.com>
AuthorDate: Thu Jan 28 14:29:02 2021 +0100
SLING-10099 : Validators should all agree for a service user to be valid and should be configurable
---
pom.xml | 4 +-
.../serviceusermapping/ServiceUserMapped.java | 2 +-
.../serviceusermapping/ServiceUserMapper.java | 4 +
.../impl/ServiceUserMapperImpl.java | 103 ++++++++++++++-------
.../sling/serviceusermapping/package-info.java | 2 +-
.../impl/ServiceUserMapperImplTest.java | 13 +--
6 files changed, 83 insertions(+), 45 deletions(-)
diff --git a/pom.xml b/pom.xml
index ddb54e6..9ba02a4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,12 +23,12 @@
<parent>
<groupId>org.apache.sling</groupId>
<artifactId>sling-bundle-parent</artifactId>
- <version>36</version>
+ <version>40</version>
<relativePath />
</parent>
<artifactId>org.apache.sling.serviceusermapper</artifactId>
- <version>1.4.7-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<name>Apache Sling Service User Mapper</name>
<description>
diff --git a/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapped.java b/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapped.java
index e100661..7b0b4a3 100644
--- a/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapped.java
+++ b/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapped.java
@@ -45,6 +45,6 @@ public interface ServiceUserMapped {
/**
* The name of the osgi property holding the sub service name.
*/
- static String SUBSERVICENAME = "subServiceName";
+ String SUBSERVICENAME = "subServiceName";
}
diff --git a/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapper.java b/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapper.java
index 303c2d6..d65cab8 100644
--- a/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapper.java
+++ b/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapper.java
@@ -58,6 +58,10 @@ import org.osgi.framework.Bundle;
*/
@ProviderType
public interface ServiceUserMapper {
+ /**
+ * Property to add as a unique id to a service registration.
+ */
+ String VALIDATOR_ID = "validator.id";
/**
* Returns the ID of a user to access the data store on behalf of the
diff --git a/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java b/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java
index 56165df..1fbfa10 100644
--- a/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java
+++ b/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java
@@ -18,19 +18,7 @@
*/
package org.apache.sling.serviceusermapping.impl;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
+import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -85,7 +73,13 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
"default mapping is applied which uses the service user \"serviceuser--\" + bundleId + [\"--\" + subServiceName]")
boolean user_enable_default_mapping() default true;
+ @AttributeDefinition(name = "Require Validation",
+ description = "Do validators have to be present and validate the service users?")
boolean require_validation() default false;
+
+ @AttributeDefinition(name = "Required Validators",
+ description = "A list of required validators ids. If not present and require validation is on not user will be valid")
+ String[] required_validators() default {};
}
/** default log */
@@ -115,6 +109,10 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
private volatile boolean requireValidation = false;
+ private final Set<String> requiredValidators = new HashSet<>();
+
+ private final List<String> presentValidators = new CopyOnWriteArrayList<>();
+
@Activate
public ServiceUserMapperImpl(final BundleContext bundleContext, final Config config) {
this(bundleContext, config, Executors.newSingleThreadExecutor());
@@ -155,6 +153,9 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
this.useDefaultMapping = config.user_enable_default_mapping();
this.requireValidation = config.require_validation();
+ if (config.required_validators() != null) {
+ requiredValidators.addAll(Arrays.asList(config.required_validators()));
+ }
RegistrationSet registrationSet = this.updateMappings();
this.executeServiceRegistrationsAsync(registrationSet);
@@ -180,9 +181,13 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
* @param serviceUserValidator
*/
@Reference(cardinality=ReferenceCardinality.MULTIPLE, policy= ReferencePolicy.DYNAMIC)
- protected synchronized void bindServiceUserValidator(final ServiceUserValidator serviceUserValidator) {
+ protected synchronized void bindServiceUserValidator(final ServiceUserValidator serviceUserValidator, final Map<String, ?> props) {
userValidators.add(serviceUserValidator);
- if (!requireValidation || !principalsValidators.isEmpty()) {
+ Object id = props.get(VALIDATOR_ID);
+ if (id instanceof String) {
+ presentValidators.add((String) id);
+ }
+ if (!requireValidation || !getPrincipalsValidators().isEmpty()) {
restartAllActiveServiceUserMappedServices();
}
}
@@ -191,8 +196,12 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
* unbind the serviceUserValidator
* @param serviceUserValidator
*/
- protected synchronized void unbindServiceUserValidator(final ServiceUserValidator serviceUserValidator) {
+ protected synchronized void unbindServiceUserValidator(final ServiceUserValidator serviceUserValidator, final Map<String, ?> props) {
userValidators.remove(serviceUserValidator);
+ Object id = props.get(VALIDATOR_ID);
+ if (id instanceof String) {
+ presentValidators.remove(id);
+ }
restartAllActiveServiceUserMappedServices();
}
@@ -201,9 +210,13 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
* @param servicePrincipalsValidator
*/
@Reference(cardinality=ReferenceCardinality.MULTIPLE, policy= ReferencePolicy.DYNAMIC)
- protected synchronized void bindServicePrincipalsValidator(final ServicePrincipalsValidator servicePrincipalsValidator) {
+ protected synchronized void bindServicePrincipalsValidator(final ServicePrincipalsValidator servicePrincipalsValidator, final Map<String, ?> props) {
principalsValidators.add(servicePrincipalsValidator);
- if (!requireValidation || !userValidators.isEmpty()) {
+ Object id = props.get(VALIDATOR_ID);
+ if (id instanceof String) {
+ presentValidators.add((String) id);
+ }
+ if (!requireValidation || !getUserValidators().isEmpty()) {
restartAllActiveServiceUserMappedServices();
}
}
@@ -212,8 +225,12 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
* unbind the servicePrincipalsValidator
* @param servicePrincipalsValidator
*/
- protected synchronized void unbindServicePrincipalsValidator(final ServicePrincipalsValidator servicePrincipalsValidator) {
+ protected synchronized void unbindServicePrincipalsValidator(final ServicePrincipalsValidator servicePrincipalsValidator, final Map<String, ?> props) {
principalsValidators.remove(servicePrincipalsValidator);
+ Object id = props.get(VALIDATOR_ID);
+ if (id instanceof String) {
+ presentValidators.remove(id);
+ }
restartAllActiveServiceUserMappedServices();
}
@@ -455,19 +472,19 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
log.debug("isValidUser: userId is null -> invalid");
return false;
}
- if ( !userValidators.isEmpty() || require) {
- for (final ServiceUserValidator validator : userValidators) {
- if ( validator.isValid(userId, serviceName, subServiceName) ) {
- log.debug("isValidUser: Validator {} accepts userId [{}] -> valid", validator, userId);
- return true;
+ List<ServiceUserValidator> validators = getUserValidators();
+ if (!validators.isEmpty()) {
+ for (final ServiceUserValidator validator : validators) {
+ if (!validator.isValid(userId, serviceName, subServiceName)) {
+ log.debug("isValidUser: Validator {} doesn't accept userId [{}] -> invalid", validator, userId);
+ return false;
}
}
- log.debug("isValidUser: No validator accepted userId [{}] -> invalid", userId);
- return false;
+ log.debug("isValidUser: All validators accepted userId [{}] -> valid", userId);
} else {
log.debug("isValidUser: No active validators for userId [{}] -> valid", userId);
- return true;
}
+ return require ? !validators.isEmpty() : true;
}
private boolean areValidPrincipals(final Iterable<String> principalNames, final String serviceName, final String subServiceName, boolean require) {
@@ -475,18 +492,34 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
log.debug("areValidPrincipals: principalNames are null -> invalid");
return false;
}
- if ( !principalsValidators.isEmpty() || require ) {
- for (final ServicePrincipalsValidator validator : principalsValidators) {
- if ( validator.isValid(principalNames, serviceName, subServiceName) ) {
- log.debug("areValidPrincipals: Validator {} accepts principal names [{}] -> valid", validator, principalNames);
- return true;
+ List<ServicePrincipalsValidator> validators = getPrincipalsValidators();
+ if (!validators.isEmpty() || require) {
+ for (final ServicePrincipalsValidator validator : validators) {
+ if (!validator.isValid(principalNames, serviceName, subServiceName)) {
+ log.debug("areValidPrincipals: Validator {} doesn't accept principal names [{}] -> invalid", validator, principalNames);
+ return false;
}
}
- log.debug("areValidPrincipals: No validator accepted principal names [{}] -> invalid", principalNames);
- return false;
+ log.debug("areValidPrincipals: All validators accepted principal names [{}] -> valid", principalNames);
} else {
log.debug("areValidPrincipals: No active validators for principal names [{}] -> valid", principalNames);
- return true;
+ }
+ return require ? !validators.isEmpty() : true;
+ }
+
+ private List<ServiceUserValidator> getUserValidators() {
+ if (presentValidators.containsAll(requiredValidators)) {
+ return userValidators;
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ private List<ServicePrincipalsValidator> getPrincipalsValidators() {
+ if (presentValidators.containsAll(requiredValidators)) {
+ return principalsValidators;
+ } else {
+ return Collections.emptyList();
}
}
diff --git a/src/main/java/org/apache/sling/serviceusermapping/package-info.java b/src/main/java/org/apache/sling/serviceusermapping/package-info.java
index 547a6af..2a6e541 100644
--- a/src/main/java/org/apache/sling/serviceusermapping/package-info.java
+++ b/src/main/java/org/apache/sling/serviceusermapping/package-info.java
@@ -17,6 +17,6 @@
* under the License.
*/
-@org.osgi.annotation.versioning.Version("1.4.0")
+@org.osgi.annotation.versioning.Version("1.5.0")
package org.apache.sling.serviceusermapping;
diff --git a/src/test/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImplTest.java b/src/test/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImplTest.java
index f94b8af..560fe88 100644
--- a/src/test/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImplTest.java
+++ b/src/test/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImplTest.java
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
@@ -195,7 +196,7 @@ public class ServiceUserMapperImplTest {
return true;
}
};
- sum.bindServiceUserValidator(serviceUserValidator);
+ sum.bindServiceUserValidator(serviceUserValidator, Collections.emptyMap());
TestCase.assertEquals(null, sum.getServiceUserID(BUNDLE1, null));
TestCase.assertEquals(ANOTHER, sum.getServiceUserID(BUNDLE2, null));
@@ -219,10 +220,10 @@ public class ServiceUserMapperImplTest {
final ServiceUserMapperImpl sum = new ServiceUserMapperImpl(null, config);
ServiceUserValidator sampleInvalid = (serviceUserId, serviceName, subServiceName) -> !SAMPLE.equals(serviceUserId);
- sum.bindServiceUserValidator(sampleInvalid);
+ sum.bindServiceUserValidator(sampleInvalid, Collections.emptyMap());
ServiceUserValidator anotherInvalid = (serviceUserId, serviceName, subServiceName) -> !ANOTHER.equals(serviceUserId);
- sum.bindServiceUserValidator(anotherInvalid);
+ sum.bindServiceUserValidator(anotherInvalid, Collections.emptyMap());
assertNull(sum.getServiceUserID(BUNDLE1, null));
assertNull(sum.getServiceUserID(BUNDLE2, null));
@@ -312,7 +313,7 @@ public class ServiceUserMapperImplTest {
ServicePrincipalsValidator validator = (servicePrincipalNames, serviceName, subServiceName) -> {
return StreamSupport.stream(servicePrincipalNames.spliterator(), false).noneMatch(SAMPLE::equals);
};
- sum.bindServicePrincipalsValidator(validator);
+ sum.bindServicePrincipalsValidator(validator, Collections.emptyMap());
assertNull(sum.getServicePrincipalNames(BUNDLE1, null));
assertNull(sum.getServicePrincipalNames(BUNDLE2, null));
@@ -334,12 +335,12 @@ public class ServiceUserMapperImplTest {
ServicePrincipalsValidator sampleInvalid = (servicePrincipalNames, serviceName, subServiceName) -> {
return StreamSupport.stream(servicePrincipalNames.spliterator(), false).noneMatch(SAMPLE::equals);
};
- sum.bindServicePrincipalsValidator(sampleInvalid);
+ sum.bindServicePrincipalsValidator(sampleInvalid, Collections.emptyMap());
ServicePrincipalsValidator anotherInvalid = (servicePrincipalNames, serviceName, subServiceName) -> {
return StreamSupport.stream(servicePrincipalNames.spliterator(), false).noneMatch(ANOTHER::equals);
};
- sum.bindServicePrincipalsValidator(anotherInvalid);
+ sum.bindServicePrincipalsValidator(anotherInvalid, Collections.emptyMap());
assertNull(sum.getServicePrincipalNames(BUNDLE1, null));
assertNull(sum.getServicePrincipalNames(BUNDLE2, null));