Files
alfresco-community-repo/source/test-java/org/alfresco/rest/api/tests/TestCMIS.java
Jan Vonka 32f51213e7 Merged 5.1.N (5.1.3) to 5.2.N (5.2.1)
135682 jvonka: Merged 5.0.N (5.0.5) to 5.1.N (5.1.3)
      135680 jvonka: Merged V4.2-BUG-FIX (4.2.8) to 5.0.N (5.0.5)
         135657 jvonka: Merged 5.0.N (5.0.5) to V4.2-BUG-FIX (4.2.8)
             REPO-2110 / MNT-17477: CMIS: SXSS+CSRF vulnerability (browser binding)
                  - tweak test (for unexpected NPE in 4.2)
                  - resolve backport conflict


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@135684 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
2017-03-07 16:26:57 +00:00

2790 lines
129 KiB
Java

/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.io.StringWriter;
import java.math.BigInteger;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.alfresco.cmis.client.AlfrescoDocument;
import org.alfresco.cmis.client.AlfrescoFolder;
import org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl;
import org.alfresco.cmis.client.type.AlfrescoType;
import org.alfresco.model.ContentModel;
import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
import org.alfresco.opencmis.PublicApiAlfrescoCmisServiceFactory;
import org.alfresco.opencmis.dictionary.CMISStrictDictionaryService;
import org.alfresco.opencmis.dictionary.QNameFilter;
import org.alfresco.opencmis.dictionary.QNameFilterImpl;
import org.alfresco.opencmis.mapping.NodeRefProperty;
import org.alfresco.repo.action.ActionModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.filestore.FileContentWriter;
import org.alfresco.repo.dictionary.DictionaryBootstrap;
import org.alfresco.repo.dictionary.DictionaryDAO;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.repo.version.VersionableAspectTest;
import org.alfresco.rest.api.tests.RepoService.SiteInformation;
import org.alfresco.rest.api.tests.RepoService.TestNetwork;
import org.alfresco.rest.api.tests.RepoService.TestPerson;
import org.alfresco.rest.api.tests.RepoService.TestSite;
import org.alfresco.rest.api.tests.client.HttpResponse;
import org.alfresco.rest.api.tests.client.PublicApiClient.CmisSession;
import org.alfresco.rest.api.tests.client.PublicApiClient.Comments;
import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse;
import org.alfresco.rest.api.tests.client.PublicApiClient.Nodes;
import org.alfresco.rest.api.tests.client.PublicApiClient.Sites;
import org.alfresco.rest.api.tests.client.PublicApiException;
import org.alfresco.rest.api.tests.client.RequestContext;
import org.alfresco.rest.api.tests.client.data.CMISNode;
import org.alfresco.rest.api.tests.client.data.Comment;
import org.alfresco.rest.api.tests.client.data.FolderNode;
import org.alfresco.rest.api.tests.client.data.MemberOfSite;
import org.alfresco.rest.api.tests.client.data.NodeRating;
import org.alfresco.rest.api.tests.client.data.NodeRating.Aggregate;
import org.alfresco.rest.api.tests.client.data.Person;
import org.alfresco.rest.api.tests.client.data.SiteRole;
import org.alfresco.rest.api.tests.client.data.Tag;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockType;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.alfresco.util.TempFileProvider;
import org.apache.chemistry.opencmis.client.api.CmisObject;
import org.apache.chemistry.opencmis.client.api.Document;
import org.apache.chemistry.opencmis.client.api.FileableCmisObject;
import org.apache.chemistry.opencmis.client.api.Folder;
import org.apache.chemistry.opencmis.client.api.ItemIterable;
import org.apache.chemistry.opencmis.client.api.ObjectId;
import org.apache.chemistry.opencmis.client.api.ObjectType;
import org.apache.chemistry.opencmis.client.api.OperationContext;
import org.apache.chemistry.opencmis.client.api.Property;
import org.apache.chemistry.opencmis.client.api.Relationship;
import org.apache.chemistry.opencmis.client.api.Repository;
import org.apache.chemistry.opencmis.client.api.SecondaryType;
import org.apache.chemistry.opencmis.client.api.Session;
import org.apache.chemistry.opencmis.client.api.SessionFactory;
import org.apache.chemistry.opencmis.client.api.Tree;
import org.apache.chemistry.opencmis.client.runtime.OperationContextImpl;
import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.SessionParameter;
import org.apache.chemistry.opencmis.commons.data.ContentStream;
import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.extensions.surf.util.URLEncoder;
public class TestCMIS extends EnterpriseTestApi
{
private static final String CMIS_VERSION_10 = "1.0";
private static final String CMIS_VERSION_11 = "1.1";
private static final String TYPE_CMIS_DOCUMENT = "cmis:document";
private static final String DOCUMENT_LIBRARY_CONTAINER_NAME = "documentLibrary";
private static final String TEST_SITE_NAME_PATTERN = "testSite-%d";
private static final String TEST_USER_NAME_PATTERN = "testUser-%d";
private static final String TEST_DOCUMENT_NAME_PATTERN = "testDocument-%s.txt";
private static final String DOCUMENT_LIBRARY_PATH_PATTERN = "/Sites/%s/" + DOCUMENT_LIBRARY_CONTAINER_NAME;
private static final String TEST_PASSWORD = "password";
private ApplicationContext ctx;
private DictionaryDAO dictionaryDAO;
private LockService lockService;
private TenantService tenantService;
private CMISStrictDictionaryService cmisDictionary;
private QNameFilter cmisTypeExclusions;
private NodeService nodeService;
private PermissionService permissionService;
private Properties globalProperties;
@Before
public void before() throws Exception
{
ctx = getTestFixture().getApplicationContext();
this.dictionaryDAO = (DictionaryDAO)ctx.getBean("dictionaryDAO");
this.lockService = (LockService) ctx.getBean("lockService");
this.tenantService = (TenantService)ctx.getBean("tenantService");
this.cmisDictionary = (CMISStrictDictionaryService)ctx.getBean("OpenCMISDictionaryService");
this.cmisTypeExclusions = (QNameFilter)ctx.getBean("cmisTypeExclusions");
this.nodeService = (NodeService) ctx.getBean("NodeService");
this.permissionService = (PermissionService) ctx.getBean("permissionService");
this.globalProperties = (Properties) ctx.getBean("global-properties");
this.globalProperties.setProperty(VersionableAspectTest.AUTO_VERSION_PROPS_KEY, "true");
}
@After
public void after()
{
this.globalProperties.setProperty(VersionableAspectTest.AUTO_VERSION_PROPS_KEY, "false");
}
private void checkSecondaryTypes(Document doc, Set<String> expectedSecondaryTypes, Set<String> expectedMissingSecondaryTypes)
{
final List<SecondaryType> secondaryTypesList = doc.getSecondaryTypes();
assertNotNull(secondaryTypesList);
List<String> secondaryTypes = new AbstractList<String>()
{
@Override
public String get(int index)
{
SecondaryType type = secondaryTypesList.get(index);
return type.getId();
}
@Override
public int size()
{
return secondaryTypesList.size();
}
};
if(expectedSecondaryTypes != null)
{
assertTrue("Missing secondary types: " + secondaryTypes, secondaryTypes.containsAll(expectedSecondaryTypes));
}
if(expectedMissingSecondaryTypes != null)
{
assertTrue("Expected missing secondary types but at least one is still present: " + secondaryTypes, !secondaryTypes.containsAll(expectedMissingSecondaryTypes));
}
}
/**
* ACE-5753 / REPO-1815 Check the return from http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/browser/root
* @throws Exception
*/
@Test
public void testBrowserBindingRoot() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
Iterator<String> personIt = network1.getPersonIds().iterator();
final String personId = personIt.next();
assertNotNull(personId);
Person person = repoService.getPerson(personId);
assertNotNull(person);
publicApiClient.setRequestContext(new RequestContext(network1.getId(), personId));
HttpResponse response = publicApiClient.get(network1.getId() + "/public/cmis/versions/1.1/browser/root", null);
assertEquals(200, response.getStatusCode());
}
/**
* REPO-2041 / MNT-16236 Upload via cmis binding atom and browser files with different maxContentSize
*/
@Test
public void testSetMaxContentSize() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
Iterator<String> personIt = network1.getPersonIds().iterator();
final String personId = personIt.next();
assertNotNull(personId);
// Create a site
final TestSite site = TenantUtil.runAsUserTenant(new TenantRunAsWork<TestSite>()
{
@Override
public TestSite doWork() throws Exception
{
String siteName = "site" + System.currentTimeMillis();
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = network1.createSite(siteInfo);
return site;
}
}, personId, network1.getId());
publicApiClient.setRequestContext(new RequestContext(network1.getId(), personId));
CmisSession cmisSessionAtom = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11, AlfrescoObjectFactoryImpl.class.getName());
CmisSession cmisSessionBrowser = publicApiClient.createPublicApiCMISSession(Binding.browser, CMIS_VERSION_11, AlfrescoObjectFactoryImpl.class.getName());
Folder documentLibrary = (Folder)cmisSessionAtom.getObjectByPath("/Sites/" + site.getSiteId() + "/documentLibrary");
// create file for upload
String fileName = "test+" + GUID.generate();
long fileLength = 6291456L; // 6MB
RandomAccessFile f = new RandomAccessFile(fileName, "rw");
f.setLength(fileLength);
Map<String, Serializable> properties = new HashMap<String, Serializable>();
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, fileName);
// change maxContentSize so that the file will be to big
double maxContentSize = 5.8; // 5MB
PublicApiAlfrescoCmisServiceFactory publicApiAlfrescoCmisServiceFactory = (PublicApiAlfrescoCmisServiceFactory) ctx.getBean("publicApiCMISServiceFactory");
publicApiAlfrescoCmisServiceFactory.setMaxContentSize(maxContentSize);
// for atom
FileChannel fc = f.getChannel();
InputStream is = Channels.newInputStream(fc);
ContentStreamImpl contentStream = new ContentStreamImpl(fileName, BigInteger.valueOf(fileLength), MimetypeMap.MIMETYPE_TEXT_PLAIN,
is);
try
{
cmisSessionAtom.createDocument(documentLibrary.getId(), fileName, properties, contentStream, VersioningState.MAJOR);
fail("The file should be to big to upload via atom binding");
}
catch(CmisConstraintException e)
{
}
// for browser
fc.position(0);
try
{
cmisSessionBrowser.createDocument(documentLibrary.getId(), fileName, properties, contentStream, VersioningState.MAJOR);
fail("The file should be to big to upload via browser binding");
}
catch(CmisConstraintException e)
{
}
// increase maxContensize so that the file is not to big
maxContentSize = 10.6; // 10MB
publicApiAlfrescoCmisServiceFactory.setMaxContentSize(maxContentSize);
// for atom
fc.position(0);
Document result = cmisSessionAtom.createDocument(documentLibrary.getId(), fileName, properties, contentStream, VersioningState.MAJOR);
assertNotNull(result);
// for browser
fc.position(0);
result = cmisSessionBrowser.createDocument(documentLibrary.getId(), fileName + "2", properties, contentStream, VersioningState.MAJOR);
assertNotNull(result);
// ignore the size check
maxContentSize = -1;
publicApiAlfrescoCmisServiceFactory.setMaxContentSize(maxContentSize);
// for atom
fc.position(0);
result = cmisSessionAtom.createDocument(documentLibrary.getId(), fileName + "3", properties, contentStream, VersioningState.MAJOR);
assertNotNull(result);
// for browser
fc.position(0);
result = cmisSessionBrowser.createDocument(documentLibrary.getId(), fileName + "4", properties, contentStream, VersioningState.MAJOR);
assertNotNull(result);
}
/**
* Tests OpenCMIS api.
*/
@SuppressWarnings("unchecked")
@Test
public void testCMIS() throws Exception
{
// Test Case cloud-2353
// Test Case cloud-2354
// Test Case cloud-2356
// Test Case cloud-2378
// Test Case cloud-2357
// Test Case cloud-2358
// Test Case cloud-2360
final TestNetwork network1 = getTestFixture().getRandomNetwork();
Iterator<String> personIt = network1.getPersonIds().iterator();
final String personId = personIt.next();
assertNotNull(personId);
Person person = repoService.getPerson(personId);
assertNotNull(person);
// Create a site
final TestSite site = TenantUtil.runAsUserTenant(new TenantRunAsWork<TestSite>()
{
@Override
public TestSite doWork() throws Exception
{
String siteName = "site" + System.currentTimeMillis();
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = network1.createSite(siteInfo);
return site;
}
}, personId, network1.getId());
publicApiClient.setRequestContext(new RequestContext(network1.getId(), personId));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName());
Nodes nodesProxy = publicApiClient.nodes();
Comments commentsProxy = publicApiClient.comments();
String expectedContent = "Ipsum and so on";
Document doc = null;
Folder documentLibrary = (Folder)cmisSession.getObjectByPath("/Sites/" + site.getSiteId() + "/documentLibrary");
FolderNode expectedDocumentLibrary = (FolderNode)CMISNode.createNode(documentLibrary);
Document testDoc = null;
Folder testFolder = null;
FolderNode testFolderNode = null;
// create some sub-folders and documents
{
for(int i = 0; i < 3; i++)
{
Map<String, String> properties = new HashMap<String, String>();
{
properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:folder");
properties.put(PropertyIds.NAME, "folder-" + i);
}
Folder f = documentLibrary.createFolder(properties);
FolderNode fn = (FolderNode)CMISNode.createNode(f);
if(testFolder == null)
{
testFolder = f;
testFolderNode = fn;
}
expectedDocumentLibrary.addFolder(fn);
for(int k = 0; k < 3; k++)
{
properties = new HashMap<String, String>();
{
properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:folder");
properties.put(PropertyIds.NAME, "folder-" + k);
}
Folder f1 = f.createFolder(properties);
FolderNode childFolder = (FolderNode)CMISNode.createNode(f1);
fn.addFolder(childFolder);
}
for(int j = 0; j < 3; j++)
{
properties = new HashMap<String, String>();
{
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, "doc-" + j);
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent(expectedContent);
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
Document d = f.createDocument(properties, fileContent, VersioningState.MAJOR);
if(testDoc == null)
{
testDoc = d;
}
CMISNode childDocument = CMISNode.createNode(d);
fn.addNode(childDocument);
}
}
for(int i = 0; i < 10; i++)
{
Map<String, String> properties = new HashMap<String, String>();
{
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, "doc-" + i);
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent(expectedContent);
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
documentLibrary.createDocument(properties, fileContent, VersioningState.MAJOR);
}
}
// try to add and remove ratings, comments, tags to folders created by CMIS
{
Aggregate aggregate = new Aggregate(1, null);
NodeRating expectedNodeRating = new NodeRating("likes", true, aggregate);
Comment expectedComment = new Comment("commenty", "commenty", false, null, person, person);
Tag expectedTag = new Tag("taggy");
NodeRating rating = nodesProxy.createNodeRating(testFolder.getId(), expectedNodeRating);
expectedNodeRating.expected(rating);
assertNotNull(rating.getId());
Tag tag = nodesProxy.createNodeTag(testFolder.getId(), expectedTag);
expectedTag.expected(tag);
assertNotNull(tag.getId());
Comment comment = commentsProxy.createNodeComment(testFolder.getId(), expectedComment);
expectedComment.expected(comment);
assertNotNull(comment.getId());
}
// try to add and remove ratings, comments, tags to documents created by CMIS
{
Aggregate aggregate = new Aggregate(1, null);
NodeRating expectedNodeRating = new NodeRating("likes", true, aggregate);
Comment expectedComment = new Comment("commenty", "commenty", false, null, person, person);
Tag expectedTag = new Tag("taggy");
NodeRating rating = nodesProxy.createNodeRating(testDoc.getId(), expectedNodeRating);
expectedNodeRating.expected(rating);
assertNotNull(rating.getId());
Tag tag = nodesProxy.createNodeTag(testDoc.getId(), expectedTag);
expectedTag.expected(tag);
assertNotNull(tag.getId());
Comment comment = commentsProxy.createNodeComment(testDoc.getId(), expectedComment);
expectedComment.expected(comment);
assertNotNull(comment.getId());
}
// descendants
{
List<Tree<FileableCmisObject>> descendants = documentLibrary.getDescendants(4);
expectedDocumentLibrary.checkDescendants(descendants);
}
// upload/setContent
{
Map<String, String> fileProps = new HashMap<String, String>();
{
fileProps.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
fileProps.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt");
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent(expectedContent);
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
doc = documentLibrary.createDocument(fileProps, fileContent, VersioningState.MAJOR);
String nodeId = stripCMISSuffix(doc.getId());
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
ContentReader reader = TenantUtil.runAsUserTenant(new TenantRunAsWork<ContentReader>()
{
@Override
public ContentReader doWork() throws Exception
{
ContentReader reader = repoService.getContent(nodeRef, ContentModel.PROP_CONTENT);
return reader;
}
}, personId, network1.getId());
String actualContent = reader.getContentString();
assertEquals(expectedContent, actualContent);
}
// get content
{
ContentStream stream = doc.getContentStream();
StringWriter writer = new StringWriter();
IOUtils.copy(stream.getStream(), writer, "UTF-8");
String actualContent = writer.toString();
assertEquals(expectedContent, actualContent);
}
// get children
{
Folder folder = (Folder)cmisSession.getObjectByPath("/Sites/" + site.getSiteId() + "/documentLibrary/" + testFolder.getName());
ItemIterable<CmisObject> children = folder.getChildren();
testFolderNode.checkChildren(children);
}
// query
{
Folder folder = (Folder)cmisSession.getObjectByPath("/Sites/" + site.getSiteId() + "/documentLibrary/" + testFolder.getName());
String folderId = folder.getId();
Set<String> expectedFolderNames = new HashSet<String>();
for(CMISNode n : testFolderNode.getFolderNodes().values())
{
expectedFolderNames.add((String)n.getProperty("cmis:name"));
}
int expectedNumFolders = expectedFolderNames.size();
int numMatchingFoldersFound = 0;
List<CMISNode> results = cmisSession.query("SELECT * FROM cmis:folder WHERE IN_TREE('" + folderId + "')", false, 0, Integer.MAX_VALUE);
for(CMISNode node : results)
{
String name = (String)node.getProperties().get("cmis:name");
if(expectedFolderNames.contains(name))
{
numMatchingFoldersFound++;
}
}
assertEquals(expectedNumFolders, numMatchingFoldersFound);
Set<String> expectedDocNames = new HashSet<String>();
for(CMISNode n : testFolderNode.getDocumentNodes().values())
{
expectedDocNames.add((String)n.getProperty("cmis:name"));
}
int expectedNumDocs = expectedDocNames.size();
int numMatchingDocsFound = 0;
results = cmisSession.query("SELECT * FROM cmis:document where IN_TREE('" + folderId + "')", false, 0, Integer.MAX_VALUE);
for(CMISNode node : results)
{
String name = (String)node.getProperties().get("cmis:name");
if(expectedDocNames.contains(name))
{
numMatchingDocsFound++;
}
}
assertEquals(expectedNumDocs, numMatchingDocsFound);
}
// versioning
{
String nodeId = stripCMISSuffix(doc.getId());
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
// checkout
ObjectId pwcId = doc.checkOut();
Document pwc = (Document)cmisSession.getObject(pwcId.getId());
Boolean isCheckedOut = TenantUtil.runAsUserTenant(new TenantRunAsWork<Boolean>()
{
@Override
public Boolean doWork() throws Exception
{
Boolean isCheckedOut = repoService.isCheckedOut(nodeRef);
return isCheckedOut;
}
}, personId, network1.getId());
assertTrue(isCheckedOut);
// checkin with new content
expectedContent = "Big bad wolf";
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent(expectedContent);
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
ObjectId checkinId = pwc.checkIn(true, Collections.EMPTY_MAP, fileContent, "checkin 1");
doc = (Document)cmisSession.getObject(checkinId.getId());
isCheckedOut = TenantUtil.runAsUserTenant(new TenantRunAsWork<Boolean>()
{
@Override
public Boolean doWork() throws Exception
{
Boolean isCheckedOut = repoService.isCheckedOut(nodeRef);
return isCheckedOut;
}
}, personId, network1.getId());
assertFalse(isCheckedOut);
// check that the content has been updated
ContentStream stream = doc.getContentStream();
StringWriter writer = new StringWriter();
IOUtils.copy(stream.getStream(), writer, "UTF-8");
String actualContent = writer.toString();
assertEquals(expectedContent, actualContent);
List<Document> allVersions = doc.getAllVersions();
assertEquals(2, allVersions.size());
assertEquals("2.0", allVersions.get(0).getVersionLabel());
assertEquals(CMIS_VERSION_10, allVersions.get(1).getVersionLabel());
}
{
// https://issues.alfresco.com/jira/browse/PUBLICAPI-95
// Test that documents are created with autoVersion=true
Map<String, String> fileProps = new HashMap<String, String>();
{
fileProps.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
fileProps.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt");
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum and so on");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
{
// a versioned document
Document autoVersionedDoc = documentLibrary.createDocument(fileProps, fileContent, VersioningState.MAJOR);
String objectId = autoVersionedDoc.getId();
String bareObjectId = stripCMISSuffix(objectId);
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, bareObjectId);
Boolean autoVersion = TenantUtil.runAsUserTenant(new TenantRunAsWork<Boolean>()
{
@Override
public Boolean doWork() throws Exception
{
Boolean autoVersion = (Boolean)repoService.getProperty(nodeRef, ContentModel.PROP_AUTO_VERSION);
return autoVersion;
}
}, personId, network1.getId());
assertEquals(Boolean.TRUE, autoVersion);
}
// https://issues.alfresco.com/jira/browse/PUBLICAPI-92
// Test that a get on an objectId without a version suffix returns the current version of the document
{
// do a few checkout, checkin cycles to create some versions
fileProps = new HashMap<String, String>();
{
fileProps.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
fileProps.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt");
}
Document autoVersionedDoc = documentLibrary.createDocument(fileProps, fileContent, VersioningState.MAJOR);
String objectId = autoVersionedDoc.getId();
String bareObjectId = stripCMISSuffix(objectId);
for(int i = 0; i < 3; i++)
{
Document doc1 = (Document)cmisSession.getObject(bareObjectId);
ObjectId pwcId = doc1.checkOut();
Document pwc = (Document)cmisSession.getObject(pwcId.getId());
ContentStreamImpl contentStream = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
expectedContent = GUID.generate();
writer.putContent(expectedContent);
ContentReader reader = writer.getReader();
contentStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
contentStream.setStream(reader.getContentInputStream());
}
pwc.checkIn(true, Collections.EMPTY_MAP, contentStream, "checkin " + i);
}
// get the object, supplying an objectId without a version suffix
Document doc1 = (Document)cmisSession.getObject(bareObjectId);
String versionLabel = doc1.getVersionLabel();
ContentStream cs = doc1.getContentStream();
String content = IOUtils.toString(cs.getStream());
assertEquals("4.0", versionLabel);
assertEquals(expectedContent, content);
}
}
}
/**
* Tests CMIS and non-CMIS public api interactions
*/
@SuppressWarnings("deprecation")
@Test
public void testScenario1() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
Iterator<String> personIt = network1.getPersonIds().iterator();
final String person = personIt.next();
assertNotNull(person);
Sites sitesProxy = publicApiClient.sites();
Comments commentsProxy = publicApiClient.comments();
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName());
ListResponse<MemberOfSite> sites = sitesProxy.getPersonSites(person, null);
assertTrue(sites.getList().size() > 0);
MemberOfSite siteMember = sites.getList().get(0);
String siteId = siteMember.getSite().getSiteId();
Folder documentLibrary = (Folder)cmisSession.getObjectByPath("/Sites/" + siteId + "/documentLibrary");
System.out.println("documentLibrary id = " + documentLibrary.getId());
Map<String, String> fileProps = new HashMap<String, String>();
{
fileProps.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
fileProps.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt");
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum and so on");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
Document doc = documentLibrary.createDocument(fileProps, fileContent, VersioningState.MAJOR);
System.out.println("Document id = " + doc.getId());
Comment c = commentsProxy.createNodeComment(doc.getId(), new Comment("comment title 1", "comment 1"));
System.out.println("Comment = " + c);
// Now lock the document
String nodeRefStr = (String) doc.getPropertyValue("alfcmis:nodeRef");
final NodeRef nodeRef = new NodeRef(nodeRefStr);
final TenantRunAsWork<Void> runAsWork = new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
lockService.lock(nodeRef, LockType.WRITE_LOCK);
return null;
}
};
RetryingTransactionCallback<Void> txnWork = new RetryingTransactionCallback<Void>()
{
@Override
public Void execute() throws Throwable
{
TenantUtil.runAsUserTenant(runAsWork, "bob", network1.getId());
return null;
}
};
transactionHelper.doInTransaction(txnWork);
// Now attempt to update the document's metadata
try
{
doc.delete();
}
catch (CmisUpdateConflictException e)
{
// Expected: ACE-762 BM-0012: NodeLockedException not handled by CMIS
}
}
//@Test
public void testInvalidMethods() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
Iterator<String> personIt = network1.getPersonIds().iterator();
final String person = personIt.next();
assertNotNull(person);
try
{
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person));
publicApiClient.post(Binding.atom, CMIS_VERSION_10, null, null);
fail();
}
catch(PublicApiException e)
{
assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, e.getHttpResponse().getStatusCode());
}
try
{
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person));
publicApiClient.head(Binding.atom, CMIS_VERSION_10, null, null);
fail();
}
catch(PublicApiException e)
{
assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, e.getHttpResponse().getStatusCode());
}
try
{
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person));
publicApiClient.options(Binding.atom, CMIS_VERSION_10, null, null);
fail();
}
catch(PublicApiException e)
{
assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, e.getHttpResponse().getStatusCode());
}
try
{
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person));
publicApiClient.trace(Binding.atom, CMIS_VERSION_10, null, null);
fail();
}
catch(PublicApiException e)
{
assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, e.getHttpResponse().getStatusCode());
}
try
{
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person));
publicApiClient.patch(Binding.atom, CMIS_VERSION_10, null, null);
fail();
}
catch(PublicApiException e)
{
assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, e.getHttpResponse().getStatusCode());
}
}
@Test
public void testPublicApi110() throws Exception
{
Iterator<TestNetwork> networksIt = getTestFixture().networksIterator();
final TestNetwork network1 = networksIt.next();
Iterator<String> personIt = network1.getPersonIds().iterator();
final String person1Id = personIt.next();
final String person2Id = personIt.next();
final List<NodeRef> nodes = new ArrayList<NodeRef>(5);
// Create some favourite targets, sites, files and folders
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
String siteName1 = "site" + GUID.generate();
SiteInformation siteInfo1 = new SiteInformation(siteName1, siteName1, siteName1, SiteVisibility.PUBLIC);
TestSite site1 = network1.createSite(siteInfo1);
String siteName2 = "site" + GUID.generate();
SiteInformation siteInfo2 = new SiteInformation(siteName2, siteName2, siteName2, SiteVisibility.PRIVATE);
TestSite site2 = network1.createSite(siteInfo2);
NodeRef nodeRef1 = repoService.createDocument(site1.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), "Test Doc1", "Test Doc1 Title", "Test Doc1 Description", "Test Content");
nodes.add(nodeRef1);
NodeRef nodeRef2 = repoService.createDocument(site1.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), "Test Doc2", "Test Doc2 Title", "Test Doc2 Description", "Test Content");
nodes.add(nodeRef2);
NodeRef nodeRef3 = repoService.createDocument(site2.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), "Test Doc2", "Test Doc2 Title", "Test Doc2 Description", "Test Content");
nodes.add(nodeRef3);
repoService.createAssociation(nodeRef2, nodeRef1, ContentModel.ASSOC_ORIGINAL);
repoService.createAssociation(nodeRef3, nodeRef1, ContentModel.ASSOC_ORIGINAL);
site1.inviteToSite(person2Id, SiteRole.SiteCollaborator);
return null;
}
}, person1Id, network1.getId());
{
OperationContext cmisOperationCtxOverride = new OperationContextImpl();
cmisOperationCtxOverride.setIncludeRelationships(IncludeRelationships.BOTH);
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person2Id, cmisOperationCtxOverride));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName());
CmisObject o1 = cmisSession.getObject(nodes.get(0).getId());
List<Relationship> relationships = o1.getRelationships();
assertEquals(1, relationships.size());
Relationship r = relationships.get(0);
CmisObject source = r.getSource();
CmisObject target = r.getTarget();
String sourceVersionSeriesId = (String)source.getProperty(PropertyIds.VERSION_SERIES_ID).getFirstValue();
String targetVersionSeriesId = (String)target.getProperty(PropertyIds.VERSION_SERIES_ID).getFirstValue();
assertEquals(nodes.get(1).getId(), sourceVersionSeriesId);
assertEquals(nodes.get(0).getId(), targetVersionSeriesId);
}
}
@Test
public void testObjectIds() throws Exception
{
String username = "enterpriseuser" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person = repoService.createUser(personInfo, username, null);
String personId = person.getId();
final List<NodeRef> folders = new ArrayList<NodeRef>();
final List<NodeRef> documents = new ArrayList<NodeRef>();
AuthenticationUtil.runAs(new RunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
String siteName = "site" + System.currentTimeMillis();
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
String name = GUID.generate();
NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name);
folders.add(folderNodeRef);
name = GUID.generate();
NodeRef docNodeRef = repoService.createDocument(folderNodeRef, name, "test content");
documents.add(docNodeRef);
return null;
}
}, personId);
NodeRef folderNodeRef = folders.get(0);
NodeRef docNodeRef = documents.get(0);
publicApiClient.setRequestContext(new RequestContext(personId));
// use cmisatom endpoint
List<Repository> repositories = publicApiClient.getCMISRepositories();
CmisSession cmisSession = publicApiClient.getCMISSession(repositories.get(0));
// test CMIS accepts NodeRefs and guids as input
// if input is NodeRef, return NodeRef. If input is guid, return guid.
{
String nodeRefStr = docNodeRef.toString();
CmisObject o = cmisSession.getObject(nodeRefStr);
assertEquals(docNodeRef.toString(), stripCMISSuffix(o.getId()));
nodeRefStr = folderNodeRef.toString();
o = cmisSession.getObject(nodeRefStr);
assertEquals(folderNodeRef.toString(), stripCMISSuffix(o.getId()));
String objectId = docNodeRef.getId();
o = cmisSession.getObject(objectId);
assertEquals(objectId, stripCMISSuffix(o.getId()));
objectId = folderNodeRef.getId();
o = cmisSession.getObject(objectId);
assertEquals(objectId, stripCMISSuffix(o.getId()));
}
// query
{
// searching by NodeRef, expect result objectIds to be Noderefs
Set<String> expectedObjectIds = new HashSet<String>();
expectedObjectIds.add(docNodeRef.toString());
int numMatchingDocs = 0;
// NodeRef input
List<CMISNode> results = cmisSession.query("SELECT * FROM cmis:document WHERE IN_TREE('" + folderNodeRef.toString() + "')", false, 0, Integer.MAX_VALUE);
assertEquals(expectedObjectIds.size(), results.size());
for(CMISNode node : results)
{
String objectId = stripCMISSuffix((String)node.getProperties().get(PropertyIds.OBJECT_ID));
if(expectedObjectIds.contains(objectId))
{
numMatchingDocs++;
}
}
assertEquals(expectedObjectIds.size(), numMatchingDocs);
// searching by guid, expect result objectIds to be NodeRefs
numMatchingDocs = 0;
// node guid input
results = cmisSession.query("SELECT * FROM cmis:document WHERE IN_TREE('" + folderNodeRef.getId() + "')", false, 0, Integer.MAX_VALUE);
assertEquals(expectedObjectIds.size(), results.size());
for(CMISNode node : results)
{
String objectId = stripCMISSuffix((String)node.getProperties().get(PropertyIds.OBJECT_ID));
System.out.println("objectId = " + objectId);
if(expectedObjectIds.contains(objectId))
{
numMatchingDocs++;
}
}
assertEquals(expectedObjectIds.size(), numMatchingDocs);
}
// public api
Iterator<TestNetwork> networksIt = getTestFixture().networksIterator();
final TestNetwork network1 = networksIt.next();
Iterator<String> personIt = network1.getPersonIds().iterator();
final String person1Id = personIt.next();
final List<NodeRef> folders1 = new ArrayList<NodeRef>();
final List<NodeRef> documents1 = new ArrayList<NodeRef>();
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
String siteName = "site" + System.currentTimeMillis();
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
String name = GUID.generate();
NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name);
folders1.add(folderNodeRef);
name = GUID.generate();
NodeRef docNodeRef = repoService.createDocument(folderNodeRef, name, "test content");
documents1.add(docNodeRef);
return null;
}
}, person1Id, network1.getId());
folderNodeRef = folders1.get(0);
docNodeRef = documents1.get(0);
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName());
// test CMIS accepts NodeRefs and guids as input
// objectIds returned from public api CMIS are always the guid
{
String nodeRefStr = docNodeRef.toString();
CmisObject o = cmisSession.getObject(nodeRefStr);
String objectId = docNodeRef.getId();
assertEquals(objectId, stripCMISSuffix(o.getId()));
nodeRefStr = folderNodeRef.toString();
o = cmisSession.getObject(nodeRefStr);
objectId = folderNodeRef.getId();
assertEquals(objectId, stripCMISSuffix(o.getId()));
o = cmisSession.getObject(objectId);
assertEquals(objectId, stripCMISSuffix(o.getId()));
objectId = folderNodeRef.getId();
o = cmisSession.getObject(objectId);
assertEquals(objectId, stripCMISSuffix(o.getId()));
}
// query
{
// searching by NodeRef, expect result objectIds to be objectId
Set<String> expectedObjectIds = new HashSet<String>();
expectedObjectIds.add(docNodeRef.getId());
int numMatchingDocs = 0;
// NodeRef input
List<CMISNode> results = cmisSession.query("SELECT * FROM cmis:document WHERE IN_TREE('" + folderNodeRef.toString() + "')", false, 0, Integer.MAX_VALUE);
assertEquals(expectedObjectIds.size(), results.size());
for(CMISNode node : results)
{
String objectId = stripCMISSuffix((String)node.getProperties().get(PropertyIds.OBJECT_ID));
if(expectedObjectIds.contains(objectId))
{
numMatchingDocs++;
}
}
assertEquals(expectedObjectIds.size(), numMatchingDocs);
// searching by guid, expect result objectIds to be objectId
numMatchingDocs = 0;
// node guid input
results = cmisSession.query("SELECT * FROM cmis:document WHERE IN_TREE('" + folderNodeRef.getId() + "')", false, 0, Integer.MAX_VALUE);
assertEquals(expectedObjectIds.size(), results.size());
for(CMISNode node : results)
{
String objectId = stripCMISSuffix((String)node.getProperties().get(PropertyIds.OBJECT_ID));
System.out.println("objectId = " + objectId);
if(expectedObjectIds.contains(objectId))
{
numMatchingDocs++;
}
}
assertEquals(expectedObjectIds.size(), numMatchingDocs);
}
}
@Test
public void testAspects() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
final List<NodeRef> folders = new ArrayList<NodeRef>();
final List<NodeRef> documents = new ArrayList<NodeRef>();
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
String siteName = "site" + System.currentTimeMillis();
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
String name = GUID.generate();
NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name);
folders.add(folderNodeRef);
for(int i = 0; i < 3; i++)
{
name = GUID.generate();
NodeRef docNodeRef = repoService.createDocument(folderNodeRef, name, "test content");
assertFalse(repoService.getAspects(docNodeRef).contains(ContentModel.ASPECT_TITLED));
documents.add(docNodeRef);
}
return null;
}
}, person1Id, network1.getId());
final NodeRef doc1NodeRef = documents.get(0);
final NodeRef doc2NodeRef = documents.get(1);
final NodeRef doc3NodeRef = documents.get(2);
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession atomCmisSession10 = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName());
CmisSession atomCmisSession11 = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11);
CmisSession browserCmisSession11 = publicApiClient.createPublicApiCMISSession(Binding.browser, CMIS_VERSION_11);
// Test that adding aspects works for both 1.0 and 1.1
// 1.0
{
AlfrescoDocument doc = (AlfrescoDocument)atomCmisSession10.getObject(doc1NodeRef.getId());
doc = (AlfrescoDocument)doc.addAspect("P:cm:titled");
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
Set<QName> aspects = repoService.getAspects(doc1NodeRef);
assertTrue("Missing aspect in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED));
return null;
}
}, person1Id, network1.getId());
doc.removeAspect("P:cm:titled");
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
Set<QName> aspects = repoService.getAspects(doc1NodeRef);
assertFalse("Unexpected aspect in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED));
return null;
}
}, person1Id, network1.getId());
}
// 1.1 atom (secondary types)
{
final Document doc = (Document)atomCmisSession11.getObject(doc2NodeRef.getId());
final List<SecondaryType> secondaryTypesList = doc.getSecondaryTypes();
final List<String> secondaryTypes = new ArrayList<String>();
if (secondaryTypesList != null)
{
for(SecondaryType secondaryType : secondaryTypesList)
{
secondaryTypes.add(secondaryType.getId());
}
}
secondaryTypes.add("P:sys:temporary");
secondaryTypes.add("P:cm:titled");
Map<String, Object> properties = new HashMap<String, Object>();
{
// create a document with 2 secondary types
properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes);
}
Document doc1 = (Document)doc.updateProperties(properties);
checkSecondaryTypes(doc1, new HashSet<String>(Arrays.asList(new String[] {"P:sys:temporary", "P:cm:titled"})), null);
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
Set<QName> aspects = repoService.getAspects(doc2NodeRef);
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED));
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TEMPORARY));
return null;
}
}, person1Id, network1.getId());
secondaryTypes.add("P:cm:author");
properties = new HashMap<String, Object>();
{
// create a document with 2 secondary types
properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes);
}
Document doc2 = (Document)doc1.updateProperties(properties);
checkSecondaryTypes(doc2, new HashSet<String>(Arrays.asList(new String[] {"P:sys:temporary", "P:cm:titled", "P:cm:author"})), null);
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
Set<QName> aspects = repoService.getAspects(doc2NodeRef);
String title = (String)repoService.getProperty(doc2NodeRef, ContentModel.PROP_TITLE);
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_AUTHOR));
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TEMPORARY));
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED));
assertEquals(null, title);
return null;
}
}, person1Id, network1.getId());
// remove a secondary type
secondaryTypes.remove("P:cm:titled");
properties = new HashMap<String, Object>();
{
properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes);
}
Document doc3 = (Document)doc2.updateProperties(properties);
checkSecondaryTypes(doc3, new HashSet<String>(Arrays.asList(new String[] {"P:sys:temporary", "P:cm:author"})),
new HashSet<String>(Arrays.asList(new String[] {"P:cm:titled"})));
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
Set<QName> aspects = repoService.getAspects(doc2NodeRef);
String title = (String)repoService.getProperty(doc2NodeRef, ContentModel.PROP_TITLE);
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_AUTHOR));
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TEMPORARY));
assertFalse("Unexpected aspect in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED));
assertEquals(null, title);
return null;
}
}, person1Id, network1.getId());
}
// 1.1 browser (secondary types)
{
Document doc = (Document)browserCmisSession11.getObject(doc3NodeRef.getId());
final List<SecondaryType> secondaryTypesList = doc.getSecondaryTypes();
final List<String> secondaryTypes = new ArrayList<String>();
if (secondaryTypesList != null)
{
for (SecondaryType secondaryType : secondaryTypesList)
{
secondaryTypes.add(secondaryType.getId());
}
}
secondaryTypes.add("P:sys:temporary");
secondaryTypes.add("P:cm:titled");
Map<String, Object> properties = new HashMap<String, Object>();
{
// create a document with 2 secondary types
properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes);
}
Document doc1 = (Document)doc.updateProperties(properties);
checkSecondaryTypes(doc1, new HashSet<String>(Arrays.asList(new String[] {"P:sys:temporary", "P:cm:titled"})), null);
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
Set<QName> aspects = repoService.getAspects(doc3NodeRef);
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED));
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TEMPORARY));
return null;
}
}, person1Id, network1.getId());
secondaryTypes.add("P:cm:author");
properties = new HashMap<String, Object>();
{
// create a document with 2 secondary types
properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes);
}
Document doc2 = (Document)doc1.updateProperties(properties);
checkSecondaryTypes(doc2, new HashSet<String>(Arrays.asList(new String[] {"P:sys:temporary", "P:cm:titled", "P:cm:author"})), null);
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
Set<QName> aspects = repoService.getAspects(doc3NodeRef);
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED));
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TEMPORARY));
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_AUTHOR));
return null;
}
}, person1Id, network1.getId());
secondaryTypes.remove("P:cm:titled");
properties = new HashMap<String, Object>();
{
// create a document with 2 secondary types
properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes);
}
Document doc3 = (Document)doc2.updateProperties(properties);
checkSecondaryTypes(doc3, new HashSet<String>(Arrays.asList(new String[] {"P:sys:temporary", "P:cm:author"})),
new HashSet<String>(Arrays.asList(new String[] {"P:cm:titled"})));
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
Set<QName> aspects = repoService.getAspects(doc3NodeRef);
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_AUTHOR));
assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TEMPORARY));
assertFalse("Unexpected aspect in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED));
return null;
}
}, person1Id, network1.getId());
}
}
/**
* ALF-18968
*
* @see QNameFilterImpl#listOfHardCodedExcludedTypes()
*/
@Test
public void testTypeFiltering() throws Exception
{
// Force an exclusion in order to test the exclusion inheritance
cmisTypeExclusions.setExcluded(ActionModel.TYPE_ACTION_BASE, true);
// Quick check
assertTrue(cmisTypeExclusions.isExcluded(ActionModel.TYPE_ACTION_BASE));
// Test that a type defined with this excluded parent type does not break the CMIS dictionary
DictionaryBootstrap bootstrap = new DictionaryBootstrap();
List<String> bootstrapModels = new ArrayList<String>();
bootstrapModels.add("publicapi/test-model.xml");
bootstrap.setModels(bootstrapModels);
bootstrap.setDictionaryDAO(dictionaryDAO);
bootstrap.setTenantService(tenantService);
bootstrap.bootstrap();
cmisDictionary.afterDictionaryInit();
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
// test that this type is excluded; the 'action' model (act prefix) is in the list of hardcoded exclusions
QName type = QName.createQName("{http://www.alfresco.org/test/testCMIS}type1");
assertTrue(cmisTypeExclusions.isExcluded(type));
// and that we can't get to it through CMIS
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName());
try
{
cmisSession.getTypeDefinition("D:testCMIS:type1");
fail("Type should not be available");
}
catch(CmisObjectNotFoundException e)
{
// ok
}
}
/**
* MNT-12680
* The creation date of version should be the same as creation date of the original node
* @throws Exception
*/
@Test
public void testCreationDate() throws Exception
{
// create a site
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, "password", null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
final String siteName = "site" + System.currentTimeMillis();
TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PUBLIC);
final TestSite site = network1.createSite(siteInfo);
final NodeRef resNode = repoService.createDocument(site.getContainerNodeRef("documentLibrary"), "testdoc.txt", "Test Doc1 Title", "Test Doc1 Description",
"Test Content");
return resNode;
}
}, person1Id, network1.getId());
// create a document
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName());
AlfrescoFolder docLibrary = (AlfrescoFolder) cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary");
Map<String, String> properties = new HashMap<String, String>();
{
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt");
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("some content");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
Document autoVersionedDoc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR);
String objectId = autoVersionedDoc.getId();
String bareObjectId = stripCMISSuffix(objectId);
// create versions
for (int i = 0; i < 3; i++)
{
Document doc1 = (Document) cmisSession.getObject(bareObjectId);
ObjectId pwcId = doc1.checkOut();
Document pwc = (Document) cmisSession.getObject(pwcId.getId());
ContentStreamImpl contentStream = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent(GUID.generate());
ContentReader reader = writer.getReader();
contentStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
contentStream.setStream(reader.getContentInputStream());
}
pwc.checkIn(true, Collections.EMPTY_MAP, contentStream, "checkin " + i);
}
GregorianCalendar cDateFirst = cmisSession.getAllVersions(bareObjectId).get(0).getCreationDate();
GregorianCalendar cDateSecond = cmisSession.getAllVersions(bareObjectId).get(2).getCreationDate();
if (cDateFirst.before(cDateSecond) || cDateFirst.after(cDateSecond))
{
fail("The creation date of version should be the same as creation date of the original node");
}
}
/**
* Test that updating properties does not automatically create a new version.
* Test that updating content creates a new version automatically.
*
*/
@Test
public void testVersioning() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
final String siteName = "site" + System.currentTimeMillis();
TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
String name = GUID.generate();
NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name);
return folderNodeRef;
}
}, person1Id, network1.getId());
// Create a document...
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName());
AlfrescoFolder docLibrary = (AlfrescoFolder)cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary");
Map<String, String> properties = new HashMap<String, String>();
{
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt");
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum and so on");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
AlfrescoDocument doc = (AlfrescoDocument)docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR);
String versionLabel = doc.getVersionLabel();
// ...and check that updating its properties does not create a new version
properties = new HashMap<String, String>();
{
properties.put(PropertyIds.DESCRIPTION, GUID.generate());
}
AlfrescoDocument doc1 = (AlfrescoDocument)doc.updateProperties(properties);
doc1 = (AlfrescoDocument)doc1.getObjectOfLatestVersion(false);
String versionLabel1 = doc1.getVersionLabel();
assertTrue(Float.parseFloat(versionLabel) < Float.parseFloat(versionLabel1));
// ...and check that updating its content creates a new version
fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum and so on and so on");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
doc1.setContentStream(fileContent, true);
AlfrescoDocument doc2 = (AlfrescoDocument)doc1.getObjectOfLatestVersion(false);
@SuppressWarnings("unused")
String versionLabel2 = doc2.getVersionLabel();
assertTrue("Set content stream should create a new version automatically", Float.parseFloat(versionLabel1) < Float.parseFloat(versionLabel2));
}
/**
* Test that updating properties does automatically create a new version if
* <b>autoVersion</b>, <b>initialVersion</b> and <b>autoVersionOnUpdateProps</b> are TRUE
*/
@Test
public void testVersioningUsingUpdateProperties() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, "password", null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
final String siteName = "site" + System.currentTimeMillis();
TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
String name = GUID.generate();
NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef("documentLibrary"), name);
return folderNodeRef;
}
}, person1Id, network1.getId());
// Create a document...
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, "1.0", AlfrescoObjectFactoryImpl.class.getName());
AlfrescoFolder docLibrary = (AlfrescoFolder)cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary");
Map<String, String> properties = new HashMap<String, String>();
{
properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document");
properties.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt");
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum and so on");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
AlfrescoDocument doc = (AlfrescoDocument)docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR);
String versionLabel = doc.getVersionLabel();
String nodeRefStr = doc.getPropertyValue(NodeRefProperty.NodeRefPropertyId).toString();
final NodeRef nodeRef = new NodeRef(nodeRefStr);
TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
// ensure autoversioning is enabled
assertTrue(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE));
Map<QName, Serializable> versionProperties = new HashMap<QName, Serializable>();
versionProperties.put(ContentModel.PROP_AUTO_VERSION, true);
versionProperties.put(ContentModel.PROP_INITIAL_VERSION, true);
versionProperties.put(ContentModel.PROP_AUTO_VERSION_PROPS, true);
nodeService.addProperties(nodeRef, versionProperties);
return null;
}
}, person1Id, network1.getId());
// ...and check that updating its properties creates a new minor version...
properties = new HashMap<String, String>();
{
properties.put(PropertyIds.DESCRIPTION, GUID.generate());
}
AlfrescoDocument doc1 = (AlfrescoDocument)doc.getObjectOfLatestVersion(false).updateProperties(properties);
doc1 = (AlfrescoDocument)doc.getObjectOfLatestVersion(false);
String versionLabel1 = doc1.getVersionLabel();
assertTrue(Double.parseDouble(versionLabel) < Double.parseDouble(versionLabel1));
// ...and check that updating its content creates a new version
fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum and so on and so on");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
doc1.setContentStream(fileContent, true);
AlfrescoDocument doc2 = (AlfrescoDocument)doc1.getObjectOfLatestVersion(false);
String versionLabel2 = doc2.getVersionLabel();
assertTrue("Set content stream should create a new version automatically", Double.parseDouble(versionLabel1) < Double.parseDouble(versionLabel2));
assertTrue("It should be latest version : " + versionLabel2, doc2.isLatestVersion());
doc2.deleteContentStream();
AlfrescoDocument doc3 = (AlfrescoDocument)doc2.getObjectOfLatestVersion(false);
String versionLabel3 = doc3.getVersionLabel();
assertTrue("Delete content stream should create a new version automatically", Double.parseDouble(versionLabel1) < Double.parseDouble(versionLabel3));
assertTrue("It should be latest version : " + versionLabel3, doc3.isLatestVersion());
}
/**
* 1) Creating a file with incorrect char in description property
* 2) Get xml with incorrect char in description
* 3) Check xml
* @throws Exception
*/
@Test
public void testGetXmlWithIncorrectDesctiption() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, "password", null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
final String siteName = "site" + System.currentTimeMillis();
NodeRef fileNode = TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PUBLIC);
final TestSite site = network1.createSite(siteInfo);
NodeRef resNode = repoService.createDocument(site.getContainerNodeRef("documentLibrary"), "testdoc \u0010.txt", "Test Doc1 Title \u0010", "d\u0010", "Test Content");
return resNode;
}
}, person1Id, network1.getId());
String cmisId = fileNode.getId();
HashMap<String, String> reqParams = new HashMap<String, String>();
reqParams.put("id", cmisId+";1.0");
reqParams.put("filter", "*");
reqParams.put("includeAllowableActions", "true");
reqParams.put("includeACL", "true");
reqParams.put("includePolicyIds", "true");
reqParams.put("includeRelationships", "both");
reqParams.put("renditionFilter", "*");
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
HttpResponse resp = publicApiClient.get(Binding.atom, CMIS_VERSION_11, "id", reqParams);
String xml = resp.getResponse();
// Response hasn't full info at error - writer just stops at incorrect character.
// Therefore we can check end tag of root element
assertTrue("No end tag was found", xml.endsWith("</atom:entry>"));
}
/**
* 1) Creating a file with currency symbols in the name, title and description (MNT-15044)
* 2) Get the document with correct chars in the properties.
* @throws Exception
*/
@Test
public void testGetXmlWithCorrectCurrencySymbols() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, "password", null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
final String siteName = "site" + System.currentTimeMillis();
NodeRef fileNode = TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PUBLIC);
final TestSite site = network1.createSite(siteInfo);
NodeRef resNode = repoService.createDocument(site.getContainerNodeRef("documentLibrary"),
"Euro \u20AC Pound \u00A3 Franc \u20A3.txt",
"Euro \u20AC Pound \u00A3 Franc \u20A3 File",
"\u20A3 \u00A3 \u20A3",
"\u20A3 \u00A3 \u20A3");
return resNode;
}
}, person1Id, network1.getId());
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession atomCmisSession10 = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName());
String objectId = fileNode.getId();
Document doc = (Document)atomCmisSession10.getObject(objectId);
String name = (String)doc.getProperty(PropertyIds.NAME).getFirstValue();
String title = (String)doc.getProperty("cm:title").getFirstValue();
String description = (String)doc.getProperty("cm:description").getFirstValue();
assertEquals("Euro \u20AC Pound \u00A3 Franc \u20A3.txt", name);
assertEquals("Euro \u20AC Pound \u00A3 Franc \u20A3 File", title);
assertEquals("\u20A3 \u00A3 \u20A3", description);
}
/*
* Test that creating a document with a number of initial aspects does not create lots of initial versions
*/
@Test
public void testALF19320() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
final String siteName = "site" + System.currentTimeMillis();
TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
String name = GUID.generate();
NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name);
return folderNodeRef;
}
}, person1Id, network1.getId());
// Create a document...
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName());
AlfrescoFolder docLibrary = (AlfrescoFolder)cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary");
Map<String, String> properties = new HashMap<String, String>();
{
// create a document with 2 aspects
properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document,P:cm:titled,P:cm:author");
properties.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt");
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum and so on");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
AlfrescoDocument doc = (AlfrescoDocument)docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR);
String versionLabel = doc.getVersionLabel();
assertEquals(CMIS_VERSION_10, versionLabel);
AlfrescoDocument doc1 = (AlfrescoDocument)doc.getObjectOfLatestVersion(false);
String versionLabel1 = doc1.getVersionLabel();
assertEquals(CMIS_VERSION_10, versionLabel1);
}
/* MNT-10175 test */
@Test
public void testAppendContentVersioning() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
final String siteName = "site" + System.currentTimeMillis();
TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
String name = GUID.generate();
NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name);
return folderNodeRef;
}
}, person1Id, network1.getId());
// Create a document
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
// Use CMIS 1.1 to test content appending
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11);
Folder docLibrary = (Folder)cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary");
String name = GUID.generate() + ".txt";
Map<String, String> properties = new HashMap<String, String>();
{
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, name);
}
// Create content to append
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum and so on");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
Document doc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR);
String versionLabel1 = doc.getObjectOfLatestVersion(false).getVersionLabel();
// append a few times
for(int i = 0; i < 5; i++)
{
doc.appendContentStream(fileContent, false);
}
String versionLabel2 = doc.getObjectOfLatestVersion(false).getVersionLabel();
// Version label should not be incremented by appending with isLustChunk = false
assertEquals(versionLabel1, versionLabel2);
doc.appendContentStream(fileContent, true);
String versionLabel3 = doc.getObjectOfLatestVersion(false).getVersionLabel();
Integer majorVer1 = Integer.valueOf(versionLabel2.substring(0, 1));
Integer majorVer2 = Integer.valueOf(versionLabel3.substring(0, 1));
Integer minorVer1 = Integer.valueOf(versionLabel2.substring(2, 3));
Integer minorVer2 = Integer.valueOf(versionLabel3.substring(2, 3));
// Only one MINOR version should be created
assertEquals(majorVer1, majorVer2);
assertEquals(Integer.valueOf(minorVer1 + 1), minorVer2);
}
@Test
public void testAppendContentStream() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
final String siteName = "site" + System.currentTimeMillis();
TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
String name = GUID.generate();
NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name);
return folderNodeRef;
}
}, person1Id, network1.getId());
// Create a document...
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11);
Folder docLibrary = (Folder)cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary");
String name = "mydoc-" + GUID.generate() + ".txt";
Map<String, String> properties = new HashMap<String, String>();
{
// create a document with 2 aspects
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, name);
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum and so on");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
Document doc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR);
// append a few times
for(int i = 0; i < 5; i++)
{
fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum and so on");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
doc.appendContentStream(fileContent, false);
}
fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum and so on");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
doc.appendContentStream(fileContent, true);
// check the appends
String path = "/Sites/" + siteName + "/documentLibrary/" + name;
Document doc1 = (Document)cmisSession.getObjectByPath(path);
ContentStream contentStream = doc1.getContentStream();
InputStream in = contentStream.getStream();
StringWriter writer = new StringWriter();
IOUtils.copy(in, writer, "UTF-8");
String content = writer.toString();
assertEquals("Ipsum and so onIpsum and so onIpsum and so onIpsum and so onIpsum and so onIpsum and so onIpsum and so on", content);
}
@Test
public void testSecondaryTypes() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
final String siteName = "site" + System.currentTimeMillis();
TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
String name = GUID.generate();
NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name);
return folderNodeRef;
}
}, person1Id, network1.getId());
// Create a document...
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11);
Folder docLibrary = (Folder)cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary");
String name = "mydoc-" + GUID.generate() + ".txt";
final List<String> secondaryTypes = new ArrayList<String>();
secondaryTypes.add("P:cm:summarizable");
Map<String, Object> properties = new HashMap<String, Object>();
{
// create a document with 2 aspects
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes);
properties.put("cm:summary", "My summary");
properties.put(PropertyIds.NAME, name);
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum and so on");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
Document doc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR);
{
// check that the secondary types and properties are present
{
checkSecondaryTypes(doc, Collections.singleton("P:cm:summarizable"), null);
String summary = (String)doc.getProperty("cm:summary").getFirstValue();
assertEquals("My summary", summary);
}
{
doc = (Document)cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary/" + name);
checkSecondaryTypes(doc, Collections.singleton("P:cm:summarizable"), null);
String summary = (String)doc.getProperty("cm:summary").getFirstValue();
assertEquals("My summary", summary);
}
}
// update property and check
{
properties = new HashMap<String, Object>();
{
properties.put("cm:summary", "My updated summary");
}
doc.updateProperties(properties);
{
doc = (Document)cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary/" + name);
checkSecondaryTypes(doc, Collections.singleton("P:cm:summarizable"), null);
String summary = (String)doc.getProperty("cm:summary").getFirstValue();
assertEquals("My updated summary", summary);
}
{
checkSecondaryTypes(doc, Collections.singleton("P:cm:summarizable"), null);
String summary = (String)doc.getProperty("cm:summary").getFirstValue();
assertEquals("My updated summary", summary);
}
}
}
/* MNT-10161 related test - mapping of cmis:description for CMIS 1.1 */
@Test
public void testMNT_10161() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
final String siteName = "site" + System.currentTimeMillis();
final String nodeDescription = "Test description";
final String nodeName = GUID.generate();
TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), nodeName);
/* create node with property description */
return repoService.createDocument(folderNodeRef, nodeName, "title", nodeDescription, "content");
}
}, person1Id, network1.getId());
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11);
Document doc =
(Document)cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary/" + nodeName + "/" + nodeName);
/* ensure we got the node */
assertNotNull(doc);
/* get mapped cmis:description */
Property<?> descrProperty = doc.getProperty(PropertyIds.DESCRIPTION);
/* ensure that cmis:description is set properly */
assertTrue(nodeDescription.equals(descrProperty.getValue()));
}
/* MNT-10687 related test - appendContent to PWC CMIS 1.1 */
@Test
public void testMNT_10687() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
final String siteName = "site" + System.currentTimeMillis();
TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
String name = GUID.generate();
NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name);
return folderNodeRef;
}
}, person1Id, network1.getId());
// Create a document...
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11);
Folder docLibrary = (Folder)cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary");
String name = "mydoc-" + GUID.generate() + ".txt";
Map<String, Object> properties = new HashMap<String, Object>();
{
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, name);
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
/* Create document */
Document doc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR);
/* Checkout document */
ObjectId pwcId = doc.checkOut();
Document pwc = (Document)cmisSession.getObject(pwcId.getId());
/* append content to PWC */
fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent(" and so on");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
pwc.appendContentStream(fileContent, true);
pwc.checkIn(false, null, null, "Check In");
ContentStream contentStream = doc.getObjectOfLatestVersion(false).getContentStream();
InputStream in = contentStream.getStream();
StringWriter writer = new StringWriter();
IOUtils.copy(in, writer, "UTF-8");
String content = writer.toString();
assertEquals("Ipsum and so on", content);
}
@Test
public void testMNT_13057() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
String guid = GUID.generate();
String name = guid + "_KRUIS_LOGO_100%_PMS.txt";
String urlFileName = guid + "_KRUIS_LOGO_100%25_PMS.txt";
final String siteName = "site" + System.currentTimeMillis();
TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
String name = GUID.generate();
NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name);
return folderNodeRef;
}
}, person1Id, network1.getId());
// Create a document...
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11);
Folder docLibrary = (Folder)cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary");
Map<String, Object> properties = new HashMap<String, Object>();
{
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, name);
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
/* Create document */
Document doc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR);
String id = doc.getId();
assertNotNull(id);
Map<String, String> params = new HashMap<String, String>();
params.put("id", URLEncoder.encode(id));
urlFileName += "?id=" + URLEncoder.encode(id);
HttpResponse response = publicApiClient.get(network1.getId() + "/public/cmis/versions/1.1/atom/content/" + urlFileName, null);
assertEquals(200, response.getStatusCode());
}
@Test
public void testMNT10430() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null,
null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.browser, CMIS_VERSION_11, AlfrescoObjectFactoryImpl.class.getName());
ObjectType objectType = cmisSession.getTypeDefinition("D:testcmis:maDoc");
// try and get the mandatory aspects
List<String> mandatoryAspects = ((AlfrescoType)objectType).getMandatoryAspects();
System.out.println("Mandatory Aspects");
for(String mandatoryAspect : mandatoryAspects)
{
System.out.println(mandatoryAspect);
}
assertTrue("The aspects should have P:cm:generalclassifiable", mandatoryAspects.contains("P:cm:generalclassifiable"));
}
@Test
public void testContentDisposition_MNT_17477() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person1 = network1.createUser(personInfo);
String person1Id = person1.getId();
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.browser, CMIS_VERSION_11, AlfrescoObjectFactoryImpl.class.getName());
Folder folder = (Folder)cmisSession.getObjectByPath("/Shared");
//
// Upload test JPG document
//
String name = GUID.generate() + ".jpg";
Map<String, Object> properties = new HashMap<>();
{
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, name);
}
ContentStreamImpl fileContent = new ContentStreamImpl();
{
fileContent.setMimeType(MimetypeMap.MIMETYPE_IMAGE_JPEG);
fileContent.setStream(this.getClass().getResourceAsStream("/test.jpg"));
}
Document doc = folder.createDocument(properties, fileContent, VersioningState.MAJOR);
String docId = doc.getId();
// note: Content-Disposition can be "inline or "attachment" for content types that are white-listed (eg. specific image types & pdf)
HttpResponse response = publicApiClient.get("/"+network1.getId()+"/public/cmis/versions/1.1/browser/root/Shared/"+name, null);
assertEquals(200, response.getStatusCode());
assertTrue(response.getHeaders().get("Content-Disposition").startsWith("inline"));
response = publicApiClient.get("/"+network1.getId()+"/public/cmis/versions/1.1/browser/root/Shared/"+name+"?download=inline", null);
assertEquals(200, response.getStatusCode());
assertTrue(response.getHeaders().get("Content-Disposition").startsWith("inline"));
response = publicApiClient.get("/"+network1.getId()+"/public/cmis/versions/1.1/browser/root/Shared/"+name+"?download=attachment", null);
assertEquals(200, response.getStatusCode());
assertTrue(response.getHeaders().get("Content-Disposition").startsWith("attachment"));
// note: AtomPub binding (via OpenCMIS) does not support "download" query parameter
response = publicApiClient.get("/"+network1.getId()+"/public/cmis/versions/1.1/atom/content?id="+docId, null);
assertEquals(200, response.getStatusCode());
assertTrue(response.getHeaders().get("Content-Disposition").startsWith("attachment"));
//
// Create test HTML document
//
name = GUID.generate() + ".html";
properties = new HashMap<>();
{
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, name);
}
fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".html"));
writer.putContent("<html><script>alert(123);</script><body>Hello <b>world</b></body</html>");
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_HTML);
fileContent.setStream(reader.getContentInputStream());
}
doc = folder.createDocument(properties, fileContent, VersioningState.MAJOR);
docId = doc.getId();
// note: Content-Disposition will always be "attachment" for content types that are not white-listed
response = publicApiClient.get("/"+network1.getId()+"/public/cmis/versions/1.1/browser/root/Shared/"+name, null);
assertTrue(response.getHeaders().get("Content-Disposition").startsWith("attachment;"));
assertEquals(200, response.getStatusCode());
response = publicApiClient.get("/"+network1.getId()+"/public/cmis/versions/1.1/browser/root/Shared/"+name+"?download=inline", null);
assertTrue(response.getHeaders().get("Content-Disposition").startsWith("attachment;"));
assertEquals(200, response.getStatusCode());
// note: AtomPub binding (via OpenCMIS) does not support "download" query parameter
response = publicApiClient.get("/"+network1.getId()+"/public/cmis/versions/1.1/atom/content?id="+docId, null);
assertTrue(response.getHeaders().get("Content-Disposition").startsWith("attachment;"));
assertEquals(200, response.getStatusCode());
}
/**
* Test delete version on versions other than latest (most recent) version (MNT-17228)
*/
@Test
public void testDeleteNonCurrentVersion() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null,
null, null, null, null, null);
TestPerson person = network1.createUser(personInfo);
String personId = person.getId();
publicApiClient.setRequestContext(new RequestContext(network1.getId(), personId));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.browser, CMIS_VERSION_11, AlfrescoObjectFactoryImpl.class.getName());
Folder homeFolder = (Folder)cmisSession.getObjectByPath("/User Homes/" + personId);
assertNotNull(homeFolder.getId());
// Create a document
String name = String.format(TEST_DOCUMENT_NAME_PATTERN, GUID.generate());
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, name);
ContentStreamImpl fileContent = new ContentStreamImpl();
ByteArrayInputStream stream = new ByteArrayInputStream(GUID.generate().getBytes());
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(stream);
Document doc = homeFolder.createDocument(properties, fileContent, VersioningState.MAJOR);
String versionLabel = doc.getVersionLabel();
assertEquals("1.0", versionLabel);
Document docVersionToDelete = null;
Document latestDoc = doc;
int cnt = 4;
for (int i = 1; i <= cnt; i++)
{
// Update content to create new versions (1.1, 1.2, 1.3, 1.4)
fileContent = new ContentStreamImpl();
{
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt"));
writer.putContent("Ipsum and so on and so on "+i);
ContentReader reader = writer.getReader();
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(reader.getContentInputStream());
}
latestDoc.setContentStream(fileContent, true);
latestDoc = latestDoc.getObjectOfLatestVersion(false);
versionLabel = latestDoc.getVersionLabel();
assertEquals("1."+i, versionLabel);
assertEquals(1+i, cmisSession.getAllVersions(latestDoc.getId()).size());
if (i == 2)
{
docVersionToDelete = latestDoc; // ie. 1.2
}
}
// Test delete with a user without permissions
String username2 = "user" + System.currentTimeMillis();
PersonInfo person2Info = new PersonInfo(username2, username2, username2, TEST_PASSWORD, null, null,
null, null, null, null, null);
TestPerson person2 = network1.createUser(person2Info);
String person2Id = person2.getId();
TenantUtil.runAsSystemTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
String nodeId = stripCMISSuffix(doc.getId());
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
// Give user person2 READ permissions to access the node
permissionService.setPermission(nodeRef, person2Id, PermissionService.READ, true);
return null;
}
}, network1.getId());
// Connect with person2
publicApiClient.setRequestContext(new RequestContext(network1.getId(), person2Id));
CmisSession cmisSession2 = publicApiClient.createPublicApiCMISSession(Binding.browser, CMIS_VERSION_11, AlfrescoObjectFactoryImpl.class.getName());
CmisObject docVersionToDeleteBy2 = cmisSession2.getObject(docVersionToDelete.getId());
try
{
// (-) Delete v 1.2 (without DELETE permission)
docVersionToDeleteBy2.delete(false);
fail("Node version was deleted without permissions.");
}
catch (CmisPermissionDeniedException ex)
{
// expected
}
// (+) Delete v 1.2 (with permission)
docVersionToDelete.delete(false);
// eg. 1.0, 1.2, 1.3, 1.4 (not 1.1)
assertEquals(cnt, cmisSession.getAllVersions(doc.getId()).size());
}
@Test
public void testMnt11631() throws Exception
{
final TestNetwork network = getTestFixture().getRandomNetwork();
String username = String.format(TEST_USER_NAME_PATTERN, System.currentTimeMillis());
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person = network.createUser(personInfo);
String personId = person.getId();
final String siteName = String.format(TEST_SITE_NAME_PATTERN, System.currentTimeMillis());
TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
String name = GUID.generate();
NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name);
return folderNodeRef;
}
}, personId, network.getId());
publicApiClient.setRequestContext(new RequestContext(network.getId(), personId));
CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11);
Folder docLibrary = (Folder) cmisSession.getObjectByPath(String.format(DOCUMENT_LIBRARY_PATH_PATTERN, siteName));
String name = String.format(TEST_DOCUMENT_NAME_PATTERN, GUID.generate());
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT);
properties.put(PropertyIds.NAME, name);
ContentStreamImpl fileContent = new ContentStreamImpl();
ByteArrayInputStream stream = new ByteArrayInputStream(GUID.generate().getBytes());
fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN);
fileContent.setStream(stream);
Document doc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR);
ObjectId pwcId = doc.checkOut();
Document pwc = (Document) cmisSession.getObject(pwcId.getId());
assertIsPwcProperty(pwc, false);
cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10);
CmisObject pwc10 = cmisSession.getObject(pwc.getId());
assertIsPwcProperty(pwc10, true);
}
private void assertIsPwcProperty(CmisObject pwc, boolean nullExpected)
{
boolean isPwcFound = false;
Boolean isPwcValueTrue = null;
for (Property<?> property : pwc.getProperties())
{
if ((null != property) && PropertyIds.IS_PRIVATE_WORKING_COPY.equals(property.getId()))
{
isPwcFound = true;
isPwcValueTrue = property.getValue();
break;
}
}
if (nullExpected)
{
assertTrue(("'" + PropertyIds.IS_PRIVATE_WORKING_COPY + "' property is not null!"), !isPwcFound || (null == isPwcValueTrue));
return;
}
assertTrue(("'" + PropertyIds.IS_PRIVATE_WORKING_COPY + "' property has not been found!"), isPwcFound);
assertNotNull(("'" + PropertyIds.IS_PRIVATE_WORKING_COPY + "' property value must not be null!"), isPwcValueTrue);
assertTrue(("'" + PropertyIds.IS_PRIVATE_WORKING_COPY + "' property value must be equal to 'true'!"), isPwcValueTrue);
}
@Test
public void testCanConnectCMISUsingDefaultTenant() throws Exception
{
testCanConnectCMISUsingDefaultTenantImpl(Binding.atom, CMIS_VERSION_11);
testCanConnectCMISUsingDefaultTenantImpl(Binding.atom, CMIS_VERSION_10);
testCanConnectCMISUsingDefaultTenantImpl(Binding.browser, CMIS_VERSION_11);
}
private void testCanConnectCMISUsingDefaultTenantImpl(Binding binding, String cmisVersion)
{
String url = httpClient.getPublicApiCmisUrl(TenantUtil.DEFAULT_TENANT, binding, cmisVersion, null);
Map<String, String> parameters = new HashMap<String, String>();
// user credentials
parameters.put(SessionParameter.USER, "admin");
parameters.put(SessionParameter.PASSWORD, "admin");
parameters.put(SessionParameter.ATOMPUB_URL, url);
parameters.put(SessionParameter.BROWSER_URL, url);
parameters.put(SessionParameter.BINDING_TYPE, binding.getOpenCmisBinding().value());
SessionFactory factory = SessionFactoryImpl.newInstance();
// perform request : http://host:port/alfresco/api/-default-/public/cmis/versions/${cmisVersion}/${binding}
List<Repository> repositories = factory.getRepositories(parameters);
assertTrue(repositories.size() > 0);
parameters.put(SessionParameter.REPOSITORY_ID, TenantUtil.DEFAULT_TENANT);
Session session = factory.createSession(parameters);
// perform request : http://host:port/alfresco/api/-default-/public/cmis/versions/${cmisVersion}/${binding}/type?id=cmis:document
ObjectType objectType = session.getTypeDefinition("cmis:document");
assertNotNull(objectType);
}
@Test
public void testACE3433() throws Exception
{
final TestNetwork network = getTestFixture().getRandomNetwork();
NodeRef rootNodeRef = TenantUtil.runAsSystemTenant(new TenantRunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
NodeRef rootNodeRef = repoService.getNodeService().getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
List<ChildAssociationRef> childAssocs = repoService.getNodeService().getChildAssocsByPropertyValue(rootNodeRef,
ContentModel.PROP_TITLE, "Company Home");
assertEquals(1, childAssocs.size());
NodeRef companyHomeNodeRef = childAssocs.get(0).getChildRef();
return companyHomeNodeRef;
}
}, network.getId());
assertNotNull(rootNodeRef);
// atom
{
Binding binding = Binding.atom;
String url = httpClient.getPublicApiCmisUrl(TenantUtil.DEFAULT_TENANT, binding, "1.1", null);
Map<String, String> parameters = new HashMap<String, String>();
// user credentials
parameters.put(SessionParameter.USER, "admin@" + network.getId());
parameters.put(SessionParameter.PASSWORD, "admin");
parameters.put(SessionParameter.ATOMPUB_URL, url);
parameters.put(SessionParameter.BINDING_TYPE, binding.getOpenCmisBinding().value());
SessionFactory factory = SessionFactoryImpl.newInstance();
Repository repository = factory.getRepositories(parameters).get(0);
String rootFolderId = repository.getRootFolderId();
assertEquals(rootNodeRef.getId(), rootFolderId);
}
{
Binding binding = Binding.browser;
String url = httpClient.getPublicApiCmisUrl(TenantUtil.DEFAULT_TENANT, binding, "1.1", null);
Map<String, String> parameters = new HashMap<String, String>();
// user credentials
parameters.put(SessionParameter.USER, "admin@" + network.getId());
parameters.put(SessionParameter.PASSWORD, "admin");
parameters.put(SessionParameter.BROWSER_URL, url);
parameters.put(SessionParameter.BINDING_TYPE, binding.getOpenCmisBinding().value());
SessionFactory factory = SessionFactoryImpl.newInstance();
Repository repository = factory.getRepositories(parameters).get(0);
String rootFolderId = repository.getRootFolderId();
assertEquals(rootNodeRef.getId(), rootFolderId);
}
}
@Test
public void testMNT12956QueryingCMIS11UsesDictionary11() throws Exception
{
final TestNetwork network1 = getTestFixture().getRandomNetwork();
String username = "user" + System.currentTimeMillis();
PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null);
TestPerson person = network1.createUser(personInfo);
String personId = person.getId();
final List<NodeRef> documents = new ArrayList<NodeRef>();
final String filename = GUID.generate();
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
String siteName = "site" + System.currentTimeMillis();
SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE);
TestSite site = repoService.createSite(null, siteInfo);
NodeRef docNodeRef = repoService.createDocument(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), filename, "test content");
documents.add(docNodeRef);
return null;
}
}, personId, network1.getId());
NodeRef docNodeRef = documents.get(0);
publicApiClient.setRequestContext(new RequestContext(network1.getId(), personId));
CmisSession atomCmisSession10 = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName());
CmisSession atomCmisSession11 = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11);
// query
{
// searching by NodeRef, expect result objectIds to be objectId
Set<String> expectedObjectIds = new HashSet<String>();
expectedObjectIds.add(docNodeRef.getId());
int numMatchingDocs = 0;
// NodeRef input
List<CMISNode> results = atomCmisSession11.query("SELECT cmis:objectId,cmis:name,cmis:secondaryObjectTypeIds FROM cmis:document WHERE cmis:name LIKE '" + filename + "'", false, 0, Integer.MAX_VALUE);
assertEquals(expectedObjectIds.size(), results.size());
for(CMISNode node : results)
{
String objectId = stripCMISSuffix((String)node.getProperties().get(PropertyIds.OBJECT_ID));
if(expectedObjectIds.contains(objectId))
{
numMatchingDocs++;
}
}
assertEquals(expectedObjectIds.size(), numMatchingDocs);
try
{
results = atomCmisSession10.query("SELECT cmis:objectId,cmis:name,cmis:secondaryObjectTypeIds FROM cmis:document WHERE cmis:name LIKE '" + filename + "'", false, 0, Integer.MAX_VALUE);
fail("OpenCMIS 1.0 knows nothing about cmis:secondaryObjectTypeIds");
}
catch (CmisInvalidArgumentException expectedException)
{
// ok
}
}
}
}