You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2013/03/21 15:48:50 UTC

svn commit: r1459341 - in /sling/whiteboard/fmeschbe/deprecate_login_administrative: jcr/base/src/main/java/org/apache/sling/jcr/base/ resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ serviceusermapper/src/main/java/org/apache/sli...

Author: fmeschbe
Date: Thu Mar 21 14:48:49 2013
New Revision: 1459341

URL: http://svn.apache.org/r1459341
Log:
Switch back to using a regular ServiceUserName service tacking the service bundle as an argument.

Reason: It makes no sense to impose on the use of the ServiceUserName serive on the using bundle. Rather the use of this service is a property of the ResourceResolverFactory and the SlingRepository service which want to derive the actual service name from its using bundle.

Removed:
    sling/whiteboard/fmeschbe/deprecate_login_administrative/serviceusermapper/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperController.java
Modified:
    sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java
    sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/SlingRepositoryProxy.java
    sling/whiteboard/fmeschbe/deprecate_login_administrative/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
    sling/whiteboard/fmeschbe/deprecate_login_administrative/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java
    sling/whiteboard/fmeschbe/deprecate_login_administrative/serviceusermapper/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapper.java
    sling/whiteboard/fmeschbe/deprecate_login_administrative/serviceusermapper/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java

Modified: sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java?rev=1459341&r1=1459340&r2=1459341&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java (original)
+++ sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java Thu Mar 21 14:48:49 2013
@@ -104,8 +104,8 @@ public abstract class AbstractSlingRepos
     @Reference
     private LogService log;
 
-    @Reference(referenceInterface = ServiceUserMapper.class)
-    private ServiceReference serviceUserMapper;
+    @Reference()
+    private ServiceUserMapper serviceUserMapper;
 
     private ComponentContext componentContext;
 
@@ -452,19 +452,16 @@ public abstract class AbstractSlingRepos
      *         the registered service.
      */
     protected final ServiceRegistration registerService() {
-        @SuppressWarnings("unchecked")
         Dictionary<String, Object> props = getServiceRegistrationProperties();
         String[] interfaces = getServiceRegistrationInterfaces();
 
         return componentContext.getBundleContext().registerService(interfaces, new ServiceFactory() {
             public Object getService(Bundle bundle, ServiceRegistration registration) {
-                final ServiceUserMapper sum = (ServiceUserMapper) bundle.getBundleContext().getService(
-                    AbstractSlingRepository.this.serviceUserMapper);
-                return new SlingRepositoryProxy(AbstractSlingRepository.this, sum);
+                return new SlingRepositoryProxy(AbstractSlingRepository.this, bundle, AbstractSlingRepository.this.serviceUserMapper);
             }
 
             public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
-                bundle.getBundleContext().ungetService(AbstractSlingRepository.this.serviceUserMapper);
+                // nothing to do (GC does the work for us)
             }
         }, // was: this
         props);

Modified: sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/SlingRepositoryProxy.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/SlingRepositoryProxy.java?rev=1459341&r1=1459340&r2=1459341&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/SlingRepositoryProxy.java (original)
+++ sling/whiteboard/fmeschbe/deprecate_login_administrative/jcr/base/src/main/java/org/apache/sling/jcr/base/SlingRepositoryProxy.java Thu Mar 21 14:48:49 2013
@@ -28,20 +28,23 @@ import javax.jcr.Value;
 
 import org.apache.sling.jcr.api.SlingRepository;
 import org.apache.sling.serviceusermapping.ServiceUserMapper;
