/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.core.commons.services.webdav;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.UUID;
import javax.ws.rs.core.UriBuilder;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.apache.poi.util.IOUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.olat.basesecurity.GroupRoles;
import org.olat.core.commons.modules.bc.FolderConfig;
import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
import org.olat.core.commons.persistence.DB;
import org.olat.core.id.Identity;
import org.olat.core.id.Roles;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.FileUtils;
import org.olat.core.util.vfs.VFSContainer;
import org.olat.core.util.vfs.VFSItem;
import org.olat.core.util.vfs.VFSLeaf;
import org.olat.core.util.vfs.VFSLockManager;
import org.olat.core.util.vfs.lock.LockInfo;
import org.olat.course.CourseFactory;
import org.olat.course.ICourse;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryService;
import org.olat.repository.manager.RepositoryEntryRelationDAO;
import org.olat.restapi.CoursePublishTest;
import org.olat.test.JunitTestHelper;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Test the commands against the WedDAV implementation of OpenOLAT
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class WebDAVCommandsTest extends WebDAVTestCase {
private static final OLog log = Tracing.createLoggerFor(WebDAVCommandsTest.class);
@Autowired
private DB dbInstance;
@Autowired
private WebDAVModule webDAVModule;
@Autowired
private VFSLockManager lockManager;
@Autowired
private RepositoryService repositoryService;
@Autowired
private RepositoryEntryRelationDAO repositoryEntryRelationDao;
@After
public void resetWebDAVModule() {
webDAVModule.setEnableLearnersBookmarksCourse(false);
webDAVModule.setEnableLearnersParticipatingCourses(false);
}
/**
* Check the DAV, Ms-Author and Allow header
* @throws IOException
* @throws URISyntaxException
*/
@Test
public void testOptions()
throws IOException, URISyntaxException {
//create a user
Identity user = JunitTestHelper.createAndPersistIdentityAsUser("webdav-1-" + UUID.randomUUID().toString());
//list root content of its webdav folder
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(user.getName(), "A6B7C8");
URI baseUri = conn.getBaseURI().build();
HttpOptions optionsRoot = conn.createOptions(baseUri);
HttpResponse optionsResponse = conn.execute(optionsRoot);
Assert.assertEquals(200, optionsResponse.getStatusLine().getStatusCode());
//check DAV header
Header davHeader = optionsResponse.getFirstHeader("DAV");
String davHeaderValue = davHeader.getValue();
Assert.assertTrue(davHeaderValue.contains("1"));
Assert.assertTrue(davHeaderValue.contains("2"));
//check ms author
Header msHeader = optionsResponse.getFirstHeader("MS-Author-Via");
Assert.assertEquals("DAV", msHeader.getValue());
//check methods
Header allowHeader = optionsResponse.getFirstHeader("Allow");
String allowValue = allowHeader.getValue();
String[] allowedMethods = new String[] {
"OPTIONS", "GET", "HEAD", "POST", "DELETE",
"TRACE", "PROPPATCH", "COPY", "MOVE", "LOCK", "UNLOCK"
};
for(String allowedMethod:allowedMethods) {
Assert.assertTrue(allowValue.contains(allowedMethod));
}
IOUtils.closeQuietly(conn);
}
@Test
public void testHead()
throws IOException, URISyntaxException {
//create a user
Identity user = JunitTestHelper.createAndPersistIdentityAsUser("webdav-2-" + UUID.randomUUID().toString());
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(user.getName(), "A6B7C8");
//create a file
String publicPath = FolderConfig.getUserHomes() + "/" + user.getName() + "/public";
VFSContainer vfsPublic = new OlatRootFolderImpl(publicPath, null);
createFile(vfsPublic, "test_head.txt");
//head file
URI publicUri = conn.getBaseURI().path("webdav").path("home").path("public").path("test_head.txt").build();
HttpResponse response = conn.head(publicUri);
Header lengthHeader = response.getFirstHeader("Content-Length");
Assert.assertNotNull(lengthHeader);
Assert.assertEquals("10", lengthHeader.getValue());
Header typeHeader = response.getFirstHeader("Content-Type");
Assert.assertNotNull(typeHeader);
Assert.assertEquals("text/plain", typeHeader.getValue());
EntityUtils.consume(response.getEntity());
IOUtils.closeQuietly(conn);
}
@Test
public void testPropFind()
throws IOException, URISyntaxException {
//create a user
Identity user = JunitTestHelper.createAndPersistIdentityAsUser("webdav-2-" + UUID.randomUUID().toString());
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(user.getName(), "A6B7C8");
//list root content of its webdav folder
URI uri = conn.getBaseURI().build();
String xml = conn.propfind(uri, 1);
Assert.assertTrue(xml.indexOf("<D:multistatus") > 0);//Windows need the D namespace
Assert.assertTrue(xml.indexOf("<D:href>/</D:href>") > 0);//check the root
Assert.assertTrue(xml.indexOf("<D:href>/webdav/</D:href>") > 0);//check the webdav folder
//check public folder
URI publicUri = conn.getBaseURI().path("webdav").path("home").path("public").build();
String publicXml = conn.propfind(publicUri, 1);
Assert.assertTrue(publicXml.indexOf("<D:multistatus") > 0);//Windows need the D namespace
Assert.assertTrue(publicXml.indexOf("<D:href>/webdav/home/public/</D:href>") > 0);//check the root
IOUtils.closeQuietly(conn);
}
@Test
public void testMkcol_public()
throws IOException, URISyntaxException {
//create a user
Identity user = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-2a-" + UUID.randomUUID().toString());
//create a file
String publicPath = FolderConfig.getUserHomes() + "/" + user.getName() + "/public";
VFSContainer vfsPublic = new OlatRootFolderImpl(publicPath, null);
Assert.assertTrue(vfsPublic.exists());
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(user.getName(), "A6B7C8");
//author check course folder
URI publicUri = conn.getBaseURI().path("webdav").path("home").path("public").build();
String publicXml = conn.propfind(publicUri, 2);
Assert.assertTrue(publicXml.indexOf("<D:href>/webdav/home/public/</D:href>") > 0);
//make a folder
URI newUri = UriBuilder.fromUri(publicUri).path("newFolder").build();
int returnMkcol = conn.mkcol(newUri);
Assert.assertEquals(201, returnMkcol);
//check if folder exists
VFSItem newItem = vfsPublic.resolve("newFolder");
Assert.assertNotNull(newItem);
Assert.assertTrue(newItem instanceof VFSContainer);
Assert.assertTrue(newItem.exists());
IOUtils.closeQuietly(conn);
}
@Test
public void testMove_public()
throws IOException, URISyntaxException {
//create a user
Identity user = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-2b-" + UUID.randomUUID().toString());
//create a file
String publicPath = FolderConfig.getUserHomes() + "/" + user.getName() + "/public";
VFSContainer vfsPublic = new OlatRootFolderImpl(publicPath, null);
createFile(vfsPublic, "test.txt");
VFSContainer subPublic = vfsPublic.createChildContainer("moveto");
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(user.getName(), "A6B7C8");
//author check course folder
URI publicUri = conn.getBaseURI().path("webdav").path("home").path("public").build();
URI fileUri = UriBuilder.fromUri(publicUri).path("test.txt").build();
String destination = UriBuilder.fromUri(publicUri).path("moveto").path("test.txt").build().toString();
int returnMove = conn.move(fileUri, destination);
Assert.assertEquals(201, returnMove);
//check move
VFSItem movedItem = subPublic.resolve("test.txt");
Assert.assertNotNull(movedItem);
Assert.assertTrue(movedItem instanceof VFSLeaf);
Assert.assertTrue(movedItem.exists());
VFSItem sourceItem = vfsPublic.resolve("test.txt");
Assert.assertNull(sourceItem);
IOUtils.closeQuietly(conn);
}
@Test
public void testCopy_public()
throws IOException, URISyntaxException {
//create a user
Identity user = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-2b-" + UUID.randomUUID().toString());
//create a file
String publicPath = FolderConfig.getUserHomes() + "/" + user.getName() + "/public";
VFSContainer vfsPublic = new OlatRootFolderImpl(publicPath, null);
createFile(vfsPublic, "test.txt");
VFSContainer subPublic = vfsPublic.createChildContainer("copyto");
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(user.getName(), "A6B7C8");
//author check course folder
URI publicUri = conn.getBaseURI().path("webdav").path("home").path("public").build();
URI fileUri = UriBuilder.fromUri(publicUri).path("test.txt").build();
String destination = UriBuilder.fromUri(publicUri).path("copyto").path("copy.txt").build().toString();
int returnMove = conn.copy(fileUri, destination);
Assert.assertEquals(201, returnMove);
//check move
VFSItem movedItem = subPublic.resolve("copy.txt");
Assert.assertNotNull(movedItem);
Assert.assertTrue(movedItem instanceof VFSLeaf);
Assert.assertTrue(movedItem.exists());
VFSItem sourceItem = vfsPublic.resolve("test.txt");
Assert.assertNotNull(sourceItem);
Assert.assertTrue(sourceItem instanceof VFSLeaf);
Assert.assertTrue(sourceItem.exists());
IOUtils.closeQuietly(conn);
}
@Test
public void testPut_course()
throws IOException, URISyntaxException {
//create a user
Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-3-" + UUID.randomUUID().toString());
deployTestCourse(author, null);
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(author.getName(), "A6B7C8");
//author check course folder
URI courseUri = conn.getBaseURI().path("webdav").path("coursefolders").build();
String publicXml = conn.propfind(courseUri, 2);
Assert.assertTrue(publicXml.indexOf("<D:href>/webdav/coursefolders/_other/Kurs/_courseelementdata/</D:href>") > 0);
//PUT in the folder
URI putUri = UriBuilder.fromUri(courseUri).path("_other").path("Kurs").path("test.txt").build();
HttpPut put = conn.createPut(putUri);
InputStream dataStream = WebDAVCommandsTest.class.getResourceAsStream("text.txt");
InputStreamEntity entity = new InputStreamEntity(dataStream, -1);
put.setEntity(entity);
HttpResponse putResponse = conn.execute(put);
Assert.assertEquals(201, putResponse.getStatusLine().getStatusCode());
//GET
HttpGet get = conn.createGet(putUri);
HttpResponse getResponse = conn.execute(get);
Assert.assertEquals(200, getResponse.getStatusLine().getStatusCode());
String text = EntityUtils.toString(getResponse.getEntity());
Assert.assertEquals("Small text", text);
IOUtils.closeQuietly(conn);
}
/**
* PROPPATCH is essential for Windows, the content of the response
* is not important but it must not return an error.
*
* @throws IOException
* @throws URISyntaxException
*/
@Test
public void testPut_PropPatch_home()
throws IOException, URISyntaxException {
//create a user
Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-3-" + UUID.randomUUID().toString());
deployTestCourse(author, null);
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(author.getName(), "A6B7C8");
//author check course folder
URI privateUri = conn.getBaseURI().path("webdav").path("home").path("private").build();
conn.propfind(privateUri, 2);
//PUT in the folder
URI putUri = UriBuilder.fromUri(privateUri).path("test.txt").build();
HttpPut put = conn.createPut(putUri);
InputStream dataStream = WebDAVCommandsTest.class.getResourceAsStream("text.txt");
InputStreamEntity entity = new InputStreamEntity(dataStream, -1);
put.setEntity(entity);
HttpResponse putResponse = conn.execute(put);
Assert.assertEquals(201, putResponse.getStatusLine().getStatusCode());
EntityUtils.consume(putResponse.getEntity());
//PROPPATCH
URI patchUri = UriBuilder.fromUri(privateUri).path("test.txt").build();
HttpPropPatch patch = conn.createPropPatch(patchUri);
StringBuilder sb = new StringBuilder();
sb.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>")
.append("<D:propertyupdate xmlns:D=\"DAV:\"")
.append(" xmlns:Z=\"http://www.w3.com/standards/z39.50/\">")
.append(" <D:set>")
.append(" <D:prop>")
.append(" <Z:authors>")
.append(" <Z:Author>Jim Whitehead</Z:Author>")
.append(" <Z:Author>Roy Fielding</Z:Author>")
.append(" </Z:authors>")
.append(" </D:prop>")
.append(" </D:set>")
.append(" <D:remove>")
.append(" <D:prop><Z:Copyright-Owner/></D:prop>")
.append(" </D:remove>")
.append(" </D:propertyupdate>");
patch.setEntity(new StringEntity(sb.toString()));
HttpResponse patchResponse = conn.execute(patch);
Assert.assertEquals(207, patchResponse.getStatusLine().getStatusCode());
IOUtils.closeQuietly(conn);
}
/**
* In the this test, an author and its assistant try to concurrently
* lock a file.
*
* @throws IOException
* @throws URISyntaxException
*/
@Test
public void testLock()
throws IOException, URISyntaxException {
//create a user
Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-4-" + UUID.randomUUID().toString());
Identity assistant = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-5-" + UUID.randomUUID().toString());
deployTestCourse(author, assistant);
WebDAVConnection authorConn = new WebDAVConnection();
authorConn.setCredentials(author.getName(), "A6B7C8");
WebDAVConnection assistantConn = new WebDAVConnection();
assistantConn.setCredentials(assistant.getName(), "A6B7C8");
//author check course folder
URI courseUri = authorConn.getBaseURI().path("webdav").path("coursefolders").build();
String publicXml = authorConn.propfind(courseUri, 2);
Assert.assertTrue(publicXml.indexOf("<D:href>/webdav/coursefolders/_other/Kurs/_courseelementdata/</D:href>") > 0);
//coauthor check course folder
String assistantPublicXml = assistantConn.propfind(courseUri, 2);
Assert.assertTrue(assistantPublicXml.indexOf("<D:href>/webdav/coursefolders/_other/Kurs/_courseelementdata/</D:href>") > 0);
//PUT a file to lock
URI putUri = UriBuilder.fromUri(courseUri).path("_other").path("Kurs").path("test.txt").build();
HttpPut put = authorConn.createPut(putUri);
InputStream dataStream = WebDAVCommandsTest.class.getResourceAsStream("text.txt");
InputStreamEntity entity = new InputStreamEntity(dataStream, -1);
put.setEntity(entity);
HttpResponse putResponse = authorConn.execute(put);
Assert.assertEquals(201, putResponse.getStatusLine().getStatusCode());
EntityUtils.consume(putResponse.getEntity());
//author lock the file in the course folder
String authorLockToken = UUID.randomUUID().toString().replace("-", "").toLowerCase();
String authorResponseLockToken = authorConn.lock(putUri, authorLockToken);
Assert.assertNotNull(authorResponseLockToken);
//coauthor try to lock the same file
String coauthorLockToken = UUID.randomUUID().toString().replace("-", "").toLowerCase();
int coauthorLock = assistantConn.lockTry(putUri, coauthorLockToken);
Assert.assertEquals(423, coauthorLock);// it's lock
//author unlock the file
int unlockCode = authorConn.unlock(putUri, authorResponseLockToken);
Assert.assertEquals(204, unlockCode);
//coauthor try a second time to lock the file
String coauthorLockToken_2 = UUID.randomUUID().toString().replace("-", "").toLowerCase();
int coauthorLock_2 = assistantConn.lockTry(putUri, coauthorLockToken_2);
Assert.assertEquals(200, coauthorLock_2);// it's lock
IOUtils.closeQuietly(authorConn);
IOUtils.closeQuietly(assistantConn);
}
/**
*
* @throws IOException
* @throws URISyntaxException
*/
@Test
public void testLock_propfind_lockedInOpenOLAT()
throws IOException, URISyntaxException {
//create a user
Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-4-" + UUID.randomUUID().toString());
Identity assistant = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-5-" + UUID.randomUUID().toString());
RepositoryEntry re = deployTestCourse(author, assistant);
ICourse course = CourseFactory.loadCourse(re.getOlatResource());
Assert.assertNotNull(course);
//the assistant lock the file as in OpenOLAT GUI
VFSContainer folderContainer = course.getCourseFolderContainer();
createFile(folderContainer, "tolock.txt");
VFSItem itemToLock = folderContainer.resolve("tolock.txt");
Assert.assertNotNull(itemToLock);
boolean locked = lockManager.lock(itemToLock, assistant, new Roles(false, false, false, true, false, false, false));
Assert.assertTrue(locked);
//author make a propfind in the locked resource
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(author.getName(), "A6B7C8");
URI toLockUri = conn.getBaseURI().path("webdav").path("coursefolders").path("_other").path("Kurs").path("tolock.txt").build();
String propfindXml = conn.propfind(toLockUri, 2);
Assert.assertTrue(propfindXml.indexOf("<D:lockscope><D:exclusive/></D:lockscope>") > 0);//not really a test
Assert.assertTrue(propfindXml.indexOf("/Identity/" + assistant.getKey() + "</D:owner>") > 0);
Assert.assertTrue(propfindXml.indexOf("<D:locktoken><D:href>opaquelocktoken:") > 0);
LockInfo lock = lockManager.getLock(itemToLock);
Assert.assertNotNull(lock);
Assert.assertNotNull(lock.getScope());
Assert.assertNotNull(lock.getType());
Assert.assertNotNull(lock.getOwner());
Assert.assertTrue(lock.getOwner().length() > 0);
Assert.assertTrue(lock.isVfsLock());
Assert.assertFalse(lock.isWebDAVLock());
Assert.assertEquals(assistant.getKey(), lock.getLockedBy());
Assert.assertEquals(1, lock.getTokensSize());
IOUtils.closeQuietly(conn);
}
/**
*
* @throws IOException
* @throws URISyntaxException
*/
@Test
public void testLock_guilike_lockedWithWebdAV()
throws IOException, URISyntaxException {
//create a user
Identity user = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-2c-" + UUID.randomUUID().toString());
//create a file
String publicPath = FolderConfig.getUserHomes() + "/" + user.getName() + "/public";
VFSContainer vfsPublic = new OlatRootFolderImpl(publicPath, null);
VFSItem item = createFile(vfsPublic, "test.txt");
//lock the item with WebDAV
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(user.getName(), "A6B7C8");
//author check file
URI textUri = conn.getBaseURI().path("webdav").path("home").path("public").path("test.txt").build();
String textPropfind = conn.propfind(textUri, 0);
log.info(textPropfind);
//author lock the file
String lockToken = conn.lock(textUri, UUID.randomUUID().toString());
Assert.assertNotNull(lockToken);
//check vfs lock
Roles adminRoles = new Roles(true, false, false, false, false, false, false);
boolean lockedForMe = lockManager.isLockedForMe(item, user, adminRoles);
Assert.assertTrue(lockedForMe);
LockInfo lock = lockManager.getLock(item);
Assert.assertNotNull(lock);
Assert.assertNotNull(lock.getScope());
Assert.assertNotNull(lock.getType());
Assert.assertNotNull(lock.getOwner());
Assert.assertTrue(lock.getOwner().length() > 0);
Assert.assertFalse(lock.isVfsLock());
Assert.assertTrue(lock.isWebDAVLock());
Assert.assertEquals(user.getKey(), lock.getLockedBy());
Assert.assertEquals(1, lock.getTokensSize());
//try to unlock which should not be possible
boolean unlocked = lockManager.unlock(item, user, adminRoles);
Assert.assertFalse(unlocked);
//check that nothing changed
LockInfo lockAfterUnlock = lockManager.getLock(item);
Assert.assertNotNull(lockAfterUnlock);
Assert.assertNotNull(lockAfterUnlock.getScope());
Assert.assertNotNull(lockAfterUnlock.getType());
Assert.assertNotNull(lockAfterUnlock.getOwner());
Assert.assertTrue(lockAfterUnlock.getOwner().length() > 0);
Assert.assertFalse(lockAfterUnlock.isVfsLock());
Assert.assertTrue(lockAfterUnlock.isWebDAVLock());
Assert.assertEquals(user.getKey(), lockAfterUnlock.getLockedBy());
Assert.assertEquals(1, lock.getTokensSize());
IOUtils.closeQuietly(conn);
}
@Test
public void testLock_public_samePathLock()
throws IOException, URISyntaxException {
//create a user
Identity user1 = JunitTestHelper.createAndPersistIdentityAsRndUser("webdav-2d");
Identity user2 = JunitTestHelper.createAndPersistIdentityAsRndUser("webdav-2e");
//create a file
String publicPath1 = FolderConfig.getUserHomes() + "/" + user1.getName() + "/public";
VFSContainer vfsPublic1 = new OlatRootFolderImpl(publicPath1, null);
VFSItem item1 = createFile(vfsPublic1, "test.txt");
Assert.assertNotNull(item1);
String publicPath2 = FolderConfig.getUserHomes() + "/" + user2.getName() + "/public";
VFSContainer vfsPublic2 = new OlatRootFolderImpl(publicPath2, null);
VFSItem item2 = createFile(vfsPublic2, "test.txt");
Assert.assertNotNull(item2);
//lock the item with WebDAV
WebDAVConnection conn1 = new WebDAVConnection();
conn1.setCredentials(user1.getName(), "A6B7C8");
//user 1 lock the file
URI textUri = conn1.getBaseURI().path("webdav").path("home").path("public").path("test.txt").build();
String textPropfind1 = conn1.propfind(textUri, 0);
Assert.assertNotNull(textPropfind1);
// lock the path /webdav/home/public/test.txt
String lockToken1 = conn1.lock(textUri, UUID.randomUUID().toString());
Assert.assertNotNull(lockToken1);
//user 2 lock its own file
WebDAVConnection conn2 = new WebDAVConnection();
conn2.setCredentials(user2.getName(), "A6B7C8");
String textPropfind2 = conn2.propfind(textUri, 0);
Assert.assertNotNull(textPropfind2);
// lock the path /webdav/home/public/test.txt
String lockToken2 = conn2.lock(textUri, UUID.randomUUID().toString());
Assert.assertNotNull(lockToken2);
//closes
conn1.close();
conn2.close();
}
@Test
public void testDelete()
throws IOException, URISyntaxException {
//create a user
Identity user = JunitTestHelper.createAndPersistIdentityAsUser("webdav-6-" + UUID.randomUUID().toString());
//create a file
String publicPath = FolderConfig.getUserHomes() + "/" + user.getName() + "/public";
VFSContainer vfsPublic = new OlatRootFolderImpl(publicPath, null);
createFile(vfsPublic, "testDelete.txt");
//check
VFSItem item = vfsPublic.resolve("testDelete.txt");
Assert.assertTrue(item instanceof VFSLeaf);
Assert.assertTrue(item.exists());
Assert.assertTrue(((VFSLeaf)item).getSize() > 0);
//delete the file
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(user.getName(), "A6B7C8");
//check public folder
URI checkUri = conn.getBaseURI().path("webdav").path("home").path("public").path("testDelete.txt").build();
String publicXml = conn.propfind(checkUri, 1);
Assert.assertTrue(publicXml.indexOf("<D:multistatus") > 0);//Windows need the D namespace
Assert.assertTrue(publicXml.indexOf("<D:href>/webdav/home/public/testDelete.txt</D:href>") > 0);//check the root
//delete the file
HttpDelete delete = conn.createDelete(checkUri);
HttpResponse deleteResponse = conn.execute(delete);
Assert.assertEquals(204, deleteResponse.getStatusLine().getStatusCode());
EntityUtils.consume(deleteResponse.getEntity());
//check if really deleted
VFSItem reloadTestLeaf = vfsPublic.resolve("testDelete.txt");
Assert.assertNull(reloadTestLeaf);
IOUtils.closeQuietly(conn);
}
@Test
public void coursePermissions_participant()
throws IOException, URISyntaxException {
webDAVModule.setEnableLearnersBookmarksCourse(true);
webDAVModule.setEnableLearnersParticipatingCourses(true);
Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("auth-webdav");
Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("participant-webdav");
URL courseWithForumsUrl = WebDAVCommandsTest.class.getResource("webdav_course.zip");
RepositoryEntry course = deployTestCourse(author, null, courseWithForumsUrl);
repositoryEntryRelationDao.addRole(participant, course, GroupRoles.participant.name());
dbInstance.commitAndCloseSession();
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(participant.getName(), "A6B7C8");
URI courseUri = conn.getBaseURI().path("webdav").path("coursefolders").build();
String publicXml = conn.propfind(courseUri, 2);
//cannot access course storage
Assert.assertFalse(publicXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/Course%20storage/</D:href>"));
//can access course elements
Assert.assertTrue(publicXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/</D:href>"));
URI courseElementUri = conn.getBaseURI().path("webdav").path("coursefolders")
.path("_other").path("WebDAV%20course").path("_courseelementdata").build();
String publicElementXml = conn.propfind(courseElementUri, 2);
Assert.assertTrue(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Folder%20for%20all/</D:href>"));
Assert.assertFalse(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Student%20read-only%20%2890600786058954%29/Readonly%20students/</D:href>"));
Assert.assertFalse(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Not%20for%20students%20%2890600786058958%29/Not%20for%20students/</D:href>"));
conn.close();
}
@Test
public void coursePermissions_owner()
throws IOException, URISyntaxException {
webDAVModule.setEnableLearnersBookmarksCourse(true);
webDAVModule.setEnableLearnersParticipatingCourses(true);
Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("auth-webdav");
URL courseWithForumsUrl = WebDAVCommandsTest.class.getResource("webdav_course.zip");
deployTestCourse(author, null, courseWithForumsUrl);
dbInstance.commitAndCloseSession();
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(author.getName(), "A6B7C8");
URI courseUri = conn.getBaseURI().path("webdav").path("coursefolders").build();
String publicXml = conn.propfind(courseUri, 2);
//cane access course storage
Assert.assertTrue(publicXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/Course%20storage/</D:href>"));
//can access course elements
Assert.assertTrue(publicXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/</D:href>"));
URI courseElementUri = conn.getBaseURI().path("webdav").path("coursefolders")
.path("_other").path("WebDAV%20course").path("_courseelementdata").build();
String publicElementXml = conn.propfind(courseElementUri, 2);
//can access all 3 course nodes
Assert.assertTrue(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Folder%20for%20all/</D:href>"));
Assert.assertTrue(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Student%20read-only%20%2890600786058954%29/Readonly%20students/</D:href>"));
Assert.assertTrue(publicElementXml.contains("<D:href>/webdav/coursefolders/_other/WebDAV%20course/_courseelementdata/Not%20for%20students%20%2890600786058958%29/Not%20for%20students/</D:href>"));
conn.close();
}
/**
* Check that different methods doesn't create directory
*
* @throws IOException
* @throws URISyntaxException
*/
@Test
public void coursePermission_participantDirectory()
throws IOException, URISyntaxException {
webDAVModule.setEnableLearnersBookmarksCourse(true);
webDAVModule.setEnableLearnersParticipatingCourses(true);
//create a user
Identity auth = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-4-" + UUID.randomUUID().toString());
Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("webdav-5");
RepositoryEntry courseEntry = deployMkdirsCourse(auth);
repositoryEntryRelationDao.addRole(participant, courseEntry, GroupRoles.participant.name());
dbInstance.commitAndCloseSession();
//put a reference file there
ICourse course = CourseFactory.loadCourse(courseEntry.getOlatResource());
VFSContainer elements = (VFSContainer)course.getCourseFolderContainer().resolve("_courseelementdata");
Assert.assertNotNull(elements);
VFSContainer directory = (VFSContainer)elements.resolve("Directory");
VFSContainer level_1_Container = directory.createChildContainer("DT_01");
VFSLeaf readonlyLeaf = level_1_Container.createChildLeaf("readonly.txt");
InputStream in = WebDAVCommandsTest.class.getResourceAsStream("text.txt");
OutputStream out = readonlyLeaf.getOutputStream(false);
FileUtils.copy(in, out);
//check
VFSItem readonlyLeafBis = level_1_Container.resolve("readonly.txt");
Assert.assertNotNull(readonlyLeafBis);
//participant try to put a file
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(participant.getName(), "A6B7C8");
URI courseUri = conn.getBaseURI().path("webdav").path("coursefolders").path("_other").path("Mkdirs").build();
//MKCOL in the folder at the second level
URI level2Uri = UriBuilder.fromUri(courseUri).path("_courseelementdata")
.path("Directory").path("DT_01").path("DT_11").build();
int mkcol2Code = conn.mkcol(level2Uri);
Assert.assertEquals(409, mkcol2Code);
//check
VFSItem level2Mkcol = level_1_Container.resolve("DT_11");
Assert.assertNull(level2Mkcol);
//MKCOL in the folder at the first level
URI level1Uri = UriBuilder.fromUri(courseUri).path("_courseelementdata")
.path("Directory").path("DT_02").build();
int mkcol1Code = conn.mkcol(level1Uri);
Assert.assertEquals(409, mkcol1Code);
VFSItem level1Mkcol = directory.resolve("DT_02");
Assert.assertNull(level1Mkcol);
//PROPFIND in second level
int propfind2Code = conn.propfindTry(level2Uri, 1);
Assert.assertEquals(404, propfind2Code);
//check
VFSItem level2Propfind = level_1_Container.resolve("DT_11");
Assert.assertNull(level2Propfind);
//PROPFIND in first level
int propfind1Code = conn.propfindTry(level2Uri, 1);
Assert.assertEquals(404, propfind1Code);
//check
VFSItem level1Propfind = level_1_Container.resolve("DT_02");
Assert.assertNull(level1Propfind);
//LOCK in the second level
int lock2Code = conn.lockTry(level2Uri, UUID.randomUUID().toString());
Assert.assertEquals(403, lock2Code);
//check
VFSItem level2Lock = level_1_Container.resolve("DT_11");
Assert.assertNull(level2Lock);
//LOCK in the first level
int lock1Code = conn.lockTry(level2Uri, UUID.randomUUID().toString());
Assert.assertEquals(403, lock1Code);
//check
VFSItem level1Lock = level_1_Container.resolve("DT_02");
Assert.assertNull(level1Lock);
//MKCOL in the folder deeper
VFSContainer level_2_Container = level_1_Container.createChildContainer("DT2_01");
VFSContainer level_3_Container = level_2_Container.createChildContainer("DT3_01");
VFSContainer level_4_Container = level_3_Container.createChildContainer("DT4_01");
Assert.assertNotNull(level_4_Container);
URI level4Uri = UriBuilder.fromUri(courseUri).path("_courseelementdata")
.path("Directory").path("DT_01").path("DT2_01").path("DT3_01").path("DT4_01").build();
int propfind4Code = conn.propfindTry(level4Uri, 1);
Assert.assertEquals(207, propfind4Code);
URI level5Uri = UriBuilder.fromUri(level4Uri).path("DT5_01").build();
int mkcol5Code = conn.mkcol(level5Uri);
Assert.assertEquals(409, mkcol5Code);
//check
VFSItem level5Mkcol = level_1_Container.resolve("DT2_01").resolve("DT3_01").resolve("DT4_01").resolve("DT5_01");
Assert.assertNull(level5Mkcol);
IOUtils.closeQuietly(conn);
}
@Test
public void customizingFolder()
throws IOException, URISyntaxException {
Identity admin = JunitTestHelper.createAndPersistIdentityAsAdmin("admin-webdav");
dbInstance.commitAndCloseSession();
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(admin.getName(), "A6B7C8");
//Has access?
URI customizingUri = conn.getBaseURI().path("webdav").path("customizing").build();
String customizingXml = conn.propfind(customizingUri, 2);
Assert.assertTrue(customizingXml.contains("<D:href>/webdav/customizing/</D:href>"));
//PUT in the folder
String randomFilename = "infos" + UUID.randomUUID() + ".txt";
URI textUri = conn.getBaseURI().path("webdav").path("customizing").path(randomFilename).build();
HttpPut put = conn.createPut(textUri);
InputStream dataStream = WebDAVCommandsTest.class.getResourceAsStream("text.txt");
InputStreamEntity entity = new InputStreamEntity(dataStream, -1);
put.setEntity(entity);
HttpResponse putResponse = conn.execute(put);
Assert.assertEquals(201, putResponse.getStatusLine().getStatusCode());
//GET
HttpGet get = conn.createGet(textUri);
HttpResponse getResponse = conn.execute(get);
Assert.assertEquals(200, getResponse.getStatusLine().getStatusCode());
String text = EntityUtils.toString(getResponse.getEntity());
Assert.assertEquals("Small text", text);
conn.close();
}
@Test
public void customizingFolder_permission()
throws IOException, URISyntaxException {
Identity user = JunitTestHelper.createAndPersistIdentityAsRndUser("user-webdav");
dbInstance.commitAndCloseSession();
WebDAVConnection conn = new WebDAVConnection();
conn.setCredentials(user.getName(), "A6B7C8");
URI customizingUri = conn.getBaseURI().path("webdav").path("customizing").build();
HttpPropFind propfind = new HttpPropFind(customizingUri);
propfind.addHeader("Depth", Integer.toString(2));
HttpResponse response = conn.execute(propfind);
Assert.assertEquals(404, response.getStatusLine().getStatusCode());
EntityUtils.consume(response.getEntity());
conn.close();
}
private VFSItem createFile(VFSContainer container, String filename) throws IOException {
VFSLeaf testLeaf = container.createChildLeaf(filename);
InputStream in = WebDAVCommandsTest.class.getResourceAsStream("text.txt");
OutputStream out = testLeaf.getOutputStream(false);
FileUtils.copy(in, out);
out.flush();
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
return container.resolve(filename);
}
private RepositoryEntry deployMkdirsCourse(Identity author)
throws URISyntaxException {
URL courseWithForumsUrl = WebDAVCommandsTest.class.getResource("mkdirs.zip");
return deployTestCourse(author, null, courseWithForumsUrl);
}
private RepositoryEntry deployTestCourse(Identity author, Identity coAuthor)
throws URISyntaxException {
URL courseWithForumsUrl = CoursePublishTest.class.getResource("myCourseWS.zip");
return deployTestCourse(author, coAuthor, courseWithForumsUrl);
}
private RepositoryEntry deployTestCourse(Identity author, Identity coAuthor, URL courseWithForumsUrl)
throws URISyntaxException {
Assert.assertNotNull(courseWithForumsUrl);
File courseWithForums = new File(courseWithForumsUrl.toURI());
String softKey = UUID.randomUUID().toString().replace("-", "").substring(0, 30);
RepositoryEntry re = CourseFactory.deployCourseFromZIP(courseWithForums, softKey, 4);
repositoryService.addRole(author, re, GroupRoles.owner.name());
if(coAuthor != null) {
repositoryService.addRole(coAuthor, re, GroupRoles.owner.name());
}
dbInstance.commitAndCloseSession();
return re;
}
}