@Test public void testReadAclAfterCopy() { DocumentModel folder1 = new DocumentModelImpl("/", "folder1", "Folder"); folder1 = session.createDocument(folder1); DocumentModel folder2 = new DocumentModelImpl("/", "folder2", "Folder"); folder2 = session.createDocument(folder2); DocumentModel doc = new DocumentModelImpl("/folder1", "doc", "File"); doc = session.createDocument(doc); // set ACL on folder2 ACL acl = new ACLImpl(); acl.add(new ACE("Everyone", "Read", true)); ACP acp = new ACPImpl(); acp.addACL(acl); folder2.setACP(acp, true); session.save(); // doc under folder1 cannot be read by joe try (CoreSession joeSession = openSessionAs("joe")) { DocumentModelList list = joeSession.query("SELECT * FROM File"); assertEquals(0, list.size()); } // copy doc under folder2 session.copy(doc.getRef(), folder2.getRef(), "doccopy"); session.save(); // check doc copy now readable by joe try (CoreSession joeSession = openSessionAs("joe")) { DocumentModelList list = joeSession.query("SELECT * FROM File"); assertEquals(1, list.size()); assertEquals("doccopy", list.get(0).getName()); } }
public DocumentModelList getPageWidgets(String docType) { DocumentModelList list = new DocumentModelListImpl(); Directories dirEnum = Directories.fromString("labs_" + docType + "_widgets"); Map<String, Serializable> filter = new HashMap<String, Serializable>(); filter.put("obsolete", "0"); list.addAll(DirectoriesUtils.getDirDocumentModelList(dirEnum, filter)); return list; }
private void emailEnglishAssertions(String filePath) throws Exception { // initialize mailboxes getPersonalMailbox("jdoe"); injectEmail(filePath); DocumentRef dayRef = new PathRef(CaseConstants.CASE_ROOT_DOCUMENT_PATH + "/2009/03/17"); assertTrue(session.exists(dayRef)); DocumentModelList envelopes = session.getChildren(dayRef, MailConstants.MAIL_ENVELOPE_TYPE); assertEquals(1, envelopes.size()); DocumentModel envelopeDoc = envelopes.get(0); Case envelope = envelopeDoc.getAdapter(Case.class); List<DocumentModel> linkedDocs = envelope.getDocuments(); assertEquals(2, linkedDocs.size()); DocumentModel firstDoc = linkedDocs.get(0); String title = (String) firstDoc.getPropertyValue(CaseConstants.TITLE_PROPERTY_NAME); assertEquals("[Fwd: RENOUVELLEMENT DE SUPPORT ANNUEL NUXEO]", title); Calendar originalReceptionDate = (Calendar) firstDoc.getPropertyValue(CaseConstants.DOCUMENT_IMPORT_DATE_PROPERTY_NAME); assertEquals( emailDateParser.parse("Wed, 14 Jan 2009 15:15:25 +0100").getTime(), originalReceptionDate.getTime().getTime()); Calendar receptionDate = (Calendar) firstDoc.getPropertyValue(CaseConstants.DOCUMENT_RECEIVE_DATE_PROPERTY_NAME); assertEquals( emailDateParser.parse("Tue, 17 Mar 2009 13:39:05 +0100").getTime(), receptionDate.getTime().getTime()); Contacts senders = Contacts.getContactsForDoc(firstDoc, CaseConstants.CONTACTS_SENDERS); assertNotNull(senders); assertEquals(1, senders.size()); Contact sender = senders.get(0); assertEquals("Sylvie KAPCOM", sender.getName()); assertEquals("*****@*****.**", sender.getEmail()); Contacts recipients = Contacts.getContactsForDoc(firstDoc, CaseConstants.CONTACTS_PARTICIPANTS); assertNotNull(recipients); assertEquals(2, recipients.size()); assertEquals("*****@*****.**", recipients.get(0).getEmail()); assertTrue( (recipients.get(1).getName() == null) || ("".equals(recipients.get(1).getName().trim()))); assertEquals("*****@*****.**", recipients.get(1).getEmail()); // testing content DocumentModel secondDoc = linkedDocs.get(1); Blob fileBlob = (Blob) secondDoc.getPropertyValue(CaseConstants.FILE_PROPERTY_NAME); assertEquals("The file blob filename is", "testpdf.pdf", fileBlob.getFilename()); assertEquals("the file blob length is", 24016, fileBlob.getLength()); String fileNamePropertyValue = (String) secondDoc.getPropertyValue(CaseConstants.FILENAME_PROPERTY_NAME); assertEquals("The filename property value is", "testpdf.pdf", fileNamePropertyValue); }
@Test public void shouldDenyAccessOnUnsupportedACL() throws Exception { assumeTrue(session.isNegativeAclAllowed()); buildAndIndexTree(); DocumentModelList docs = ess.query(new NxQueryBuilder(session).nxql("select * from Document")); Assert.assertEquals(10, docs.totalSize()); // check for user with no rights CoreSession restrictedSession = getRestrictedSession("toto"); try { docs = ess.query(new NxQueryBuilder(restrictedSession).nxql("select * from Document")); Assert.assertEquals(0, docs.totalSize()); // add READ rights and check that user now has access DocumentRef ref = new PathRef("/folder0/folder1/folder2"); ACP acp = new ACPImpl(); ACL acl = ACPImpl.newACL(ACL.LOCAL_ACL); acl.add(new ACE("toto", SecurityConstants.READ, true)); acp.addACL(acl); session.setACP(ref, acp, true); TransactionHelper.commitOrRollbackTransaction(); waitForCompletion(); startTransaction(); docs = ess.query( new NxQueryBuilder(restrictedSession) .nxql("select * from Document order by dc:title")); Assert.assertEquals(8, docs.totalSize()); // Add an unsupported negative ACL ref = new PathRef("/folder0/folder1/folder2/folder3/folder4/folder5"); acp = new ACPImpl(); acl = ACPImpl.newACL(ACL.LOCAL_ACL); acl.add(new ACE("bob", SecurityConstants.EVERYTHING, false)); acp.addACL(acl); session.setACP(ref, acp, true); session.save(); TransactionHelper.commitOrRollbackTransaction(); waitForCompletion(); startTransaction(); docs = ess.query( new NxQueryBuilder(restrictedSession) .nxql("select * from Document order by dc:title")); // can view folder2, folder3 and folder4 Assert.assertEquals(3, docs.totalSize()); } finally { restrictedSession.close(); } }
@Test public void shouldStoreOnlyEffectiveACEs() throws Exception { buildAndIndexTree(); DocumentModelList docs = ess.query(new NxQueryBuilder(session).nxql("select * from Document")); Assert.assertEquals(10, docs.totalSize()); CoreSession restrictedSession = getRestrictedSession("toto"); try { docs = ess.query(new NxQueryBuilder(restrictedSession).nxql("select * from Document")); Assert.assertEquals(0, docs.totalSize()); DocumentRef ref = new PathRef("/folder0"); ACP acp = new ACPImpl(); ACL acl = ACPImpl.newACL(ACL.LOCAL_ACL); acl.add(ACE.builder("toto", SecurityConstants.READ).build()); acp.addACL(acl); session.setACP(ref, acp, true); TransactionHelper.commitOrRollbackTransaction(); waitForCompletion(); startTransaction(); docs = ess.query( new NxQueryBuilder(restrictedSession) .nxql("select * from Document order by dc:title")); Assert.assertEquals(10, docs.totalSize()); acp = new ACPImpl(); acl = ACPImpl.newACL(ACL.LOCAL_ACL); // make the ACE archived Date now = new Date(); Calendar begin = new GregorianCalendar(); begin.setTimeInMillis(now.toInstant().minus(10, ChronoUnit.DAYS).toEpochMilli()); Calendar end = new GregorianCalendar(); end.setTimeInMillis(now.toInstant().minus(2, ChronoUnit.DAYS).toEpochMilli()); acl.add(ACE.builder("toto", SecurityConstants.READ).begin(begin).end(end).build()); acp.addACL(acl); session.setACP(ref, acp, true); TransactionHelper.commitOrRollbackTransaction(); waitForCompletion(); startTransaction(); docs = ess.query( new NxQueryBuilder(restrictedSession) .nxql("select * from Document order by dc:title")); Assert.assertEquals(0, docs.totalSize()); } finally { restrictedSession.close(); } }
@Test public void testQueryFulltext() throws Exception { Map<String, Serializable> filter = new HashMap<String, Serializable>(); Set<String> fulltext = new HashSet<String>(); DocumentModelList entries; entries = dir.query(filter, fulltext); assertEquals(4, entries.size()); // null fulltext set should be equivalent to empty one entries = dir.query(filter, null); assertEquals(4, entries.size()); }
/** * Returns the CSIDs of CollectionObject records that are related to a Movement record. * * @param movementCsid the CSID of a Movement record. * @param coreSession a repository session. * @throws ClientException * @return the CSIDs of the CollectionObject records, if any, which are related to the Movement * record. */ private Set<String> getCollectionObjectCsidsRelatedToMovement( String movementCsid, CoreSession coreSession) throws ClientException { Set<String> csids = new HashSet<>(); // Via an NXQL query, get a list of active relation records where: // * This movement record's CSID is the subject CSID of the relation, // and its object document type is a CollectionObject doctype; // or // * This movement record's CSID is the object CSID of the relation, // and its subject document type is a CollectionObject doctype. // // Some values below are hard-coded for readability, rather than // being obtained from constants. String query = String.format( "SELECT * FROM %1$s WHERE " // collectionspace_core:tenantId = 1 " + "(" + " (%2$s:subjectCsid = '%3$s' " + " AND %2$s:objectDocumentType = '%4$s') " + " OR " + " (%2$s:objectCsid = '%3$s' " + " AND %2$s:subjectDocumentType = '%4$s') " + ")" + ACTIVE_DOCUMENT_WHERE_CLAUSE_FRAGMENT, RELATION_DOCTYPE, RELATIONS_COMMON_SCHEMA, movementCsid, COLLECTIONOBJECT_DOCTYPE); DocumentModelList relationDocModels = coreSession.query(query); if (relationDocModels == null || relationDocModels.isEmpty()) { // Encountering a Movement record that is not related to any // CollectionObject is potentially a normal occurrence, so no // error messages are logged here when we stop handling this event. return csids; } // Iterate through the list of Relation records found and build // a list of CollectionObject CSIDs, by extracting the relevant CSIDs // from those Relation records. String csid; for (DocumentModel relationDocModel : relationDocModels) { csid = getCsidForDesiredDocTypeFromRelation( relationDocModel, COLLECTIONOBJECT_DOCTYPE, MOVEMENT_DOCTYPE); if (Tools.notBlank(csid)) { csids.add(csid); } } return csids; }
@Test public void testReadAclAfterSetACP() { DocumentModel folder = new DocumentModelImpl("/", "folder", "Folder"); folder = session.createDocument(folder); DocumentModel doc = new DocumentModelImpl("/folder", "doc", "File"); doc = session.createDocument(doc); session.save(); // nothing can be seen by joe try (CoreSession joeSession = openSessionAs("joe")) { DocumentModelList list = joeSession.query("SELECT * FROM Folder"); assertEquals(0, list.size()); list = joeSession.query("SELECT * FROM File"); assertEquals(0, list.size()); } // set ACL on folder ACL acl = new ACLImpl(); acl.add(new ACE("Everyone", "Read", true)); ACP acp = new ACPImpl(); acp.addACL(acl); folder.setACP(acp, true); session.save(); // now joe sees things try (CoreSession joeSession = openSessionAs("joe")) { DocumentModelList list = joeSession.query("SELECT * FROM Folder"); assertEquals(1, list.size()); assertEquals(folder.getId(), list.get(0).getId()); list = joeSession.query("SELECT * FROM File"); assertEquals(1, list.size()); assertEquals(doc.getId(), list.get(0).getId()); } }
@Test public void shouldIndexOnCopy() throws Exception { buildAndIndexTree(); DocumentRef src = new PathRef("/folder0/folder1/folder2"); DocumentRef dst = new PathRef("/folder0"); session.copy(src, dst, "folder2-copy"); TransactionHelper.commitOrRollbackTransaction(); waitForCompletion(); startTransaction(); DocumentModelList docs = ess.query(new NxQueryBuilder(session).nxql("select * from Document")); Assert.assertEquals(18, docs.totalSize()); }
@Test public void testGetEntries() throws Exception { DocumentModelList l; l = dir.getEntries(); assertEquals(4, l.size()); DocumentModel entry = null; for (DocumentModel e : l) { if (e.getId().equals("1")) { entry = e; break; } } assertNotNull(entry); assertEquals("foo1", entry.getProperty("schema3", "thefoo")); }
public static DocumentModelList getDirectoryEntries(String directoryName, String... entryIds) throws ClientException { if (entryIds == null) { return null; } DirectoryService dirService = Framework.getService(DirectoryService.class); try (Session session = dirService.open(directoryName)) { DocumentModelList result = new DocumentModelListImpl(); for (String entryId : entryIds) { DocumentModel entry = session.getEntry(entryId); if (entry != null) { result.add(entry); } } return result; } }
@Test public void testReadOnlyEntryInGetEntriesResults() throws Exception { Map<String, String> orderBy = new HashMap<String, String>(); orderBy.put("schema3:uid", "asc"); DocumentModelComparator comp = new DocumentModelComparator(orderBy); DocumentModelList results = dir.getEntries(); Collections.sort(results, comp); // by default no backing dir is readonly assertFalse(BaseSession.isReadOnlyEntry(results.get(0))); assertFalse(BaseSession.isReadOnlyEntry(results.get(1))); assertFalse(BaseSession.isReadOnlyEntry(results.get(2))); assertFalse(BaseSession.isReadOnlyEntry(results.get(3))); memdir1.setReadOnly(true); memdir2.setReadOnly(false); memdir3.setReadOnly(false); results = dir.getEntries(); Collections.sort(results, comp); assertTrue(BaseSession.isReadOnlyEntry(results.get(0))); assertTrue(BaseSession.isReadOnlyEntry(results.get(1))); assertFalse(BaseSession.isReadOnlyEntry(results.get(2))); assertFalse(BaseSession.isReadOnlyEntry(results.get(3))); memdir1.setReadOnly(false); memdir2.setReadOnly(false); memdir3.setReadOnly(true); results = dir.getEntries(); Collections.sort(results, comp); assertFalse(BaseSession.isReadOnlyEntry(results.get(0))); assertFalse(BaseSession.isReadOnlyEntry(results.get(1))); assertTrue(BaseSession.isReadOnlyEntry(results.get(2))); assertTrue(BaseSession.isReadOnlyEntry(results.get(3))); }
@Test public void testGetEntries() throws ClientException { Session session = getLDAPDirectory("userDirectory").getSession(); try { DocumentModelList entries = session.getEntries(); assertNotNull(entries); assertEquals(4, entries.size()); List<String> entryIds = new ArrayList<String>(); for (DocumentModel entry : entries) { entryIds.add(entry.getId()); } Collections.sort(entryIds); assertEquals("Administrator", entryIds.get(0)); assertEquals("user1", entryIds.get(1)); assertEquals("user2", entryIds.get(2)); assertEquals("user3", entryIds.get(3)); } finally { session.close(); } }
@Test public void testBlobFilenamePresent() throws Exception { createDocs(); ExportedDocument exportedDoc = new ExportedDocumentImpl(docToExport, true); assertEquals("File", exportedDoc.getType()); session.removeDocument(docToExport.getRef()); session.save(); assertEquals(0, session.getChildren(workspace.getRef()).size()); DocumentWriter writer = new DocumentModelWriter(session, rootDocument.getPathAsString()); writer.write(exportedDoc); DocumentModelList children = session.getChildren(workspace.getRef()); assertEquals(1, children.size()); DocumentModel importedDocument = children.get(0); Blob blob = (Blob) importedDocument.getProperty("file", "content"); assertEquals("dummyBlob.txt", blob.getFilename()); }
@Test public void testQuery1() { try (Session session = getLDAPDirectory("userDirectory").getSession()) { Map<String, Serializable> filter = new HashMap<String, Serializable>(); filter.put("username", "user"); Set<String> fulltext = new HashSet<String>(); fulltext.add("username"); DocumentModelList entries = session.query(filter, fulltext); assertNotNull(entries); assertEquals(2, entries.size()); List<String> entryIds = new ArrayList<String>(); for (DocumentModel entry : entries) { entryIds.add(entry.getId()); } Collections.sort(entryIds); assertEquals("*****@*****.**", entryIds.get(0)); assertEquals("*****@*****.**", entryIds.get(1)); } }
/** Looks if an existing Document has the same value for a given property. */ public static DocumentModel getExistingDocByPropertyName( CoreSession documentManager, String path, String value, String propertyName) throws ClientException { DocumentModel existing = null; String parentId = documentManager.getDocument(new PathRef(path)).getId(); String query = "SELECT * FROM Document WHERE ecm:parentId = '" + parentId + "' AND " + propertyName + " = '" + value.replace("'", "\\\'") + "' AND ecm:currentLifeCycleState != '" + LifeCycleConstants.DELETED_STATE + "'"; DocumentModelList docs = documentManager.query(query, 1); if (docs.size() > 0) { existing = docs.get(0); } return existing; }
@Override public List<String> getProjection( Map<String, Serializable> filter, Set<String> fulltext, String columnName) { // There's no way to do an efficient getProjection to a source with // multiple subdirectories given the current API (we'd need an API that // passes several columns). // So just do a non-optimal implementation for now. final DocumentModelList entries = query(filter, fulltext); final List<String> results = new ArrayList<String>(entries.size()); for (DocumentModel entry : entries) { final Object value = entry.getProperty(schemaName, columnName); if (value == null) { results.add(null); } else { results.add(value.toString()); } } return results; }
/** * Returns a document model for a record identified by a CSID. * * @param session a repository session. * @param collectionObjectCsid a CollectionObject identifier (CSID) * @return a document model for the record identified by the supplied CSID. */ protected static DocumentModel getDocModelFromCsid( CoreSession session, String collectionObjectCsid) { DocumentModelList collectionObjectDocModels = null; try { final String query = "SELECT * FROM " + NuxeoUtils.BASE_DOCUMENT_TYPE + " WHERE " + NuxeoUtils.getByNameWhereClause(collectionObjectCsid); collectionObjectDocModels = session.query(query); } catch (Exception e) { logger.warn("Exception in query to get document model for CollectionObject: ", e); } if (collectionObjectDocModels == null || collectionObjectDocModels.isEmpty()) { logger.warn("Could not get document models for CollectionObject(s)."); return null; } else if (collectionObjectDocModels.size() != 1) { logger.debug("Found more than 1 document with CSID=" + collectionObjectCsid); return null; } return collectionObjectDocModels.get(0); }
@Test public void shouldReindexSubTreeInTrash() throws Exception { buildAndIndexTree(); startTransaction(); DocumentRef ref = new PathRef("/folder0/folder1/folder2"); Assert.assertTrue(session.exists(ref)); session.followTransition(ref, "delete"); TransactionHelper.commitOrRollbackTransaction(); // let the bulkLifeCycleChangeListener do its work waitForCompletion(); assertNumberOfCommandProcessed(8); startTransaction(); DocumentModelList docs = ess.query( new NxQueryBuilder(session) .nxql("select * from Document where ecm:currentLifeCycleState != 'deleted'")); // for (DocumentModel doc : docs) { // System.out.println(doc.getPathAsString()); // } Assert.assertEquals(2, docs.totalSize()); }
protected void updateUserCatalog(UserManager userManager) throws ClientException { DocumentModelList allUsers = userManager.searchUsers(null); userCatalog = new HashMap<String, DocumentModelList>(); String userSortField = userManager.getUserSortField(); for (DocumentModel user : allUsers) { // FIXME: this should use a "display name" dedicated API String displayName = null; if (userSortField != null) { // XXX hack, principals have only one model org.nuxeo.ecm.core.api.DataModel dm = user.getDataModels().values().iterator().next(); displayName = (String) dm.getData(userSortField); } if (StringUtils.isEmpty(displayName)) { displayName = user.getId(); } String firstLetter = displayName.substring(0, 1).toUpperCase(); DocumentModelList list = userCatalog.get(firstLetter); if (list == null) { list = new DocumentModelListImpl(); userCatalog.put(firstLetter, list); } list.add(user); } }
@Test public void testReadAclSecurityUpdate() { // check that aclOptimization update the user aclr cache // NXP-13109 DocumentModel root = session.getRootDocument(); // Create a doc and set a new ACLR on it DocumentModel doc = new DocumentModelImpl(root.getPathAsString(), "foo", "Folder"); doc = session.createDocument(doc); ACP acp = doc.getACP(); assertNotNull(acp); acp = new ACPImpl(); ACL acl = new ACLImpl(); acl.add(new ACE("Everyone", "Read", true)); acp.addACL(acl); doc.setACP(acp, true); session.save(); CoreSession joeSession = openSessionAs("joe"); try { DocumentModelList list; list = joeSession.query("SELECT * FROM Folder"); assertEquals(1, list.size()); // Remove the document, so the ACLR created is not anymore assigned session.removeDocument(doc.getRef()); session.save(); list = joeSession.query("SELECT * FROM Folder"); assertEquals(0, list.size()); } finally { closeSession(joeSession); } CoreSession bobSession = openSessionAs("bob"); try { DocumentModelList list; // Perform a query to init the ACLR cache list = bobSession.query("SELECT * FROM Folder"); assertEquals(0, list.size()); // Create a new doc with the same ACLR doc = new DocumentModelImpl(root.getPathAsString(), "bar", "Folder"); doc = session.createDocument(doc); doc.setACP(acp, true); session.save(); // Check that the ACLR has been added to the user cache list = bobSession.query("SELECT * FROM Folder"); assertEquals(1, list.size()); } finally { closeSession(bobSession); } }
/** * Returns the most recent Movement record related to a CollectionObject. * * <p>This method currently returns the related Movement record with the latest (i.e. most recent * in time) Location Date field value. * * @param session a repository session. * @param collectionObjectCsid a CollectionObject identifier (CSID) * @throws ClientException * @return the most recent Movement record related to the CollectionObject identified by the * supplied CSID. */ protected static DocumentModel getMostRecentMovement( CoreSession session, String collectionObjectCsid) throws ClientException { DocumentModel mostRecentMovementDocModel = null; // Get Relation records for Movements related to this CollectionObject. // // Some values below are hard-coded for readability, rather than // being obtained from constants. String query = String.format( "SELECT * FROM %1$s WHERE " // collectionspace_core:tenantId = 1 " + "(" + " (%2$s:subjectCsid = '%3$s' " + " AND %2$s:objectDocumentType = '%4$s') " + " OR " + " (%2$s:objectCsid = '%3$s' " + " AND %2$s:subjectDocumentType = '%4$s') " + ")" + ACTIVE_DOCUMENT_WHERE_CLAUSE_FRAGMENT, RELATION_DOCTYPE, RELATIONS_COMMON_SCHEMA, collectionObjectCsid, MOVEMENT_DOCTYPE); if (logger.isTraceEnabled()) { logger.trace("query=" + query); } DocumentModelList relationDocModels = session.query(query); if (relationDocModels == null || relationDocModels.isEmpty()) { logger.warn( "Unexpectedly found no relations to Movement records to/from to this CollectionObject record."); return mostRecentMovementDocModel; } else { if (logger.isTraceEnabled()) { logger.trace( "Found " + relationDocModels.size() + " relations to Movement records to/from this CollectionObject record."); } } // Iterate through related movement records, to find the related // Movement record with the most recent location date. GregorianCalendar mostRecentLocationDate = EARLIEST_COMPARISON_DATE; // Note: the following value is used to compare any two records, rather // than to identify the most recent value so far encountered. Thus, it may // occasionally be set backward or forward in time, within the loop below. GregorianCalendar comparisonCreationDate = EARLIEST_COMPARISON_DATE; DocumentModel movementDocModel; Set<String> alreadyProcessedMovementCsids = new HashSet<>(); String relatedMovementCsid; for (DocumentModel relationDocModel : relationDocModels) { // Due to the 'OR' operator in the query above, related Movement // record CSIDs may reside in either the subject or object CSID fields // of the relation record. Whichever CSID value doesn't match the // CollectionObject's CSID is inferred to be the related Movement record's CSID. relatedMovementCsid = (String) relationDocModel.getProperty(RELATIONS_COMMON_SCHEMA, SUBJECT_CSID_PROPERTY); if (relatedMovementCsid.equals(collectionObjectCsid)) { relatedMovementCsid = (String) relationDocModel.getProperty(RELATIONS_COMMON_SCHEMA, OBJECT_CSID_PROPERTY); } if (Tools.isBlank(relatedMovementCsid)) { continue; } // Because of the OR clause used in the query above, there may be // two or more Relation records returned in the query results that // reference the same Movement record, as either the subject // or object of a relation to the same CollectionObject record; // we need to filter out those duplicates. if (alreadyProcessedMovementCsids.contains(relatedMovementCsid)) { continue; } else { alreadyProcessedMovementCsids.add(relatedMovementCsid); } if (logger.isTraceEnabled()) { logger.trace("Related movement CSID=" + relatedMovementCsid); } movementDocModel = getDocModelFromCsid(session, relatedMovementCsid); if (movementDocModel == null) { continue; } // Verify that the Movement record is active. This will also exclude // versioned Movement records from the computation of the current // location, for tenants that are versioning such records. if (!isActiveDocument(movementDocModel)) { if (logger.isTraceEnabled()) { logger.trace("Skipping this inactive Movement record ..."); } continue; } GregorianCalendar locationDate = (GregorianCalendar) movementDocModel.getProperty(MOVEMENTS_COMMON_SCHEMA, LOCATION_DATE_PROPERTY); // If the current Movement record lacks a location date, it cannot // be established as the most recent Movement record; skip over it. if (locationDate == null) { continue; } GregorianCalendar creationDate = (GregorianCalendar) movementDocModel.getProperty(COLLECTIONSPACE_CORE_SCHEMA, CREATED_AT_PROPERTY); if (locationDate.after(mostRecentLocationDate)) { mostRecentLocationDate = locationDate; if (creationDate != null) { comparisonCreationDate = creationDate; } mostRecentMovementDocModel = movementDocModel; // If the current Movement record's location date is identical // to that of the (at this time) most recent Movement record, then // instead compare the two records using their creation date values } else if (locationDate.compareTo(mostRecentLocationDate) == 0) { if (creationDate != null && creationDate.after(comparisonCreationDate)) { // The most recent location date value doesn't need to be // updated here, as the two records' values are identical comparisonCreationDate = creationDate; mostRecentMovementDocModel = movementDocModel; } } } return mostRecentMovementDocModel; }
@Test public void testQuery() throws Exception { Map<String, Serializable> filter = new HashMap<String, Serializable>(); DocumentModelList entries; DocumentModel e; // empty filter means everything (like getEntries) entries = dir.query(filter); assertNotNull(entries); assertEquals(4, entries.size()); // no result filter.put("thefoo", "f"); entries = dir.query(filter); assertEquals(0, entries.size()); // query matching one source // source with two subdirs filter.put("thefoo", "foo1"); entries = dir.query(filter); assertEquals(1, entries.size()); e = entries.get(0); assertEquals("1", e.getId()); assertEquals("bar1", e.getProperty("schema3", "thebar")); // simple source filter.put("thefoo", "foo3"); entries = dir.query(filter); assertEquals(1, entries.size()); e = entries.get(0); assertEquals("3", e.getId()); assertEquals("bar3", e.getProperty("schema3", "thebar")); // query matching two subdirectories in one source filter.put("thefoo", "foo1"); filter.put("thebar", "bar1"); entries = dir.query(filter); assertEquals(1, entries.size()); e = entries.get(0); assertEquals("1", e.getId()); assertEquals("foo1", e.getProperty("schema3", "thefoo")); assertEquals("bar1", e.getProperty("schema3", "thebar")); // query not matching although each subdirectory in the source matches filter.put("thefoo", "foo1"); filter.put("thebar", "bar2"); entries = dir.query(filter); assertEquals(0, entries.size()); // query matching two sources filter.clear(); e = dir.getEntry("1"); e.setProperty("schema3", "thefoo", "matchme"); dir.updateEntry(e); e = dir.getEntry("3"); e.setProperty("schema3", "thefoo", "matchme"); dir.updateEntry(e); filter.put("thefoo", "matchme"); entries = dir.query(filter); assertEquals(2, entries.size()); e = entries.get(0); assertEquals("1", e.getId()); assertEquals("bar1", e.getProperty("schema3", "thebar")); e = entries.get(1); assertEquals("3", e.getId()); assertEquals("bar3", e.getProperty("schema3", "thebar")); }
@Override @SuppressWarnings("boxing") public DocumentModelList query( Map<String, Serializable> filter, Set<String> fulltext, Map<String, String> orderBy, boolean fetchReferences) { // list of entries final DocumentModelList results = new DocumentModelListImpl(); if (!isCurrentUserAllowed(SecurityConstants.READ)) { return results; } init(); // entry ids already seen (mapped to the source name) final Map<String, String> seen = new HashMap<String, String>(); if (fulltext == null) { fulltext = Collections.emptySet(); } Set<String> readOnlyEntries = new HashSet<String>(); for (SourceInfo sourceInfo : sourceInfos) { // accumulated map for each entry final Map<String, Map<String, Object>> maps = new HashMap<String, Map<String, Object>>(); // number of dirs seen for each entry final Map<String, Integer> counts = new HashMap<String, Integer>(); // list of optional dirs where filter matches default values List<SubDirectoryInfo> optionalDirsMatching = new ArrayList<SubDirectoryInfo>(); for (SubDirectoryInfo dirInfo : sourceInfo.subDirectoryInfos) { // compute filter final Map<String, Serializable> dirFilter = new HashMap<String, Serializable>(); for (Entry<String, Serializable> e : filter.entrySet()) { final String fieldName = dirInfo.fromSource.get(e.getKey()); if (fieldName == null) { continue; } dirFilter.put(fieldName, e.getValue()); } if (dirInfo.isOptional) { // check if filter matches directory default values boolean matches = true; for (Map.Entry<String, Serializable> dirFilterEntry : dirFilter.entrySet()) { Object defaultValue = dirInfo.defaultEntry.get(dirFilterEntry.getKey()); Object filterValue = dirFilterEntry.getValue(); if (defaultValue == null && filterValue != null) { matches = false; } else if (defaultValue != null && !defaultValue.equals(filterValue)) { matches = false; } } if (matches) { optionalDirsMatching.add(dirInfo); } } // compute fulltext Set<String> dirFulltext = new HashSet<String>(); for (String sourceFieldName : fulltext) { final String fieldName = dirInfo.fromSource.get(sourceFieldName); if (fieldName != null) { dirFulltext.add(fieldName); } } // make query to subdirectory DocumentModelList l = dirInfo.getSession().query(dirFilter, dirFulltext, null, fetchReferences); for (DocumentModel entry : l) { final String id = entry.getId(); Map<String, Object> map = maps.get(id); if (map == null) { map = new HashMap<String, Object>(); maps.put(id, map); counts.put(id, 1); } else { counts.put(id, counts.get(id) + 1); } for (Entry<String, String> e : dirInfo.toSource.entrySet()) { map.put(e.getValue(), entry.getProperty(dirInfo.dirSchemaName, e.getKey())); } if (BaseSession.isReadOnlyEntry(entry)) { readOnlyEntries.add(id); } } } // add default entry values for optional dirs for (SubDirectoryInfo dirInfo : optionalDirsMatching) { // add entry for every data found in other dirs Set<String> existingIds = new HashSet<String>( dirInfo .getSession() .getProjection(Collections.<String, Serializable>emptyMap(), dirInfo.idField)); for (Entry<String, Map<String, Object>> result : maps.entrySet()) { final String id = result.getKey(); if (!existingIds.contains(id)) { counts.put(id, counts.get(id) + 1); final Map<String, Object> map = result.getValue(); for (Entry<String, String> e : dirInfo.toSource.entrySet()) { String value = e.getValue(); if (!map.containsKey(value)) { map.put(value, dirInfo.defaultEntry.get(e.getKey())); } } } } } // intersection, ignore entries not in all subdirectories final int numdirs = sourceInfo.subDirectoryInfos.size(); for (Iterator<String> it = maps.keySet().iterator(); it.hasNext(); ) { final String id = it.next(); if (counts.get(id) != numdirs) { it.remove(); } } // now create entries ((ArrayList<?>) results).ensureCapacity(results.size() + maps.size()); for (Entry<String, Map<String, Object>> e : maps.entrySet()) { final String id = e.getKey(); if (seen.containsKey(id)) { log.warn( String.format( "Entry '%s' is present in source '%s' but also in source '%s'. " + "The second one will be ignored.", id, seen.get(id), sourceInfo.source.name)); continue; } final Map<String, Object> map = e.getValue(); seen.put(id, sourceInfo.source.name); final DocumentModel entry = BaseSession.createEntryModel(null, schemaName, id, map, readOnlyEntries.contains(id)); results.add(entry); } } if (orderBy != null && !orderBy.isEmpty()) { directory.orderEntries(results, orderBy); } return results; }
@Override @SuppressWarnings("boxing") public DocumentModelList getEntries() { if (!isCurrentUserAllowed(SecurityConstants.READ)) { return null; } init(); // list of entries final DocumentModelList results = new DocumentModelListImpl(); // entry ids already seen (mapped to the source name) final Map<String, String> seen = new HashMap<String, String>(); Set<String> readOnlyEntries = new HashSet<String>(); for (SourceInfo sourceInfo : sourceInfos) { // accumulated map for each entry final Map<String, Map<String, Object>> maps = new HashMap<String, Map<String, Object>>(); // number of dirs seen for each entry final Map<String, Integer> counts = new HashMap<String, Integer>(); for (SubDirectoryInfo dirInfo : sourceInfo.requiredSubDirectoryInfos) { final DocumentModelList entries = dirInfo.getSession().getEntries(); for (DocumentModel entry : entries) { final String id = entry.getId(); // find or create map for this entry Map<String, Object> map = maps.get(id); if (map == null) { map = new HashMap<String, Object>(); maps.put(id, map); counts.put(id, 1); } else { counts.put(id, counts.get(id) + 1); } // put entry data in map for (Entry<String, String> e : dirInfo.toSource.entrySet()) { map.put(e.getValue(), entry.getProperty(dirInfo.dirSchemaName, e.getKey())); } if (BaseSession.isReadOnlyEntry(entry)) { readOnlyEntries.add(id); } } } for (SubDirectoryInfo dirInfo : sourceInfo.optionalSubDirectoryInfos) { final DocumentModelList entries = dirInfo.getSession().getEntries(); Set<String> existingIds = new HashSet<String>(); for (DocumentModel entry : entries) { final String id = entry.getId(); final Map<String, Object> map = maps.get(id); if (map != null) { existingIds.add(id); // put entry data in map for (Entry<String, String> e : dirInfo.toSource.entrySet()) { map.put(e.getValue(), entry.getProperty(dirInfo.dirSchemaName, e.getKey())); } } else { log.warn( String.format( "Entry '%s' for source '%s' is present in optional directory '%s' " + "but not in any required one. " + "It will be skipped.", id, sourceInfo.source.name, dirInfo.dirName)); } } for (Entry<String, Map<String, Object>> mapEntry : maps.entrySet()) { if (!existingIds.contains(mapEntry.getKey())) { final Map<String, Object> map = mapEntry.getValue(); // put entry data in map for (Entry<String, String> e : dirInfo.toSource.entrySet()) { // fill with default values for this directory if (!map.containsKey(e.getValue())) { map.put(e.getValue(), dirInfo.defaultEntry.get(e.getKey())); } } } } } // now create entries for all full maps int numdirs = sourceInfo.requiredSubDirectoryInfos.size(); ((ArrayList<?>) results).ensureCapacity(results.size() + maps.size()); for (Entry<String, Map<String, Object>> e : maps.entrySet()) { final String id = e.getKey(); if (seen.containsKey(id)) { log.warn( String.format( "Entry '%s' is present in source '%s' but also in source '%s'. " + "The second one will be ignored.", id, seen.get(id), sourceInfo.source.name)); continue; } final Map<String, Object> map = e.getValue(); if (counts.get(id) != numdirs) { log.warn( String.format( "Entry '%s' for source '%s' is not present in all directories. " + "It will be skipped.", id, sourceInfo.source.name)); continue; } seen.put(id, sourceInfo.source.name); final DocumentModel entry = BaseSession.createEntryModel(null, schemaName, id, map, readOnlyEntries.contains(id)); results.add(entry); } } return results; }
@Test public void testWriteOperations() throws Exception { // ------------------------------------------------------ // Check #createFolder // ------------------------------------------------------ // Not allowed to create a folder in a non FolderItem try { fileSystemItemManagerService.createFolder( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(), "A new folder", principal); fail("Folder creation in a non folder item should fail."); } catch (NuxeoException e) { assertEquals( String.format( "Cannot create a folder in file system item with id %s because it is not a folder but is: " + "DocumentBackedFileItem(id=\"%s\", name=\"Joe.odt\")", DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(), DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId()), e.getMessage()); } // Folder creation FolderItem newFolderItem = fileSystemItemManagerService.createFolder( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), "A new folder", principal); assertNotNull(newFolderItem); assertEquals(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), newFolderItem.getParentId()); assertEquals("A new folder", newFolderItem.getName()); DocumentModelList folderChildren = session.query( String.format( "select * from Document where ecm:parentId = '%s' and ecm:primaryType = 'Folder' order by dc:title asc", folder.getId())); DocumentModel newFolder = folderChildren.get(0); assertTrue(newFolder.isFolder()); assertEquals("A new folder", newFolder.getTitle()); // Parent folder children check assertEquals( 6, fileSystemItemManagerService .getChildren(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), principal) .size()); // ------------------------------------------------------ // Check #createFile // ------------------------------------------------------ // File creation Blob blob = new StringBlob("Content of a new file."); blob.setFilename("New file.odt"); blob.setMimeType("application/vnd.oasis.opendocument.text"); FileItem fileItem = fileSystemItemManagerService.createFile(newFolderItem.getId(), blob, principal); assertNotNull(fileItem); assertEquals(newFolderItem.getId(), fileItem.getParentId()); assertEquals("New file.odt", fileItem.getName()); folderChildren = session.query( String.format("select * from Document where ecm:parentId = '%s'", newFolder.getId())); assertEquals(1, folderChildren.size()); DocumentModel newFile = folderChildren.get(0); assertEquals("File", newFile.getType()); assertEquals("New file.odt", newFile.getTitle()); assertEquals("/syncRoot1/aFolder/A new folder/New file.odt", newFile.getPathAsString()); Blob newFileBlob = (Blob) newFile.getPropertyValue("file:content"); assertEquals("New file.odt", newFileBlob.getFilename()); assertEquals("Content of a new file.", newFileBlob.getString()); assertEquals( "nxfile/test/" + newFile.getId() + "/blobholder:0/New%20file.odt", fileItem.getDownloadURL()); assertEquals("MD5", fileItem.getDigestAlgorithm()); assertEquals(newFileBlob.getDigest(), fileItem.getDigest()); // Parent folder children check assertEquals( 1, fileSystemItemManagerService.getChildren(newFolderItem.getId(), principal).size()); // ------------------------------------------------------ // Check #updateFile // ------------------------------------------------------ String fileItemId = fileItem.getId(); String fileItemParentId = fileItem.getParentId(); blob = new StringBlob("Modified content of an existing file."); fileItem = fileSystemItemManagerService.updateFile(fileItemId, blob, principal); assertNotNull(fileItem); assertEquals(fileItemId, fileItem.getId()); assertEquals(fileItemParentId, fileItem.getParentId()); assertEquals("New file.odt", fileItem.getName()); folderChildren = session.query( String.format("select * from Document where ecm:parentId = '%s'", newFolder.getId())); assertEquals(1, folderChildren.size()); DocumentModel updatedFile = folderChildren.get(0); assertEquals("File", updatedFile.getType()); assertEquals("New file.odt", updatedFile.getTitle()); assertEquals("/syncRoot1/aFolder/A new folder/New file.odt", updatedFile.getPathAsString()); Blob updatedFileBlob = (Blob) updatedFile.getPropertyValue("file:content"); assertEquals("New file.odt", updatedFileBlob.getFilename()); assertEquals("Modified content of an existing file.", updatedFileBlob.getString()); assertEquals( "nxfile/test/" + updatedFile.getId() + "/blobholder:0/New%20file.odt", fileItem.getDownloadURL()); assertEquals("MD5", fileItem.getDigestAlgorithm()); assertEquals(updatedFileBlob.getDigest(), fileItem.getDigest()); // ------------------------------------------------------ // Check #delete // ------------------------------------------------------ // File deletion fileSystemItemManagerService.delete( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + updatedFile.getId(), principal); updatedFile = session.getDocument(new IdRef(updatedFile.getId())); assertEquals("deleted", updatedFile.getCurrentLifeCycleState()); // Parent folder children check assertTrue( fileSystemItemManagerService.getChildren(newFolderItem.getId(), principal).isEmpty()); // ------------------------------------------------------ // Check #rename // ------------------------------------------------------ // Folder rename String fsItemId = DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(); FileSystemItem fsItem = fileSystemItemManagerService.rename(fsItemId, "Jack's folder has a new name", principal); assertEquals(fsItemId, fsItem.getId()); String expectedSyncRoot1Id = DEFAULT_SYNC_ROOT_ITEM_ID_PREFIX + syncRoot1.getId(); assertEquals(expectedSyncRoot1Id, fsItem.getParentId()); assertEquals("Jack's folder has a new name", fsItem.getName()); folder = session.getDocument(folder.getRef()); assertEquals("Jack's folder has a new name", folder.getTitle()); // File rename with title != filename // => should rename filename but not title assertEquals("aFile", file.getTitle()); assertEquals("Joe.odt", ((Blob) file.getPropertyValue("file:content")).getFilename()); fsItemId = DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(); fsItem = fileSystemItemManagerService.rename(fsItemId, "File new name.odt", principal); assertEquals(fsItemId, fsItem.getId()); assertEquals(DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + folder.getId(), fsItem.getParentId()); assertEquals("File new name.odt", fsItem.getName()); file = session.getDocument(file.getRef()); assertEquals("aFile", file.getTitle()); Blob fileBlob = (Blob) file.getPropertyValue("file:content"); assertEquals("File new name.odt", fileBlob.getFilename()); fileItem = (FileItem) fsItem; assertEquals( "nxfile/test/" + file.getId() + "/blobholder:0/File%20new%20name.odt", fileItem.getDownloadURL()); assertEquals("MD5", fileItem.getDigestAlgorithm()); assertEquals(fileBlob.getDigest(), fileItem.getDigest()); // File rename with title == filename // => should rename filename and title blob = new StringBlob("File for a doc with title == filename."); blob.setFilename("Title-filename equality.odt"); blob.setMimeType("application/vnd.oasis.opendocument.text"); fileItem = fileSystemItemManagerService.createFile(newFolderItem.getId(), blob, principal); // Note that the PathSegmentService truncates doc title at 24 characters newFile = session.getDocument( new PathRef("/syncRoot1/aFolder/A new folder/Title-filename equality.")); assertEquals("Title-filename equality.odt", newFile.getTitle()); assertEquals( "Title-filename equality.odt", ((Blob) newFile.getPropertyValue("file:content")).getFilename()); fileItem = (FileItem) fileSystemItemManagerService.rename( DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + newFile.getId(), "Renamed title-filename equality.odt", principal); assertEquals("Renamed title-filename equality.odt", fileItem.getName()); newFile = session.getDocument(newFile.getRef()); assertEquals("Renamed title-filename equality.odt", newFile.getTitle()); newFileBlob = (Blob) newFile.getPropertyValue("file:content"); assertEquals("Renamed title-filename equality.odt", newFileBlob.getFilename()); assertEquals( "nxfile/test/" + newFile.getId() + "/blobholder:0/Renamed%20title-filename%20equality.odt", fileItem.getDownloadURL()); assertEquals("MD5", fileItem.getDigestAlgorithm()); assertEquals(newFileBlob.getDigest(), fileItem.getDigest()); // ------------------------------------------------------ // Check #move // ------------------------------------------------------ // Not allowed to move a file system item to a non FolderItem String srcFsItemId = DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + note.getId(); String destFsItemId = DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId(); try { fileSystemItemManagerService.move(srcFsItemId, destFsItemId, principal); fail("Move to a non folder item should fail."); } catch (NuxeoException e) { assertEquals( String.format( "Cannot move a file system item to file system item with id %s because it is not a folder.", DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + file.getId()), e.getMessage()); } // Move to a FolderItem destFsItemId = DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX + subFolder.getId(); FileSystemItem movedFsItem = fileSystemItemManagerService.move(srcFsItemId, destFsItemId, principal); assertEquals(srcFsItemId, movedFsItem.getId()); assertEquals(destFsItemId, movedFsItem.getParentId()); assertEquals("aNote.txt", movedFsItem.getName()); note = session.getDocument(note.getRef()); assertEquals("/syncRoot1/aFolder/aSubFolder/aNote", note.getPathAsString()); assertEquals("aNote", note.getTitle()); }
@Test public void documentManagementInTestCasesExample() throws ClientException { SchemaManager typeService = Framework.getLocalService(SchemaManager.class); DocumentType[] types = typeService.getDocumentTypes(); for (DocumentType type : types) { System.out.println(type.getName()); } DocumentModel mydoc = session.createDocumentModel("File"); // DocumentModel mydoc = session.createDocumentModel("/", "toto", // "File"); mydoc.setPathInfo("/", "toto"); mydoc.setPropertyValue("dc:title", "Toto"); mydoc = session.createDocument(mydoc); session.save(); DocumentModelList docs = session.query("SELECT * FROM Document WHERE dc:title = 'Toto'"); assertEquals(1, docs.size()); mydoc = docs.get(0); assertEquals("toto", mydoc.getName()); assertEquals("project", mydoc.getCurrentLifeCycleState()); for (String state : mydoc.getAllowedStateTransitions()) { System.out.println("Transition : " + state); } // session.followTransition(mydoc.getRef(), "approve"); mydoc.followTransition("approve"); mydoc.setPropertyValue("dc:description", "My Description"); mydoc = session.saveDocument(mydoc); session.save(); assertEquals("approved", mydoc.getCurrentLifeCycleState()); assertEquals("0.0", mydoc.getVersionLabel()); assertEquals(0, session.getVersions(mydoc.getRef()).size()); session.checkIn(mydoc.getRef(), VersioningOption.MINOR, ""); mydoc = session.getDocument(mydoc.getRef()); assertEquals("0.1", mydoc.getVersionLabel()); assertEquals(1, session.getVersions(mydoc.getRef()).size()); DocumentModel folder = session.createDocumentModel("/", "folder", "Folder"); folder.setPropertyValue("dc:title", "Folder"); folder = session.createDocument(folder); session.save(); assertEquals(0, session.getChildren(folder.getRef()).size()); session.publishDocument(mydoc, folder); assertEquals(1, session.getChildren(folder.getRef()).size()); DocumentModel folder2 = session.createDocumentModel("/", "folder2", "Folder"); folder2.setPropertyValue("dc:title", "Folder2"); folder2 = session.createDocument(folder2); session.save(); DocumentModel proxy = session.createProxy(mydoc.getRef(), folder2.getRef()); assertEquals("Toto", proxy.getPropertyValue("dc:title")); mydoc.setPropertyValue("dc:title", "Tutu"); session.saveDocument(mydoc); session.save(); proxy = session.getDocument(proxy.getRef()); assertEquals("Tutu", proxy.getPropertyValue("dc:title")); proxy.setPropertyValue("dc:title", "Tata"); session.saveDocument(proxy); session.save(); mydoc = session.getDocument(mydoc.getRef()); assertEquals("Tata", mydoc.getPropertyValue("dc:title")); }
@Test public void shouldFilterTreeOnSecurity() throws Exception { buildAndIndexTree(); DocumentModelList docs = ess.query(new NxQueryBuilder(session).nxql("select * from Document")); Assert.assertEquals(10, docs.totalSize()); // check for user with no rights startTransaction(); CoreSession restrictedSession = getRestrictedSession("toto"); try { docs = ess.query(new NxQueryBuilder(restrictedSession).nxql("select * from Document")); Assert.assertEquals(0, docs.totalSize()); // add READ rights and check that user now has access DocumentRef ref = new PathRef("/folder0/folder1/folder2"); ACP acp = new ACPImpl(); ACL acl = ACPImpl.newACL(ACL.LOCAL_ACL); acl.add(new ACE("toto", SecurityConstants.READ, true)); acp.addACL(acl); session.setACP(ref, acp, true); TransactionHelper.commitOrRollbackTransaction(); waitForCompletion(); if (syncMode) { // in sync we split recursive update into 2 commands: // 1 sync non recurse + 1 async recursive assertNumberOfCommandProcessed(9); } else { assertNumberOfCommandProcessed(8); } startTransaction(); docs = ess.query(new NxQueryBuilder(restrictedSession).nxql("select * from Document")); Assert.assertEquals(8, docs.totalSize()); // block rights and check that blocking is taken into account ref = new PathRef("/folder0/folder1/folder2/folder3/folder4/folder5"); acp = new ACPImpl(); acl = ACPImpl.newACL(ACL.LOCAL_ACL); acl.add(new ACE(SecurityConstants.EVERYONE, SecurityConstants.EVERYTHING, false)); acl.add(new ACE("Administrator", SecurityConstants.EVERYTHING, true)); acp.addACL(acl); session.setACP(ref, acp, true); session.save(); TransactionHelper.commitOrRollbackTransaction(); waitForCompletion(); if (syncMode) { assertNumberOfCommandProcessed(6); } else { assertNumberOfCommandProcessed(5); } startTransaction(); docs = ess.query(new NxQueryBuilder(restrictedSession).nxql("select * from Document")); Assert.assertEquals(3, docs.totalSize()); } finally { restrictedSession.close(); } }
@Test public void testReadAclAfterCreate() { DocumentModel folder = new DocumentModelImpl("/", "folder", "Folder"); folder = session.createDocument(folder); session.save(); // folder can be seen by a member UserPrincipal joeMember = new UserPrincipal("joe", Arrays.asList("Everyone", "members"), false, false); try (CoreSession joeSession = openSessionAs(joeMember)) { DocumentModelList list = joeSession.query("SELECT * FROM Folder"); assertEquals(1, list.size()); assertEquals(folder.getId(), list.get(0).getId()); } // but not as a non-member try (CoreSession joeSession = openSessionAs("joe")) { DocumentModelList list = joeSession.query("SELECT * FROM Folder"); assertEquals(0, list.size()); } // set ACL on folder ACL acl = new ACLImpl(); acl.add(new ACE("Everyone", "Read", true)); ACP acp = new ACPImpl(); acp.addACL(acl); folder.setACP(acp, true); session.save(); // the folder can be seen by joe try (CoreSession joeSession = openSessionAs("joe")) { DocumentModelList list = joeSession.query("SELECT * FROM Folder"); assertEquals(1, list.size()); assertEquals(folder.getId(), list.get(0).getId()); } // create a doc under the folder DocumentModel doc = new DocumentModelImpl("/folder", "doc", "File"); doc = session.createDocument(doc); session.save(); // the doc can be seen by joe try (CoreSession joeSession = openSessionAs("joe")) { DocumentModelList list = joeSession.query("SELECT * FROM File"); assertEquals(1, list.size()); assertEquals(doc.getId(), list.get(0).getId()); } }
@Test public void testReadAclSecurity() { // Check that all permissions that contain Browse enable to list a // document using aclOptimization SecurityService securityService = NXCore.getSecurityService(); String[] browsePermissions = securityService.getPermissionsToCheck(BROWSE); // Check for test permission contribution assertTrue(Arrays.asList(browsePermissions).contains("ViewTest")); List<String> docNames = new ArrayList<String>(browsePermissions.length); DocumentModel root = session.getRootDocument(); for (String permission : browsePermissions) { // Create a folder with only the browse permission String name = "joe-has-" + permission + "-permission"; docNames.add(name); DocumentModel folder = new DocumentModelImpl(root.getPathAsString(), name, "Folder"); folder = session.createDocument(folder); ACP acp = folder.getACP(); assertNotNull(acp); // the acp inherited from root is returned acp = new ACPImpl(); ACL acl = new ACLImpl(); acl.add(new ACE("joe", permission, true)); acp.addACL(acl); folder.setACP(acp, true); } session.save(); CoreSession joeSession = openSessionAs("joe"); try { DocumentModelList list; list = joeSession.query("SELECT * FROM Folder"); List<String> names = new ArrayList<String>(); for (DocumentModel doc : list) { names.add(doc.getName()); } assertEquals( "Expecting " + docNames + " got " + names, browsePermissions.length, list.size()); list = joeSession.query("SELECT * FROM Folder WHERE ecm:isProxy = 0"); names.clear(); for (DocumentModel doc : list) { names.add(doc.getName()); } assertEquals( "Expecting " + docNames + " got " + names, browsePermissions.length, list.size()); // Add a new folder to update the read acls DocumentModel folder = new DocumentModelImpl(root.getPathAsString(), "new-folder", "Folder"); folder = session.createDocument(folder); ACP acp = folder.getACP(); assertNotNull(acp); // the acp inherited from root is returned acp = new ACPImpl(); ACL acl = new ACLImpl(); acl.add(new ACE("joe", browsePermissions[0], true)); acl.add(new ACE("bob", browsePermissions[0], true)); acp.addACL(acl); folder.setACP(acp, true); session.save(); list = joeSession.query("SELECT * FROM Folder"); assertEquals(browsePermissions.length + 1, list.size()); } finally { closeSession(joeSession); } }