diff --git a/config/alfresco/extension/ehcache-custom.xml.sample.cluster b/config/alfresco/extension/ehcache-custom.xml.sample.cluster
index e8ba537c27..654f1b47cb 100644
--- a/config/alfresco/extension/ehcache-custom.xml.sample.cluster
+++ b/config/alfresco/extension/ehcache-custom.xml.sample.cluster
@@ -497,6 +497,23 @@
replicateAsynchronously = false"/>
+
+
+
+
+
createPersonProperties(String userName)
+ {
+ HashMap properties = new HashMap();
+ properties.put(ContentModel.PROP_USERNAME, userName);
+ return properties;
+ }
+
+ protected void createAuthentication(String name)
+ {
+ if(authenticationDAO.userExists(name))
+ {
+ authenticationService.deleteAuthentication(name);
+ }
+ authenticationService.createAuthentication(name, name.toCharArray());
+ if(personService.personExists(name))
+ {
+ personService.deletePerson(name);
+ }
+ personService.createPerson(createPersonProperties(name));
+ }
+
+ protected void createGroup(String name)
+ {
+ authorityService.createAuthority(AuthorityType.GROUP, name);
+ }
+
+ protected void runAs(String userName)
+ {
+ authenticationService.authenticate(userName, userName.toCharArray());
+ assertNotNull(authenticationService.getCurrentUserName());
+ // for(GrantedAuthority authority : woof.getAuthorities())
+ // {
+ // System.out.println("Auth = "+authority.getAuthority());
+ // }
+
+ }
+
+ protected NodeRef[] build1000Nodes(final String authority, final int returnNodes, final boolean inherit)
+ {
+ return build1000Nodes(authority, PermissionService.READ, returnNodes, inherit);
+ }
+
+ protected NodeRef[] buildOwnedNodes(final String authority, final int returnNodes)
+ {
+ runAs("admin");
+
+ final NodeRef[] nodes = new NodeRef[returnNodes];
+
+ RetryingTransactionCallback cb = new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ int i = 0;
+ int k = returnNodes > 0 ? 1000/returnNodes : 0;
+ String namePrefix = "simple" + System.currentTimeMillis();
+
+ NodeRef folder = fileFolderService.create(rootNodeRef, namePrefix, ContentModel.TYPE_FOLDER).getNodeRef();
+
+ NodeRef folder_1000 = fileFolderService.create(folder, namePrefix + "-1000-", ContentModel.TYPE_FOLDER).getNodeRef();
+ permissionService.setInheritParentPermissions(folder_1000, false);
+ permissionService.setPermission(folder_1000, authority, PermissionService.READ, true);
+ for(int j = 0; j < 1000; j++)
+ {
+ NodeRef file = fileFolderService.create(folder_1000, namePrefix + "-1000-"+j, ContentModel.TYPE_CONTENT).getNodeRef();
+ ownableService.setOwner(file, authority);
+
+ if(returnNodes > 0)
+ {
+ if(j % k == 0)
+ {
+ nodes[i++] = file;
+ }
+ }
+ }
+
+ return null;
+ }
+ };
+ retryingTransactionHelper.doInTransaction(cb, false, false);
+
+ return nodes;
+ }
+
+ protected void buildNodes(final String user, final String permission, final int n, final boolean inherit)
+ {
+ RetryingTransactionCallback cb = new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ String namePrefix = "simple" + System.currentTimeMillis();
+
+ NodeRef folder = fileFolderService.create(rootNodeRef, namePrefix, ContentModel.TYPE_FOLDER).getNodeRef();
+
+ NodeRef folder_n = fileFolderService.create(folder, namePrefix + "-n", ContentModel.TYPE_FOLDER).getNodeRef();
+ permissionService.setInheritParentPermissions(folder_n, false);
+ permissionService.setPermission(folder_n, user, PermissionService.READ, true);
+ for(int j = 0; j < n; j++)
+ {
+ NodeRef file = fileFolderService.create(folder_n, namePrefix + "-n-"+j, ContentModel.TYPE_CONTENT).getNodeRef();
+ if(!inherit)
+ {
+ permissionService.setInheritParentPermissions(file, false);
+ if(permission != null)
+ {
+ permissionService.setPermission(file, user, permission, true);
+ }
+ }
+ }
+
+ return null;
+ }
+ };
+ retryingTransactionHelper.doInTransaction(cb, false, false);
+ }
+
+ protected NodeRef[] build1000Nodes(final String authority, final String permission, final int returnNodes, final boolean inherit)
+ {
+ runAs("admin");
+
+ final NodeRef[] nodes = new NodeRef[returnNodes];
+
+ RetryingTransactionCallback cb = new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ int i = 0;
+ int k = returnNodes > 0 ? 1000/returnNodes : 0;
+ String namePrefix = "simple" + System.currentTimeMillis();
+
+ NodeRef folder = fileFolderService.create(rootNodeRef, namePrefix, ContentModel.TYPE_FOLDER).getNodeRef();
+
+ NodeRef folder_1000 = fileFolderService.create(folder, namePrefix + "-1000-", ContentModel.TYPE_FOLDER).getNodeRef();
+ permissionService.setInheritParentPermissions(folder_1000, false);
+ permissionService.setPermission(folder_1000, authority, permission, true);
+ for(int j = 0; j < 1000; j++)
+ {
+ NodeRef file = fileFolderService.create(folder_1000, namePrefix + "-1000-"+j, ContentModel.TYPE_CONTENT).getNodeRef();
+ if(!inherit)
+ {
+ permissionService.setInheritParentPermissions(file, false);
+ permissionService.setPermission(file, authority, permission, true);
+ }
+ if(returnNodes > 0)
+ {
+ if(j % k == 0)
+ {
+ nodes[i++] = file;
+ }
+ }
+ }
+
+ return null;
+ }
+ };
+ retryingTransactionHelper.doInTransaction(cb, false, false);
+
+ return nodes;
+ }
+
+ protected NodeRef[] build1000Nodes(final String authority, final String permission, final boolean inherit)
+ {
+ return build1000Nodes(authority, permission, 0, inherit);
+ }
+
+ protected void build1000NodesReadDenied(final String authority)
+ {
+ runAs("admin");
+
+ RetryingTransactionCallback cb = new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ String name = "simple" + System.currentTimeMillis();
+
+ NodeRef folder = fileFolderService.create(rootNodeRef, name, ContentModel.TYPE_FOLDER).getNodeRef();
+
+ NodeRef folder_1001 = fileFolderService.create(folder, name + "-1001", ContentModel.TYPE_FOLDER).getNodeRef();
+ permissionService.setPermission(folder_1001, authority, PermissionService.READ, true);
+ permissionService.setInheritParentPermissions(folder_1001, false);
+ for(int j = 0; j < 1000; j++)
+ {
+ NodeRef file = fileFolderService.create(folder_1001, name + "-1001-"+j, ContentModel.TYPE_CONTENT).getNodeRef();
+ permissionService.setInheritParentPermissions(file, false);
+ permissionService.setPermission(file, authority, PermissionService.READ, false);
+ }
+
+ return null;
+ }
+ };
+ retryingTransactionHelper.doInTransaction(cb, false, false);
+ }
+
+ protected void buildNodes()
+ {
+ final Random random = new Random(42);
+
+ runAs("admin");
+
+ permissionService.setPermission(rootNodeRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ, true);
+
+ for(int ii = 0; ii < COUNT; ii++)
+ {
+ final String namePrefix = "name" + System.currentTimeMillis() + "-";
+ final int i = ii;
+ System.out.println("Loop " + i);
+ RetryingTransactionCallback cb = new RetryingTransactionCallback()
+ {
+
+ public Void execute() throws Throwable
+ {
+ NodeRef folder = fileFolderService.create(rootNodeRef, namePrefix + i, ContentModel.TYPE_FOLDER).getNodeRef();
+
+ NodeRef folder_1000 = fileFolderService.create(folder, namePrefix + "1000-"+i, ContentModel.TYPE_FOLDER).getNodeRef();
+ permissionService.setPermission(folder_1000, "1000", PermissionService.READ, true);
+ permissionService.setInheritParentPermissions(folder_1000, false);
+ for(int j = 0; j < 1000; j++)
+ {
+ NodeRef file = fileFolderService.create(folder_1000, namePrefix + "1000-"+i+"-"+j, ContentModel.TYPE_CONTENT).getNodeRef();
+ //permissionService.setInheritParentPermissions(file, false);
+ //permissionService.setPermission(file, "1000", PermissionService.READ, true);
+ }
+
+ NodeRef folder_100 = fileFolderService.create(folder, namePrefix + "100-"+i, ContentModel.TYPE_FOLDER).getNodeRef();
+ permissionService.setPermission(folder_100, "100", PermissionService.READ, true);
+ permissionService.setInheritParentPermissions(folder_100, false);
+ for(int j = 0; j < 100; j++)
+ {
+ NodeRef file = fileFolderService.create(folder_100, namePrefix + "100-"+i+"-"+j, ContentModel.TYPE_CONTENT).getNodeRef();
+ }
+
+ NodeRef folder_10 = fileFolderService.create(folder, namePrefix + "10-"+i, ContentModel.TYPE_FOLDER).getNodeRef();
+ permissionService.setPermission(folder_10, "10", PermissionService.READ, true);
+ permissionService.setInheritParentPermissions(folder_10, false);
+ for(int j = 0; j < 10; j++)
+ {
+ NodeRef file = fileFolderService.create(folder_10, namePrefix + "10-"+i+"-"+j, ContentModel.TYPE_CONTENT).getNodeRef();
+ }
+
+ NodeRef folder_10_1 = fileFolderService.create(folder, namePrefix + "10_1-"+i, ContentModel.TYPE_FOLDER).getNodeRef();
+ permissionService.setPermission(folder_10_1, "GROUP_X", PermissionService.READ, true);
+ permissionService.setInheritParentPermissions(folder_10_1, false);
+ for(int j = 0; j < 10; j++)
+ {
+ NodeRef file = fileFolderService.create(folder_10_1, "namePrefix + 10_1-"+i+"-"+j, ContentModel.TYPE_CONTENT).getNodeRef();
+ }
+
+ NodeRef folder_1 = fileFolderService.create(folder, namePrefix + "1"+i, ContentModel.TYPE_FOLDER).getNodeRef();
+ permissionService.setPermission(folder_1, "1", PermissionService.READ, true);
+ permissionService.setInheritParentPermissions(folder_1, false);
+ NodeRef file = fileFolderService.create(folder_1, namePrefix + "1-1-1", ContentModel.TYPE_CONTENT).getNodeRef();
+
+ double rn = random.nextDouble();
+
+ if(rn < 0.1)
+ {
+ NodeRef rf = fileFolderService.create(folder, namePrefix + "0.1", ContentModel.TYPE_CONTENT).getNodeRef();
+ //permissionService.setPermission(rf, "01", PermissionService.READ, true);
+ //permissionService.setInheritParentPermissions(rf, false);
+ c01.increment();
+ }
+
+ if(rn < 0.01)
+ {
+ NodeRef rf = fileFolderService.create(folder, namePrefix + "0.01", ContentModel.TYPE_CONTENT).getNodeRef();
+ //permissionService.setPermission(rf, "001", PermissionService.READ, true);
+ //permissionService.setInheritParentPermissions(rf, false);
+ c001.increment();
+ }
+
+ if(rn < 0.001)
+ {
+ NodeRef rf = fileFolderService.create(folder, namePrefix + "0.001", ContentModel.TYPE_CONTENT).getNodeRef();
+ //permissionService.setPermission(rf, "0001", PermissionService.READ, true);
+ //permissionService.setInheritParentPermissions(rf, false);
+ c0001.increment();
+ }
+ return null;
+ }
+ };
+ retryingTransactionHelper.doInTransaction(cb, false, false);
+
+ }
+ }
+
+ protected void setupBasicTree(final String authority) throws Exception
+ {
+ runAs("admin");
+
+ final String[] dirs = new String[] {"a", "a/b", "a/b/c", "a/b/c/d", "e", "e/f", "e/f/g", "e/f/g/h", "x", "x/y"};
+
+ for(int j = 0; j < dirs.length; j++)
+ {
+ String path = dirs[j];
+ String dir;
+ String file;
+ int k = path.lastIndexOf('/');
+ if(k == -1)
+ {
+ dir = "";
+ file = path;
+ }
+ else
+ {
+ dir = path.substring(0, k);
+ file = path.substring(k+1);
+ }
+ fService.createDirectory(AVMStore + ":/" + dir, file);
+ }
+
+// fService.createDirectory("main:/", "a");
+// fService.createDirectory("main:/a", "b");
+// fService.createDirectory("main:/a/b", "c");
+// fService.createDirectory("main:/", "d");
+// fService.createDirectory("main:/d", "e");
+// fService.createDirectory("main:/d/e", "f");
+
+// desc = avmService.lookup(-1, storeName + ":/base");
+// nodeRef = AVMNodeConverter.ToNodeRef(-1, desc.getPath());
+// permissionService.setPermission(nodeRef, PermissionService.ALL_AUTHORITIES, PermissionService.ALL_PERMISSIONS, true);
+// permissionService.deletePermission(nodeRef, PermissionService.ALL_AUTHORITIES, PermissionService.ALL_PERMISSIONS);
+
+ AVMNodeDescriptor nodeDesc = fService.lookup(-1, AVMStore + ":/");
+ NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, nodeDesc.getPath());
+ //permissionService.setPermission(nodeRef, "1", PermissionService.READ, true);
+
+// for(int ii = 0; ii < COUNT; ii++)
+// {
+// final int i = ii;
+// final int j =
+// if(ii % 100 == 0)
+// {
+// System.out.println("Loop " + i);
+// }
+ RetryingTransactionCallback cb = new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ for(int i = 0; i < WEB_COUNT; i++)
+ {
+ if(i % 100 == 0)
+ {
+ System.out.println("Loop " + i);
+ }
+ int j = i % webAuthorities.length;
+
+ String dir = AVMStore + ":/" + dirs[i % 10];
+ String file = "foo" + i;
+ String path = dir + "/" + file;
+
+ fService.createFile(dir, file).close();
+ ContentWriter writer = fService.getContentWriter(path, true);
+ writer.setEncoding("UTF-8");
+ writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
+ //writer.putContent("I am " + path);
+ writer.putContent("I am main");
+
+ //String authority = webAuthorities[j];
+ NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, path);
+ permissionService.setPermission(nodeRef, authority, PermissionService.READ, true);
+ permissionService.setInheritParentPermissions(nodeRef, false);
+ }
+
+ return null;
+ }
+ };
+ retryingTransactionHelper.doInTransaction(cb, false, false);
+ //}
+
+// fService.createDirectory("main:/", "a");
+// fService.createDirectory("main:/a", "b");
+// fService.createDirectory("main:/a/b", "c");
+// fService.createDirectory("main:/", "d");
+// fService.createDirectory("main:/d", "e");
+// fService.createDirectory("main:/d/e", "f");
+//
+// AVMNodeDescriptor nodeDesc = fService.lookup(-1, "main:/");
+// NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, nodeDesc.getPath());
+// permissionService.setPermission(nodeRef, "1", PermissionService.READ, true);
+
+// fService.createFile("main:/a/b/c", "foo").close();
+// ContentWriter writer = fService.getContentWriter("main:/a/b/c/foo", true);
+// writer.setEncoding("UTF-8");
+// writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
+// writer.putContent("I am main:/a/b/c/foo");
+
+// AVMNodeDescriptor nodeDesc = fService.lookup(-1, "main:/a/b/c/foo");
+// NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, nodeDesc.getPath());
+// permissionService.setPermission(nodeRef, "1", PermissionService.READ, true);
+
+// fService.createFile("main:/a/b/c", "bar").close();
+// writer = fService.getContentWriter("main:/a/b/c/bar", true);
+// writer.setEncoding("UTF-8");
+// writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
+// writer.putContent("I am main:/a/b/c/bar");
+
+// nodeDesc = fService.lookup(-1, "main:/a/b/c/foo");
+// nodeRef = AVMNodeConverter.ToNodeRef(-1, nodeDesc.getPath());
+// permissionService.setPermission(nodeRef, "1", PermissionService.READ, true);
+
+ fService.createSnapshot(AVMStore, null, null);
+
+ //testTX.commit();
+ }
+
+ protected void deleteAuthentication(String name)
+ {
+ if(authenticationDAO.userExists(name))
+ {
+ authenticationService.deleteAuthentication(name);
+ }
+ if(personService.personExists(name))
+ {
+ personService.deletePerson(name);
+ }
+ }
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ nodeService = (NodeService) applicationContext.getBean("nodeService");
+ dictionaryService = (DictionaryService) applicationContext.getBean(ServiceRegistry.DICTIONARY_SERVICE
+ .getLocalName());
+ permissionService = (PermissionServiceSPI) applicationContext.getBean("permissionService");
+ namespacePrefixResolver = (NamespacePrefixResolver) applicationContext
+ .getBean(ServiceRegistry.NAMESPACE_SERVICE.getLocalName());
+ authenticationService = (MutableAuthenticationService) applicationContext.getBean("authenticationService");
+ authenticationComponent = (AuthenticationComponent) applicationContext.getBean("authenticationComponent");
+ serviceRegistry = (ServiceRegistry) applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
+ permissionModelDAO = (ModelDAO) applicationContext.getBean("permissionsModelDAO");
+ personService = (PersonService) applicationContext.getBean("personService");
+ authorityService = (AuthorityService) applicationContext.getBean("authorityService");
+ authorityDAO = (AuthorityDAO) applicationContext.getBean("authorityDAO");
+ accessControlListDao = (AccessControlListDAO) applicationContext.getBean("admNodeACLDAO");
+ fileFolderService = (FileFolderService)applicationContext.getBean("fileFolderService");
+
+ authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
+ authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("authenticationDao");
+ nodeDAO = (NodeDAO) applicationContext.getBean("nodeDAO");
+ aclDaoComponent = (AclDAO) applicationContext.getBean("aclDAO");
+
+ retryingTransactionHelper = (RetryingTransactionHelper) applicationContext.getBean("retryingTransactionHelper");
+
+ transactionService = (TransactionService) applicationContext.getBean("transactionComponent");
+
+ ownableService = (OwnableService) applicationContext.getBean("ownableService");
+
+ testTX = transactionService.getUserTransaction();
+ testTX.begin();
+
+ StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.nanoTime());
+ rootNodeRef = nodeService.getRootNode(storeRef);
+
+ QName children = ContentModel.ASSOC_CHILDREN;
+ QName system = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "system");
+ QName container = ContentModel.TYPE_CONTAINER;
+ QName types = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "people");
+
+// systemNodeRef = nodeService.createNode(rootNodeRef, children, system, container).getChildRef();
+// NodeRef typesNodeRef = nodeService.createNode(systemNodeRef, children, types, container).getChildRef();
+// Map props = createPersonProperties("andy");
+// nodeService.createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props).getChildRef();
+// props = createPersonProperties("lemur");
+// nodeService.createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props).getChildRef();
+
+ // create an authentication object e.g. the user
+ if(authenticationDAO.userExists("andy"))
+ {
+ authenticationService.deleteAuthentication("andy");
+ }
+ authenticationService.createAuthentication("andy", "andy".toCharArray());
+
+ if(authenticationDAO.userExists("lemur"))
+ {
+ authenticationService.deleteAuthentication("lemur");
+ }
+ authenticationService.createAuthentication("lemur", "lemur".toCharArray());
+
+ if(authenticationDAO.userExists(AuthenticationUtil.getAdminUserName()))
+ {
+ authenticationService.deleteAuthentication(AuthenticationUtil.getAdminUserName());
+ }
+ authenticationService.createAuthentication(AuthenticationUtil.getAdminUserName(), "admin".toCharArray());
+
+ authenticationComponent.clearCurrentSecurityContext();
+
+ fService = (AVMService)applicationContext.getBean("AVMService");
+ fIndexerAndSearcher = (IndexerAndSearcher)applicationContext.getBean("indexerAndSearcherFactory");
+ wpService = (WebProjectService)applicationContext.getBean("WebProjectService");
+
+ if (fService.getStore(AVMStore) != null)
+ {
+ fService.purgeStore(AVMStore);
+ }
+ fService.createStore(AVMStore);
+
+ for(String authority : authorities)
+ {
+ createAuthentication(authority);
+ }
+
+ for(String authority : webAuthorities)
+ {
+ createAuthentication(authority);
+ }
+
+ // TODO define permission group to include Read in permissionDefinitions
+ // assign user to new permission group - should be able to read any node?
+
+ createGroup("X");
+ authorityService.addAuthority(authorityService.getName(AuthorityType.GROUP, "X"), "10_1");
+
+ authenticationComponent.clearCurrentSecurityContext();
+ }
+
+ protected void tearDown() throws Exception
+ {
+// if(fService.getStore(AVMStore) != null)
+// {
+// fService.purgeStore(AVMStore);
+// }
+// for(String authority : authorities)
+// {
+// deleteAuthentication(authority);
+// }
+// for(String authority : webAuthorities)
+// {
+// deleteAuthentication(authority);
+// }
+
+ if ((testTX.getStatus() == Status.STATUS_ACTIVE) || (testTX.getStatus() == Status.STATUS_MARKED_ROLLBACK))
+ {
+ testTX.rollback();
+ }
+ AuthenticationUtil.clearCurrentSecurityContext();
+ super.tearDown();
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/security/permissions/impl/ReadPermissionTest.java b/source/java/org/alfresco/repo/security/permissions/impl/ReadPermissionTest.java
new file mode 100644
index 0000000000..dd3bf17629
--- /dev/null
+++ b/source/java/org/alfresco/repo/security/permissions/impl/ReadPermissionTest.java
@@ -0,0 +1,455 @@
+package org.alfresco.repo.security.permissions.impl;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.repo.avm.AVMNodeConverter;
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.cmr.search.ResultSet;
+import org.alfresco.service.cmr.search.SearchParameters;
+import org.alfresco.service.cmr.search.SearchService;
+import org.alfresco.service.cmr.security.PermissionService;
+import org.alfresco.service.namespace.QName;
+
+// Unit tests for ALF-3952 "Search/Read Permissions Evaluation Performance"
+public class ReadPermissionTest extends AbstractReadPermissionTest
+{
+// public void testDynamicAuthority() throws Exception
+// {
+// SearchParameters sp;
+// ResultSet results;
+//
+// buildNodes("1001", null, 10, false);
+//
+// runAs("1001");
+//
+// sp = new SearchParameters();
+// sp.addStore(rootNodeRef.getStoreRef());
+// sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+// sp.setQuery("TYPE:\"cm:content\"");
+// sp.setMaxItems(Integer.MAX_VALUE);
+// sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+// sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+// results = serviceRegistry.getSearchService().query(sp);
+// int length = results.length();
+// results.close();
+//
+// assertEquals(10, length);
+// }
+
+ public void testAdminCanRead()
+ {
+ buildNodes("1001", "Read", 10, true);
+
+ SearchParameters sp;
+ ResultSet results;
+
+ runAs("admin");
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(10, results.length());
+ results.close();
+ }
+
+ public void testAVM() throws Exception
+ {
+ try
+ {
+ runAs("admin");
+
+ setupBasicTree("Web1");
+
+ runAs("Web1");
+
+ StoreRef storeRef = AVMNodeConverter.ToStoreRef(AVMStore);
+ long start;
+ long end;
+ SearchParameters sp;
+ ResultSet results;
+
+ // Text index
+ sp = new SearchParameters();
+ sp.addStore(storeRef);
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ start = System.nanoTime();
+ results = serviceRegistry.getSearchService().query(sp);
+ assertEquals(WEB_COUNT, results.length());
+ results.close();
+ end = System.nanoTime();
+ System.out.println("AVM in "+((end-start)/1e9));
+
+ sp = new SearchParameters();
+ sp.addStore(storeRef);
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ // sp.setQuery("TEXT:\"I am\"");
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ start = System.nanoTime();
+ results = serviceRegistry.getSearchService().query(sp);
+ assertEquals(WEB_COUNT, results.length());
+ results.close();
+ end = System.nanoTime();
+ System.out.println("AVM in "+((end-start)/1e9));
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+ public void testReadDeny()
+ {
+ SearchParameters sp;
+ ResultSet results;
+
+ build1000NodesReadDenied("1001");
+
+ runAs("1001");
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ int length = results.length();
+ results.close();
+
+ assertEquals(0, length);
+ }
+
+ public void testNoRead()
+ {
+ SearchParameters sp;
+ ResultSet results;
+
+ build1000Nodes("1001", PermissionService.WRITE, true);
+
+ runAs("1001");
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ int length = results.length();
+ results.close();
+
+ assertEquals(0, length);
+ }
+
+ protected void buildContainers(final String username, final String permission)
+ {
+ runAs("admin");
+
+ RetryingTransactionCallback cb = new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ int i = 0;
+ String namePrefix = "simple" + System.currentTimeMillis();
+
+ NodeRef n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{test}01"),
+ ContentModel.TYPE_CONTAINER).getChildRef();
+ permissionService.setPermission(n1, username, permission, true);
+
+ return null;
+ }
+ };
+ retryingTransactionHelper.doInTransaction(cb, false, false);
+ }
+
+ public void testNodeOwner()
+ {
+ SearchParameters sp;
+ ResultSet results;
+
+ buildOwnedNodes("1001", 0);
+
+ runAs(AuthenticationUtil.getAdminUserName());
+ runAs("1001");
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("PATH:\"//*\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ int length = results.length();
+ results.close();
+
+ assertEquals(1001, length); // folder + children
+ }
+
+ public void testChangePermissions()
+ {
+ SearchParameters sp;
+ ResultSet results;
+
+ NodeRef[] nodes = build1000Nodes("1001", 4, false);
+
+ runAs("1001");
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ int length = results.length();
+ results.close();
+
+ assertEquals(1000, length);
+
+ for(int i = 0; i < 4; i++)
+ {
+ permissionService.deletePermission(nodes[i], "1001", PermissionService.READ);
+ }
+
+ //setPermission(nodes[0], "10", permission, allow)
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ length = results.length();
+ results.close();
+
+ assertEquals(1000-4, length);
+ }
+
+ public void testQueryReadPermission()
+ {
+ buildNodes();
+
+ SearchParameters sp;
+ ResultSet results;
+
+ runAs("1000");
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(1000*COUNT, results.length());
+ results.close();
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(1000*COUNT, results.length());
+ results.close();
+
+ runAs("100");
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(100*COUNT, results.length());
+ results.close();
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(100*COUNT, results.length());
+ results.close();
+
+ runAs("10");
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(10*COUNT, results.length());
+ results.close();
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(10*COUNT, results.length());
+ results.close();
+
+ // test user member of group with read permission can read
+ runAs("10_1");
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(10*COUNT, results.length());
+ results.close();
+
+ runAs("1");
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(COUNT, results.length());
+ results.close();
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(COUNT, results.length());
+ results.close();
+
+ runAs("01");
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(c01.count(), results.length());
+ results.close();
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(c01.count(), results.length());
+ results.close();
+
+ runAs("001");
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(c001.count(), results.length());
+ results.close();
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(c001.count(), results.length());
+ results.close();
+
+ runAs("0001");
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(c0001.count(), results.length());
+ results.close();
+
+ sp = new SearchParameters();
+ sp.addStore(rootNodeRef.getStoreRef());
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery("TYPE:\"cm:content\"");
+ sp.setMaxItems(Integer.MAX_VALUE);
+ sp.setMaxPermissionChecks(Integer.MAX_VALUE);
+ sp.setMaxPermissionCheckTimeMillis(Integer.MAX_VALUE);
+ results = serviceRegistry.getSearchService().query(sp);
+ results.setBulkFetch(false);
+ assertEquals(c0001.count(), results.length());
+ results.close();
+ }
+}