You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by md...@apache.org on 2014/07/29 15:32:15 UTC

svn commit: r1614345 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/

Author: mduerig
Date: Tue Jul 29 13:32:15 2014
New Revision: 1614345

URL: http://svn.apache.org/r1614345
Log:
OAK-2000: Observation events accessibility not checked correctly
Pass a dedicated permission provider to all event listeners

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/PermissionProviderFactory.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/FilterBuilder.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/FilterBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/FilterBuilder.java?rev=1614345&r1=1614344&r2=1614345&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/FilterBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/FilterBuilder.java Tue Jul 29 13:32:15 2014
@@ -43,7 +43,6 @@ import org.apache.jackrabbit.oak.api.Pro
 import org.apache.jackrabbit.oak.plugins.nodetype.TypePredicate;
 import org.apache.jackrabbit.oak.plugins.observation.filter.UniversalFilter.Selector;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
-import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
 /**
@@ -173,13 +172,13 @@ public final class FilterBuilder {
      * A condition that hold for accessible items as determined by the passed permission
      * provider.
      *
-     * @param permissionProvider  permission provider for checking whether an item is accessible.
+     * @param permissionProviderFactory  permission provider for checking whether an item is accessible.
      * @return  access control condition
      * @see  ACFilter
      */
     @Nonnull
