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/10 12:34:46 UTC

svn commit: r1769102 - in /sling/trunk/bundles/jcr/resource: pom.xml src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrProviderStateFactory.java src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java

Author: jsedding
Date: Thu Nov 10 12:34:46 2016
New Revision: 1769102

URL: http://svn.apache.org/viewvc?rev=1769102&view=rev
Log:
SLING-5135 - Whitelist legit usages of loginAdministrative and administrative ResourceResolver

- avoid explicit check for LoginAdminWhitelist by using the same
  mechanism for loginAdministrative and loginService to pass
  the "usingBundle" to the AbstractSlingRepository2 instance
- the above allows to remove the dependency to o.a.s.jcr.base
  from o.a.s.jcr.resource

Modified:
    sling/trunk/bundles/jcr/resource/pom.xml
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrProviderStateFactory.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java

Modified: sling/trunk/bundles/jcr/resource/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/pom.xml?rev=1769102&r1=1769101&r2=1769102&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/pom.xml (original)
+++ sling/trunk/bundles/jcr/resource/pom.xml Thu Nov 10 12:34:46 2016
@@ -155,12 +155,6 @@
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.jcr.base</artifactId>
-            <version>2.4.1-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.api</artifactId>
             <version>2.15.0</version>
             <scope>provided</scope>

Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrProviderStateFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrProviderStateFactory.java?rev=1769102&r1=1769101&r2=1769102&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrProviderStateFactory.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrProviderStateFactory.java Thu Nov 10 12:34:46 2016
@@ -24,7 +24,9 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
 
+import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import javax.jcr.Credentials;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
@@ -35,7 +37,6 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
 import org.apache.sling.jcr.api.SlingRepository;
-import org.apache.sling.jcr.base.LoginAdminWhitelist;
 import org.apache.sling.jcr.resource.api.JcrResourceConstants;
 import org.apache.sling.jcr.resource.internal.HelperData;
 import org.apache.sling.spi.resource.provider.ResourceProvider;
@@ -56,121 +57,97 @@ public class JcrProviderStateFactory {
     private final AtomicReference<DynamicClassLoaderManager> dynamicClassLoaderManagerReference;
 
     private final PathMapper pathMapper;
-    
-    private final LoginAdminWhitelist loginAdminWhitelist;
 
     public JcrProviderStateFactory(final ServiceReference repositoryReference,
             final SlingRepository repository,
             final AtomicReference<DynamicClassLoaderManager> dynamicClassLoaderManagerReference,
-            final PathMapper pathMapper,
-            final LoginAdminWhitelist loginAdminWhitelist) {
+            final PathMapper pathMapper) {
         this.repository = repository;
         this.repositoryReference = repositoryReference;
         this.dynamicClassLoaderManagerReference = dynamicClassLoaderManagerReference;
         this.pathMapper = pathMapper;
-        this.loginAdminWhitelist = loginAdminWhitelist;
     }
     
     /** Get the calling Bundle from auth info, fail if not provided 
      *  @throws LoginException if no calling bundle info provided
      */
-    private Bundle requireCallingBundle(@Nonnull Map<String, Object> authenticationInfo) throws LoginException {
+    @CheckForNull
+    private Bundle extractCallingBundle(@Nonnull Map<String, Object> authenticationInfo) throws LoginException {
         final Object obj = authenticationInfo.get(ResourceProvider.AUTH_SERVICE_BUNDLE);
-        if(obj == null) {
-            throw new LoginException("Calling bundle missing in authentication info");
-        } else if(!(obj instanceof Bundle)) {
+        if(obj != null && !(obj instanceof Bundle)) {
             throw new LoginException("Invalid calling bundle object in authentication info");
         }
         return (Bundle)obj;
     }
-    
-    /** Fail if the calling bundle is not whitelisted for loginAdministrative 
-     *  @throws LoginException if bundle not whitelisted or no calling bundle info provided
-     */
-    private void checkLoginAdminWhitelist(@Nonnull Map<String, Object> authenticationInfo) throws LoginException {
-        final Bundle b = requireCallingBundle(authenticationInfo);
-        if(!loginAdminWhitelist.allowLoginAdministrative(b)) {
-            throw new LoginException("Bundle is not whitelisted for loginAdministrative:" + b.getSymbolicName());
-        }
-    }
 
     @SuppressWarnings("deprecation")
     JcrProviderState createProviderState(final @Nonnull Map<String, Object> authenticationInfo) throws LoginException {
-        // by default any session used by the resource resolver returned is
-        // closed when the resource resolver is closed
-        boolean logoutSession = true;
+        boolean isLoginAdministrative = Boolean.TRUE.equals(authenticationInfo.get(ResourceProvider.AUTH_ADMIN));
+
+        // check whether a session is provided in the authenticationInfo
+        Session session = getSession(authenticationInfo);
+        if (session != null && !isLoginAdministrative) {
+            // by default any session used by the resource resolver returned is
+            // closed when the resource resolver is closed, except when the session
+            // was provided in the authenticationInfo
+            return createJcrProviderState(session, false, authenticationInfo, null);
+        }
 
-        // derive the session to be used
-        Session session;
         BundleContext bc = null;
         try {
-            if (Boolean.TRUE.equals(authenticationInfo.get(ResourceProvider.AUTH_ADMIN))) {
-                // We need to do our own whitelist check here as the repository
-                // considers this bundle as the calling bundle but we want to whitelist
-                // according to the bundle that's calling us.
-                checkLoginAdminWhitelist(authenticationInfo);
-                session = repository.loginAdministrative(null);
-            } else {
-                session = getSession(authenticationInfo);
-                if (session == null) {
-
-                    final Object serviceBundleObject = authenticationInfo.get(ResourceProvider.AUTH_SERVICE_BUNDLE);
-                    if (serviceBundleObject instanceof Bundle) {
-
-                        final String subServiceName = (authenticationInfo
-                                .get(ResourceResolverFactory.SUBSERVICE) instanceof String)
-                                        ? (String) authenticationInfo.get(ResourceResolverFactory.SUBSERVICE) : null;
-
-                        bc = ((Bundle) serviceBundleObject).getBundleContext();
-
-                        final SlingRepository repo = (SlingRepository) bc.getService(repositoryReference);
-                        if (repo == null) {
-                            logger.warn(
-                                    "getResourceProviderInternal: Cannot login service because cannot get SlingRepository on behalf of bundle {} ({})",
-                                    bc.getBundle().getSymbolicName(), bc.getBundle().getBundleId());
-                            throw new LoginException(); // TODO: correct ??
-                        }
-
-                        try {
-                            session = repo.loginService(subServiceName, null);
-                        } finally {
-                            // unget the repository if the service cannot
-                            // login to it, otherwise the repository service
-                            // is let go off when the resource resolver is
-                            // closed and the session logged out
-                            if (session == null) {
-                                bc.ungetService(repositoryReference);
-                            }
-                        }
+            final Bundle bundle = extractCallingBundle(authenticationInfo);
+            if (bundle != null) {
+                bc = bundle.getBundleContext();
+                final SlingRepository repo = (SlingRepository) bc.getService(repositoryReference);
+                if (repo == null) {
+                    logger.warn("Cannot login {} because cannot get SlingRepository on behalf of bundle {} ({})",
+                            isLoginAdministrative ? "admin" : "service",
+                            bundle.getSymbolicName(),
+                            bundle.getBundleId());
+                    throw new LoginException(); // TODO: correct ??
+                }
 
+                try {
+                    if (isLoginAdministrative) {
+                        session = repo.loginAdministrative(null);
                     } else {
-
-                        // requested non-admin session to any workspace (or
-                        // default)
-                        final Credentials credentials = getCredentials(authenticationInfo);
-                        session = repository.login(credentials, null);
-
+                        final Object subService = authenticationInfo.get(ResourceResolverFactory.SUBSERVICE);
+                        final String subServiceName = subService instanceof String ? (String) subService : null;
+                        session = repo.loginService(subServiceName, null);
                     }
-
-                } else {
-
-                    // session provided; no special workspace; just make sure
-                    // the session is not logged out when the resolver is closed
-                    logoutSession = false;
+                } catch (Throwable t) {
+                    // unget the repository if the service cannot
+                    // login to it, otherwise the repository service
+                    // is let go off when the resource resolver is
+                    // closed and the session logged out
+                    if (session == null) {
+                        bc.ungetService(repositoryReference);
+                    }
+                    throw t;
                 }
+            } else if (isLoginAdministrative) {
+                throw new LoginException("Calling bundle missing in authentication info");
+            } else {
+                // requested non-admin session
+                final Credentials credentials = getCredentials(authenticationInfo);
+                session = repository.login(credentials, null);
             }
         } catch (final RepositoryException re) {
             throw getLoginException(re);
         }
 
-        session = handleImpersonation(session, authenticationInfo, logoutSession);
+        return createJcrProviderState(session, true, authenticationInfo, bc);
+    }
 
+    private JcrProviderState createJcrProviderState(
+            @Nonnull final Session s,
+            final boolean logoutSession,
+            @Nonnull final Map<String, Object> authenticationInfo,
+            @Nullable final BundleContext ctx
+    ) throws LoginException {
+        final Session session = handleImpersonation(s, authenticationInfo, logoutSession);
         final HelperData data = new HelperData(this.dynamicClassLoaderManagerReference, this.pathMapper);
-        if (bc == null) {
-            return new JcrProviderState(session, data, logoutSession);
-        } else {
-            return new JcrProviderState(session, data, logoutSession, bc, repositoryReference);
-        }
+        return new JcrProviderState(session, data, logoutSession, ctx, ctx == null ? null : repositoryReference);
     }
 
     /**

Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java?rev=1769102&r1=1769101&r2=1769102&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java Thu Nov 10 12:34:46 2016
@@ -49,7 +49,6 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
 import org.apache.sling.jcr.api.SlingRepository;
-import org.apache.sling.jcr.base.LoginAdminWhitelist;
 import org.apache.sling.jcr.resource.api.JcrResourceConstants;
 import org.apache.sling.jcr.resource.internal.JcrListenerBaseConfig;
 import org.apache.sling.jcr.resource.internal.JcrModifiableValueMap;
@@ -104,9 +103,6 @@ public class JcrResourceProvider extends
     @Reference
     private PathMapper pathMapper;
 
-    @Reference
-    private LoginAdminWhitelist loginAdminWhitelist;
-
     /** This service is only available on OAK, therefore optional and static) */
     @Reference(policy=ReferencePolicy.STATIC, cardinality=ReferenceCardinality.OPTIONAL)
     private Executor executor;
@@ -138,7 +134,7 @@ public class JcrResourceProvider extends
         this.repository = repository;
 
         this.stateFactory = new JcrProviderStateFactory(repositoryReference, repository,
-                classLoaderManagerReference, pathMapper, loginAdminWhitelist);
+                classLoaderManagerReference, pathMapper);
     }
 
     @Deactivate