diff --git a/config/alfresco/public-services-security-context.xml b/config/alfresco/public-services-security-context.xml
index 56f8d1e251..f64f63f569 100644
--- a/config/alfresco/public-services-security-context.xml
+++ b/config/alfresco/public-services-security-context.xml
@@ -243,6 +243,8 @@
${system.readpermissions.bulkfetchsize}
+
+
@@ -250,6 +252,7 @@
+
diff --git a/source/java/org/alfresco/repo/blog/BlogService.java b/source/java/org/alfresco/repo/blog/BlogService.java
index b4a9621196..1caca65c8b 100644
--- a/source/java/org/alfresco/repo/blog/BlogService.java
+++ b/source/java/org/alfresco/repo/blog/BlogService.java
@@ -1,157 +1,159 @@
-/*
- * Copyright (C) 2005-2011 Alfresco Software Limited.
- *
- * This file is part of Alfresco
- *
- * Alfresco is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Alfresco is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Alfresco. If not, see .
- */
-package org.alfresco.repo.blog;
-
-import java.util.Date;
-
-import org.alfresco.model.ContentModel;
-import org.alfresco.query.PagingRequest;
-import org.alfresco.query.PagingResults;
-import org.alfresco.service.cmr.repository.ChildAssociationRef;
-import org.alfresco.service.cmr.repository.NodeRef;
-import org.alfresco.service.cmr.site.SiteService;
-
-/**
- * The Blog Service handles the management (CRUD) of Alfresco blog data, namely the blog posts which are
- * exposed in the Share UI under the "Blog" heading. The {@link BlogIntegrationService}, a separate service, is
- * concerned with the integration of Alfresco blog content with external Blog-hosting sites.
- *
- * Please note that this service is a work in progress and currently exists primarily to support the blogs REST API.
- *
- * @author Neil Mc Erlean (based on existing webscript controllers in the REST API)
- * @since 4.0
- */
-public interface BlogService
-{
- /**
- * Creates a new blog post within the specified container node.
- *
- * @param blogContainerNode the container node for blog posts (under the site).
- * @param blogTitle the title of the blog post.
- * @param blogContent text/html content of the blog post.
- * @param isDraft true if the blog post is a draft post, else false.
- *
- * @return The {@link ChildAssociationRef} of the newly created blog post.
- *
- * @see SiteService#getContainer(String, String) to retrieve the blogContainerNode
- */
- ChildAssociationRef createBlogPost(NodeRef blogContainerNode, String blogTitle,
- String blogContent, boolean isDraft);
-
- /**
- * Gets the draft blog posts created by the specified user.
- *
- * @param blogContainerNode the container node for blog posts (under the site).
- * @param username to limit results to blogs with this cm:creator. null means all users.
- * @param pagingReq an object defining the paging parameters for the result set.
- *
- * @return a {@link PagingResults} object containing some or all of the results (subject to paging).
- *
- * @see SiteService#getContainer(String, String) to retrieve the blogContainerNode
- */
- PagingResults getDrafts(NodeRef blogContainerNode, String username, PagingRequest pagingReq);
-
- /**
- * Gets the (internally, Alfresco-) published blog posts.
- *
- * @param blogContainerNode the container node for blog posts (under the site).
- * @param fromDate an inclusive date limit for the results (more recent than).
- * @param toDate an inclusive date limit for the results (before).
- * @param byUser if not null limits results to posts by the specified user.
- * if null results will be by all users.
- * @param pagingReq an object defining the paging parameters for the result set.
- *
- * @return a {@link PagingResults} object containing some or all of the results (subject to paging).
- *
- * @see SiteService#getContainer(String, String) to retrieve the blogContainerNode
- */
- PagingResults getPublished(NodeRef blogContainerNode, Date fromDate, Date toDate, String byUser, PagingRequest pagingReq);
-
- /**
- * Gets blog posts published externally (i.e. to an external blog hosting site).
- *
- * @param blogContainerNode the container node for blog posts (under the site).
- * @param pagingReq an object defining the paging parameters for the result set.
- *
- * @return a {@link PagingResults} object containing some or all of the results (subject to paging).
- *
- * @see SiteService#getContainer(String, String) to retrieve the blogContainerNode
- */
- PagingResults getPublishedExternally(NodeRef blogContainerNode, PagingRequest pagingReq);
-
- /**
- * Gets draft blog posts by the currently authenticated user along with all published posts.
- *
- * @param blogContainerNode the container node for blog posts (under the site).
- * @param fromDate an inclusive date limit for the results (more recent than).
- * @param toDate an inclusive date limit for the results (before).
- * @param tag if specified, only returns posts tagged with this tag.
- * @param pagingReq an object defining the paging parameters for the result set.
- *
- * @return a {@link PagingResults} object containing some or all of the results (subject to paging).
- *
- * @see SiteService#getContainer(String, String) to retrieve the blogContainerNode
- *
- * @deprecated This method is a domain-specific query used by the Blog REST API and is not considered suitable for general use.
- */
- PagingResults getMyDraftsAndAllPublished(NodeRef blogContainerNode, Date fromDate, Date toDate,
- String tag, PagingRequest pagingReq);
-
- /**
- * Returns true if the specified blog-post node is a 'draft' blog post.
- *
- * @param blogPostNode a NodeRef representing a blog-post.
- * @return true if it is a draft post, else false.
- */
- boolean isDraftBlogPost(NodeRef blogPostNode);
-
- /**
- * A simple data object for storage of blog-related data.
- *
- * @author Neil Mc Erlean
- * @since 4.0
- */
- public class BlogPostInfo
- {
- private final NodeRef nodeRef;
- private final String name;
-
- public BlogPostInfo(NodeRef nodeRef, String name)
- {
- this.nodeRef = nodeRef;
- this.name = name;
- }
- /**
- * Gets the NodeRef representing this blog-post.
- */
- public NodeRef getNodeRef()
- {
- return nodeRef;
- }
-
- /**
- * Gets the {@link ContentModel#PROP_NAME cm:name} of the blog post.
- * @return
- */
- public String getName()
- {
- return name;
- }
- }
-}
+/*
+ * Copyright (C) 2005-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.blog;
+
+import java.util.Date;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.query.PagingRequest;
+import org.alfresco.query.PagingResults;
+import org.alfresco.repo.security.permissions.PermissionCheckValue;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.site.SiteService;
+
+/**
+ * The Blog Service handles the management (CRUD) of Alfresco blog data, namely the blog posts which are
+ * exposed in the Share UI under the "Blog" heading. The {@link BlogIntegrationService}, a separate service, is
+ * concerned with the integration of Alfresco blog content with external Blog-hosting sites.
+ *
+ * Please note that this service is a work in progress and currently exists primarily to support the blogs REST API.
+ *
+ * @author Neil Mc Erlean (based on existing webscript controllers in the REST API)
+ * @since 4.0
+ */
+public interface BlogService
+{
+ /**
+ * Creates a new blog post within the specified container node.
+ *
+ * @param blogContainerNode the container node for blog posts (under the site).
+ * @param blogTitle the title of the blog post.
+ * @param blogContent text/html content of the blog post.
+ * @param isDraft true if the blog post is a draft post, else false.
+ *
+ * @return The {@link ChildAssociationRef} of the newly created blog post.
+ *
+ * @see SiteService#getContainer(String, String) to retrieve the blogContainerNode
+ */
+ ChildAssociationRef createBlogPost(NodeRef blogContainerNode, String blogTitle,
+ String blogContent, boolean isDraft);
+
+ /**
+ * Gets the draft blog posts created by the specified user.
+ *
+ * @param blogContainerNode the container node for blog posts (under the site).
+ * @param username to limit results to blogs with this cm:creator. null means all users.
+ * @param pagingReq an object defining the paging parameters for the result set.
+ *
+ * @return a {@link PagingResults} object containing some or all of the results (subject to paging).
+ *
+ * @see SiteService#getContainer(String, String) to retrieve the blogContainerNode
+ */
+ PagingResults getDrafts(NodeRef blogContainerNode, String username, PagingRequest pagingReq);
+
+ /**
+ * Gets the (internally, Alfresco-) published blog posts.
+ *
+ * @param blogContainerNode the container node for blog posts (under the site).
+ * @param fromDate an inclusive date limit for the results (more recent than).
+ * @param toDate an inclusive date limit for the results (before).
+ * @param byUser if not null limits results to posts by the specified user.
+ * if null results will be by all users.
+ * @param pagingReq an object defining the paging parameters for the result set.
+ *
+ * @return a {@link PagingResults} object containing some or all of the results (subject to paging).
+ *
+ * @see SiteService#getContainer(String, String) to retrieve the blogContainerNode
+ */
+ PagingResults getPublished(NodeRef blogContainerNode, Date fromDate, Date toDate, String byUser, PagingRequest pagingReq);
+
+ /**
+ * Gets blog posts published externally (i.e. to an external blog hosting site).
+ *
+ * @param blogContainerNode the container node for blog posts (under the site).
+ * @param pagingReq an object defining the paging parameters for the result set.
+ *
+ * @return a {@link PagingResults} object containing some or all of the results (subject to paging).
+ *
+ * @see SiteService#getContainer(String, String) to retrieve the blogContainerNode
+ */
+ PagingResults getPublishedExternally(NodeRef blogContainerNode, PagingRequest pagingReq);
+
+ /**
+ * Gets draft blog posts by the currently authenticated user along with all published posts.
+ *
+ * @param blogContainerNode the container node for blog posts (under the site).
+ * @param fromDate an inclusive date limit for the results (more recent than).
+ * @param toDate an inclusive date limit for the results (before).
+ * @param tag if specified, only returns posts tagged with this tag.
+ * @param pagingReq an object defining the paging parameters for the result set.
+ *
+ * @return a {@link PagingResults} object containing some or all of the results (subject to paging).
+ *
+ * @see SiteService#getContainer(String, String) to retrieve the blogContainerNode
+ *
+ * @deprecated This method is a domain-specific query used by the Blog REST API and is not considered suitable for general use.
+ */
+ PagingResults getMyDraftsAndAllPublished(NodeRef blogContainerNode, Date fromDate, Date toDate,
+ String tag, PagingRequest pagingReq);
+
+ /**
+ * Returns true if the specified blog-post node is a 'draft' blog post.
+ *
+ * @param blogPostNode a NodeRef representing a blog-post.
+ * @return true if it is a draft post, else false.
+ */
+ boolean isDraftBlogPost(NodeRef blogPostNode);
+
+ /**
+ * A simple data object for storage of blog-related data.
+ *
+ * @author Neil Mc Erlean
+ * @since 4.0
+ */
+ public class BlogPostInfo implements PermissionCheckValue
+ {
+ private final NodeRef nodeRef;
+ private final String name;
+
+ public BlogPostInfo(NodeRef nodeRef, String name)
+ {
+ this.nodeRef = nodeRef;
+ this.name = name;
+ }
+ /**
+ * Gets the NodeRef representing this blog-post.
+ */
+ @Override
+ public NodeRef getNodeRef()
+ {
+ return nodeRef;
+ }
+
+ /**
+ * Gets the {@link ContentModel#PROP_NAME cm:name} of the blog post.
+ * @return
+ */
+ public String getName()
+ {
+ return name;
+ }
+ }
+}
diff --git a/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java b/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java
index 33fbae2a51..8eb4ec7644 100644
--- a/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java
+++ b/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java
@@ -28,9 +28,9 @@ import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.ResourceBundle.Control;
import java.util.Set;
import java.util.Stack;
-import java.util.ResourceBundle.Control;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
@@ -41,7 +41,7 @@ import org.alfresco.query.PagingResults;
import org.alfresco.repo.node.getchildren.GetChildrenCannedQuery;
import org.alfresco.repo.node.getchildren.GetChildrenCannedQueryFactory;
import org.alfresco.repo.search.QueryParameterDefImpl;
-import org.alfresco.repo.security.permissions.impl.acegi.WrappedList;
+import org.alfresco.repo.security.permissions.PermissionCheckedValue.PermissionCheckedValueMixin;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.model.FileExistsException;
@@ -409,11 +409,6 @@ public class FileFolderServiceImpl implements FileFolderService
{
return totalCount;
}
- @Override
- public boolean permissionsApplied()
- {
- return results.permissionsApplied();
- }
};
}
@@ -703,7 +698,7 @@ public class FileFolderServiceImpl implements FileFolderService
List results = toFileInfo(nodeRefs);
// avoid re-applying permissions (for "list" canned queries)
- return new WrappedList(results, cq.permissionsApplied(), cq.hasMoreItems());
+ return PermissionCheckedValueMixin.create(results);
}
private Set buildTypes(boolean files, boolean folders, Set ignoreQNameTypes)
diff --git a/source/java/org/alfresco/repo/node/getchildren/GetChildrenCannedQuery.java b/source/java/org/alfresco/repo/node/getchildren/GetChildrenCannedQuery.java
index 4f1ebe16b9..2712ee66b0 100644
--- a/source/java/org/alfresco/repo/node/getchildren/GetChildrenCannedQuery.java
+++ b/source/java/org/alfresco/repo/node/getchildren/GetChildrenCannedQuery.java
@@ -48,9 +48,9 @@ import org.alfresco.repo.domain.node.ReferenceablePropertiesEntity;
import org.alfresco.repo.domain.qname.QNameDAO;
import org.alfresco.repo.domain.query.CannedQueryDAO;
import org.alfresco.repo.node.getchildren.FilterPropString.FilterTypeString;
+import org.alfresco.repo.security.permissions.PermissionCheckedValue.PermissionCheckedValueMixin;
import org.alfresco.repo.security.permissions.impl.acegi.AbstractCannedQueryPermissions;
import org.alfresco.repo.security.permissions.impl.acegi.MethodSecurityBean;
-import org.alfresco.repo.security.permissions.impl.acegi.WrappedList;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
@@ -156,7 +156,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions> sortPairs = (List)sortDetails.getSortPairs();
// Set sort / filter params
@@ -234,21 +234,9 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions 0) && (requestTotalCountMax > requestedCount))
- {
- requestedCount = requestTotalCountMax;
- }
-
- if (requestedCount != Integer.MAX_VALUE)
- {
- requestedCount++; // add one for "hasMoreItems"
- }
-
- final WrappedList rawResult = new WrappedList(new ArrayList(100), requestedCount);
+ final int requestedCount = parameters.getResultsRequired();
+ final List rawResult = new ArrayList(Math.min(1000, requestedCount));
UnsortedChildQueryCallback callback = new UnsortedChildQueryCallback()
{
public boolean handle(NodeRef nodeRef)
@@ -256,7 +244,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions(rawResult.getWrapped(), true, (rawResult.size() == requestedCount));
+ result = PermissionCheckedValueMixin.create(rawResult);
}
if (start != null)
@@ -482,7 +470,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions 0) && (requestTotalCountMax > requestedCount)) ? requestTotalCountMax : requestedCount);
int cnt = results.size();
@@ -693,7 +681,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions results = applyPermissions(nodeRefs, nodeRefs.size());
+ List results = applyPostQueryPermissions(nodeRefs, nodeRefs.size());
for (NodeRef nodeRef : results)
{
diff --git a/source/java/org/alfresco/repo/node/getchildren/GetChildrenCannedQueryTest.java b/source/java/org/alfresco/repo/node/getchildren/GetChildrenCannedQueryTest.java
index 0b6a854005..f940f95b6c 100644
--- a/source/java/org/alfresco/repo/node/getchildren/GetChildrenCannedQueryTest.java
+++ b/source/java/org/alfresco/repo/node/getchildren/GetChildrenCannedQueryTest.java
@@ -498,7 +498,6 @@ public class GetChildrenCannedQueryTest extends TestCase
PagingResults results = list(parentNodeRef, -1, -1, 0);
assertFalse(results.hasMoreItems());
- assertTrue(results.permissionsApplied());
List nodeRefs = results.getPage();
@@ -516,7 +515,6 @@ public class GetChildrenCannedQueryTest extends TestCase
results = list(parentNodeRef, -1, -1, 0);
assertFalse(results.hasMoreItems());
- assertTrue(results.permissionsApplied());
nodeRefs = results.getPage();
@@ -767,7 +765,7 @@ public class GetChildrenCannedQueryTest extends TestCase
totalCount = results.getTotalResultCount().getFirst();
}
- return new PagingNodeRefResultsImpl(nodeRefs, results.hasMoreItems(), totalCount, false, true);
+ return new PagingNodeRefResultsImpl(nodeRefs, results.hasMoreItems(), totalCount, false);
}
private class PagingNodeRefResultsImpl implements PagingResults
@@ -775,18 +773,16 @@ public class GetChildrenCannedQueryTest extends TestCase
private List nodeRefs;
private boolean hasMorePages;
- private boolean permissionsApplied;
private Integer totalResultCount; // null => not requested (or unknown)
private Boolean isTotalResultCountCutoff; // null => unknown
- public PagingNodeRefResultsImpl(List nodeRefs, boolean hasMorePages, Integer totalResultCount, Boolean isTotalResultCountCutoff, boolean permissionsApplied)
+ public PagingNodeRefResultsImpl(List nodeRefs, boolean hasMorePages, Integer totalResultCount, Boolean isTotalResultCountCutoff)
{
this.nodeRefs = nodeRefs;
this.hasMorePages = hasMorePages;
this.totalResultCount= totalResultCount;
this.isTotalResultCountCutoff = isTotalResultCountCutoff;
- this.permissionsApplied = permissionsApplied;
}
public List getPage()
@@ -799,11 +795,6 @@ public class GetChildrenCannedQueryTest extends TestCase
return hasMorePages;
}
- public boolean permissionsApplied()
- {
- return permissionsApplied;
- }
-
public Pair getTotalResultCount()
{
return new Pair(totalResultCount, (isTotalResultCountCutoff ? null : totalResultCount));
diff --git a/source/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java b/source/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java
index 9a47684d76..c22ea0b0f9 100644
--- a/source/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java
+++ b/source/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java
@@ -358,11 +358,6 @@ public class AuthorityDAOImpl implements AuthorityDAO, NodeServicePolicies.Befor
{
return results.getTotalResultCount();
}
- @Override
- public boolean permissionsApplied()
- {
- return results.permissionsApplied();
- }
};
if (start != null)
@@ -428,11 +423,6 @@ public class AuthorityDAOImpl implements AuthorityDAO, NodeServicePolicies.Befor
{
return ppr.getTotalResultCount();
}
- @Override
- public boolean permissionsApplied()
- {
- return ppr.permissionsApplied();
- }
};
}
diff --git a/source/java/org/alfresco/repo/security/authority/AuthorityServiceImpl.java b/source/java/org/alfresco/repo/security/authority/AuthorityServiceImpl.java
index 891a0d2c55..5bce944791 100644
--- a/source/java/org/alfresco/repo/security/authority/AuthorityServiceImpl.java
+++ b/source/java/org/alfresco/repo/security/authority/AuthorityServiceImpl.java
@@ -370,11 +370,6 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
{
return new Pair(auths.size(), auths.size());
}
- @Override
- public boolean permissionsApplied()
- {
- return true; // note: for now, assume ACL_ALLOW for "other" authorities (as per public-services-security.xml)
- }
};
}
diff --git a/source/java/org/alfresco/repo/security/permissions/PermissionCheckCollection.java b/source/java/org/alfresco/repo/security/permissions/PermissionCheckCollection.java
new file mode 100644
index 0000000000..b2aa22637c
--- /dev/null
+++ b/source/java/org/alfresco/repo/security/permissions/PermissionCheckCollection.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2005-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.security.permissions;
+
+import java.util.Collection;
+
+import org.springframework.aop.IntroductionAdvisor;
+import org.springframework.aop.framework.ProxyFactory;
+import org.springframework.aop.support.DefaultIntroductionAdvisor;
+import org.springframework.aop.support.DelegatingIntroductionInterceptor;
+
+/**
+ * Interface for collection-based results that describe permission filtering
+ * behaviour around cut-off limits.
+ *
+ * @author Derek Hulley
+ * @since 4.0
+ */
+public interface PermissionCheckCollection
+{
+ /**
+ * Get the desired number of results. Permission checks can stop once the number of
+ * return objects reaches this number.
+ *
+ * @return the number of results desired
+ */
+ int getTargetResultCount();
+
+ /**
+ * Get the maximum time for permission checks to execute before cutting the results off.
+ * Zero: Ignore this value.
+ *
+ * @return the time allowed for permission checks before cutoff
+ */
+ long getCutOffAfterTimeMs();
+
+ /**
+ * Get the maximum number of permission checks to perform before cutting the results off
+ *
+ * @return the maximum number of permission checks before cutoff
+ */
+ int getCutOffAfterCount();
+
+ /**
+ * Helper 'introduction' to allow simple addition of the {@link PermissionCheckCollection} interface to
+ * existing collections.
+ *
+ * @param the type of the Collection in use
+ *
+ * @author Derek Hulley
+ * @since 4.0
+ */
+ @SuppressWarnings("serial")
+ public static class PermissionCheckCollectionMixin extends DelegatingIntroductionInterceptor implements PermissionCheckCollection
+ {
+ private final int targetResultCount;
+ private final long cutOffAfterTimeMs;
+ private final int cutOffAfterCount;
+
+ private PermissionCheckCollectionMixin(int targetResultCount, long cutOffAfterTimeMs, int cutOffAfterCount)
+ {
+ super();
+ this.targetResultCount = targetResultCount;
+ this.cutOffAfterTimeMs = cutOffAfterTimeMs;
+ this.cutOffAfterCount = cutOffAfterCount;
+ if (cutOffAfterTimeMs <= 0)
+ {
+ cutOffAfterTimeMs = 0;
+ }
+ if (cutOffAfterCount <= 0)
+ {
+ cutOffAfterCount = 0;
+ }
+ }
+
+ @Override
+ public int getTargetResultCount()
+ {
+ return targetResultCount;
+ }
+
+ @Override
+ public long getCutOffAfterTimeMs()
+ {
+ return cutOffAfterTimeMs;
+ }
+
+ @Override
+ public int getCutOffAfterCount()
+ {
+ return cutOffAfterCount;
+ }
+
+ /**
+ * Helper method to create a {@link PermissionCheckCollection} from an existing Collection
+ *
+ * @param the type of the Collection
+ * @param collection the Collection to proxy
+ * @param targetResultCount the desired number of results or default to the collection size
+ * @param cutOffAfterTimeMs the number of milliseconds to wait before cut-off or zero to use the system default
+ * time-based cut-off.
+ * @param cutOffAfterCount the number of permission checks to process before cut-off or zero to use the system default
+ * count-based cut-off.
+ * @return a Collection of the same type but including the
+ * {@link PermissionCheckCollection} interface
+ */
+ @SuppressWarnings("unchecked")
+ public static final Collection create(
+ Collection collection,
+ int targetResultCount, long cutOffAfterTimeMs, int cutOffAfterCount)
+ {
+ if (targetResultCount <= 0)
+ {
+ targetResultCount = collection.size();
+ }
+ // Create the mixin
+ DelegatingIntroductionInterceptor mixin = new PermissionCheckCollectionMixin(
+ targetResultCount,
+ cutOffAfterTimeMs,
+ cutOffAfterCount);
+ // Create the advisor
+ IntroductionAdvisor advisor = new DefaultIntroductionAdvisor(mixin, PermissionCheckCollection.class);
+ // Proxy
+ ProxyFactory pf = new ProxyFactory(collection);
+ pf.addAdvisor(advisor);
+ Object proxiedObject = pf.getProxy();
+
+ // Done
+ return (Collection) proxiedObject;
+ }
+ }
+}
diff --git a/source/java/org/alfresco/repo/security/permissions/PermissionCheckCollectionTest.java b/source/java/org/alfresco/repo/security/permissions/PermissionCheckCollectionTest.java
new file mode 100644
index 0000000000..156b8d3256
--- /dev/null
+++ b/source/java/org/alfresco/repo/security/permissions/PermissionCheckCollectionTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2005-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.security.permissions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.alfresco.repo.security.permissions.PermissionCheckCollection.PermissionCheckCollectionMixin;
+
+/**
+ * Tests {@link PermissionCheckCollection}
+ *
+ * @author Derek Hulley
+ * @since 4.0
+ */
+public class PermissionCheckCollectionTest extends TestCase
+{
+ @Override
+ protected void setUp() throws Exception
+ {
+ }
+
+ public void testBasicWrapping() throws Exception
+ {
+ List list = new ArrayList();
+ list.add(1);
+ list.add(2);
+ list.add(3);
+
+ final int targetResultCount = 2000;
+ final long cutOffAfterTimeMs = 10000L;
+ final int cutOffAfterCount = 1000;
+
+ Collection proxiedList = PermissionCheckCollectionMixin.create(list, targetResultCount, cutOffAfterTimeMs, cutOffAfterCount);
+
+ // Check
+ assertTrue("Proxied object must still be a List", proxiedList instanceof List);
+ assertEquals("List values incorrect", 3, proxiedList.size());
+ assertTrue("Proxied object must also be a PermissionCheckCollection", proxiedList instanceof PermissionCheckCollection);
+ @SuppressWarnings("unchecked")
+ PermissionCheckCollection proxiedPermissionCheckCollection = (PermissionCheckCollection) proxiedList;
+ assertEquals("targetResultCount value incorrect", targetResultCount, proxiedPermissionCheckCollection.getTargetResultCount());
+ assertEquals("cutOffAfterTimeMs value incorrect", cutOffAfterTimeMs, proxiedPermissionCheckCollection.getCutOffAfterTimeMs());
+ assertEquals("cutOffAfterCount value incorrect", cutOffAfterCount, proxiedPermissionCheckCollection.getCutOffAfterCount());
+ }
+
+ public void testVolumeWrapping() throws Exception
+ {
+ int count = 10000;
+ long before = System.nanoTime();
+ for (int i = 0; i < count; i++)
+ {
+ testBasicWrapping();
+ }
+ long after = System.nanoTime();
+ double average = ((double) (after - before) / (double) count) / (double) 1.0E6;
+ System.out.println("Average is " + average + "ms per wrap.");
+ }
+}
diff --git a/source/java/org/alfresco/repo/security/permissions/PermissionCheckValue.java b/source/java/org/alfresco/repo/security/permissions/PermissionCheckValue.java
new file mode 100644
index 0000000000..57b7122aac
--- /dev/null
+++ b/source/java/org/alfresco/repo/security/permissions/PermissionCheckValue.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2005-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.security.permissions;
+
+import org.alfresco.service.cmr.repository.NodeRef;
+
+/**
+ * Interface for objects that can provide information to allow permission checks
+ *
+ * Implement this interface to enable the permission filtering layers to extract
+ * information in order to check permissions.
+ *
+ * @author Derek Hulley
+ * @since 4.0
+ */
+public interface PermissionCheckValue
+{
+ /**
+ * Get the underlying node value that needs to be permission checked.
+ *
+ * @return the underlying value to filter
+ */
+ NodeRef getNodeRef();
+}
diff --git a/source/java/org/alfresco/repo/security/permissions/PermissionCheckedCollection.java b/source/java/org/alfresco/repo/security/permissions/PermissionCheckedCollection.java
new file mode 100644
index 0000000000..8c9aaf734c
--- /dev/null
+++ b/source/java/org/alfresco/repo/security/permissions/PermissionCheckedCollection.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2005-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.security.permissions;
+
+import java.util.Collection;
+
+import org.springframework.aop.IntroductionAdvisor;
+import org.springframework.aop.framework.ProxyFactory;
+import org.springframework.aop.support.DefaultIntroductionAdvisor;
+import org.springframework.aop.support.DelegatingIntroductionInterceptor;
+
+/**
+ * Interface for collection-based results that carry extra information
+ * about the state of permission cut-offs.
+ *
+ * @author Derek Hulley
+ * @since 4.0
+ */
+public interface PermissionCheckedCollection
+{
+ /**
+ * Check if the results have been truncated by permission check limits.
+ * This can only be called when {@link #isFiltered()} is true.
+ *
+ * @return true - if the results (usually a collection) have been
+ * cut off by permission check limits
+ */
+ boolean isCutOff();
+
+ /**
+ * Get the number of objects in the original (unfiltered) collection that did
+ * not have any permission checks.
+ *
+ * @return number of entries from the original collection that were not checked
+ */
+ int sizeUnchecked();
+
+ /**
+ * Get the number of objects in the original (unfiltered) collection.
+ *
+ * @return number of entries in the original, pre-checked collection
+ */
+ int sizeOriginal();
+
+ /**
+ * Helper 'introduction' to allow simple addition of the {@link PermissionCheckedCollection} interface to
+ * existing collections.
+ *
+ * @param the type of the Collection in use
+ *
+ * @author Derek Hulley
+ * @since 4.0
+ */
+ @SuppressWarnings("serial")
+ public static class PermissionCheckedCollectionMixin extends DelegatingIntroductionInterceptor implements PermissionCheckedCollection
+ {
+ private final boolean isCutOff;
+ private final int sizeUnchecked;
+ private final int sizeOriginal;
+ private PermissionCheckedCollectionMixin(boolean isCutOff, int sizeUnchecked, int sizeOriginal)
+ {
+ super();
+ this.isCutOff = isCutOff;
+ this.sizeUnchecked = sizeUnchecked;
+ this.sizeOriginal = sizeOriginal;
+ }
+ @Override
+ public boolean isCutOff()
+ {
+ return isCutOff;
+ }
+ @Override
+ public int sizeUnchecked()
+ {
+ return sizeUnchecked;
+ }
+ @Override
+ public int sizeOriginal()
+ {
+ return sizeOriginal;
+ }
+ /**
+ * Helper method to create a {@link PermissionCheckedCollection} from an existing Collection
+ *
+ * @param the type of the Collection
+ * @param collection the Collection to proxy
+ * @param isCutOff true if permission checking was cut off before completion
+ * @param sizeUnchecked number of entries from the original collection that were not checked
+ * @param sizeOriginal number of entries in the original, pre-checked collection
+ * @return a Collection of the same type but including the
+ * {@link PermissionCheckedCollection} interface
+ */
+ @SuppressWarnings("unchecked")
+ public static final Collection create(
+ Collection collection,
+ boolean isCutOff, int sizeUnchecked, int sizeOriginal)
+ {
+ // Create the mixin
+ DelegatingIntroductionInterceptor mixin = new PermissionCheckedCollectionMixin(
+ isCutOff,
+ sizeUnchecked,
+ sizeOriginal
+ );
+ // Create the advisor
+ IntroductionAdvisor advisor = new DefaultIntroductionAdvisor(mixin, PermissionCheckedCollection.class);
+ // Proxy
+ ProxyFactory pf = new ProxyFactory(collection);
+ pf.addAdvisor(advisor);
+ Object proxiedObject = pf.getProxy();
+
+ // Done
+ return (Collection) proxiedObject;
+ }
+ }
+}
diff --git a/source/java/org/alfresco/repo/security/permissions/PermissionCheckedCollectionTest.java b/source/java/org/alfresco/repo/security/permissions/PermissionCheckedCollectionTest.java
new file mode 100644
index 0000000000..feb6ce7aa0
--- /dev/null
+++ b/source/java/org/alfresco/repo/security/permissions/PermissionCheckedCollectionTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2005-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.security.permissions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.alfresco.repo.security.permissions.PermissionCheckedCollection.PermissionCheckedCollectionMixin;
+
+/**
+ * Tests {@link PermissionCheckedCollection}
+ *
+ * @author Derek Hulley
+ * @since 4.0
+ */
+public class PermissionCheckedCollectionTest extends TestCase
+{
+ @Override
+ protected void setUp() throws Exception
+ {
+ }
+
+ public void testBasicWrapping() throws Exception
+ {
+ List list = new ArrayList();
+ list.add(1);
+ list.add(2);
+ list.add(3);
+
+ final boolean isCutOff = true;
+ final int sizeUnchecked = 100;
+ final int sizeOriginal = 900;
+
+ Collection proxiedList = PermissionCheckedCollectionMixin.create(
+ list, isCutOff, sizeUnchecked, sizeOriginal);
+
+ // Check
+ assertTrue("Proxied object must still be a List", proxiedList instanceof List);
+ assertEquals("List values incorrect", 3, proxiedList.size());
+ assertTrue("Proxied object must also be a PermissionCheckedCollection", proxiedList instanceof PermissionCheckedCollection);
+ @SuppressWarnings("unchecked")
+ PermissionCheckedCollection proxiedPermissionCheckedCollection = (PermissionCheckedCollection) proxiedList;
+ assertEquals("cutOff value incorrect", isCutOff, proxiedPermissionCheckedCollection.isCutOff());
+ assertEquals("sizeUnchecked value incorrect", sizeUnchecked, proxiedPermissionCheckedCollection.sizeUnchecked());
+ assertEquals("sizeOriginal value incorrect", sizeOriginal, proxiedPermissionCheckedCollection.sizeOriginal());
+ }
+
+ public void testVolumeWrapping() throws Exception
+ {
+ int count = 10000;
+ long before = System.nanoTime();
+ for (int i = 0; i < count; i++)
+ {
+ testBasicWrapping();
+ }
+ long after = System.nanoTime();
+ double average = ((double) (after - before) / (double) count) / (double) 1.0E6;
+ System.out.println("Average is " + average + "ms per wrap.");
+ }
+}
diff --git a/source/java/org/alfresco/repo/security/permissions/PermissionCheckedValue.java b/source/java/org/alfresco/repo/security/permissions/PermissionCheckedValue.java
new file mode 100644
index 0000000000..71c67616ee
--- /dev/null
+++ b/source/java/org/alfresco/repo/security/permissions/PermissionCheckedValue.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2005-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.security.permissions;
+
+import org.springframework.aop.IntroductionAdvisor;
+import org.springframework.aop.framework.ProxyFactory;
+import org.springframework.aop.support.DefaultIntroductionAdvisor;
+import org.springframework.aop.support.DelegatingIntroductionInterceptor;
+
+/**
+ * Marker interface for objects that have already passed permission checking.
+ *
+ * @author Derek Hulley
+ * @since 4.0
+ */
+public interface PermissionCheckedValue
+{
+ /**
+ * Helper 'introduction' to allow simple addition of the {@link PermissionCheckedValue} interface to
+ * existing objects.
+ *
+ * @author Derek Hulley
+ * @since 4.0
+ */
+ @SuppressWarnings("serial")
+ public static class PermissionCheckedValueMixin extends DelegatingIntroductionInterceptor implements PermissionCheckedValue
+ {
+ private PermissionCheckedValueMixin()
+ {
+ super();
+ }
+ /**
+ * Helper method to create a {@link PermissionCheckedValue} from an existing Object.
+ *
+ * @param collection the Object to proxy
+ * @return a Object of the same type but including the
+ * {@link PermissionCheckedValue} interface
+ */
+ @SuppressWarnings("unchecked")
+ public static final T create(T object)
+ {
+ // Create the mixin
+ DelegatingIntroductionInterceptor mixin = new PermissionCheckedValueMixin();
+ // Create the advisor
+ IntroductionAdvisor advisor = new DefaultIntroductionAdvisor(mixin, PermissionCheckedValue.class);
+ // Proxy
+ ProxyFactory pf = new ProxyFactory(object);
+ pf.addAdvisor(advisor);
+ Object proxiedObject = pf.getProxy();
+
+ // Done
+ return (T) proxiedObject;
+ }
+ }
+}
diff --git a/source/java/org/alfresco/repo/security/permissions/impl/acegi/ACLEntryAfterInvocationProvider.java b/source/java/org/alfresco/repo/security/permissions/impl/acegi/ACLEntryAfterInvocationProvider.java
index ef0ca49719..fc45aa7125 100644
--- a/source/java/org/alfresco/repo/security/permissions/impl/acegi/ACLEntryAfterInvocationProvider.java
+++ b/source/java/org/alfresco/repo/security/permissions/impl/acegi/ACLEntryAfterInvocationProvider.java
@@ -36,17 +36,16 @@ import net.sf.acegisecurity.ConfigAttributeDefinition;
import net.sf.acegisecurity.afterinvocation.AfterInvocationProvider;
import org.alfresco.cmis.CMISResultSet;
-import org.alfresco.error.AlfrescoRuntimeException;
-import org.alfresco.query.PagingResults;
-import org.alfresco.query.PermissionedResults;
-import org.alfresco.repo.blog.BlogService.BlogPostInfo;
import org.alfresco.repo.search.SimpleResultSetMetaData;
import org.alfresco.repo.search.impl.lucene.PagingLuceneResultSet;
import org.alfresco.repo.search.impl.lucene.SolrJSONResultSet;
import org.alfresco.repo.search.impl.querymodel.QueryEngineResults;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.security.permissions.PermissionCheckCollection;
+import org.alfresco.repo.security.permissions.PermissionCheckValue;
+import org.alfresco.repo.security.permissions.PermissionCheckedCollection.PermissionCheckedCollectionMixin;
+import org.alfresco.repo.security.permissions.PermissionCheckedValue;
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
-import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
@@ -57,7 +56,6 @@ import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PermissionService;
-import org.alfresco.service.cmr.security.PersonService.PersonInfo;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
@@ -255,125 +253,57 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
}
return null;
}
+ else if (PermissionCheckedValue.class.isAssignableFrom(returnedObject.getClass()))
+ {
+ // The security provider was not already present
+ return decide(authentication, object, config, (PermissionCheckedValue) returnedObject);
+ }
+ else if (PermissionCheckValue.class.isAssignableFrom(returnedObject.getClass()))
+ {
+ return decide(authentication, object, config, (PermissionCheckValue) returnedObject);
+ }
else if (StoreRef.class.isAssignableFrom(returnedObject.getClass()))
{
- if (log.isDebugEnabled())
- {
- log.debug("Store access");
- }
return decide(authentication, object, config, nodeService.getRootNode((StoreRef) returnedObject)).getStoreRef();
}
else if (NodeRef.class.isAssignableFrom(returnedObject.getClass()))
{
- if (log.isDebugEnabled())
- {
- log.debug("Node access");
- }
return decide(authentication, object, config, (NodeRef) returnedObject);
}
- else if (FileInfo.class.isAssignableFrom(returnedObject.getClass()))
- {
- return decide(authentication, object, config, (FileInfo) returnedObject);
- }
- else if (PagingResults.class.isAssignableFrom(returnedObject.getClass()))
- {
- if (PermissionedResults.class.isAssignableFrom(returnedObject.getClass()) &&
- (! ((PermissionedResults)returnedObject).permissionsApplied()))
- {
- throw new AlfrescoRuntimeException("Not implemented");
- /*
- if (log.isDebugEnabled())
- {
- log.debug("Paging Results access");
- }
- return decide(authentication, object, config, ((PagingResults>) returnedObject);
- */
- }
- else
- {
- if (log.isDebugEnabled())
- {
- log.debug("Paging Results access - already checked permissions for " + object.getClass().getName());
- }
-
- return returnedObject;
- }
- }
else if (Pair.class.isAssignableFrom(returnedObject.getClass()))
{
return decide(authentication, object, config, (Pair) returnedObject);
}
else if (ChildAssociationRef.class.isAssignableFrom(returnedObject.getClass()))
{
- if (log.isDebugEnabled())
- {
- log.debug("Child Association access");
- }
return decide(authentication, object, config, (ChildAssociationRef) returnedObject);
}
else if (SolrJSONResultSet.class.isAssignableFrom(returnedObject.getClass()))
{
- if (log.isDebugEnabled())
- {
- log.debug("SolrJSONResultSet - already checked permissions for " + object.getClass().getName());
- }
return returnedObject;
}
else if (CMISResultSet.class.isAssignableFrom(returnedObject.getClass()))
{
- if (log.isDebugEnabled())
- {
- log.debug("CMIS Result Set - already checked permissions for " + object.getClass().getName());
- }
return returnedObject;
}
else if (PagingLuceneResultSet.class.isAssignableFrom(returnedObject.getClass()))
{
- if (log.isDebugEnabled())
- {
- log.debug("Result Set access");
- }
return decide(authentication, object, config, (PagingLuceneResultSet) returnedObject);
}
else if (ResultSet.class.isAssignableFrom(returnedObject.getClass()))
{
- if (log.isDebugEnabled())
- {
- log.debug("Result Set access");
- }
return decide(authentication, object, config, (ResultSet) returnedObject);
}
else if (QueryEngineResults.class.isAssignableFrom(returnedObject.getClass()))
{
- if (log.isDebugEnabled())
- {
- log.debug("Result Set access");
- }
return decide(authentication, object, config, (QueryEngineResults) returnedObject);
}
else if (Collection.class.isAssignableFrom(returnedObject.getClass()))
{
- if (PermissionedResults.class.isAssignableFrom(returnedObject.getClass()) &&
- ((PermissionedResults)returnedObject).permissionsApplied())
- {
- // Already checked - don't need to re-check (eg. WrappedList - used by unsorted GetChildren CQ)
- return returnedObject;
- }
- else
- {
- if (log.isDebugEnabled())
- {
- log.debug("Collection Access");
- }
- return decide(authentication, object, config, (Collection) returnedObject);
- }
+ return decide(authentication, object, config, (Collection) returnedObject);
}
else if (returnedObject.getClass().isArray())
{
- if (log.isDebugEnabled())
- {
- log.debug("Array Access");
- }
return decide(authentication, object, config, (Object[]) returnedObject);
}
else
@@ -477,16 +407,22 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
return false;
}
- private FileInfo decide(Authentication authentication, Object object, ConfigAttributeDefinition config, FileInfo returnedObject) throws AccessDeniedException
+ private PermissionCheckedValue decide(Authentication authentication, Object object, ConfigAttributeDefinition config, PermissionCheckedValue returnedObject) throws AccessDeniedException
{
- // Filter check done later
- NodeRef nodeRef = returnedObject.getNodeRef();
- // this is virtually equivalent to the noderef
- decide(authentication, object, config, nodeRef);
- // the noderef was allowed
+ // This passes as it has already been filtered
+ // TODO: Get the filter that was applied and double-check
return returnedObject;
}
-
+
+ private PermissionCheckValue decide(Authentication authentication, Object object, ConfigAttributeDefinition config, PermissionCheckValue returnedObject) throws AccessDeniedException
+ {
+ // Get the wrapped value
+ NodeRef nodeRef = returnedObject.getNodeRef();
+ decide(authentication, object, config, nodeRef);
+ // This passes
+ return returnedObject;
+ }
+
@SuppressWarnings("rawtypes")
private Pair decide(Authentication authentication, Object object, ConfigAttributeDefinition config, Pair returnedObject) throws AccessDeniedException
{
@@ -496,6 +432,7 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
return returnedObject;
}
+ @SuppressWarnings("rawtypes")
private List extractSupportedDefinitions(ConfigAttributeDefinition config)
{
List definitions = new ArrayList();
@@ -866,6 +803,7 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
return new QueryEngineResults(answer);
}
+ @SuppressWarnings({ "rawtypes", "unchecked" })
private Collection decide(Authentication authentication, Object object, ConfigAttributeDefinition config, Collection returnedObject) throws AccessDeniedException
{
if (returnedObject == null)
@@ -874,68 +812,78 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
}
List supportedDefinitions = extractSupportedDefinitions(config);
-
- if (supportedDefinitions.size() == 0)
- {
- if (returnedObject instanceof WrappedList>)
- {
- ((WrappedList>)returnedObject).setHasMoreItems(false);
- ((WrappedList>)returnedObject).setPermissionsApplied(true);
- }
-
- return returnedObject;
- }
-
- Set