diff --git a/pom.xml b/pom.xml
index 0024cfcb..c629d286 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
4.0.0
org.italiangrid
storm-webdav-server
- 1.0.2
+ 1.0.3
jar
storm-webdav-server
@@ -42,6 +42,7 @@
3.2.5.RELEASE
2.1.3.RELEASE
+ 1.10.19
@@ -337,6 +338,14 @@
commons-cli
${commons-cli.version}
+
+
+ org.mockito
+ mockito-core
+ ${mockito-core.version}
+ test
+
+
diff --git a/src/main/java/org/italiangrid/storm/webdav/authz/CopyMoveAuthzVoter.java b/src/main/java/org/italiangrid/storm/webdav/authz/CopyMoveAuthzVoter.java
index eaa8a551..c687556c 100644
--- a/src/main/java/org/italiangrid/storm/webdav/authz/CopyMoveAuthzVoter.java
+++ b/src/main/java/org/italiangrid/storm/webdav/authz/CopyMoveAuthzVoter.java
@@ -25,6 +25,7 @@
import org.italiangrid.storm.webdav.config.StorageAreaConfiguration;
import org.italiangrid.storm.webdav.config.StorageAreaInfo;
+import org.italiangrid.storm.webdav.server.PathResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDecisionVoter;
@@ -45,10 +46,13 @@ public class CopyMoveAuthzVoter implements
.compile(WEBDAV_PATH_REGEX);
final StorageAreaConfiguration saConfig;
-
- public CopyMoveAuthzVoter(StorageAreaConfiguration saConfig) {
+ final PathResolver pathResolver;
+
+ public CopyMoveAuthzVoter(StorageAreaConfiguration saConfig,
+ PathResolver pathResolver) {
this.saConfig = saConfig;
+ this.pathResolver = pathResolver;
}
@Override
@@ -85,18 +89,8 @@ private StorageAreaInfo getSAFromPath(String destinationURL)
throws MalformedURLException {
URL url = new URL(destinationURL);
-
- String path = dropSlashWebdavFromPath(url.getPath());
-
- for (StorageAreaInfo sa : saConfig.getStorageAreaInfo()) {
- for (String ap : sa.accessPoints()) {
- if (path.startsWith(ap)) {
- return sa;
- }
- }
- }
-
- return null;
+ String pathInContext = dropSlashWebdavFromPath(url.getPath());
+ return pathResolver.resolveStorageArea(pathInContext);
}
@Override
diff --git a/src/main/java/org/italiangrid/storm/webdav/server/DefaultPathResolver.java b/src/main/java/org/italiangrid/storm/webdav/server/DefaultPathResolver.java
index fe4b4cc3..f7a7878b 100644
--- a/src/main/java/org/italiangrid/storm/webdav/server/DefaultPathResolver.java
+++ b/src/main/java/org/italiangrid/storm/webdav/server/DefaultPathResolver.java
@@ -22,6 +22,7 @@
import org.eclipse.jetty.util.URIUtil;
import org.italiangrid.storm.webdav.config.StorageAreaConfiguration;
import org.italiangrid.storm.webdav.config.StorageAreaInfo;
+import org.italiangrid.storm.webdav.server.PathResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,18 +33,18 @@ public class DefaultPathResolver implements PathResolver {
private static final Logger logger = LoggerFactory
.getLogger(DefaultPathResolver.class);
- private final NavigableMap contextMap;
+ private final NavigableMap contextMap;
public DefaultPathResolver(StorageAreaConfiguration cfg) {
this.saConfig = cfg;
- contextMap = new TreeMap();
+ contextMap = new TreeMap();
for (StorageAreaInfo sa : saConfig.getStorageAreaInfo()) {
for (String ap : sa.accessPoints()) {
logger.debug("Adding path mapping for sa {}: {} -> {}", sa.name(), ap,
sa.rootPath());
- contextMap.put(ap, sa.rootPath());
+ contextMap.put(ap, sa);
}
}
@@ -61,11 +62,11 @@ protected String stripContextPath(String context, String path) {
@Override
public String resolvePath(String pathInContext) {
- for (Map.Entry e : contextMap.descendingMap().entrySet()) {
+ for (Map.Entry e : contextMap.descendingMap().entrySet()) {
if (pathInContext.startsWith(e.getKey())) {
- String resolvedPath = URIUtil.addPaths(e.getValue(),
+ String resolvedPath = URIUtil.addPaths(e.getValue().rootPath(),
stripContextPath(e.getKey(), pathInContext));
if (logger.isDebugEnabled()) {
@@ -80,4 +81,22 @@ public String resolvePath(String pathInContext) {
return null;
}
+ @Override
+ public StorageAreaInfo resolveStorageArea(String pathInContext) {
+
+ for (Map.Entry e : contextMap.descendingMap().entrySet()) {
+
+ if (pathInContext.startsWith(e.getKey())) {
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("{} matches with access point {}. Resolved storage area name: {}",
+ pathInContext, e.getKey(), e.getValue().name());
+ }
+
+ return e.getValue();
+ }
+ }
+ return null;
+ }
+
}
diff --git a/src/main/java/org/italiangrid/storm/webdav/server/PathResolver.java b/src/main/java/org/italiangrid/storm/webdav/server/PathResolver.java
index 75ebe003..8c74fcca 100644
--- a/src/main/java/org/italiangrid/storm/webdav/server/PathResolver.java
+++ b/src/main/java/org/italiangrid/storm/webdav/server/PathResolver.java
@@ -15,9 +15,13 @@
*/
package org.italiangrid.storm.webdav.server;
+import org.italiangrid.storm.webdav.config.StorageAreaInfo;
+
public interface PathResolver {
public String resolvePath(String pathInContext);
+
+ public StorageAreaInfo resolveStorageArea(String pathInContext);
}
diff --git a/src/main/java/org/italiangrid/storm/webdav/spring/web/SecurityConfig.java b/src/main/java/org/italiangrid/storm/webdav/spring/web/SecurityConfig.java
index e598fbd5..ddf19cc8 100644
--- a/src/main/java/org/italiangrid/storm/webdav/spring/web/SecurityConfig.java
+++ b/src/main/java/org/italiangrid/storm/webdav/spring/web/SecurityConfig.java
@@ -33,6 +33,7 @@
import org.italiangrid.storm.webdav.config.ServiceConfiguration;
import org.italiangrid.storm.webdav.config.StorageAreaConfiguration;
import org.italiangrid.storm.webdav.config.StorageAreaInfo;
+import org.italiangrid.storm.webdav.server.PathResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -61,11 +62,14 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
VOMapDetailsService vomsMapDetailsService;
+
+ @Autowired
+ PathResolver pathResolver;
@Bean
public AccessDecisionVoter customVoter() {
- return new CopyMoveAuthzVoter(saConfiguration);
+ return new CopyMoveAuthzVoter(saConfiguration, pathResolver);
}
@Bean
diff --git a/src/test/java/org/italiangrid/storm/webdav/authz/vomsmap/PathResolverTests.java b/src/test/java/org/italiangrid/storm/webdav/authz/vomsmap/PathResolverTests.java
new file mode 100644
index 00000000..942bf84b
--- /dev/null
+++ b/src/test/java/org/italiangrid/storm/webdav/authz/vomsmap/PathResolverTests.java
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) Istituto Nazionale di Fisica Nucleare, 2014.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.italiangrid.storm.webdav.authz.vomsmap;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.italiangrid.storm.webdav.config.StorageAreaConfiguration;
+import org.italiangrid.storm.webdav.config.StorageAreaInfo;
+import org.italiangrid.storm.webdav.server.DefaultPathResolver;
+import org.italiangrid.storm.webdav.server.PathResolver;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class PathResolverTests {
+
+ private final String ROOTDIR = "/storage";
+
+ /*
+ * Map SA-name -> VO name
+ */
+ private static Map input;
+
+ @BeforeClass
+ public static void init() {
+
+ input = new HashMap();
+ input.put("test.vo.bis", "testers.eu-emi.eu");
+ input.put("test.vo", "test.vo");
+ input.put("test1", "testers.eu-emi.eu");
+ input.put("test12", "test.vo");
+ input.put("12test.", "testers.eu-emi.eu");
+ input.put("12test", "test.vo");
+ input.put("1", "testers.eu-emi.eu");
+ input.put("12", "test.vo");
+ input.put(".", "testers.eu-emi.eu");
+ input.put(".1", "test.vo");
+ }
+
+ PathResolver pathResolver;
+ StorageAreaConfiguration saConfig;
+ List saInfoList;
+
+ @Before
+ public void setup() {
+
+ saInfoList = new ArrayList();
+ for (String ap : input.keySet()) {
+ saInfoList.add(getMockSAInfo(ap, input.get(ap)));
+ }
+
+ saConfig = mock(StorageAreaConfiguration.class);
+ when(saConfig.getStorageAreaInfo()).thenReturn(saInfoList);
+
+ pathResolver = new DefaultPathResolver(saConfig);
+ }
+
+ private StorageAreaInfo getMockSAInfo(String name, String voname) {
+
+ StorageAreaInfo saInfo = mock(StorageAreaInfo.class);
+
+ String ap = "/".concat(name);
+ String rootPath = ROOTDIR.concat("/").concat(voname);
+
+ when(saInfo.name()).thenReturn(name);
+ when(saInfo.accessPoints()).thenReturn(Arrays.asList(ap));
+ when(saInfo.rootPath()).thenReturn(rootPath);
+ when(saInfo.vos()).thenReturn(new HashSet(Arrays.asList(voname)));
+
+ return saInfo;
+ }
+
+ @Test
+ public void checkResolvedRootPath() {
+
+ for (String name : input.keySet()) {
+
+ String pathToTest = "/".concat(name).concat("/testdir");
+ String expectedRootPath = ROOTDIR.concat("/").concat(input.get(name))
+ .concat("/testdir");
+
+ String rootPath = pathResolver.resolvePath(pathToTest);
+ Assert.assertEquals(expectedRootPath, rootPath);
+ }
+
+ }
+
+ @Test
+ public void checkResolvedStorageArea() {
+
+ for (String name : input.keySet()) {
+
+ String pathToTest = "/".concat(name).concat("/testdir");
+ String expectedRootPath = ROOTDIR.concat("/").concat(input.get(name))
+ .concat("/testdir");
+
+ StorageAreaInfo sa = pathResolver.resolveStorageArea(pathToTest);
+ Assert.assertEquals(expectedRootPath, sa.rootPath() + "/testdir");
+ }
+ }
+
+}