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 @@
package it.inaf.oats.vospace;
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.Node;
import org.springframework.http.MediaType;
......
......@@ -18,6 +18,13 @@ public class URIUtils {
// Slashes are treated separately
private static final Pattern FORBIDDEN_CHARS = Pattern.compile("[\\x00\\x08\\x0B\\x0C\\x0E-\\x1F" + Pattern.quote("<>?\":\\|'`*") + "]");
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) {
String result = null;
......
......@@ -19,6 +19,7 @@ import it.inaf.oats.vospace.exception.NodeNotFoundException;
import it.inaf.oats.vospace.exception.PermissionDeniedException;
import it.inaf.oats.vospace.exception.ProtocolNotSupportedException;
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.NodeDAO;
import it.inaf.oats.vospace.persistence.model.Location;
......@@ -58,6 +59,9 @@ public class UriService {
@Autowired
private LocationDAO locationDAO;
@Autowired
private LinkedServiceDAO linkedServiceDAO;
@Autowired
private HttpServletRequest servletRequest;
......@@ -168,7 +172,7 @@ public class UriService {
JobService.JobDirection jobType
= JobDirection.getJobDirectionEnumFromTransfer(transfer);
Node node = this.getEndpointNode(relativePath, jobType, user);
switch (jobType) {
case pushToVoSpace:
case pullToVoSpace:
......@@ -178,7 +182,7 @@ public class UriService {
break;
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);
if (!NodeUtils.checkIfReadable(node, creator, groups)) {
throw PermissionDeniedException.forPath(relativePath);
......@@ -197,24 +201,36 @@ public class UriService {
return fileServiceClient.startArchiveJob(transfer, job.getJobId());
}
Location location = locationDAO.getNodeLocation(relativePath).orElse(null);
boolean isLinkNode = node instanceof LinkNode;
String endpoint;
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;
if (isLinkNode) {
endpoint = ((LinkNode) node).getTarget();
} 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();
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);
}
......@@ -287,21 +303,27 @@ public class UriService {
}
private Node followLinkRecursive(LinkNode linkNode, int depth) {
if(depth >= linkMaxDepth) {
throw new InternalFaultException("Max link depth reached at link node: "
if (depth >= linkMaxDepth) {
throw new InternalFaultException("Max link depth reached at link node: "
+ NodeUtils.getVosPath(linkNode));
}
String targetPath = URIUtils.returnVosPathFromNodeURI(linkNode.getTarget(), authority);
Optional<Node> targetNodeOpt = nodeDao.listNode(targetPath);
Node targetNode = targetNodeOpt.orElseThrow(() -> new InternalFaultException("Broken Link to target: " + targetPath));
if(targetNode instanceof LinkNode) {
return this.followLinkRecursive(linkNode, ++depth);
} else {
return targetNode;
String linkTarget = linkNode.getTarget();
if (URIUtils.isURIInternal(linkTarget)) {
return linkNode;
} else {
String targetPath = URIUtils.returnVosPathFromNodeURI(linkTarget, authority);
Optional<Node> targetNodeOpt = nodeDao.listNode(targetPath);
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 {
jdbcTemplate = new JdbcTemplate(dataSource);
}
boolean isLinkedServiceUrl(String targetUrl) {
public boolean isLinkedServiceUrl(String targetUrl) {
String sql = " SELECT COUNT(*) > 0\n"
+ "FROM linked_service\n"
+ "WHERE ? LIKE service_base_url || '%'";
......
......@@ -8,7 +8,9 @@ package it.inaf.oats.vospace;
import it.inaf.oats.vospace.exception.InvalidURIException;
import java.net.URISyntaxException;
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.assertTrue;
import org.junit.jupiter.api.Test;
public class URIUtilsTest {
......@@ -84,6 +86,12 @@ public class URIUtilsTest {
String test3 = URIUtils.returnURIFromVosPath("/test1/te# !?st2", authority);
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.
Finish editing this message first!
Please register or to comment