+import org.osgi.framework.Bundle;
 
 public class SlingRepositoryProxy implements SlingRepository {
 
     private final SlingRepository delegatee;
 
+    private final Bundle usingBundle;
     private final ServiceUserMapper serviceUserMapper;
 
-    public SlingRepositoryProxy(final SlingRepository delegatee, final ServiceUserMapper serviceUserMapper) {
+    public SlingRepositoryProxy(final SlingRepository delegatee, final Bundle usingBundle, final ServiceUserMapper serviceUserMapper) {
         this.delegatee = delegatee;
+        this.usingBundle = usingBundle;
         this.serviceUserMapper = serviceUserMapper;
     }
 
     public final Session loginService(String serviceInfo, String workspace) throws LoginException, RepositoryException {
-        final String userName = this.serviceUserMapper.getUserForService(serviceInfo);
+        final String userName = this.serviceUserMapper.getUserForService(this.usingBundle, serviceInfo);
         final SimpleCredentials creds = new SimpleCredentials(userName, new char[0]);
 
         Session admin = null;

Modified: sling/whiteboard/fmeschbe/deprecate_login_administrative/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/deprecate_login_administrative/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java?rev=1459341&r1=1459340&r2=1459341&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/deprecate_login_administrative/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java (original)
+++ sling/whiteboard/fmeschbe/deprecate_login_administrative/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java Thu Mar 21 14:48:49 2013
@@ -50,7 +50,6 @@ import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.event.EventAdmin;
@@ -160,8 +159,8 @@ public class ResourceResolverFactoryActi
     EventAdmin eventAdmin;
 
     /** Service User Mapper */
-    @Reference(referenceInterface = ServiceUserMapper.class)
-    private ServiceReference serviceUserMapper;
+    @Reference()
+    private ServiceUserMapper serviceUserMapper;
 
     /** ComponentContext */
     private volatile ComponentContext componentContext;
@@ -355,17 +354,15 @@ public class ResourceResolverFactoryActi
             local.factoryRegistration = localContext.getBundleContext().registerService(
                 ResourceResolverFactory.class.getName(), new ServiceFactory() {
                     public Object getService(Bundle bundle, ServiceRegistration registration) {
-                        final ServiceUserMapper sum = (ServiceUserMapper) bundle.getBundleContext().getService(
-                            ResourceResolverFactoryActivator.this.serviceUserMapper);
                         final ResourceResolverFactoryImpl r = new ResourceResolverFactoryImpl(
-                            ResourceResolverFactoryActivator.this, bundle, sum);
+                            ResourceResolverFactoryActivator.this, bundle,
+                            ResourceResolverFactoryActivator.this.serviceUserMapper);
                         r.activate(localContext.getBundleContext());
                         return r;
                     }
 
                     public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
                         ((ResourceResolverFactoryImpl) service).deactivate();
-                        bundle.getBundleContext().ungetService(ResourceResolverFactoryActivator.this.serviceUserMapper);
                     }
                 }, serviceProps);
 

Modified: sling/whiteboard/fmeschbe/deprecate_login_administrative/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/deprecate_login_administrative/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java?rev=1459341&r1=1459340&r2=1459341&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/deprecate_login_administrative/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java (original)
+++ sling/whiteboard/fmeschbe/deprecate_login_administrative/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java Thu Mar 21 14:48:49 2013
@@ -74,12 +74,12 @@ public class ResourceResolverFactoryImpl
     // ---------- Resource Resolver Factory ------------------------------------
 
     public ResourceResolver getServiceResourceResolver(String serviceInfo) throws LoginException {
-        final String userName = this.serviceUserMapper.getUserForService(serviceInfo);
+        final String userName = this.serviceUserMapper.getUserForService(this.usingBundle, serviceInfo);
 
         // TODO: What to do if userName is null ????
         if (userName == null) {
             throw new LoginException("Cannot derive user name for service "
-                + this.serviceUserMapper.getServiceName(serviceInfo));
+                + this.serviceUserMapper.getServiceName(this.usingBundle, serviceInfo));
         }
 
         HashMap<String, Object> props = new HashMap<String, Object>();

Modified: sling/whiteboard/fmeschbe/deprecate_login_administrative/serviceusermapper/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapper.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/deprecate_login_administrative/serviceusermapper/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapper.java?rev=1459341&r1=1459340&r2=1459341&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/deprecate_login_administrative/serviceusermapper/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapper.java (original)
+++ sling/whiteboard/fmeschbe/deprecate_login_administrative/serviceusermapper/src/main/java/org/apache/sling/serviceusermapping/ServiceUserMapper.java Thu Mar 21 14:48:49 2013
@@ -18,27 +18,61 @@
  */
 package org.apache.sling.serviceusermapping;
 
+import org.osgi.framework.Bundle;
+
 import aQute.bnd.annotation.ProviderType;
 
+/**
+ * The <code>ServiceUserMapper</code> service can be used to map a service
+ * provided by a bundle to the name of a user account used to access the
+ * ResourceResolver used by the service to access its data.
+ * <p>
+ * The goal of this service is to allow services to be implemented accessing the
+ * storage with service-specific accounts which are tailored to allow the
+ * service appropriate access without requiring administrative level access to
+ * the storage.
+ * <p>
+ * In addition to allowing to phase out the use of
+ * {@code ResourceResolver.getAdministrativeResourceResolver} and
+ * {@code SlingRepository.loginAdministrative} it also allows to better account
+ * for changes to the storage by the different services.
+ * <p>
+ * This service is not intended to be used by the general user but by
+ * implementations of the {@code ResourceResolverFactory} and
+ * {@code SlingRepository} services.
+ * <p>
+ * This service is not intended to be implemented by clients.
+ */
 @ProviderType
 public interface ServiceUserMapper {
 
     /**
+     * The name of the Bundle manifest header providing the name of the service
+     * provided by the bundle. If this header is missing or empty, the bundle's
+     * symbolic name is used instead to name the service.
+     */
+    String BUNDLE_HEADER_SERVICE_NAME = "Sling-Service";
+
+    /**
      * Returns the name of the service represented by the {@code bundle} and the
      * {@code serviceInfo}.
      *
+     * @param bundle The bundle implementing the service request access to
+     *            resources.
      * @param serviceInfo Additional information about the concrete service
      *            requesting access. This parameter is optional and may be
      *            {@code null}.
      * @return The name of the service represented by the bundle along with the
      *         additional service information.
      */
-    String getServiceName(String serviceInfo);
+    String getServiceName(Bundle bundle, String serviceInfo);
 
     /**
      * Returns the name of a user to the be used to access the Sling Resource
      * tree or the JCR Repository.
      *
+     * @param bundle The bundle implementing the service request access to
+     *            resources.
      * @param serviceInfo Additional information about the concrete service
      *            requesting access. This parameter is optional and may be
      *            {@code null}.
@@ -46,6 +80,5 @@ public interface ServiceUserMapper {
      *         for the service. This may be {@code null} to only grant guest
      *         level (or anonymous level) access to the resources.
      */
-    String getUserForService(String serviceInfo);
-
+    String getUserForService(Bundle bundle, String serviceInfo);
 }

Modified: sling/whiteboard/fmeschbe/deprecate_login_administrative/serviceusermapper/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/deprecate_login_administrative/serviceusermapper/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java?rev=1459341&r1=1459340&r2=1459341&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/deprecate_login_administrative/serviceusermapper/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java (original)
+++ sling/whiteboard/fmeschbe/deprecate_login_administrative/serviceusermapper/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java Thu Mar 21 14:48:49 2013
@@ -18,32 +18,110 @@
  */
 package org.apache.sling.serviceusermapping.impl;
 
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.ConfigurationPolicy;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.PropertyUnbounded;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.commons.osgi.PropertiesUtil;
 import org.apache.sling.serviceusermapping.ServiceUserMapper;
 import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(metatype = true, ds = true, policy = ConfigurationPolicy.REQUIRE)
+@Service()
+public class ServiceUserMapperImpl implements ServiceUserMapper {
+
+    @Property(
+            label = "Service Mappings",
+            description = "Provides mappings from service name to user names. "
+                + "Each entry is of the form 'serviceName [ \":\" serviceInfo ] \"=\" userName' "
+                + "where serviceName and serviceInfo identify the service and userName would "
+                + "defines the name of the user to provide to the service. Invalid entries are logged and ignored.",
+            unbounded = PropertyUnbounded.ARRAY)
+    private static final String PROP_SERVICE2USER_MAPPING = "user.mapping";
+
+    private static final String[] PROP_SERVICE2USER_MAPPING_DEFAULT = {};
+
+    private static final String PROP_DEFAULT_USER = "user.default";
+
+    @Property(
+            name = PROP_DEFAULT_USER,
+            label = "Default User",
+            description = "The name of the user to use as the default if no service mapping"
+                + "applies. If this property is missing or empty the default user name reflects "
+                + "an anonymous user.")
+    private static final String PROP_DEFAULT_USER_DEFAULT = "";
+
+    /** default log */
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private Mapping[] serviceUserMappings;
+
+    private String defaultUser;
+
+    @Activate
+    @Modified
+    private void configure(Map<String, Object> config) {
+        final String[] props = PropertiesUtil.toStringArray(config.get(PROP_SERVICE2USER_MAPPING),
+            PROP_SERVICE2USER_MAPPING_DEFAULT);
+
+        ArrayList<Mapping> mappings = new ArrayList<Mapping>(props.length);
+        for (String prop : props) {
+            if (prop != null) {
+                try {
+                    Mapping mapping = new Mapping(prop);
+                    mappings.add(mapping);
+                } catch (IllegalArgumentException iae) {
+                    log.info("configure: Ignoring '{}': {}", prop, iae.getMessage());
+                }
+            }
+        }
 
-class ServiceUserMapperImpl implements ServiceUserMapper {
+        this.serviceUserMappings = mappings.toArray(new Mapping[mappings.size()]);
+        this.defaultUser = PropertiesUtil.toString(config.get(PROP_DEFAULT_USER), PROP_DEFAULT_USER_DEFAULT);
+    }
 
-    private String bundleServiceName;
+    public String getServiceName(Bundle bundle, String serviceInfo) {
+        final String serviceName = getServiceName(bundle);
+        return (serviceInfo == null) ? serviceName : serviceName +  ":" + serviceInfo;
+    }
 
-    private final ServiceUserMapperController controller;
+    public String getUserForService(Bundle bundle, String serviceInfo) {
+        final String serviceName = getServiceName(bundle);
 
-    ServiceUserMapperImpl(final Bundle bundle, final ServiceUserMapperController controller) {
-        final String name = (String) bundle.getHeaders().get("Sling-ResourceResolver-Service");
-        if (name != null && name.trim().length() > 0) {
-            this.bundleServiceName = name.trim();
-        } else {
-            this.bundleServiceName = bundle.getSymbolicName();
+        // try with serviceInfo first
+        for (Mapping mapping : this.serviceUserMappings) {
+            final String user = mapping.map(serviceName, serviceInfo);
+            if (user != null) {
+                return user;
+            }
         }
 
-        this.controller = controller;
-    }
+        // second round without serviceInfo
+        for (Mapping mapping : this.serviceUserMappings) {
+            final String user = mapping.map(serviceName, null);
+            if (user != null) {
+                return user;
+            }
+        }
 
-    public String getServiceName(String serviceInfo) {
-        return controller.getServiceName(this.bundleServiceName, serviceInfo);
+        // finally, fall back to default user
+        return this.defaultUser;
     }
 
-    public String getUserForService(String serviceInfo) {
-        return controller.getUserForService(this.bundleServiceName, serviceInfo);
-    }
+    private String getServiceName(final Bundle bundle) {
+        final String name = (String) bundle.getHeaders().get(BUNDLE_HEADER_SERVICE_NAME);
+        if (name != null && name.trim().length() > 0) {
+            return name.trim();
+        }
 
+        return bundle.getSymbolicName();
+    }
 }