Skip to content
Snippets Groups Projects
Commit 14bcca9c authored by srosse's avatar srosse
Browse files

OO-5234: fine grained locking of hidden files for WebDAV

parent 00e281c5
Branches
Tags
No related merge requests found
......@@ -86,7 +86,7 @@ public class LocalFileImpl extends LocalImpl implements VFSLeaf {
try {
bis = new BufferedInputStream( new FileInputStream(getBasefile()) );
} catch (FileNotFoundException e) {
log.warn("Could not create input stream for file::" + getBasefile().getAbsolutePath(), e);
log.warn("Could not create input stream for file::{}", getBasefile().getAbsolutePath(), e);
}
return bis;
}
......@@ -118,7 +118,7 @@ public class LocalFileImpl extends LocalImpl implements VFSLeaf {
try {
os = new FileOutputStream(getBasefile(), append);
} catch (FileNotFoundException e) {
log.warn("Could not create output stream for file::" + getBasefile().getAbsolutePath(), e);
log.warn("Could not create output stream for file::{}", getBasefile().getAbsolutePath(), e);
}
return os;
}
......
......@@ -20,6 +20,7 @@
package org.olat.core.util.vfs.lock;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
......@@ -28,6 +29,7 @@ import java.util.UUID;
import java.util.Vector;
import org.apache.logging.log4j.Logger;
import org.olat.core.commons.modules.bc.FolderConfig;
import org.olat.core.commons.modules.bc.FolderModule;
import org.olat.core.commons.persistence.DB;
import org.olat.core.commons.services.vfs.VFSMetadata;
......@@ -293,9 +295,38 @@ public class VFSLockManagerImpl implements VFSLockManager {
return lock;
}
/**
* Determine if the file can be locked or not. It's almost the same as the canMeta()
* implementation but some extra permission for specific WebDAV help files used by
* MacOS, Word...
*
* @param item The file
* @param type The type of application which want the lock
* @return true if it can locked
*/
public final boolean canLock(VFSItem item, VFSLockApplicationType type) {
if (item == null) return false;
if(item.canMeta() == VFSConstants.YES) {
return true;
}
if(type == VFSLockApplicationType.webdav) {
File file = extractFile(item);
if(file != null) {
Path bFile = ((LocalImpl)item).getBasefile().toPath();
if(bFile.startsWith(FolderConfig.getCanonicalRootPath())) {
String filename = item.getName();
return filename.startsWith(".~") || (filename.startsWith("._") && !filename.startsWith("._oo_"));
}
}
}
return false;
}
@Override
public LockResult lock(VFSItem item, Identity identity, VFSLockApplicationType type, String appName) {
if (item == null || item.canMeta() != VFSConstants.YES) {
if (!canLock(item, type)) {
return LockResult.LOCK_FAILED;
}
......
......@@ -24,6 +24,7 @@ import java.util.UUID;
import org.junit.Assert;
import org.junit.Test;
import org.olat.core.commons.modules.bc.FolderConfig;
import org.olat.core.commons.persistence.DB;
import org.olat.core.commons.services.vfs.VFSMetadata;
import org.olat.core.commons.services.vfs.VFSRepositoryService;
......@@ -100,6 +101,68 @@ public class VFSLockManagerTest extends OlatTestCase {
Assert.assertFalse(lockedAlt);
}
@Test
public void canLockStandardFiles() {
Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("webdav-lock-10");
VFSContainer homeFolder = VFSManager.olatRootContainer(FolderConfig.getUserHome(id), null);
VFSContainer publicContainer = VFSManager.getOrCreateContainer(homeFolder, "public");
// Some files
VFSLeaf docLeaf = publicContainer.createChildLeaf("Bonjour.docx");
Assert.assertTrue(lockManager.canLock(docLeaf, null));
VFSLeaf docHelpLeaf = publicContainer.createChildLeaf("~$Bonjour.docx");
Assert.assertTrue(lockManager.canLock(docHelpLeaf, null));
}
@Test
public void canLockOpenOlatSystemFiles() {
Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("webdav-lock-11");
VFSContainer homeFolder = VFSManager.olatRootContainer(FolderConfig.getUserHome(id), null);
VFSContainer publicContainer = VFSManager.getOrCreateContainer(homeFolder, "public");
// OpenOlat system files
VFSLeaf openolatMetadataLeaf = publicContainer.createChildLeaf("._oo_meta_Bonjour.docx");
Assert.assertFalse(lockManager.canLock(openolatMetadataLeaf, null));
VFSLeaf openolatThumbnailLeaf = publicContainer.createChildLeaf("._oo_th_Bonjour.docx");
Assert.assertFalse(lockManager.canLock(openolatThumbnailLeaf, null));
VFSLeaf openolatVersionLeaf = publicContainer.createChildLeaf("._oo_vr_Bonjour.docx");
Assert.assertFalse(lockManager.canLock(openolatVersionLeaf, null));
}
@Test
public void canLockHiddenFiles() {
Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("webdav-lock-12");
VFSContainer homeFolder = VFSManager.olatRootContainer(FolderConfig.getUserHome(id), null);
VFSContainer publicContainer = VFSManager.getOrCreateContainer(homeFolder, "public");
// macos hidden files
VFSLeaf dsStoreLeaf = publicContainer.createChildLeaf(".DS_Store");
Assert.assertFalse(lockManager.canLock(dsStoreLeaf, null));
VFSLeaf macLeaf = publicContainer.createChildLeaf("__MACOSX");
Assert.assertFalse(lockManager.canLock(macLeaf, null));
VFSLeaf hiddenLeaf = publicContainer.createChildLeaf(".somefile");
Assert.assertFalse(lockManager.canLock(hiddenLeaf, null));
}
@Test
public void canLockWebDAVHelpFiles() {
Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("webdav-lock-14");
VFSContainer homeFolder = VFSManager.olatRootContainer(FolderConfig.getUserHome(id), null);
VFSContainer publicContainer = VFSManager.getOrCreateContainer(homeFolder, "public");
// help files
VFSLeaf wordLeaf = publicContainer.createChildLeaf(".~WRD0000");
Assert.assertFalse(lockManager.canLock(wordLeaf, null));
VFSLeaf macLockLeaf = publicContainer.createChildLeaf("._file");
Assert.assertFalse(lockManager.canLock(macLockLeaf, null));
// help files used by WebDAV
VFSLeaf webDAVWordLeaf = publicContainer.createChildLeaf(".~WRD0001");
Assert.assertTrue(lockManager.canLock(webDAVWordLeaf, VFSLockApplicationType.webdav));
VFSLeaf webDAVMacLockLeaf = publicContainer.createChildLeaf("._leaf");
Assert.assertTrue(lockManager.canLock(webDAVMacLockLeaf, VFSLockApplicationType.webdav));
}
/**
* A new file cannot be locked
*/
......@@ -312,7 +375,7 @@ public class VFSLockManagerTest extends OlatTestCase {
}
/**
* A shared lock for collaboration wwith myself
* A shared lock for collaboration with myself
*/
@Test
public void lockVfsAgainstCollaborationAndMe() {
......
/**
* <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.vfs.manager;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import org.junit.Assert;
import org.junit.Test;
import org.olat.core.commons.modules.bc.FolderConfig;
import org.olat.core.commons.services.vfs.VFSRepositoryModule;
import org.olat.core.id.Identity;
import org.olat.core.util.vfs.VFSConstants;
import org.olat.test.JunitTestHelper;
import org.olat.test.OlatTestCase;
/**
*
* Initial date: 19 janv. 2021<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class VFSRepositoryModuleTest extends OlatTestCase {
@Test
public void canMetaStandardFiles() {
Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("webdav-lock-1");
String userHome = FolderConfig.getUserHome(id);
File file = new File(FolderConfig.getCanonicalRoot(), userHome);
File publicFolder = new File(file, "public");
// Standard files
Assert.assertEquals(VFSConstants.YES, VFSRepositoryModule.canMeta(new File(publicFolder, "Bonjour.docx")));
Assert.assertEquals(VFSConstants.YES, VFSRepositoryModule.canMeta(new File(publicFolder, "Hello image.jpeg")));
Assert.assertEquals(VFSConstants.YES, VFSRepositoryModule.canMeta(new File(publicFolder, "~Hello.tiff")));
// System files
Assert.assertEquals(VFSConstants.NO, VFSRepositoryModule.canMeta(new File(publicFolder, ".DS_Store")));
Assert.assertEquals(VFSConstants.NO, VFSRepositoryModule.canMeta(new File(publicFolder, "__MACOSX")));
// Hidden files
Assert.assertEquals(VFSConstants.NO, VFSRepositoryModule.canMeta(new File(publicFolder, ".Hello.tiff")));
// OpenOlat System files
Assert.assertEquals(VFSConstants.NO, VFSRepositoryModule.canMeta(new File(publicFolder, "._oo_meta_image.jpg")));
Assert.assertEquals(VFSConstants.NO, VFSRepositoryModule.canMeta(new File(publicFolder, "._oo_th_image.jpg")));
Assert.assertEquals(VFSConstants.NO, VFSRepositoryModule.canMeta(new File(publicFolder, "._oo_vr_image.jpg")));
}
@Test
public void canMetaExternalFiles() throws IOException {
File file = File.createTempFile("external", "file");
Assert.assertEquals(VFSConstants.NO, VFSRepositoryModule.canMeta(file));
Files.deleteIfExists(file.toPath());
}
}
......@@ -109,6 +109,7 @@ import org.junit.runners.Suite;
org.olat.core.commons.services.vfs.manager.VFSStatsDAOTest.class,
org.olat.core.commons.services.vfs.manager.VFSThumbnailDAOTest.class,
org.olat.core.commons.services.vfs.manager.VFSRepositoryServiceTest.class,
org.olat.core.commons.services.vfs.manager.VFSRepositoryModuleTest.class,
org.olat.core.commons.services.vfs.manager.VFSLockManagerTest.class,
org.olat.core.commons.services.vfs.manager.VFSVersioningTest.class,
org.olat.core.commons.services.help.ConfluenceHelperTest.class,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment