From f7e6f83b2e80a2b7034bf69b8e21195dd0618264 Mon Sep 17 00:00:00 2001 From: enricovianello Date: Fri, 15 May 2015 16:28:24 +0200 Subject: [PATCH 1/6] fix for https://issues.infn.it/jira/browse/STOR-795 --- .../webdav/authz/CopyMoveAuthzVoter.java | 22 +++++--------- .../webdav/server/DefaultPathResolver.java | 29 +++++++++++++++---- .../storm/webdav/server/PathResolver.java | 4 +++ .../webdav/spring/web/SecurityConfig.java | 6 +++- 4 files changed, 41 insertions(+), 20 deletions(-) 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 From 4c0123f678c1632babbda75f2e613258d88f4870 Mon Sep 17 00:00:00 2001 From: enricovianello Date: Tue, 19 May 2015 10:22:10 +0200 Subject: [PATCH 2/6] Added PathResolver tests --- pom.xml | 9 ++ .../authz/vomsmap/PathResolverTests.java | 104 ++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 src/test/java/org/italiangrid/storm/webdav/authz/vomsmap/PathResolverTests.java diff --git a/pom.xml b/pom.xml index 0024cfcb..3b7eafe6 100644 --- a/pom.xml +++ b/pom.xml @@ -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/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..a72509b5 --- /dev/null +++ b/src/test/java/org/italiangrid/storm/webdav/authz/vomsmap/PathResolverTests.java @@ -0,0 +1,104 @@ +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.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; + + static { + + 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"); + + } + + 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 checkPathResolver() { + + for (String name : input.keySet()) { + + String pathToTest = "/".concat(name).concat("/testdir"); + String expectedRootPath = ROOTDIR.concat("/").concat(input.get(name)) + .concat("/testdir"); + + checkResolvedRootPath(pathToTest, expectedRootPath); + checkResolvedStorageArea(pathToTest, expectedRootPath); + + } + + } + + private void checkResolvedRootPath(String pathToTest, String expectedRootPath) { + + String rootPath = pathResolver.resolvePath(pathToTest); + Assert.assertEquals(expectedRootPath, rootPath); + } + + private void checkResolvedStorageArea(String pathToTest, + String expectedRootPath) { + + StorageAreaInfo sa = pathResolver.resolveStorageArea(pathToTest); + Assert.assertEquals(expectedRootPath, sa.rootPath() + "/testdir"); + } + +} From ae1e357fd96b5c90b3d982e7b996cc05b6d0134b Mon Sep 17 00:00:00 2001 From: enricovianello Date: Tue, 19 May 2015 10:36:24 +0200 Subject: [PATCH 3/6] Cosmetic fixes to PathResolver tests --- .../authz/vomsmap/PathResolverTests.java | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) 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 index a72509b5..b3d0408e 100644 --- a/src/test/java/org/italiangrid/storm/webdav/authz/vomsmap/PathResolverTests.java +++ b/src/test/java/org/italiangrid/storm/webdav/authz/vomsmap/PathResolverTests.java @@ -13,6 +13,7 @@ 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; @@ -27,7 +28,8 @@ public class PathResolverTests { */ private static Map input; - static { + @BeforeClass + public static void init() { input = new HashMap(); input.put("test.vo.bis", "testers.eu-emi.eu"); @@ -36,7 +38,10 @@ public class PathResolverTests { 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; @@ -73,32 +78,32 @@ private StorageAreaInfo getMockSAInfo(String name, String voname) { } @Test - public void checkPathResolver() { + public void checkResolvedRootPath() { for (String name : input.keySet()) { String pathToTest = "/".concat(name).concat("/testdir"); String expectedRootPath = ROOTDIR.concat("/").concat(input.get(name)) .concat("/testdir"); - - checkResolvedRootPath(pathToTest, expectedRootPath); - checkResolvedStorageArea(pathToTest, expectedRootPath); - + + String rootPath = pathResolver.resolvePath(pathToTest); + Assert.assertEquals(expectedRootPath, rootPath); } } + + @Test + public void checkResolvedStorageArea() { - private void checkResolvedRootPath(String pathToTest, String expectedRootPath) { - - String rootPath = pathResolver.resolvePath(pathToTest); - Assert.assertEquals(expectedRootPath, rootPath); - } - - private void checkResolvedStorageArea(String pathToTest, - String expectedRootPath) { + for (String name : input.keySet()) { - StorageAreaInfo sa = pathResolver.resolveStorageArea(pathToTest); - Assert.assertEquals(expectedRootPath, sa.rootPath() + "/testdir"); + 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"); + } } } From 0dd7fcf154d07e7c06d1cea74634e57cc726f16e Mon Sep 17 00:00:00 2001 From: enricovianello Date: Tue, 19 May 2015 10:54:27 +0200 Subject: [PATCH 4/6] Cosmetic fixes --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 3b7eafe6..af9598cb 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ 3.2.5.RELEASE 2.1.3.RELEASE - 1.10.19 + 1.10.19 @@ -338,14 +338,14 @@ commons-cli ${commons-cli.version} - + org.mockito mockito-core ${mockito-core.version} test - + From 320416114082fe00af827e3b3986389d233599bc Mon Sep 17 00:00:00 2001 From: enricovianello Date: Tue, 19 May 2015 11:46:19 +0200 Subject: [PATCH 5/6] Bump version to 1.0.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index af9598cb..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 From dd0adb99f7adfcf1d7410b77be025906728c6c29 Mon Sep 17 00:00:00 2001 From: enricovianello Date: Tue, 19 May 2015 15:58:58 +0200 Subject: [PATCH 6/6] Fixed missing license header --- .../webdav/authz/vomsmap/PathResolverTests.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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 index b3d0408e..942bf84b 100644 --- a/src/test/java/org/italiangrid/storm/webdav/authz/vomsmap/PathResolverTests.java +++ b/src/test/java/org/italiangrid/storm/webdav/authz/vomsmap/PathResolverTests.java @@ -1,3 +1,18 @@ +/** + * 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;