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 2018/11/02 21:28:32 UTC
[sling-org-apache-sling-serviceusermapper] branch issues/SLING-7930
created (now 2ae5d5f)
This is an automated email from the ASF dual-hosted git repository.
pauls pushed a change to branch issues/SLING-7930
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-serviceusermapper.git.
at 2ae5d5f Initial attempt on providing default ServiceUserMapped and only mapping service users that verify.
This branch includes the following new commits:
new 2ae5d5f Initial attempt on providing default ServiceUserMapped and only mapping service users that verify.
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[sling-org-apache-sling-serviceusermapper] 01/01: Initial attempt
on providing default ServiceUserMapped and only mapping service users that
verify.
Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
pauls pushed a commit to branch issues/SLING-7930
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-serviceusermapper.git
commit 2ae5d5f92c01a08c809bcef6f67f591fa33464b3
Author: Karl Pauls <ka...@gmail.com>
AuthorDate: Fri Nov 2 22:28:19 2018 +0100
Initial attempt on providing default ServiceUserMapped and only mapping service users that verify.
---
.../impl/ServiceUserMappedBundleFilter.java | 101 ++++++++++++++++++---
.../impl/ServiceUserMapperImpl.java | 27 +++++-
.../impl/ServiceUserMappedBundleFilterTest.java | 45 +++++++--
.../impl/ServiceUserMapperImplTest.java | 11 ++-
4 files changed, 155 insertions(+), 29 deletions(-)
diff --git a/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMappedBundleFilter.java b/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMappedBundleFilter.java
index bdf794c..ae95071 100644
--- a/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMappedBundleFilter.java
+++ b/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMappedBundleFilter.java
@@ -24,14 +24,19 @@ import java.util.Iterator;
import java.util.Map;
import org.apache.sling.serviceusermapping.Mapping;
+import org.apache.sling.serviceusermapping.ServiceUserMapped;
+import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.hooks.service.EventListenerHook;
import org.osgi.framework.hooks.service.FindHook;
import org.osgi.framework.hooks.service.ListenerHook;
+import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
/**
* The <code>ServiceUserMappingBundleFilter</code> only allows the bundle for which the service mapping is available to see it.
@@ -40,20 +45,40 @@ import org.osgi.service.component.annotations.Component;
service = {EventListenerHook.class, FindHook.class} )
public class ServiceUserMappedBundleFilter implements EventListenerHook, FindHook {
+ @Reference
+ volatile ServiceUserMapperImpl mapper;
+
+ volatile BundleContext context;
+
+ @Activate
+ void start(BundleContext context) {
+ this.context = context;
+ }
+
@Override
public void event(ServiceEvent serviceEvent, Map map) {
ServiceReference serviceReference = serviceEvent.getServiceReference();
- if (isServiceMappingReference(serviceReference)) {
+ if (isServiceMappingReference(serviceReference) && serviceEvent.getType() == ServiceEvent.REGISTERED) {
Object serviceName = serviceReference.getProperty(Mapping.SERVICENAME);
+ String subserviceName = getSubServiceName(serviceReference);
+ Iterator<Map.Entry<BundleContext, Collection<ListenerHook.ListenerInfo>>> it = map.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<BundleContext, Collection<ListenerHook.ListenerInfo>> entry = it.next();
+ BundleContext ctx = entry.getKey();
- if (serviceName != null && serviceName instanceof String) {
- Iterator<Map.Entry<BundleContext, Collection<ListenerHook.ListenerInfo>>> it = map.entrySet().iterator();
- while (it.hasNext()) {
- BundleContext ctx = it.next().getKey();
-
- String bundleServiceName = ServiceUserMapperImpl.getServiceName(ctx.getBundle());
- if (!serviceName.equals(bundleServiceName)) {
+ if (!ctx.getBundle().equals(context.getBundle()) && !isValid(ctx.getBundle(), serviceName, subserviceName)) {
+ boolean keep = false;
+ Iterator<ListenerHook.ListenerInfo> iter = entry.getValue().iterator();
+ while (iter.hasNext()) {
+ if (!matchDefault(ctx.getBundle(), serviceName, subserviceName, iter.next().getFilter(), serviceReference)) {
+ iter.remove();
+ }
+ else {
+ keep = true;
+ }
+ }
+ if (!keep) {
it.remove();
}
}
@@ -64,21 +89,64 @@ public class ServiceUserMappedBundleFilter implements EventListenerHook, FindHoo
@Override
public void find(BundleContext bundleContext, String name, String filter, boolean allServices,
Collection references) {
- String bundleServiceName = ServiceUserMapperImpl.getServiceName(bundleContext.getBundle());
Iterator<ServiceReference> it = references.iterator();
while (it.hasNext()) {
ServiceReference serviceReference = it.next();
if (isServiceMappingReference(serviceReference)) {
Object serviceName = serviceReference.getProperty(Mapping.SERVICENAME);
-
- if (serviceName != null && !serviceName.equals(bundleServiceName)) {
- it.remove();
+ String subserviceName = getSubServiceName(serviceReference);
+ if (!isValid(bundleContext.getBundle(), serviceName, subserviceName)) {
+ if (!matchDefault(bundleContext.getBundle(), serviceName, subserviceName, filter, serviceReference)) {
+ it.remove();
+ }
}
}
}
}
+ private boolean isValid(Bundle bundle, Object serviceName, String subserviceName) {
+ String bundleServiceName = mapper.getServiceName(bundle);
+ if (bundleServiceName.equals(serviceName)) {
+ Iterable<String> principals = mapper.getServicePrincipalNames(bundle, subserviceName);
+ if (principals != null && principals.iterator().hasNext()) {
+ return true;
+ }
+ String user = mapper.getServiceUserID(bundle, subserviceName);
+ if (user != null && !user.isEmpty()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private boolean matchDefault(Bundle bundle, Object serviceName, String subserviceName, String filter, ServiceReference ref) {
+ if ( mapper.getServiceName(context.getBundle()).equals(serviceName) ) {
+ try {
+ if (filter != null && context.createFilter(filter).match(ref)) {
+ for (Mapping mapping : mapper.getActiveMappings()) {
+ if (mapping.getServiceName().equals(mapper.getServiceName(bundle))) {
+ return false;
+ }
+ }
+ Iterable<String> principals = mapper.getServicePrincipalNames(bundle, subserviceName);
+ if (principals != null && principals.iterator().hasNext()) {
+ return true;
+ }
+ String user = mapper.getServiceUserID(bundle, subserviceName);
+ if (user != null && !user.isEmpty()) {
+ return true;
+ }
+ }
+ } catch (InvalidSyntaxException e) {
+ // this shouldn't happen as the framework will have validated the filter already
+ throw new RuntimeException(e);
+ }
+ }
+ return false;
+ }
+
private static boolean isServiceMappingReference(ServiceReference serviceReference) {
Object objectClass = serviceReference.getProperty(Constants.OBJECTCLASS);
for (Object o : (Object[]) objectClass) {
@@ -89,6 +157,11 @@ public class ServiceUserMappedBundleFilter implements EventListenerHook, FindHoo
return false;
}
-
-
+ private static String getSubServiceName(ServiceReference ref) {
+ Object subserviceName = ref.getProperty(ServiceUserMapped.SUBSERVICENAME);
+ if (subserviceName != null && subserviceName instanceof String) {
+ return (String) subserviceName;
+ }
+ return null;
+ }
}
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 7fb23e4..492513b 100644
--- a/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java
+++ b/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java
@@ -34,6 +34,7 @@ import java.util.TreeSet;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicReference;
import org.apache.sling.serviceusermapping.Mapping;
import org.apache.sling.serviceusermapping.ServicePrincipalsValidator;
@@ -81,7 +82,7 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
@AttributeDefinition(name = "Default Mapping",
description = "If enabled and no mapping for a requested service user exists and no " +
" default user is defined, a " +
- "default mapping is applied which uses the service user \"serviceuser@\" + {bundleId} + [\":\" + subServiceName]")
+ "default mapping is applied which uses the service user \"serviceuser--\" + bundleId + [\"--\" + subServiceName]")
boolean user_enable_default_mapping() default true;
}
@@ -92,7 +93,7 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
private String defaultUser;
- private boolean useDefaultMapping;
+ volatile boolean useDefaultMapping;
private Map<Long, MappingConfigAmendment> amendments = new HashMap<>();
@@ -108,7 +109,9 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
private ExecutorService executorService;
- public boolean registerAsync = true;
+ boolean registerAsync = true;
+
+ private final AtomicReference<ServiceRegistration> defaultRegistration = new AtomicReference<>();
@Activate
@Modified
@@ -340,6 +343,10 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
private void executeServiceRegistrations(final RegistrationSet registrationSet) {
+ ServiceRegistration reg = defaultRegistration.getAndSet(null);
+ if (reg != null) {
+ reg.unregister();
+ }
if (registrationSet == null) {
return;
}
@@ -388,6 +395,16 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
}
}
+ if (this.useDefaultMapping || (defaultUser != null && !defaultUser.isEmpty())) {
+ Dictionary<String, Object> properties = new Hashtable<>();
+ properties.put(Mapping.SERVICENAME, getServiceName(savedBundleContext.getBundle()));
+ final ServiceRegistration serviceRegistration = savedBundleContext.registerService(ServiceUserMappedImpl.SERVICEUSERMAPPED,
+ new ServiceUserMappedImpl(), properties);
+ ServiceRegistration oldServiceRegistration = this.defaultRegistration.getAndSet(serviceRegistration);
+ if (oldServiceRegistration != null) {
+ oldServiceRegistration.unregister();
+ }
+ }
}
private String internalGetUserId(final String serviceName, final String subServiceName) {
@@ -417,7 +434,7 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
}
// use default mapping if configured and no default user
- if ( this.defaultUser == null || this.defaultUser.isEmpty() ) {
+ if ( this.useDefaultMapping && (this.defaultUser == null || this.defaultUser.isEmpty() )) {
final String userName = "serviceuser--" + serviceName + (subServiceName == null ? "" : "--" + subServiceName);
log.debug("internalGetUserId: no mapping found, using default mapping [{}]", userName);
return userName;
@@ -497,7 +514,7 @@ public class ServiceUserMapperImpl implements ServiceUserMapper {
return null;
}
- static String getServiceName(final Bundle bundle) {
+ String getServiceName(final Bundle bundle) {
return bundle.getSymbolicName();
}
diff --git a/src/test/java/org/apache/sling/serviceusermapping/impl/ServiceUserMappedBundleFilterTest.java b/src/test/java/org/apache/sling/serviceusermapping/impl/ServiceUserMappedBundleFilterTest.java
index e95ef7e..08fe051 100644
--- a/src/test/java/org/apache/sling/serviceusermapping/impl/ServiceUserMappedBundleFilterTest.java
+++ b/src/test/java/org/apache/sling/serviceusermapping/impl/ServiceUserMappedBundleFilterTest.java
@@ -53,14 +53,21 @@ public class ServiceUserMappedBundleFilterTest {
final static BundleContext bundleContext1;
final static BundleContext bundleContext2;
+ final static BundleContext mapperContext;
static {
+ Bundle mapper = mock(Bundle.class);
+ when(mapper.getSymbolicName()).thenReturn("mapper");
+ mapperContext = mock(BundleContext.class);
+ when(mapperContext.getBundle()).thenReturn(mapper);
+
bundleContext1 = mock(BundleContext.class);
Bundle bundle1 = mock(Bundle.class);
when(bundleContext1.getBundle()).thenReturn(bundle1);
when(bundle1.getSymbolicName()).thenReturn(BUNDLE1);
+
bundleContext2 = mock(BundleContext.class);
Bundle bundle2 = mock(Bundle.class);
when(bundleContext2.getBundle()).thenReturn(bundle2);
@@ -83,12 +90,24 @@ public class ServiceUserMappedBundleFilterTest {
when(serviceEvent.getServiceReference()).thenReturn(serviceReference);
when(serviceReference.getProperty(Constants.OBJECTCLASS)).thenReturn(new String[]{ServiceUserMappedImpl.SERVICEUSERMAPPED});
when(serviceReference.getProperty(Mapping.SERVICENAME)).thenReturn(BUNDLE1);
+ when(serviceEvent.getType()).thenReturn(ServiceEvent.REGISTERED);
+
+
+ ServiceUserMappedBundleFilter eventListenerHook = new ServiceUserMappedBundleFilter();
+ eventListenerHook.mapper = new ServiceUserMapperImpl();
+ eventListenerHook.start(mapperContext);
- EventListenerHook eventListenerHook = new ServiceUserMappedBundleFilter();
- eventListenerHook.event(serviceEvent, map);
+ Map<BundleContext, Collection<ListenerHook.ListenerInfo>> map1 = new HashMap<>(map);
+ eventListenerHook.event(serviceEvent, map1);
- TestCase.assertEquals(1, map.size());
+ TestCase.assertEquals(0, map1.size());
+
+ Map<BundleContext, Collection<ListenerHook.ListenerInfo>> map2 = new HashMap<>(map);
+ eventListenerHook.mapper.useDefaultMapping = true;
+ eventListenerHook.event(serviceEvent, map2);
+
+ TestCase.assertEquals(1, map2.size());
TestCase.assertTrue(map.containsKey(bundleContext1));
}
@@ -108,10 +127,24 @@ public class ServiceUserMappedBundleFilterTest {
when(serviceReference2.getProperty(Mapping.SERVICENAME)).thenReturn(BUNDLE2);
when(serviceReference2.getProperty(Constants.OBJECTCLASS)).thenReturn(new String[]{ServiceUserMappedImpl.SERVICEUSERMAPPED});
- FindHook findHook = new ServiceUserMappedBundleFilter();
- findHook.find(bundleContext1, null, null, false, collection);
+ ServiceUserMappedBundleFilter findHook = new ServiceUserMappedBundleFilter();
+
+ findHook.mapper = new ServiceUserMapperImpl();
+ findHook.start(mapperContext);
- TestCase.assertEquals(1, collection.size());
+ List collection1 = new ArrayList(collection);
+ findHook.find(bundleContext1, null, null, false, collection1);
+
+ TestCase.assertEquals(0, collection1.size());
+
+ findHook.mapper.useDefaultMapping = true;
+
+ List collection2 = new ArrayList(collection);
+ findHook.find(bundleContext1, null, null, false, collection2);
+
+ TestCase.assertEquals(1, collection2.size());
TestCase.assertTrue(collection.contains(serviceReference1));
+
+
}
}
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 41da0f6..1fc5abb 100644
--- a/src/test/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImplTest.java
+++ b/src/test/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImplTest.java
@@ -424,7 +424,7 @@ public class ServiceUserMapperImplTest {
final ServiceRegistrationContextHelper context = new ServiceRegistrationContextHelper();
sum.configure(context.getBundleContext(), config);
- TestCase.assertEquals(2, context.getRegistrations(ServiceUserMappedImpl.SERVICEUSERMAPPED).size());
+ TestCase.assertEquals(3, context.getRegistrations(ServiceUserMappedImpl.SERVICEUSERMAPPED).size());
final MappingConfigAmendment mca1 = new MappingConfigAmendment();
@@ -439,7 +439,7 @@ public class ServiceUserMapperImplTest {
mca1.configure(mca1Config);
sum.bindAmendment(mca1, mca1ConfigMap);
- TestCase.assertEquals(3, context.getRegistrations(ServiceUserMappedImpl.SERVICEUSERMAPPED).size());
+ TestCase.assertEquals(4, context.getRegistrations(ServiceUserMappedImpl.SERVICEUSERMAPPED).size());
final MappingConfigAmendment mca2 = new MappingConfigAmendment();
@@ -454,11 +454,11 @@ public class ServiceUserMapperImplTest {
mca2.configure(mca2Config);
sum.bindAmendment(mca2, mca2ConfigMap);
- TestCase.assertEquals(4, context.getRegistrations(ServiceUserMappedImpl.SERVICEUSERMAPPED).size());
+ TestCase.assertEquals(5, context.getRegistrations(ServiceUserMappedImpl.SERVICEUSERMAPPED).size());
sum.unbindAmendment(mca1, mca1ConfigMap);
- TestCase.assertEquals(3, context.getRegistrations(ServiceUserMappedImpl.SERVICEUSERMAPPED).size());
+ TestCase.assertEquals(4, context.getRegistrations(ServiceUserMappedImpl.SERVICEUSERMAPPED).size());
}
@@ -466,6 +466,7 @@ public class ServiceUserMapperImplTest {
final BundleContext bundleContext = mock(BundleContext.class);
+ final Bundle bundle = mock(Bundle.class);
final Map<String, Map<Object, Dictionary>> registrations = new HashMap<>();
public ServiceRegistrationContextHelper() {
@@ -478,6 +479,8 @@ public class ServiceUserMapperImplTest {
return registerService((String) arguments[0], arguments[1], (Dictionary) arguments[2]);
}
});
+ when(bundleContext.getBundle()).thenReturn(bundle);
+ when(bundle.getSymbolicName()).thenReturn("mock");
}
private ServiceRegistration registerService(String string, Object o, Dictionary dictionary) {