From 7e0a732731b03d0fd28d956da15fbdf04a223708 Mon Sep 17 00:00:00 2001
From: Sonia Zorba <sonia.zorba@inaf.it>
Date: Thu, 11 Nov 2021 17:42:20 +0100
Subject: [PATCH] Fixed special characters issue on pullFromVoSpace

---
 .../inaf/oats/vospace/FileServiceClient.java  |  1 -
 .../java/it/inaf/oats/vospace/UriService.java |  6 +++-
 .../it/inaf/oats/vospace/UriServiceTest.java  | 32 +++++++++++++++++++
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/src/main/java/it/inaf/oats/vospace/FileServiceClient.java b/src/main/java/it/inaf/oats/vospace/FileServiceClient.java
index 89d6912..d593893 100644
--- a/src/main/java/it/inaf/oats/vospace/FileServiceClient.java
+++ b/src/main/java/it/inaf/oats/vospace/FileServiceClient.java
@@ -28,7 +28,6 @@ import org.springframework.http.HttpMethod;
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Component;
 import org.springframework.web.client.RestTemplate;
-import static org.springframework.web.servlet.mvc.method.RequestMappingInfo.paths;
 
 @Component
 public class FileServiceClient {
diff --git a/src/main/java/it/inaf/oats/vospace/UriService.java b/src/main/java/it/inaf/oats/vospace/UriService.java
index aacc7fa..03162bb 100644
--- a/src/main/java/it/inaf/oats/vospace/UriService.java
+++ b/src/main/java/it/inaf/oats/vospace/UriService.java
@@ -26,6 +26,7 @@ import it.inaf.oats.vospace.persistence.model.Location;
 import it.inaf.oats.vospace.persistence.model.LocationType;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -41,6 +42,7 @@ import net.ivoa.xml.vospace.v2.Transfer;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
 
 @Service
 public class UriService {
@@ -179,7 +181,8 @@ public class UriService {
 
     private String getEndpoint(JobSummary job, Transfer transfer) {
 
-        String relativePath = URIUtils.returnVosPathFromNodeURI(transfer.getTarget(), authority);
+        String relativePath = StringUtils.uriDecode(URIUtils
+                .returnVosPathFromNodeURI(transfer.getTarget(), authority), StandardCharsets.UTF_8);
 
         User user = (User) servletRequest.getUserPrincipal();
         String creator = user.getName();
@@ -201,6 +204,7 @@ public class UriService {
             case pullFromVoSpace:
                 // Refresh relative path: it can differ in case of links followed 
                 relativePath = NodeUtils.getVosPath(node);
+                relativePath = StringUtils.uriDecode(relativePath, StandardCharsets.UTF_8);
                 if (!NodeUtils.checkIfReadable(node, creator, groups)) {
                     throw PermissionDeniedException.forPath(relativePath);
                 }
diff --git a/src/test/java/it/inaf/oats/vospace/UriServiceTest.java b/src/test/java/it/inaf/oats/vospace/UriServiceTest.java
index 3b98d4f..a62f19e 100644
--- a/src/test/java/it/inaf/oats/vospace/UriServiceTest.java
+++ b/src/test/java/it/inaf/oats/vospace/UriServiceTest.java
@@ -560,6 +560,38 @@ public class UriServiceTest {
         assertTrue(ex.getMessage().contains("no protocol"));
     }
 
+    @Test
+    public void testPullFileWithSpecialChars() {
+
+        DataNode node = new DataNode();
+        node.setUri("vos://example.com!vospace/(%20+%20).txt");
+
+        Property publicProperty = new Property();
+        publicProperty.setUri(NodeProperties.PUBLIC_READ_URI);
+        publicProperty.setValue(String.valueOf(true));
+        node.getProperties().add(publicProperty);
+
+        when(nodeDAO.listNode(eq("/( + ).txt"))).thenReturn(Optional.of(node));
+
+        Transfer transfer = new Transfer();
+        transfer.setDirection("pullFromVoSpace");
+        transfer.setTarget("vos://example.com!vospace/(%20+%20).txt");
+
+        Protocol protocol = new Protocol();
+        protocol.setUri("ivo://ivoa.net/vospace/core#httpget");
+        transfer.getProtocols().add(protocol);
+
+        JobSummary job = new JobSummary();
+        JobSummary.JobInfo jobInfo = new JobSummary.JobInfo();
+        jobInfo.getAny().add(transfer);
+        job.setJobInfo(jobInfo);
+
+        Transfer negotiatedTransfer = uriService.getNegotiatedTransfer(job, transfer);
+
+        assertEquals(1, negotiatedTransfer.getProtocols().size());
+        assertTrue(negotiatedTransfer.getProtocols().get(0).getEndpoint().contains("/%28%20%2B%20%29.txt"));
+    }
+
     private void testArchiveViewEndpoint(String viewUri) {
 
         Transfer transfer = new Transfer();
-- 
GitLab