Skip to content
Snippets Groups Projects
Commit 5c25743f authored by srosse's avatar srosse
Browse files

OO-1004: encode softly the webdav names for group and resources to preserve as...

OO-1004: encode softly the webdav names for group and resources to preserve as much as characters as possible
parent 6b24e804
No related branches found
No related tags found
No related merge requests found
Showing
with 94 additions and 30 deletions
......@@ -28,12 +28,11 @@ package org.olat.core.commons.modules.bc;
import org.olat.core.commons.services.webdav.WebDAVProvider;
import org.olat.core.id.Identity;
import org.olat.core.manager.BasicManager;
import org.olat.core.util.vfs.VFSContainer;
/**
*
*/
public class BriefcaseWebDAVProvider extends BasicManager implements WebDAVProvider {
public class BriefcaseWebDAVProvider implements WebDAVProvider {
private static final String MOUNTPOINT = "home";
......
......@@ -26,6 +26,7 @@ package org.olat.core.commons.services.webdav.servlets;
import java.io.UnsupportedEncodingException;
import java.text.Normalizer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
......@@ -474,7 +475,19 @@ public final class RequestUtil {
}
/**
* This method remove some special characters as space, >, <,
* slash .. but preserve Umlauts. () are acceptable
* @return
*/
public static String normalizeFilename(String filename) {
String nameSanitized = filename/*.replace(" ", "_")*/
.replace("/", "_").replace("\\", "_")
.replace("?", "_").replace("<", "_").replace(">", "_")
.replace("%", "_").replace("\"", "'").replace(":", "_")
.replace("*", "_");
String nameNormalized = Normalizer.normalize(nameSanitized, Normalizer.Form.NFC);
return nameNormalized;
}
}
......@@ -26,6 +26,7 @@ import java.io.RandomAccessFile;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.text.Normalizer;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
......@@ -276,8 +277,7 @@ public class WebDAVDispatcherImpl
documentBuilder.setEntityResolver(
new WebdavResolver(req.getServletContext()));
} catch(ParserConfigurationException e) {
throw new ServletException
("webdavservlet.jaxpfailed");
throw new ServletException("webdavservlet.jaxpfailed");
}
return documentBuilder;
}
......@@ -288,8 +288,8 @@ public class WebDAVDispatcherImpl
if (webDAVManager == null) {
resp.sendError(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} else if(webDAVModule == null || !webDAVModule.isEnabled()) {
resp.sendError(WebdavStatus.SC_FORBIDDEN);
} else if (webDAVManager.handleAuthentication(req, resp)) {
resp.sendError(WebdavStatus.SC_FORBIDDEN);
} else if (webDAVManager.handleAuthentication(req, resp)) {
webdavService(req, resp);
} else {
//the method handleAuthentication will send the challenges for authentication
......@@ -402,6 +402,8 @@ public class WebDAVDispatcherImpl
if ((result == null) || (result.equals(""))) {
result = "/";
}
result = Normalizer.normalize(result, Normalizer.Form.NFC);
return (result);
}
......@@ -2004,11 +2006,12 @@ public class WebDAVDispatcherImpl
if (resource.isDirectory() && (!href.endsWith("/")))
href += "/";
generatedXML.writeText(rewriteUrl(href));
String nfcNormalizedHref = Normalizer.normalize(href, Normalizer.Form.NFC);
generatedXML.writeText(rewriteUrl(nfcNormalizedHref));
generatedXML.writeElement("D", "href", XMLWriter.CLOSING);
String resourceName = path;
String resourceName = Normalizer.normalize(path, Normalizer.Form.NFC);
int lastSlash = path.lastIndexOf('/');
if (lastSlash != -1)
resourceName = resourceName.substring(lastSlash + 1);
......@@ -2278,14 +2281,17 @@ public class WebDAVDispatcherImpl
if (!toAppend.startsWith("/"))
toAppend = "/" + toAppend;
generatedXML.writeText(rewriteUrl(RequestUtil.normalize(absoluteUri + toAppend)));
String normalizedUrl = RequestUtil.normalize(absoluteUri + toAppend);
String nfcNormalizedUrl = Normalizer.normalize(normalizedUrl, Normalizer.Form.NFC);
generatedXML.writeText(rewriteUrl(nfcNormalizedUrl));
generatedXML.writeElement("D", "href", XMLWriter.CLOSING);
String resourceName = path;
String resourceName = Normalizer.normalize(path, Normalizer.Form.NFC);
int lastSlash = path.lastIndexOf('/');
if (lastSlash != -1)
if (lastSlash != -1) {
resourceName = resourceName.substring(lastSlash + 1);
}
switch (type) {
......
......@@ -22,8 +22,8 @@ package org.olat.course;
import java.util.ArrayList;
import java.util.List;
import org.olat.core.commons.services.webdav.servlets.RequestUtil;
import org.olat.core.id.Identity;
import org.olat.core.util.Formatter;
import org.olat.core.util.vfs.MergeSource;
import org.olat.core.util.vfs.NamedContainerImpl;
import org.olat.core.util.vfs.VFSConstants;
......@@ -114,7 +114,7 @@ class CoursefolderWebDAVMergeSource extends MergeSource {
RepositoryManager rm = RepositoryManager.getInstance();
List<RepositoryEntry> entries = rm.queryByEditor(identity, CourseModule.getCourseTypeName());
for(RepositoryEntry entry:entries) {
String courseTitle = Formatter.makeStringFilesystemSave(entry.getDisplayname());
String courseTitle = RequestUtil.normalizeFilename(entry.getDisplayname());
if(childName.equals(courseTitle)) {
NamedContainerImpl cfContainer = new CoursefolderWebDAVNamedContainer(childName, entry.getOlatResource());
String nextPath = path.substring(childName.length() + 1);
......@@ -133,7 +133,7 @@ class CoursefolderWebDAVMergeSource extends MergeSource {
List<VFSContainer> containers = new ArrayList<>();
// Add all found repo entries to merge source
for (RepositoryEntry re:courseEntries) {
String courseTitle = Formatter.makeStringFilesystemSave(re.getDisplayname());
String courseTitle = RequestUtil.normalizeFilename(re.getDisplayname());
NamedContainerImpl cfContainer = new CoursefolderWebDAVNamedContainer(courseTitle, re.getOlatResource());
addContainerToList(cfContainer, containers);
}
......
......@@ -29,8 +29,8 @@ import org.olat.collaboration.CollaborationManager;
import org.olat.collaboration.CollaborationTools;
import org.olat.core.CoreSpringFactory;
import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
import org.olat.core.commons.services.webdav.servlets.RequestUtil;
import org.olat.core.id.Identity;
import org.olat.core.util.Formatter;
import org.olat.core.util.notifications.SubscriptionContext;
import org.olat.core.util.vfs.MergeSource;
import org.olat.core.util.vfs.NamedContainerImpl;
......@@ -129,7 +129,7 @@ class GroupfoldersWebDAVMergeSource extends MergeSource {
continue;
}
name = Formatter.makeStringFilesystemSave(name);
name = RequestUtil.normalizeFilename(name);
if(childName.equals(name)) {
String nextPath = path.substring(childName.length() + 1);
VFSContainer grpContainer = getGroupContainer(name, group, false);
......@@ -209,10 +209,9 @@ class GroupfoldersWebDAVMergeSource extends MergeSource {
// create container and set quota
OlatRootFolderImpl localImpl = new OlatRootFolderImpl(folderPath, this);
//already done in OlatRootFolderImpl localImpl.getBasefile().mkdirs(); // lazy initialize dirs
NamedContainerImpl grpContainer = new NamedContainerImpl(Formatter.makeStringFilesystemSave(name), localImpl);
//fxdiff VCRP-8: collaboration tools folder access control
String containerName = RequestUtil.normalizeFilename(name);
NamedContainerImpl grpContainer = new NamedContainerImpl(containerName, localImpl);
boolean writeAccess;
if (!isOwner) {
// check if participants have read/write access
......
......@@ -30,11 +30,11 @@ import java.io.File;
import org.olat.core.commons.modules.bc.vfs.OlatNamedContainerImpl;
import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
import org.olat.core.commons.persistence.DBFactory;
import org.olat.core.commons.services.webdav.servlets.RequestUtil;
import org.olat.core.gui.media.CleanupAfterDeliveryFileMediaResource;
import org.olat.core.gui.media.MediaResource;
import org.olat.core.id.OLATResourceable;
import org.olat.core.manager.BasicManager;
import org.olat.core.util.Formatter;
import org.olat.core.util.WebappHelper;
import org.olat.core.util.ZipUtil;
import org.olat.core.util.vfs.LocalFileImpl;
......@@ -77,7 +77,7 @@ public class SharedFolderManager extends BasicManager {
public VFSContainer getNamedSharedFolder(RepositoryEntry re, boolean urlCompliant) {
String name = re.getDisplayname();
if(urlCompliant) {
name = Formatter.makeStringFilesystemSave(name);
name = RequestUtil.normalizeFilename(name);
}
return new OlatNamedContainerImpl(name, getSharedFolder(re.getOlatResource()));
}
......
......@@ -27,11 +27,11 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.olat.core.commons.services.webdav.servlets.RequestUtil;
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.Formatter;
import org.olat.core.util.vfs.MergeSource;
import org.olat.core.util.vfs.VFSContainer;
import org.olat.core.util.vfs.VFSItem;
......@@ -95,7 +95,7 @@ public class SharedFolderWebDAVMergeSource extends MergeSource {
//lookup in my shared folders
List<RepositoryEntry> ownerEntries = repoManager.queryByOwner(identity, SharedFolderFileResource.TYPE_NAME);
for (RepositoryEntry re : ownerEntries) {
String name = Formatter.makeStringFilesystemSave(re.getDisplayname());
String name = RequestUtil.normalizeFilename(re.getDisplayname());
if(childName.equals(name)) {
VFSContainer shared = getSharedContainer(re, false);
String nextPath = path.substring(childName.length() + 1);
......@@ -112,7 +112,7 @@ public class SharedFolderWebDAVMergeSource extends MergeSource {
List<String> types = Collections.singletonList(SharedFolderFileResource.TYPE_NAME);
List<RepositoryEntry> allEntries = repoManager.queryByTypeLimitAccess(identity, types, registeredUserRole);
for (RepositoryEntry re : allEntries) {
String name = Formatter.makeStringFilesystemSave(re.getDisplayname());
String name = RequestUtil.normalizeFilename(re.getDisplayname());
if(childName.equals(name)) {
VFSContainer shared = getSharedContainer(re, true);
String nextPath = path.substring(childName.length() + 1);
......@@ -124,7 +124,7 @@ public class SharedFolderWebDAVMergeSource extends MergeSource {
List<Long> publiclyReadableFoldersKeys = getSharedKeys();
List<RepositoryEntry> entries = repoManager.lookupRepositoryEntries(publiclyReadableFoldersKeys);
for (RepositoryEntry re:entries) {
String name = Formatter.makeStringFilesystemSave(re.getDisplayname());
String name = RequestUtil.normalizeFilename(re.getDisplayname());
if (childName.equals(name) &&
(re.getAccess() >= RepositoryEntry.ACC_USERS || (re.getAccess() == RepositoryEntry.ACC_OWNERS && re.isMembersOnly()))) {
......
......@@ -29,7 +29,6 @@ import java.util.List;
import org.olat.core.commons.services.webdav.WebDAVProvider;
import org.olat.core.id.Identity;
import org.olat.core.logging.LogDelegator;
import org.olat.core.util.vfs.VFSContainer;
import org.olat.core.util.vfs.callbacks.ReadOnlyCallback;
import org.olat.core.util.vfs.callbacks.VFSSecurityCallback;
......@@ -40,7 +39,7 @@ import org.olat.core.util.vfs.callbacks.VFSSecurityCallback;
*
* @author Alexander Schneider, Gregor Wassmann
*/
public class SharedFolderWebDAVProvider extends LogDelegator implements WebDAVProvider {
public class SharedFolderWebDAVProvider implements WebDAVProvider {
private static List<String> publiclyReadableFolders;
protected static final VFSSecurityCallback readOnlyCallback = new ReadOnlyCallback();
......
/**
* <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.servlets;
import junit.framework.Assert;
import org.junit.Test;
/**
*
* Initial date: 04.03.2014<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class RequestUtilsTest {
@Test
public void testNormalizeFilename() {
String simpleFilename = RequestUtil.normalizeFilename("Test");
Assert.assertEquals("Test", simpleFilename);
String accentFilename = RequestUtil.normalizeFilename("Test\u00E9\u00E4");
Assert.assertEquals("Test\u00E9\u00E4", accentFilename);
String moreSpecialChars = RequestUtil.normalizeFilename("%12 ?()_//");
Assert.assertEquals("_12 _()___", moreSpecialChars);
}
}
......@@ -80,6 +80,7 @@ import org.junit.runners.Suite;
org.olat.commons.coordinate.CoordinatorTest.class,//ok
org.olat.core.commons.services.webdav.WebDAVCommandsTest.class,//ok
org.olat.core.commons.services.webdav.manager.WebDAVManagerTest.class,//ok
org.olat.core.commons.services.webdav.servlets.RequestUtilsTest.class,//ok
org.olat.core.commons.services.taskexecutor.PersistentTaskDAOTest.class,//ok
org.olat.core.commons.services.taskexecutor.TaskExecutorManagerTest.class,//ok
org.olat.admin.user.delete.service.UserDeletionManagerTest.class,//ok
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment