You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2016/02/05 13:24:08 UTC

svn commit: r1728654 - in /sling/trunk/bundles/resourceresolver/src: main/java/org/apache/sling/resourceresolver/impl/ main/java/org/apache/sling/resourceresolver/impl/helper/ main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ test/ja...

Author: cziegeler
Date: Fri Feb  5 12:24:08 2016
New Revision: 1728654

URL: http://svn.apache.org/viewvc?rev=1728654&view=rev
Log:
SLING-5487 : Resource access security is not implemented correctly

Added:
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ProviderManager.java
      - copied, changed from r1728626, sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ResolveContextManager.java
Removed:
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ResolveContextManager.java
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/SecureResourceProviderDecorator.java
Modified:
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/BasicResolveContext.java
    sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControlTest.java
    sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/stateful/SecureResourceProviderDecoratorTest.java

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java?rev=1728654&r1=1728653&r2=1728654&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java Fri Feb  5 12:24:08 2016
@@ -111,7 +111,7 @@ public class ResourceResolverImpl extend
 
     ResourceResolverImpl(final CommonResourceResolverFactoryImpl factory, final boolean isAdmin, final Map<String, Object> authenticationInfo, final ResourceProviderStorage storage) throws LoginException {
         this.factory = factory;
-        this.context = new ResourceResolverContext(this);
+        this.context = new ResourceResolverContext(this, factory.getResourceAccessSecurityTracker());
         this.control = createControl(storage, authenticationInfo, isAdmin);
         this.factory.register(this, control);
     }
@@ -131,7 +131,7 @@ public class ResourceResolverImpl extend
         if (authenticationInfo != null) {
             authInfo.putAll(authenticationInfo);
         }
-        this.context = new ResourceResolverContext(this);
+        this.context = new ResourceResolverContext(this, factory.getResourceAccessSecurityTracker());
         this.control = createControl(factory.getResourceProviderTracker().getResourceProviderStorage(), authInfo, resolver.control.isAdmin());
         this.factory.register(this, control);
     }
@@ -150,7 +150,7 @@ public class ResourceResolverImpl extend
     throws LoginException {
         final ResourceResolverControl control = new ResourceResolverControl(isAdmin, authenticationInfo, storage);
 
-        this.context.getResolveContextManager().authenticateAll(storage.getAuthRequiredHandlers(), control);
+        this.context.getProviderManager().authenticateAll(storage.getAuthRequiredHandlers(), control);
 
         return control;
     }

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java?rev=1728654&r1=1728653&r2=1728654&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java Fri Feb  5 12:24:08 2016
@@ -17,8 +17,11 @@
  */
 package org.apache.sling.resourceresolver.impl.helper;
 
+import javax.annotation.Nonnull;
+
 import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.resourceresolver.impl.providers.stateful.ResolveContextManager;
+import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker;
+import org.apache.sling.resourceresolver.impl.providers.stateful.ProviderManager;
 
 /**
  * The resource resolver context.
@@ -29,18 +32,18 @@ public class ResourceResolverContext {
 
     private final ResourceResolver resolver;
 
-    private final ResolveContextManager resolveContextManager;
+    private final ProviderManager providerManager;
 
-    public ResourceResolverContext(final ResourceResolver resolver) {
+    public ResourceResolverContext(@Nonnull final ResourceResolver resolver, @Nonnull final ResourceAccessSecurityTracker tracker) {
         this.resolver = resolver;
-        this.resolveContextManager = new ResolveContextManager(resolver);
+        this.providerManager = new ProviderManager(resolver, tracker);
     }
 
     public ResourceResolver getResourceResolver() {
         return this.resolver;
     }
 
-    public ResolveContextManager getResolveContextManager() {
-        return this.resolveContextManager;
+    public ProviderManager getProviderManager() {
+        return this.providerManager;
     }
 }

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java?rev=1728654&r1=1728653&r2=1728654&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java Fri Feb  5 12:24:08 2016
@@ -132,7 +132,7 @@ public class ResourceResolverControl {
      * Refreshes all refreshable providers.
      */
     public void refresh(@Nonnull final ResourceResolverContext context) {
-        for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllUsedRefreshable()) {
+        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllUsedRefreshable()) {
             p.refresh();
         }
     }