-    public Condition accessControl(@Nonnull PermissionProvider permissionProvider) {
-        return new ACCondition(checkNotNull(permissionProvider));
+    public Condition accessControl(@Nonnull PermissionProviderFactory permissionProviderFactory) {
+        return new ACCondition(checkNotNull(permissionProviderFactory));
     }
 
     /**
@@ -400,15 +399,15 @@ public final class FilterBuilder {
     }
 
     private static class ACCondition implements Condition {
-        private final PermissionProvider permissionProvider;
+        private final PermissionProviderFactory permissionProviderFactory;
 
-        public ACCondition(PermissionProvider permissionProvider) {
-            this.permissionProvider = permissionProvider;
+        public ACCondition(PermissionProviderFactory permissionProviderFactory) {
+            this.permissionProviderFactory = permissionProviderFactory;
         }
 
         @Override
         public EventFilter createFilter(NodeState before, NodeState after) {
-            return new ACFilter(before, after, permissionProvider);
+            return new ACFilter(before, after, permissionProviderFactory.create());
         }
     }
 

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/PermissionProviderFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/PermissionProviderFactory.java?rev=1614345&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/PermissionProviderFactory.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/PermissionProviderFactory.java Tue Jul 29 13:32:15 2014
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.plugins.observation.filter;
+
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
+
+/**
+ * Factory for {@link PermissionProvider} instances.
+ */
+public interface PermissionProviderFactory {
+
+    /**
+     * Create a new {@code PermissionProvider} instance.
+     * @return
+     */
+    @Nonnull
+    PermissionProvider create();
+}

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java?rev=1614345&r1=1614344&r2=1614345&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java Tue Jul 29 13:32:15 2014
@@ -42,14 +42,12 @@ import org.apache.jackrabbit.commons.obs
 import org.apache.jackrabbit.oak.api.ContentSession;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.plugins.observation.CommitRateLimiter;
-import org.apache.jackrabbit.oak.plugins.observation.filter.ACFilter;
 import org.apache.jackrabbit.oak.plugins.observation.filter.EventFilter;
 import org.apache.jackrabbit.oak.plugins.observation.filter.FilterProvider;
 import org.apache.jackrabbit.oak.plugins.observation.filter.Filters;
 import org.apache.jackrabbit.oak.spi.commit.BackgroundObserver;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.commit.Observer;
-import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.whiteboard.CompositeRegistration;
 import org.apache.jackrabbit.oak.spi.whiteboard.Registration;
@@ -84,7 +82,6 @@ class ChangeProcessor implements Observe
 
     private final ContentSession contentSession;
     private final NamePathMapper namePathMapper;
-    private final PermissionProvider permissionProvider;
     private final ListenerTracker tracker;
     private final EventListener eventListener;
     private final AtomicReference<FilterProvider> filterProvider;
@@ -100,7 +97,6 @@ class ChangeProcessor implements Observe
     public ChangeProcessor(
             ContentSession contentSession,
             NamePathMapper namePathMapper,
-            PermissionProvider permissionProvider,
             ListenerTracker tracker,
             FilterProvider filters,
             StatisticManager statisticManager,
@@ -108,7 +104,6 @@ class ChangeProcessor implements Observe
             CommitRateLimiter commitRateLimiter) {
         this.contentSession = contentSession;
         this.namePathMapper = namePathMapper;
-        this.permissionProvider = permissionProvider;
         this.tracker = tracker;
         eventListener = tracker.getTrackedListener();
         filterProvider = new AtomicReference<FilterProvider>(filters);
@@ -269,9 +264,8 @@ class ChangeProcessor implements Observe
                 if (provider.includeCommit(contentSession.toString(), info)) {
                     for (String path : provider.getSubTrees()) {
                         EventFilter userFilter = provider.getFilter(previousRoot, root);
-                        EventFilter acFilter = new ACFilter(previousRoot, root, permissionProvider);
-                        EventIterator events = new EventQueue(
-                                namePathMapper, info, previousRoot, root, path, Filters.all(userFilter, acFilter, VISIBLE_FILTER));
+                        EventIterator events = new EventQueue(namePathMapper, info, previousRoot, root,
+                                path, Filters.all(userFilter, VISIBLE_FILTER));
 
                         if (events.hasNext() && runningMonitor.enterIf(running)) {
                             try {

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java?rev=1614345&r1=1614344&r2=1614345&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java Tue Jul 29 13:32:15 2014
@@ -24,12 +24,14 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.plugins.observation.filter.GlobbingPathFilter.STAR;
 import static org.apache.jackrabbit.oak.plugins.observation.filter.GlobbingPathFilter.STAR_STAR;
 
+import java.security.Principal;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
@@ -53,6 +55,7 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.plugins.observation.filter.FilterBuilder;
 import org.apache.jackrabbit.oak.plugins.observation.filter.FilterBuilder.Condition;
 import org.apache.jackrabbit.oak.plugins.observation.filter.FilterProvider;
+import org.apache.jackrabbit.oak.plugins.observation.filter.PermissionProviderFactory;
 import org.apache.jackrabbit.oak.plugins.observation.filter.Selectors;
 import org.apache.jackrabbit.oak.spi.commit.Observable;
 import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
@@ -85,6 +88,7 @@ public class ObservationManagerImpl impl
     private final StatisticManager statisticManager;
     private final int queueLength;
     private final CommitRateLimiter commitRateLimiter;
+    private final PermissionProviderFactory permissionProviderFactory;
 
     /**
      * Create a new instance based on a {@link ContentSession} that needs to implement
@@ -108,6 +112,15 @@ public class ObservationManagerImpl impl
         this.statisticManager = sessionContext.getStatisticManager();
         this.queueLength = queueLength;
         this.commitRateLimiter = commitRateLimiter;
+        this.permissionProviderFactory = new PermissionProviderFactory() {
+            Set<Principal> principals = sessionDelegate.getAuthInfo().getPrincipals();
+            @Nonnull
+            @Override
+            public PermissionProvider create() {
+                return authorizationConfig.getPermissionProvider(
+                        sessionDelegate.getRoot(), sessionDelegate.getWorkspaceName(), principals);
+            }
+        };
     }
 
     public void dispose() {
@@ -130,8 +143,11 @@ public class ObservationManagerImpl impl
         if (processor == null) {
             LOG.debug(OBSERVATION,
                     "Registering event listener {} with filter {}", listener, filterProvider);
+            // TODO sharing the namePathMapper across different thread might lead to lock contention.
+            // If this turns out to be problematic we might create a dedicated snapshot for each
+            // session. See OAK-1368.
             processor = new ChangeProcessor(sessionDelegate.getContentSession(), namePathMapper,
-                    createPermissionProvider(), tracker, filterProvider, statisticManager, queueLength,
+                    tracker, filterProvider, statisticManager, queueLength,
                     commitRateLimiter);
             processors.put(listener, processor);
             processor.start(whiteboard);
@@ -223,7 +239,8 @@ public class ObservationManagerImpl impl
                     filterBuilder.moveSubtree(),
                     filterBuilder.eventType(eventTypes),
                     filterBuilder.uuid(Selectors.PARENT, uuids),
-                    filterBuilder.nodeType(Selectors.PARENT, validateNodeTypeNames(nodeTypeName))));
+                    filterBuilder.nodeType(Selectors.PARENT, validateNodeTypeNames(nodeTypeName)),
+                    filterBuilder.accessControl(permissionProviderFactory)));
 
         // FIXME support multiple path in ListenerTracker
         ListenerTracker tracker = new WarningListenerTracker(
@@ -265,15 +282,6 @@ public class ObservationManagerImpl impl
     }
 
     //------------------------------------------------------------< private >---
-    /**
-     * Create a new permission provider instance for the current revision of the
-     * {@code Root} associated with the {@code sessionDelegate}.
-     *
-     * @return a new permission provider.
-     */
-    private PermissionProvider createPermissionProvider() {
-        return authorizationConfig.getPermissionProvider(sessionDelegate.getRoot(), sessionDelegate.getWorkspaceName(), sessionDelegate.getAuthInfo().getPrincipals());
-    }
 
     /**
      * Validates the given node type names.