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();
+ }
+ }
+}