@@ -141,7 +141,7 @@ public class ResourceResolverControl {
      * Returns {@code true} if all providers are live.
      */
     public boolean isLive(@Nonnull final ResourceResolverContext context) {
-        for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllAuthenticated()) {
+        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllAuthenticated()) {
             if (!p.isLive()) {
                 return false;
             }
@@ -199,7 +199,7 @@ public class ResourceResolverControl {
 
         final AuthenticatedResourceProvider provider = this.getBestMatchingProvider(context, path);
         if ( provider != null ) {
-            final Resource resourceCandidate = provider.getResource(path, parent, parameters, isResolve);
+            final Resource resourceCandidate = provider.getResource(path, parent, parameters);
             if (resourceCandidate != null) {
                 return resourceCandidate;
             }
@@ -271,8 +271,8 @@ public class ResourceResolverControl {
                 } else {
                     Resource rsrc = null;
                     try {
-                        final AuthenticatedResourceProvider rp = context.getResolveContextManager().getOrCreateProvider(handler, this);
-                        rsrc = rp == null ? null : rp.getResource(childPath, parent, null, false);
+                        final AuthenticatedResourceProvider rp = context.getProviderManager().getOrCreateProvider(handler, this);
+                        rsrc = rp == null ? null : rp.getResource(childPath, parent, null);
                     } catch ( final LoginException ignore) {
                         // ignore
                     }
@@ -307,7 +307,7 @@ public class ResourceResolverControl {
      */
     public Collection<String> getAttributeNames(final ResourceResolverContext context) {
         final Set<String> names = new LinkedHashSet<String>();
-        for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllBestEffort(storage.getAttributableHandlers(), this)) {
+        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllBestEffort(storage.getAttributableHandlers(), this)) {
             final Collection<String> newNames = p.getAttributeNames(this.authenticationInfo);
             if (newNames != null) {
                 names.addAll(newNames);
@@ -322,7 +322,7 @@ public class ResourceResolverControl {
      * the providers.
      */
     public Object getAttribute(final ResourceResolverContext context, final String name) {
-        for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllBestEffort(storage.getAttributableHandlers(), this)) {
+        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllBestEffort(storage.getAttributableHandlers(), this)) {
             Object attribute = p.getAttribute(name, this.authenticationInfo);
             if (attribute != null) {
                 return attribute;
@@ -378,7 +378,7 @@ public class ResourceResolverControl {
      * Revert changes on all modifiable ResourceProviders.
      */
     public void revert(final ResourceResolverContext context) {
-        for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllUsedModifiable()) {
+        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllUsedModifiable()) {
             p.revert();
         }
     }
@@ -387,7 +387,7 @@ public class ResourceResolverControl {
      * Commit changes on all modifiable ResourceProviders.
      */
     public void commit(final ResourceResolverContext context) throws PersistenceException {
-        for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllUsedModifiable()) {
+        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllUsedModifiable()) {
             p.commit();
         }
     }
@@ -396,7 +396,7 @@ public class ResourceResolverControl {
      * Check if any modifiable ResourceProvider has uncommited changes.
      */
     public boolean hasChanges(final ResourceResolverContext context) {
-        for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllUsedModifiable()) {
+        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllUsedModifiable()) {
             if (p.hasChanges()) {
                 return true;
             }
@@ -409,7 +409,7 @@ public class ResourceResolverControl {
      */
     public String[] getSupportedLanguages(final ResourceResolverContext context) {
         final Set<String> supportedLanguages = new LinkedHashSet<String>();
-        for (AuthenticatedResourceProvider p : context.getResolveContextManager().getAllBestEffort(storage.getLanguageQueryableHandlers(), this)) {
+        for (AuthenticatedResourceProvider p : context.getProviderManager().getAllBestEffort(storage.getLanguageQueryableHandlers(), this)) {
             supportedLanguages.addAll(Arrays.asList(p.getSupportedLanguages()));
         }
         return supportedLanguages.toArray(new String[supportedLanguages.size()]);
@@ -432,7 +432,7 @@ public class ResourceResolverControl {
             final ResourceResolverContext context,
             final String language) {
         final List<AuthenticatedResourceProvider> queryableProviders = new ArrayList<AuthenticatedResourceProvider>();
-        for (final AuthenticatedResourceProvider p : context.getResolveContextManager().getAllBestEffort(storage.getLanguageQueryableHandlers(), this)) {
+        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllBestEffort(storage.getLanguageQueryableHandlers(), this)) {
             if (ArrayUtils.contains(p.getSupportedLanguages(), language)) {
                 queryableProviders.add(p);
             }
@@ -460,7 +460,7 @@ public class ResourceResolverControl {
     @SuppressWarnings("unchecked")
     public <AdapterType> AdapterType adaptTo(final ResourceResolverContext context, Class<AdapterType> type) {
         // TODO - improve by providing an iterator instead of a list (getAllBestEffort)
-        for (AuthenticatedResourceProvider p : context.getResolveContextManager().getAllBestEffort(storage.getAdaptableHandlers(), this)) {
+        for (AuthenticatedResourceProvider p : context.getProviderManager().getAllBestEffort(storage.getAdaptableHandlers(), this)) {
             final Object adaptee = p.adaptTo(type);
             if (adaptee != null) {
                 return (AdapterType) adaptee;
@@ -478,14 +478,14 @@ public class ResourceResolverControl {
         }
         AuthenticatedResourceProvider srcProvider = null;
         try {
-            srcProvider = context.getResolveContextManager().getOrCreateProvider(srcNode.getValue(), this);
+            srcProvider = context.getProviderManager().getOrCreateProvider(srcNode.getValue(), this);
         } catch (LoginException e) {
             // ignore
         }
         if ( srcProvider == null ) {
             throw new PersistenceException("Source resource does not exist.", null, srcAbsPath, null);
         }
-        final Resource srcResource = srcProvider.getResource(srcAbsPath, null, null, false);
+        final Resource srcResource = srcProvider.getResource(srcAbsPath, null, null);
         if ( srcResource == null ) {
             throw new PersistenceException("Source resource does not exist.", null, srcAbsPath, null);
         }
@@ -497,14 +497,14 @@ public class ResourceResolverControl {
         }
         AuthenticatedResourceProvider destProvider = null;
         try {
-            destProvider = context.getResolveContextManager().getOrCreateProvider(destNode.getValue(), this);
+            destProvider = context.getProviderManager().getOrCreateProvider(destNode.getValue(), this);
         } catch (LoginException e) {
             // ignore
         }
         if ( destProvider == null ) {
             throw new PersistenceException("Destination resource does not exist.", null, destAbsPath, null);
         }
-        final Resource destResource = destProvider.getResource(destAbsPath, null, null, false);
+        final Resource destResource = destProvider.getResource(destAbsPath, null, null);
         if ( destResource == null ) {
             throw new PersistenceException("Destination resource does not exist.", null, destAbsPath, null);
         }
@@ -522,7 +522,7 @@ public class ResourceResolverControl {
         for (final Entry<String, Node<ResourceProviderHandler>> entry : parent.getChildren().entrySet()) {
             if ( entry.getValue().getValue() != null ) {
                 try {
-                    context.getResolveContextManager().getOrCreateProvider(entry.getValue().getValue(), this);
+                    context.getProviderManager().getOrCreateProvider(entry.getValue().getValue(), this);
                     hasMoreProviders = true;
                 } catch ( final LoginException ignore) {
                     // ignore
@@ -613,7 +613,7 @@ public class ResourceResolverControl {
             final String path) {
         try {
             final Node<ResourceProviderHandler> node = storage.getTree().getBestMatchingNode(path);
-            return node == null ? null : context.getResolveContextManager().getOrCreateProvider(node.getValue(), this);
+            return node == null ? null : context.getProviderManager().getOrCreateProvider(node.getValue(), this);
         } catch ( final LoginException le ) {
             // ignore
             return null;
@@ -630,7 +630,7 @@ public class ResourceResolverControl {
         final Node<ResourceProviderHandler> node = storage.getTree().getBestMatchingNode(path);
         if ( node != null && node.getValue().getInfo().isModifiable() ) {
             try {
-                return context.getResolveContextManager().getOrCreateProvider(node.getValue(), this);
+                return context.getProviderManager().getOrCreateProvider(node.getValue(), this);
             } catch ( final LoginException le ) {
                 // ignore
                 return null;

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java?rev=1728654&r1=1728653&r2=1728654&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java Fri Feb  5 12:24:08 2016
@@ -24,59 +24,91 @@ import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
 import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
-import org.apache.sling.api.resource.runtime.dto.AuthType;
+import org.apache.sling.api.security.AccessSecurityException;
+import org.apache.sling.api.security.ResourceAccessSecurity;
+import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker;
+import org.apache.sling.resourceresolver.impl.ResourceResolverImpl;
+import org.apache.sling.resourceresolver.impl.helper.AbstractIterator;
 import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
 import org.apache.sling.spi.resource.provider.ResolveContext;
 import org.apache.sling.spi.resource.provider.ResourceContext;
 import org.apache.sling.spi.resource.provider.ResourceProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
- * This {@link StatefulResourceProvider} implementation authenticates the
- * underlying {@link ResourceProvider}. The authentication can be done during
- * creation of the object (for {@link AuthType#required}) or before invoking the
- * first method (for {@link AuthType#lazy}).
+ * This {@link AuthenticatedResourceProvider} implementation keeps a resource
+ * provider and the authentication information (through the {@link ResolveContext}.
+ *
+ * The methods are similar to {@link ResourceProvider}.
  */
 public class AuthenticatedResourceProvider {
 
+    private static final Logger logger = LoggerFactory.getLogger(ResourceResolverImpl.class);
+
     private static final String FORBIDDEN_ATTRIBUTE = ResourceResolverFactory.PASSWORD;
 
-    public static final AuthenticatedResourceProvider UNAUTHENTICATED_PROVIDER = new AuthenticatedResourceProvider(null, null);
+    public static final AuthenticatedResourceProvider UNAUTHENTICATED_PROVIDER = new AuthenticatedResourceProvider(null, false, null, null);
 
     private final ResourceProvider<Object> provider;
 
-    private final ResolveContext<Object> cachedContext;
+    private final ResolveContext<Object> resolveContext;
 
-    private volatile boolean authenticated;
+    private final ResourceAccessSecurityTracker tracker;
 
+    private final boolean useRAS;
 
-    public AuthenticatedResourceProvider(final ResourceProvider<Object> provider,
-            final ResolveContext<Object> resolveContext) {
+    public AuthenticatedResourceProvider(@Nonnull final ResourceProvider<Object> provider,
+            final boolean useRAS,
+            @Nonnull final ResolveContext<Object> resolveContext,
+            @Nonnull final ResourceAccessSecurityTracker tracker) {
         this.provider = provider;
-        this.cachedContext = resolveContext;
-    }
-
-    public ResolveContext<Object> getResolveContext() {
-        return this.cachedContext;
-    }
-
+        this.resolveContext = resolveContext;
+        this.tracker = tracker;
+        this.useRAS = useRAS;
+    }
+
+    /**
+     * Get the resolve context.
+     * @return The resolve context
+     */
+    public @Nonnull ResolveContext<Object> getResolveContext() {
+        return this.resolveContext;
+    }
+
+    /**
+     * #see {@link ResourceProvider#refresh(ResolveContext)}
+     */
     public void refresh() {
-        this.provider.refresh(this.cachedContext);
+        this.provider.refresh(this.resolveContext);
     }
 
+    /**
+     * #see {@link ResourceProvider#isLive(ResolveContext)}
+     */
     public boolean isLive() {
-        return this.provider.isLive(this.cachedContext);
+        return this.provider.isLive(this.resolveContext);
     }
 
+    /**
+     * #see {@link ResourceProvider#getParent(ResolveContext, Resource)}
+     */
     public Resource getParent(final Resource child) {
-        return this.provider.getParent(this.cachedContext, child);
+        return wrapResource(this.provider.getParent(this.resolveContext, child));
     }
 
-    public Resource getResource(String path, Resource parent, final Map<String, String> parameters, boolean isResolve) {
-        ResourceContext resourceContext = ResourceContext.EMPTY_CONTEXT;
+    /**
+     * #see {@link ResourceProvider#getResource(ResolveContext, String, ResourceContext, Resource)}
+     */
+    public Resource getResource(final String path, final Resource parent, final Map<String, String> parameters) {
+        final ResourceContext resourceContext;
         if ( parameters != null ) {
             resourceContext = new ResourceContext() {
 
@@ -85,17 +117,25 @@ public class AuthenticatedResourceProvid
                     return parameters;
                 }
             };
+        } else {
+            resourceContext = ResourceContext.EMPTY_CONTEXT;
         }
-        return this.provider.getResource(this.cachedContext, path, resourceContext, parent);
+        return wrapResource(this.provider.getResource(this.resolveContext, path, resourceContext, parent));
     }
 
-    public Iterator<Resource> listChildren(Resource parent) {
-        return this.provider.listChildren(this.cachedContext, parent);
+    /**
+     * #see {@link ResourceProvider#listChildren(ResolveContext, Resource)}
+     */
+    public Iterator<Resource> listChildren(final Resource parent) {
+        return wrapIterator(this.provider.listChildren(this.resolveContext, parent));
     }
 
+    /**
+     * #see {@link ResourceProvider#getAttributeNames(ResolveContext)}
+     */
     public Collection<String> getAttributeNames(final Map<String, Object> authInfo) {
         Set<String> attributeNames = new LinkedHashSet<String>();
-        Collection<String> rpAttributeNames = this.provider.getAttributeNames(this.cachedContext);
+        Collection<String> rpAttributeNames = this.provider.getAttributeNames(this.resolveContext);
         if (rpAttributeNames != null) {
             attributeNames.addAll(rpAttributeNames);
         }
@@ -106,80 +146,262 @@ public class AuthenticatedResourceProvid
         return attributeNames;
     }
 
+    /**
+     * #see {@link ResourceProvider#getAttribute(ResolveContext, String)}
+     */
     public Object getAttribute(final String name, final Map<String, Object> authInfo) {
         if (FORBIDDEN_ATTRIBUTE.equals(name)) {
             return null;
         }
-        Object attribute = this.provider.getAttribute(this.cachedContext, name);
+        Object attribute = this.provider.getAttribute(this.resolveContext, name);
         if (attribute == null) {
             attribute = authInfo.get(name);
         }
         return attribute;
     }
 
-    public Resource create(final ResourceResolver resolver, String path, Map<String, Object> properties) throws PersistenceException {
-        return this.provider.create(this.cachedContext, path, properties);
+    /**
+     * #see {@link ResourceProvider#create(ResolveContext, String, Map)}
+     */
+    public Resource create(final ResourceResolver resolver,
+            final String path,
+            final Map<String, Object> properties)
+    throws PersistenceException {
+        if ( this.canCreate(resolver, path) ) {
+            return this.provider.create(this.resolveContext, path, properties);
+        } else {
+            return null;
+        }
     }
 
-    public void delete(Resource resource) throws PersistenceException {
-        this.provider.delete(this.cachedContext, resource);
+    /**
+     * #see {@link ResourceProvider#delete(ResolveContext, Resource)}
+     */
+    public void delete(final Resource resource) throws PersistenceException {
+        if ( this.canDelete(resource) ) {
+            this.provider.delete(this.resolveContext, resource);
+        } else {
+            throw new PersistenceException("Unable to delete resource " + resource.getPath());
+        }
     }
 
+    /**
+     * #see {@link ResourceProvider#revert(ResolveContext)}
+     */
     public void revert() {
-        this.provider.revert(this.cachedContext);
+        this.provider.revert(this.resolveContext);
     }
 
+    /**
+     * #see {@link ResourceProvider#commit(ResolveContext)}
+     */
     public void commit() throws PersistenceException {
-        this.provider.commit(this.cachedContext);
+        this.provider.commit(this.resolveContext);
     }
 
+    /**
+     * #see {@link ResourceProvider#hasChanges(ResolveContext)}
+     */
     public boolean hasChanges() {
-        return this.provider.hasChanges(this.cachedContext);
+        return this.provider.hasChanges(this.resolveContext);
     }
 
+    /**
+     * #see {@link ResourceProvider#getQueryLanguageProvider()}
+     */
     private QueryLanguageProvider<Object> getQueryLanguageProvider() {
         return this.provider.getQueryLanguageProvider();
     }
 
+    /**
+     * #see {@link QueryLanguageProvider#getSupportedLanguages(ResolveContext)}
+     */
     public String[] getSupportedLanguages() {
         final QueryLanguageProvider<Object> jcrQueryProvider = getQueryLanguageProvider();
         if (jcrQueryProvider == null) {
             return null;
         }
-        return jcrQueryProvider.getSupportedLanguages(this.cachedContext);
+        return jcrQueryProvider.getSupportedLanguages(this.resolveContext);
     }
 
-    public Iterator<Resource> findResources(String query, String language) {
+    /**
+     * #see {@link QueryLanguageProvider}{@link #findResources(String, String)}
+     */
+    public Iterator<Resource> findResources(final String query, final String language) {
         final QueryLanguageProvider<Object> jcrQueryProvider = getQueryLanguageProvider();
         if (jcrQueryProvider == null) {
             return null;
         }
-        return jcrQueryProvider.findResources(this.cachedContext, query, language);
+        return wrapIterator(jcrQueryProvider.findResources(this.resolveContext, transformQuery(query, language), language));
     }
 
+    /**
+     * #see {@link QueryLanguageProvider#queryResources(ResolveContext, String, String)}
+     */
     @SuppressWarnings({ "unchecked", "rawtypes" })
-    public Iterator<Map<String, Object>> queryResources(String query, String language) {
+    public Iterator<Map<String, Object>> queryResources(final String query, final String language) {
         final QueryLanguageProvider<Object> jcrQueryProvider = getQueryLanguageProvider();
         if (jcrQueryProvider == null) {
             return null;
         }
-        return (Iterator) jcrQueryProvider.queryResources(this.cachedContext, query, language);
+        return (Iterator) jcrQueryProvider.queryResources(this.resolveContext, transformQuery(query, language), language);
+    }
+
+    /**
+     * #see {@link ResourceProvider#adaptTo(ResolveContext, Class)}
+     */
+    public <AdapterType> AdapterType adaptTo(final Class<AdapterType> type) {
+        return this.provider.adaptTo(this.resolveContext, type);
+    }
+
+    /**
+     * #see {@link ResourceProvider#copy(ResolveContext, String, String)}
+     */
+    public boolean copy(final String srcAbsPath, final String destAbsPath) throws PersistenceException {
+        return this.provider.copy(this.resolveContext, srcAbsPath, destAbsPath);
+    }
+
+    /**
+     * #see {@link ResourceProvider#move(ResolveContext, String, String)}
+     */
+    public boolean move(final String srcAbsPath, final String destAbsPath) throws PersistenceException {
+        return this.provider.move(this.resolveContext, srcAbsPath, destAbsPath);
+    }
+
+    private boolean canCreate(final ResourceResolver resolver, final String path) {
+        boolean allowed = true;
+        if ( this.useRAS ) {
+            final ResourceAccessSecurity security = tracker.getProviderResourceAccessSecurity();
+            if ( security != null ) {
+                allowed = security.canCreate(path, resolver);
+            } else {
+                allowed = false;
+            }
+        }
+
+        if ( allowed ) {
+            final ResourceAccessSecurity security = tracker.getApplicationResourceAccessSecurity();
+            if (security != null) {
+                allowed = security.canCreate(path, resolver);
+            }
+        }
+        return allowed;
+    }
+
+    private boolean canDelete(final Resource resource) {
+        boolean allowed = true;
+        if ( this.useRAS ) {
+            final ResourceAccessSecurity security = tracker.getProviderResourceAccessSecurity();
+            if ( security != null ) {
+                allowed = security.canDelete(resource);
+            } else {
+                allowed = false;
+            }
+        }
+
+        if ( allowed ) {
+            final ResourceAccessSecurity security = tracker.getApplicationResourceAccessSecurity();
+            if (security != null) {
+                allowed = security.canDelete(resource);
+            }
+        }
+        return allowed;
     }
 
-    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
-        return this.provider.adaptTo(this.cachedContext, type);
+    /**
+     * applies resource access security if configured
+     */
+    private String transformQuery ( final String query, final String language ) {
+        String returnValue = query;
+
+        if (this.useRAS) {
+            final ResourceAccessSecurity resourceAccessSecurity = tracker
+                    .getProviderResourceAccessSecurity();
+            if (resourceAccessSecurity != null) {
+                try {
+                    returnValue = resourceAccessSecurity.transformQuery(
+                            returnValue, language, this.resolveContext.getResourceResolver());
+                } catch (AccessSecurityException e) {
+                    logger.error(
+                            "AccessSecurityException occurred while trying to transform the query {} (language {}).",
+                            new Object[] { query, language }, e);
+                }
+            }
+        }
+
+        final ResourceAccessSecurity resourceAccessSecurity = tracker
+                .getApplicationResourceAccessSecurity();
+        if (resourceAccessSecurity != null) {
+            try {
+                returnValue = resourceAccessSecurity.transformQuery(
+                        returnValue, language, this.resolveContext.getResourceResolver());
+            } catch (AccessSecurityException e) {
+                logger.error(
+                        "AccessSecurityException occurred while trying to transform the query {} (language {}).",
+                        new Object[] { query, language }, e);
+            }
+        }
+
+        return returnValue;
     }
 
-    public boolean copy(String srcAbsPath, String destAbsPath) throws PersistenceException {
-        return this.provider.copy(this.cachedContext, srcAbsPath, destAbsPath);
+    /**
+     * Wrap a resource with additional resource access security
+     * @param rsrc The resource or {@code null}.
+     * @return The wrapped resource or {@code null}
+     */
+    private @CheckForNull Resource wrapResource(@CheckForNull Resource rsrc) {
+        Resource returnValue = null;
+
+        if (useRAS && rsrc != null) {
+            final ResourceAccessSecurity resourceAccessSecurity = tracker.getProviderResourceAccessSecurity();
+            if (resourceAccessSecurity != null) {
+                returnValue = resourceAccessSecurity.getReadableResource(rsrc);
+            }
+        } else {
+            returnValue = rsrc;
+        }
+
+        if ( returnValue != null ) {
+            final ResourceAccessSecurity resourceAccessSecurity = tracker.getApplicationResourceAccessSecurity();
+            if (resourceAccessSecurity != null) {
+                returnValue = resourceAccessSecurity.getReadableResource(returnValue);
+            }
+        }
+
+        return returnValue;
     }
 
-    public boolean move(String srcAbsPath, String destAbsPath) throws PersistenceException {
-        return this.provider.move(this.cachedContext, srcAbsPath, destAbsPath);
+    private Iterator<Resource> wrapIterator(Iterator<Resource> iterator) {
+        if (iterator == null) {
+            return iterator;
+        } else {
+            return new SecureIterator(iterator);
+        }
+    }
+
+    private class SecureIterator extends AbstractIterator<Resource> {
+
+        private final Iterator<Resource> iterator;
+
+        public SecureIterator(Iterator<Resource> iterator) {
+            this.iterator = iterator;
+        }
+
+        @Override
+        protected Resource seek() {
+            while (iterator.hasNext()) {
+                final Resource resource = wrapResource(iterator.next());
+                if (resource != null) {
+                    return resource;
+                }
+            }
+            return null;
+        }
     }
 
     @Override
     public String toString() {
-        return "[" + getClass().getSimpleName() + "# rp: " + this.provider + ", authenticated: " + authenticated + "]";
+        return "[" + getClass().getSimpleName() + "# rp: " + this.provider + "]";
     }
 }

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/BasicResolveContext.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/BasicResolveContext.java?rev=1728654&r1=1728653&r2=1728654&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/BasicResolveContext.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/BasicResolveContext.java Fri Feb  5 12:24:08 2016
@@ -39,7 +39,7 @@ public class BasicResolveContext<T> impl
 
     private final ResourceResolver resolver;
 
-    private final ResolveContextManager resolveContextManager;
+    private final ProviderManager resolveContextManager;
 
     private final ResourceResolverControl control;
 
@@ -54,7 +54,7 @@ public class BasicResolveContext<T> impl
     private volatile ResolveContext<Object> parentResolveContext;
 
     public BasicResolveContext(@Nonnull final ResourceResolver resolver,
-            @Nonnull final ResolveContextManager resolveContextManager,
+            @Nonnull final ProviderManager resolveContextManager,
             @Nonnull final ResourceResolverControl control,
             @CheckForNull final T providerState,
             @Nonnull final String parentPath) {

Copied: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ProviderManager.java (from r1728626, sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ResolveContextManager.java)
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ProviderManager.java?p2=sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ProviderManager.java&p1=sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ResolveContextManager.java&r1=1728626&r2=1728654&rev=1728654&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ResolveContextManager.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ProviderManager.java Fri Feb  5 12:24:08 2016
@@ -30,6 +30,7 @@ import org.apache.sling.api.resource.Log
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.resource.runtime.dto.AuthType;
+import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker;
 import org.apache.sling.resourceresolver.impl.helper.ResourceResolverControl;
 import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
 import org.apache.sling.spi.resource.provider.ResolveContext;
@@ -43,9 +44,9 @@ import org.slf4j.LoggerFactory;
  *
  * This class is not thread safe (same as the resource resolver).
  */
-public class ResolveContextManager {
+public class ProviderManager {
 
-    private static final Logger logger = LoggerFactory.getLogger(ResolveContextManager.class);
+    private static final Logger logger = LoggerFactory.getLogger(ProviderManager.class);
 
     private final ResourceResolver resolver;
 
@@ -60,9 +61,12 @@ public class ResolveContextManager {
     /** Set of refreshable resource providers. */
     private final List<AuthenticatedResourceProvider> refreshable = new ArrayList<AuthenticatedResourceProvider>();
 
-    public ResolveContextManager(@Nonnull final ResourceResolver resolver) {
+    private final ResourceAccessSecurityTracker tracker;
+
+    public ProviderManager(@Nonnull final ResourceResolver resolver, @Nonnull final ResourceAccessSecurityTracker tracker) {
         this.contextMap = new IdentityHashMap<ResourceProviderHandler, AuthenticatedResourceProvider>();
         this.resolver = resolver;
+        this.tracker = tracker;
     }
 
     /**
@@ -157,7 +161,10 @@ public class ResolveContextManager {
                 control,
                 contextData,
                 ResourceUtil.getParent(handler.getInfo().getPath()));
-        final AuthenticatedResourceProvider rp = new AuthenticatedResourceProvider(provider, context);
+        final AuthenticatedResourceProvider rp = new AuthenticatedResourceProvider(provider,
+                handler.getInfo().getUseResourceAccessSecurity(),
+                context,
+                this.tracker);
         if ( isAuthenticated ) {
             this.authenticated.add(rp);
         }

Modified: sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControlTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControlTest.java?rev=1728654&r1=1728653&r2=1728654&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControlTest.java (original)
+++ sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControlTest.java Fri Feb  5 12:24:08 2016
@@ -140,7 +140,7 @@ public class ResourceResolverControlTest
         ResourceProviderStorage storage = new ResourceProviderStorage(handlers);
 
         crp = new ResourceResolverControl(false, authInfo, storage);
-        context = new ResourceResolverContext(rr);
+        context = new ResourceResolverContext(rr, securityTracker);
     }
 
     /**
@@ -175,7 +175,7 @@ public class ResourceResolverControlTest
     @Test
     public void loginLogout() throws LoginException {
 
-        context.getResolveContextManager().authenticateAll(handlers, crp);
+        context.getProviderManager().authenticateAll(handlers, crp);
 
         verify(subProvider).authenticate(authInfo);
 

Modified: sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/stateful/SecureResourceProviderDecoratorTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/stateful/SecureResourceProviderDecoratorTest.java?rev=1728654&r1=1728653&r2=1728654&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/stateful/SecureResourceProviderDecoratorTest.java (original)
+++ sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/stateful/SecureResourceProviderDecoratorTest.java Fri Feb  5 12:24:08 2016
@@ -34,9 +34,10 @@ import java.util.Iterator;
 import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.security.AccessSecurityException;
 import org.apache.sling.api.security.ResourceAccessSecurity;
 import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker;
-import org.apache.sling.resourceresolver.impl.providers.stateful.SecureResourceProviderDecorator;
+import org.apache.sling.resourceresolver.impl.providers.stateful.AuthenticatedResourceProvider;
 import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
 import org.apache.sling.spi.resource.provider.ResolveContext;
 import org.apache.sling.spi.resource.provider.ResourceProvider;
@@ -49,13 +50,13 @@ public class SecureResourceProviderDecor
     private ResourceAccessSecurity security;
     private ResourceResolver rr;
     private ResolveContext resolveContext;
-    private SecureResourceProviderDecorator src;
+    private AuthenticatedResourceProvider src;
     private ResourceProvider rp;
     private Resource first;
     private Resource second;
 
     @Before
-    public void prepare() throws PersistenceException {
+    public void prepare() throws PersistenceException, AccessSecurityException {
 
         rr = mock(ResourceResolver.class);
         resolveContext = mock(ResolveContext.class);
@@ -67,6 +68,7 @@ public class SecureResourceProviderDecor
 
         when(security.getReadableResource(first)).thenReturn(first);
         when(security.getReadableResource(second)).thenReturn(null);
+        when(security.transformQuery("FIND ALL", "MockQueryLanguage", rr)).thenReturn("FIND ALL");
 
         QueryLanguageProvider qlp = mock(QueryLanguageProvider.class);
 
@@ -83,7 +85,7 @@ public class SecureResourceProviderDecor
             }
         };
 
-        src = new SecureResourceProviderDecorator(rp, resolveContext, securityTracker);
+        src = new AuthenticatedResourceProvider(rp, false, resolveContext, securityTracker);
 
     }