Skip to content
Snippets Groups Projects
Commit c5e4fcb8 authored by Nicola Fulvio Calabria's avatar Nicola Fulvio Calabria
Browse files

Added external link logic to URIService

parent 11f818f8
No related branches found
No related tags found
No related merge requests found
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
package it.inaf.oats.vospace; package it.inaf.oats.vospace;
import it.inaf.ia2.aa.data.User; import it.inaf.ia2.aa.data.User;
import it.inaf.oats.vospace.exception.InvalidURIException;
import net.ivoa.xml.vospace.v2.LinkNode; import net.ivoa.xml.vospace.v2.LinkNode;
import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Node;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
......
...@@ -18,6 +18,13 @@ public class URIUtils { ...@@ -18,6 +18,13 @@ public class URIUtils {
// Slashes are treated separately // Slashes are treated separately
private static final Pattern FORBIDDEN_CHARS = Pattern.compile("[\\x00\\x08\\x0B\\x0C\\x0E-\\x1F" + Pattern.quote("<>?\":\\|'`*") + "]"); private static final Pattern FORBIDDEN_CHARS = Pattern.compile("[\\x00\\x08\\x0B\\x0C\\x0E-\\x1F" + Pattern.quote("<>?\":\\|'`*") + "]");
private static final String SCHEME = "vos"; private static final String SCHEME = "vos";
public static boolean isURIInternal(String URI) {
if(URI == null)
throw new IllegalArgumentException("URI can't be null");
return URI.toLowerCase().startsWith(SCHEME);
}
public static String returnURIFromVosPath(String vosPath, String authority) { public static String returnURIFromVosPath(String vosPath, String authority) {
String result = null; String result = null;
......
...@@ -19,6 +19,7 @@ import it.inaf.oats.vospace.exception.NodeNotFoundException; ...@@ -19,6 +19,7 @@ import it.inaf.oats.vospace.exception.NodeNotFoundException;
import it.inaf.oats.vospace.exception.PermissionDeniedException; import it.inaf.oats.vospace.exception.PermissionDeniedException;
import it.inaf.oats.vospace.exception.ProtocolNotSupportedException; import it.inaf.oats.vospace.exception.ProtocolNotSupportedException;
import it.inaf.oats.vospace.exception.NodeBusyException; import it.inaf.oats.vospace.exception.NodeBusyException;
import it.inaf.oats.vospace.persistence.LinkedServiceDAO;
import it.inaf.oats.vospace.persistence.LocationDAO; import it.inaf.oats.vospace.persistence.LocationDAO;
import it.inaf.oats.vospace.persistence.NodeDAO; import it.inaf.oats.vospace.persistence.NodeDAO;
import it.inaf.oats.vospace.persistence.model.Location; import it.inaf.oats.vospace.persistence.model.Location;
...@@ -58,6 +59,9 @@ public class UriService { ...@@ -58,6 +59,9 @@ public class UriService {
@Autowired @Autowired
private LocationDAO locationDAO; private LocationDAO locationDAO;
@Autowired
private LinkedServiceDAO linkedServiceDAO;
@Autowired @Autowired
private HttpServletRequest servletRequest; private HttpServletRequest servletRequest;
...@@ -168,7 +172,7 @@ public class UriService { ...@@ -168,7 +172,7 @@ public class UriService {
JobService.JobDirection jobType JobService.JobDirection jobType
= JobDirection.getJobDirectionEnumFromTransfer(transfer); = JobDirection.getJobDirectionEnumFromTransfer(transfer);
Node node = this.getEndpointNode(relativePath, jobType, user); Node node = this.getEndpointNode(relativePath, jobType, user);
switch (jobType) { switch (jobType) {
case pushToVoSpace: case pushToVoSpace:
case pullToVoSpace: case pullToVoSpace:
...@@ -178,7 +182,7 @@ public class UriService { ...@@ -178,7 +182,7 @@ public class UriService {
break; break;
case pullFromVoSpace: case pullFromVoSpace:
// Refresh relative path: it can differ in case of links // Refresh relative path: it can differ in case of links followed
relativePath = NodeUtils.getVosPath(node); relativePath = NodeUtils.getVosPath(node);
if (!NodeUtils.checkIfReadable(node, creator, groups)) { if (!NodeUtils.checkIfReadable(node, creator, groups)) {
throw PermissionDeniedException.forPath(relativePath); throw PermissionDeniedException.forPath(relativePath);
...@@ -197,24 +201,36 @@ public class UriService { ...@@ -197,24 +201,36 @@ public class UriService {
return fileServiceClient.startArchiveJob(transfer, job.getJobId()); return fileServiceClient.startArchiveJob(transfer, job.getJobId());
} }
Location location = locationDAO.getNodeLocation(relativePath).orElse(null); boolean isLinkNode = node instanceof LinkNode;
String endpoint; String endpoint;
if (location != null && location.getType() == LocationType.PORTAL) { if (isLinkNode) {
String fileName = nodeDao.getNodeOsName(relativePath); endpoint = ((LinkNode) node).getTarget();
endpoint = "http://" + location.getSource().getHostname() + location.getSource().getBaseUrl();
if (!endpoint.endsWith("/")) {
endpoint += "/";
}
endpoint += fileName;
} else { } else {
endpoint = fileServiceUrl + urlEncodePath(relativePath);
Location location = locationDAO.getNodeLocation(relativePath).orElse(null);
if (location != null && location.getType() == LocationType.PORTAL) {
String fileName = nodeDao.getNodeOsName(relativePath);
endpoint = "http://" + location.getSource().getHostname() + location.getSource().getBaseUrl();
if (!endpoint.endsWith("/")) {
endpoint += "/";
}
endpoint += fileName;
} else {
endpoint = fileServiceUrl + urlEncodePath(relativePath);
}
} }
endpoint += "?jobId=" + job.getJobId(); endpoint += "?jobId=" + job.getJobId();
if (!"true".equals(NodeProperties.getNodePropertyByURI(node, NodeProperties.PUBLIC_READ_URI))) { if (isLinkNode) {
String linkTarget = ((LinkNode) node).getTarget();
if (linkedServiceDAO.isLinkedServiceUrl(linkTarget)) {
endpoint += "&token=" + getEndpointToken(linkTarget);
}
} else if (!"true".equals(NodeProperties.getNodePropertyByURI(node, NodeProperties.PUBLIC_READ_URI))) {
endpoint += "&token=" + getEndpointToken(fileServiceUrl + relativePath); endpoint += "&token=" + getEndpointToken(fileServiceUrl + relativePath);
} }
...@@ -287,21 +303,27 @@ public class UriService { ...@@ -287,21 +303,27 @@ public class UriService {
} }
private Node followLinkRecursive(LinkNode linkNode, int depth) { private Node followLinkRecursive(LinkNode linkNode, int depth) {
if(depth >= linkMaxDepth) { if (depth >= linkMaxDepth) {
throw new InternalFaultException("Max link depth reached at link node: " throw new InternalFaultException("Max link depth reached at link node: "
+ NodeUtils.getVosPath(linkNode)); + NodeUtils.getVosPath(linkNode));
} }
String targetPath = URIUtils.returnVosPathFromNodeURI(linkNode.getTarget(), authority); String linkTarget = linkNode.getTarget();
Optional<Node> targetNodeOpt = nodeDao.listNode(targetPath); if (URIUtils.isURIInternal(linkTarget)) {
Node targetNode = targetNodeOpt.orElseThrow(() -> new InternalFaultException("Broken Link to target: " + targetPath)); return linkNode;
} else {
if(targetNode instanceof LinkNode) { String targetPath = URIUtils.returnVosPathFromNodeURI(linkTarget, authority);
return this.followLinkRecursive(linkNode, ++depth);
} else { Optional<Node> targetNodeOpt = nodeDao.listNode(targetPath);
return targetNode; Node targetNode = targetNodeOpt.orElseThrow(() -> new InternalFaultException("Broken Link to target: " + targetPath));
if (targetNode instanceof LinkNode) {
return this.followLinkRecursive(linkNode, ++depth);
} else {
return targetNode;
}
} }
} }
} }
...@@ -27,7 +27,7 @@ public class LinkedServiceDAO { ...@@ -27,7 +27,7 @@ public class LinkedServiceDAO {
jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate = new JdbcTemplate(dataSource);
} }
boolean isLinkedServiceUrl(String targetUrl) { public boolean isLinkedServiceUrl(String targetUrl) {
String sql = " SELECT COUNT(*) > 0\n" String sql = " SELECT COUNT(*) > 0\n"
+ "FROM linked_service\n" + "FROM linked_service\n"
+ "WHERE ? LIKE service_base_url || '%'"; + "WHERE ? LIKE service_base_url || '%'";
......
...@@ -8,7 +8,9 @@ package it.inaf.oats.vospace; ...@@ -8,7 +8,9 @@ package it.inaf.oats.vospace;
import it.inaf.oats.vospace.exception.InvalidURIException; import it.inaf.oats.vospace.exception.InvalidURIException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class URIUtilsTest { public class URIUtilsTest {
...@@ -84,6 +86,12 @@ public class URIUtilsTest { ...@@ -84,6 +86,12 @@ public class URIUtilsTest {
String test3 = URIUtils.returnURIFromVosPath("/test1/te# !?st2", authority); String test3 = URIUtils.returnURIFromVosPath("/test1/te# !?st2", authority);
assertEquals("vos://"+authority+"/test1/te%23%20!%3Fst2", test3); assertEquals("vos://"+authority+"/test1/te%23%20!%3Fst2", test3);
} }
@Test
public void testIsURIInternal() {
assertTrue(URIUtils.isURIInternal("vos://"+authority+"/test1/test2"));
assertFalse(URIUtils.isURIInternal("http://host.ia2.inaf.it/test1/test2"));
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment