You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2011/10/11 09:53:54 UTC

svn commit: r1181648 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl: ACLProvider.java CachingEntryCollector.java EntryCollector.java

Author: angela
Date: Tue Oct 11 07:53:54 2011
New Revision: 1181648

URL: http://svn.apache.org/viewvc?rev=1181648&view=rev
Log:
JCR-3064 - modified patch originally posted by alex parvulescu, omitting some calls to SystemSession.getNode during ac-evaluation

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/CachingEntryCollector.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/EntryCollector.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java?rev=1181648&r1=1181647&r2=1181648&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java Tue Oct 11 07:53:54 2011
@@ -203,7 +203,8 @@ public class ACLProvider extends Abstrac
             
             if (isAccessControlled(accessControlledNode)) {
                 if (permissions.canRead(aclNode.getPrimaryPath(), aclNode.getNodeId())) {
-                    acls.add(new UnmodifiableAccessControlList(entryCollector.getEntries(accessControlledNode), accessControlledNode.getPath(), Collections.<String, Integer>emptyMap()));
+                    List<AccessControlEntry> aces = entryCollector.getEntries(accessControlledNode).getACEs();
+                    acls.add(new UnmodifiableAccessControlList(aces, accessControlledNode.getPath(), Collections.<String, Integer>emptyMap()));
                 } else {
                     throw new AccessDeniedException("Access denied at " + Text.getRelativeParent(aclNode.getPath(), 1));
                 }
@@ -282,7 +283,8 @@ public class ACLProvider extends Abstrac
         if (isAccessControlled(node)) {
             if (permissions.grants(node.getPrimaryPath(), Permission.READ_AC)) {
                 // retrieve the entries for the access controlled node
-                acls.add(new UnmodifiableAccessControlList(entryCollector.getEntries(node), node.getPath(), Collections.<String, Integer>emptyMap()));
+                List<AccessControlEntry> aces = entryCollector.getEntries(node).getACEs();
+                acls.add(new UnmodifiableAccessControlList(aces, node.getPath(), Collections.<String, Integer>emptyMap()));
             } else {
                 throw new AccessDeniedException("Access denied at " + node.getPath());
             }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/CachingEntryCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/CachingEntryCollector.java?rev=1181648&r1=1181647&r2=1181648&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/CachingEntryCollector.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/CachingEntryCollector.java Tue Oct 11 07:53:54 2011
@@ -25,8 +25,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.jcr.RepositoryException;
-import javax.jcr.security.AccessControlEntry;
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -45,7 +43,7 @@ class CachingEntryCollector extends Entr
      * nodeID (key). The map only contains an entry if the corresponding Node
      * is access controlled.
      */
-    private final Map<NodeId, CacheEntry> cache;
+    private final Map<NodeId, Entries> cache;
     private final Object monitor = new Object();
 
     /**
@@ -75,14 +73,12 @@ class CachingEntryCollector extends Entr
      * @see EntryCollector#getEntries(org.apache.jackrabbit.core.NodeImpl)
      */
     @Override    
-    protected List<AccessControlEntry> getEntries(NodeImpl node) throws RepositoryException {
-        List<AccessControlEntry> entries;
+    protected Entries getEntries(NodeImpl node) throws RepositoryException {
+        Entries entries;
         NodeId nodeId = node.getNodeId();
         synchronized (monitor) {
-            CacheEntry ce = cache.get(nodeId);
-            if (ce != null) {
-                entries = ce.entries;
-            } else {
+            entries = cache.get(nodeId);
+            if (entries == null) {
                 // fetch entries and update the cache
                 entries = updateCache(node);
             }
@@ -94,13 +90,11 @@ class CachingEntryCollector extends Entr
      * @see EntryCollector#getEntries(org.apache.jackrabbit.core.id.NodeId)
      */
     @Override
-    protected List<AccessControlEntry> getEntries(NodeId nodeId) throws RepositoryException {
-        List<AccessControlEntry> entries;
+    protected Entries getEntries(NodeId nodeId) throws RepositoryException {
+        Entries entries;
         synchronized (monitor) {
-            CacheEntry ce = cache.get(nodeId);
-            if (ce != null) {
-                entries = ce.entries;
-            } else {
+            entries = cache.get(nodeId);
+            if (entries == null) {
                 // fetch entries and update the cache
                 NodeImpl n = getNodeById(nodeId);
                 entries = updateCache(n);
@@ -117,8 +111,8 @@ class CachingEntryCollector extends Entr
      * @return The list of entries present on the specified node or an empty list.
      * @throws RepositoryException If an error occurs.
      */
-    private List<AccessControlEntry> updateCache(NodeImpl node) throws RepositoryException {
-        List<AccessControlEntry> entries = super.getEntries(node);
+    private Entries updateCache(NodeImpl node) throws RepositoryException {
+        Entries entries = super.getEntries(node);
         if (!entries.isEmpty()) {
             // find the next access control ancestor in the hierarchy
             // 'null' indicates that there is no ac-controlled ancestor.
@@ -137,11 +131,12 @@ class CachingEntryCollector extends Entr
                 }
             }
 
-            // build a new cacheEntry and add it to the cache
-            CacheEntry ce = new CacheEntry(entries, nextId);
-            cache.put(node.getNodeId(), ce);
+            // adjust the 'nextId' to point to the next access controlled
+            // ancestor node instead of the parent and remember the entries.
+            entries.setNextId(nextId);
+            cache.put(node.getNodeId(), entries);
             
-            log.debug("Update cache for node with ID {0}: {1}", node, ce);
+            log.debug("Update cache for node with ID {0}: {1}", node, entries);
         } // else: not access controlled -> ignore.
         return entries;
     }
@@ -166,32 +161,10 @@ class CachingEntryCollector extends Entr
     }
 
     /**
-     * Returns the id of the next access-controlled ancestor if the specified
-     * is contained in the cache. Otherwise the method of the super-class is called.
-     *
-     * @param nodeId The id of the node.
-     * @return the id of the next access-controlled ancestor if the specified
-     * is contained in the cache; otherwise the id of the parent.
-     * @throws RepositoryException
-     * @see EntryCollector#getParentId(org.apache.jackrabbit.core.id.NodeId)
-     */
-    @Override
-    protected NodeId getParentId(NodeId nodeId) throws RepositoryException {
-        synchronized (monitor) {
-            CacheEntry ce = cache.get(nodeId);
-            if (ce != null) {
-                return ce.nextAcNodeId;
-            } else {
-                // no cache entry
-                return super.getParentId(nodeId);
-            }
-        }
-    }
-
-    /**
      * @see EntryCollector#notifyListeners(org.apache.jackrabbit.core.security.authorization.AccessControlModifications)
      */
     @Override
+    @SuppressWarnings("unchecked")
     public void notifyListeners(AccessControlModifications modifications) {
         /* Update cache for all affected access controlled nodes */
         for (Object key : modifications.getNodeIdentifiers()) {
@@ -210,12 +183,12 @@ class CachingEntryCollector extends Entr
                 } else if ((type & POLICY_REMOVED) == POLICY_REMOVED) {
                     // clear the entry and change the entries having a nextID
                     // pointing to this node.
-                    CacheEntry ce = cache.remove(nodeId);
+                    Entries ce = cache.remove(nodeId);
                     if (ce != null) {
-                        NodeId nextId = ce.nextAcNodeId;
-                        for (CacheEntry entry : cache.values()) {
-                            if (nodeId.equals(entry.nextAcNodeId)) {
-                                entry.nextAcNodeId = nextId;
+                        NodeId nextId = ce.getNextId();
+                        for (Entries entry : cache.values()) {
+                            if (nodeId.equals(entry.getNextId())) {
+                                entry.setNextId(nextId);
                             }
                         }
                     }
@@ -231,27 +204,4 @@ class CachingEntryCollector extends Entr
         }
         super.notifyListeners(modifications);
     }
-
-    //--------------------------------------------------------------------------
-    /**
-     *
-     */
-    private static class CacheEntry {
-
-        private final List<AccessControlEntry> entries;
-        private NodeId nextAcNodeId;
-
-        private CacheEntry(List<AccessControlEntry> entries, NodeId nextAcNodeId) {
-            this.entries = entries;
-            this.nextAcNodeId = nextAcNodeId;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            sb.append("size = ").append(entries.size()).append(", ");
-            sb.append("nextAcNodeId = ").append(nextAcNodeId);
-            return sb.toString();
-        }
-    }
 }
\ No newline at end of file

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/EntryCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/EntryCollector.java?rev=1181648&r1=1181647&r2=1181648&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/EntryCollector.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/EntryCollector.java Tue Oct 11 07:53:54 2011
@@ -139,22 +139,18 @@ public class EntryCollector extends Acce
             NodeImpl root = (NodeImpl) systemSession.getRootNode();
             if (ACLProvider.isRepoAccessControlled(root)) {
                 NodeImpl aclNode = root.getNode(N_REPO_POLICY);
-                List<AccessControlEntry> entries = new ACLTemplate(aclNode).getEntries();
-                if (!entries.isEmpty() && filter != null) {
-                    filter.filterEntries(entries, userAces, groupAces);
-                }
+                filterEntries(filter, new ACLTemplate(aclNode).getEntries(), userAces, groupAces);
             }
         } else {
-            NodeId next = node.getNodeId();
+            filterEntries(filter, getEntries(node).getACEs(), userAces, groupAces);
+            NodeId next = node.getParentId();
             while (next != null) {
-                List<AccessControlEntry> entries = getEntries(next);
-                if (!entries.isEmpty() && filter != null) {
-                    filter.filterEntries(entries, userAces, groupAces);
-                }
-                next = getParentId(next);
+                Entries entries = getEntries(next);
+                filterEntries(filter, entries.getACEs(), userAces, groupAces);
+                next = entries.getNextId();
             }
         }
-        
+
         List<AccessControlEntry> entries = new ArrayList<AccessControlEntry>(userAces.size() + groupAces.size());
         entries.addAll(userAces);
         entries.addAll(groupAces);
@@ -163,6 +159,23 @@ public class EntryCollector extends Acce
     }
 
     /**
+     * Filter the specified access control <code>entries</code>
+     *
+     * @param filter
+     * @param aces
+     * @param userAces
+     * @param groupAces
+     */
+    @SuppressWarnings("unchecked")
+    private static void filterEntries(EntryFilter filter, List<AccessControlEntry> aces,
+                                      LinkedList<AccessControlEntry> userAces,
+                                      LinkedList<AccessControlEntry> groupAces) {
+        if (!aces.isEmpty() && filter != null) {
+            filter.filterEntries(aces, userAces, groupAces);
+        }
+    }
+
+    /**
      * Retrieve the access control entries defined for the given node. If the
      * node is not access controlled or if the ACL is empty this method returns
      * an empty list.
@@ -171,17 +184,17 @@ public class EntryCollector extends Acce
      * @return
      * @throws RepositoryException
      */
-    protected List<AccessControlEntry> getEntries(NodeImpl node) throws RepositoryException {
-        List<AccessControlEntry> entries;
+    protected Entries getEntries(NodeImpl node) throws RepositoryException {
+        List<AccessControlEntry> aces;
         if (ACLProvider.isAccessControlled(node)) {
             // collect the aces of that node.
             NodeImpl aclNode = node.getNode(N_POLICY);
-            entries = new ACLTemplate(aclNode).getEntries();
+            aces = new ACLTemplate(aclNode).getEntries();
         } else {
             // not access controlled
-            entries = Collections.emptyList();
+            aces = Collections.emptyList();
         }
-        return entries;
+        return new Entries(aces, node.getParentId());
     }
 
     /**
@@ -190,29 +203,12 @@ public class EntryCollector extends Acce
      * @return
      * @throws RepositoryException
      */
-    protected List<AccessControlEntry> getEntries(NodeId nodeId) throws RepositoryException {
+    protected Entries getEntries(NodeId nodeId) throws RepositoryException {
         NodeImpl node = getNodeById(nodeId);
         return getEntries(node);
     }
 
     /**
-     * Returns the parentId of the given nodeId.
-     *
-     * @param nodeId
-     * @return
-     * @throws RepositoryException
-     */
-    protected NodeId getParentId(NodeId nodeId) throws RepositoryException {
-        NodeId parentId;
-        if (rootID.equals(nodeId)) {
-            parentId = null; // root node reached.
-        } else {
-            parentId = getNodeById(nodeId).getParentId();
-        }
-        return parentId;
-    }
-
-    /**
      *
      * @param nodeId
      * @return
@@ -428,4 +424,50 @@ public class EntryCollector extends Acce
             }
         }
     }
-}
\ No newline at end of file
+
+    //--------------------------------------------------------------------------
+    /**
+     * Inner class combining a list of access control entries with the information
+     * where to start looking for inherited entries.
+     *
+     * Thus <code>nextId</code> either points to the parent of the access
+     * controlled node associated with <code>aces</code> or to the next
+     * access controlled ancestor. It is <code>null</code> if the root node has
+     * been reached and there is no additional ancestor to retrieve access control
+     * entries from.
+     */
+    static class Entries {
+
+        private final List<AccessControlEntry> aces;
+        private NodeId nextId;
+
+        Entries(List<AccessControlEntry> aces, NodeId nextId) {
+            this.aces = aces;
+            this.nextId = nextId;
+        }
+
+        List<AccessControlEntry> getACEs() {
+            return aces;
+        }
+
+        NodeId getNextId() {
+            return nextId;
+        }
+
+        void setNextId(NodeId nextId) {
+            this.nextId = nextId;
+        }
+
+        boolean isEmpty() {
+            return aces.isEmpty();
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append("size = ").append(aces.size()).append(", ");
+            sb.append("nextNodeId = ").append(nextId);
+            return sb.toString();
+        }
+    }
+}