Loading src/main/java/it/inaf/oats/vospace/BaseNodeController.java +17 −1 Original line number Original line Diff line number Diff line Loading @@ -6,15 +6,21 @@ package it.inaf.oats.vospace; package it.inaf.oats.vospace; import it.inaf.oats.vospace.datamodel.NodeUtils; import it.inaf.oats.vospace.datamodel.NodeUtils; import it.inaf.oats.vospace.exception.InvalidArgumentException; import it.inaf.oats.vospace.exception.InvalidURIException; import it.inaf.oats.vospace.exception.InvalidURIException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.vospace.v2.LinkNode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; public abstract class BaseNodeController { public abstract class BaseNodeController { @Autowired @Autowired private HttpServletRequest servletRequest; private HttpServletRequest servletRequest; @Value("${vospace-authority}") protected String authority; protected String getPath() { protected String getPath() { String requestURL = servletRequest.getRequestURL().toString(); String requestURL = servletRequest.getRequestURL().toString(); try { try { Loading @@ -27,4 +33,14 @@ public abstract class BaseNodeController { protected String getParentPath(String path) { protected String getParentPath(String path) { return NodeUtils.getParentPath(path); return NodeUtils.getParentPath(path); } } protected void validateInternalLinkNode(LinkNode linkNode) { String target = linkNode.getTarget(); // I validate it here to add context easily if (target == null) { throw new InvalidArgumentException("LinkNode in payload has no target element specified"); } URIUtils.returnVosPathFromNodeURI(linkNode.getTarget(), authority); } } } src/main/java/it/inaf/oats/vospace/CreateNodeController.java +2 −14 Original line number Original line Diff line number Diff line Loading @@ -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.InvalidArgumentException; import it.inaf.oats.vospace.exception.InvalidURIException; 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; Loading @@ -17,7 +16,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping; import org.slf4j.Logger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @RestController @RestController public class CreateNodeController extends BaseNodeController { public class CreateNodeController extends BaseNodeController { Loading @@ -27,9 +25,6 @@ public class CreateNodeController extends BaseNodeController { @Autowired @Autowired private CreateNodeService createNodeService; private CreateNodeService createNodeService; @Value("${vospace-authority}") private String authority; @PutMapping(value = {"/nodes", "/nodes/**"}, @PutMapping(value = {"/nodes", "/nodes/**"}, consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}, consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}) produces = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}) Loading @@ -40,7 +35,7 @@ public class CreateNodeController extends BaseNodeController { LOG.debug("createNodeController called for node with URI {} and PATH {}", node.getUri(), path); LOG.debug("createNodeController called for node with URI {} and PATH {}", node.getUri(), path); // Get Node path (and validates it too) // Get Node path (and validates it too) String decodedURIPathFromNode = URIUtils.returnVosPathFromNodeURI(node.getUri(), authority); String decodedURIPathFromNode = URIUtils.returnVosPathFromNodeURI(node.getUri(), this.authority); LOG.debug("createNodeController URI: {} decoded as {}", node.getUri(), decodedURIPathFromNode); LOG.debug("createNodeController URI: {} decoded as {}", node.getUri(), decodedURIPathFromNode); Loading @@ -59,14 +54,7 @@ public class CreateNodeController extends BaseNodeController { private void validateInputNode(Node node) { private void validateInputNode(Node node) { if (node instanceof LinkNode) { if (node instanceof LinkNode) { LinkNode linkNode = (LinkNode) node; this.validateInternalLinkNode((LinkNode) node); String target = linkNode.getTarget(); // I validate it here to add context easily if (target == null) { throw new InvalidArgumentException("LinkNode in payload has no target element specified"); } URIUtils.returnVosPathFromNodeURI(linkNode.getTarget(), authority); } } } } Loading src/main/java/it/inaf/oats/vospace/SetNodeController.java +4 −0 Original line number Original line Diff line number Diff line Loading @@ -13,6 +13,7 @@ import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.List; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.LinkNode; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.View; import net.ivoa.xml.vospace.v2.View; import org.slf4j.Logger; import org.slf4j.Logger; Loading Loading @@ -65,8 +66,11 @@ public class SetNodeController extends BaseNodeController { // This method cannot be used to modify the accepts or provides list of Views for the Node. // This method cannot be used to modify the accepts or provides list of Views for the Node. // Only DataNodes has Views (see VOSpace Data Model) // Only DataNodes has Views (see VOSpace Data Model) // Also if input node is LinkNode, target must be validated as internal URI if (node instanceof DataNode) { if (node instanceof DataNode) { checkViews((DataNode) node, (DataNode) toBeModifiedNode); checkViews((DataNode) node, (DataNode) toBeModifiedNode); } else if(node instanceof LinkNode) { this.validateInternalLinkNode((LinkNode) node); } } //The service SHOULD throw a HTTP 500 status code including an InternalFault fault //The service SHOULD throw a HTTP 500 status code including an InternalFault fault Loading src/main/java/it/inaf/oats/vospace/UriService.java +22 −5 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,7 @@ import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.LinkNode; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Protocol; import net.ivoa.xml.vospace.v2.Protocol; import net.ivoa.xml.vospace.v2.Transfer; import net.ivoa.xml.vospace.v2.Transfer; Loading Loading @@ -127,7 +128,16 @@ public class UriService { User user) { User user) { Optional<Node> optNode = nodeDao.listNode(relativePath); Optional<Node> optNode = nodeDao.listNode(relativePath); if (optNode.isPresent()) { if (optNode.isPresent()) { return optNode.get(); Node node = optNode.get(); if (jobType.equals(JobService.JobDirection.pullFromVoSpace)) { if (node instanceof LinkNode) { if (!NodeUtils.checkIfReadable(node, user.getName(), user.getGroups())) { throw PermissionDeniedException.forPath(relativePath); } node = this.followLink((LinkNode) node); } } return node; } else { } else { switch (jobType) { switch (jobType) { case pullFromVoSpace: case pullFromVoSpace: Loading @@ -152,8 +162,8 @@ public class UriService { List<String> groups = user.getGroups(); List<String> groups = user.getGroups(); // Check privileges write or read according to job type // Check privileges write or read according to job type 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) { Loading Loading @@ -266,4 +276,11 @@ public class UriService { return (Transfer) job.getJobInfo().getAny().get(0); return (Transfer) job.getJobInfo().getAny().get(0); } } private Node followLink(LinkNode linkNode) { String targetPath = URIUtils.returnVosPathFromNodeURI(linkNode.getTarget(), authority); Optional<Node> targetNode = nodeDao.listNode(targetPath); return targetNode.orElseThrow(() -> new InternalFaultException("Broken Link to target: " + targetPath)); } } } Loading
src/main/java/it/inaf/oats/vospace/BaseNodeController.java +17 −1 Original line number Original line Diff line number Diff line Loading @@ -6,15 +6,21 @@ package it.inaf.oats.vospace; package it.inaf.oats.vospace; import it.inaf.oats.vospace.datamodel.NodeUtils; import it.inaf.oats.vospace.datamodel.NodeUtils; import it.inaf.oats.vospace.exception.InvalidArgumentException; import it.inaf.oats.vospace.exception.InvalidURIException; import it.inaf.oats.vospace.exception.InvalidURIException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.vospace.v2.LinkNode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; public abstract class BaseNodeController { public abstract class BaseNodeController { @Autowired @Autowired private HttpServletRequest servletRequest; private HttpServletRequest servletRequest; @Value("${vospace-authority}") protected String authority; protected String getPath() { protected String getPath() { String requestURL = servletRequest.getRequestURL().toString(); String requestURL = servletRequest.getRequestURL().toString(); try { try { Loading @@ -27,4 +33,14 @@ public abstract class BaseNodeController { protected String getParentPath(String path) { protected String getParentPath(String path) { return NodeUtils.getParentPath(path); return NodeUtils.getParentPath(path); } } protected void validateInternalLinkNode(LinkNode linkNode) { String target = linkNode.getTarget(); // I validate it here to add context easily if (target == null) { throw new InvalidArgumentException("LinkNode in payload has no target element specified"); } URIUtils.returnVosPathFromNodeURI(linkNode.getTarget(), authority); } } }
src/main/java/it/inaf/oats/vospace/CreateNodeController.java +2 −14 Original line number Original line Diff line number Diff line Loading @@ -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.InvalidArgumentException; import it.inaf.oats.vospace.exception.InvalidURIException; 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; Loading @@ -17,7 +16,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping; import org.slf4j.Logger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @RestController @RestController public class CreateNodeController extends BaseNodeController { public class CreateNodeController extends BaseNodeController { Loading @@ -27,9 +25,6 @@ public class CreateNodeController extends BaseNodeController { @Autowired @Autowired private CreateNodeService createNodeService; private CreateNodeService createNodeService; @Value("${vospace-authority}") private String authority; @PutMapping(value = {"/nodes", "/nodes/**"}, @PutMapping(value = {"/nodes", "/nodes/**"}, consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}, consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}) produces = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}) Loading @@ -40,7 +35,7 @@ public class CreateNodeController extends BaseNodeController { LOG.debug("createNodeController called for node with URI {} and PATH {}", node.getUri(), path); LOG.debug("createNodeController called for node with URI {} and PATH {}", node.getUri(), path); // Get Node path (and validates it too) // Get Node path (and validates it too) String decodedURIPathFromNode = URIUtils.returnVosPathFromNodeURI(node.getUri(), authority); String decodedURIPathFromNode = URIUtils.returnVosPathFromNodeURI(node.getUri(), this.authority); LOG.debug("createNodeController URI: {} decoded as {}", node.getUri(), decodedURIPathFromNode); LOG.debug("createNodeController URI: {} decoded as {}", node.getUri(), decodedURIPathFromNode); Loading @@ -59,14 +54,7 @@ public class CreateNodeController extends BaseNodeController { private void validateInputNode(Node node) { private void validateInputNode(Node node) { if (node instanceof LinkNode) { if (node instanceof LinkNode) { LinkNode linkNode = (LinkNode) node; this.validateInternalLinkNode((LinkNode) node); String target = linkNode.getTarget(); // I validate it here to add context easily if (target == null) { throw new InvalidArgumentException("LinkNode in payload has no target element specified"); } URIUtils.returnVosPathFromNodeURI(linkNode.getTarget(), authority); } } } } Loading
src/main/java/it/inaf/oats/vospace/SetNodeController.java +4 −0 Original line number Original line Diff line number Diff line Loading @@ -13,6 +13,7 @@ import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.List; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.LinkNode; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.View; import net.ivoa.xml.vospace.v2.View; import org.slf4j.Logger; import org.slf4j.Logger; Loading Loading @@ -65,8 +66,11 @@ public class SetNodeController extends BaseNodeController { // This method cannot be used to modify the accepts or provides list of Views for the Node. // This method cannot be used to modify the accepts or provides list of Views for the Node. // Only DataNodes has Views (see VOSpace Data Model) // Only DataNodes has Views (see VOSpace Data Model) // Also if input node is LinkNode, target must be validated as internal URI if (node instanceof DataNode) { if (node instanceof DataNode) { checkViews((DataNode) node, (DataNode) toBeModifiedNode); checkViews((DataNode) node, (DataNode) toBeModifiedNode); } else if(node instanceof LinkNode) { this.validateInternalLinkNode((LinkNode) node); } } //The service SHOULD throw a HTTP 500 status code including an InternalFault fault //The service SHOULD throw a HTTP 500 status code including an InternalFault fault Loading
src/main/java/it/inaf/oats/vospace/UriService.java +22 −5 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,7 @@ import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.uws.v1.JobSummary; import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.LinkNode; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Protocol; import net.ivoa.xml.vospace.v2.Protocol; import net.ivoa.xml.vospace.v2.Transfer; import net.ivoa.xml.vospace.v2.Transfer; Loading Loading @@ -127,7 +128,16 @@ public class UriService { User user) { User user) { Optional<Node> optNode = nodeDao.listNode(relativePath); Optional<Node> optNode = nodeDao.listNode(relativePath); if (optNode.isPresent()) { if (optNode.isPresent()) { return optNode.get(); Node node = optNode.get(); if (jobType.equals(JobService.JobDirection.pullFromVoSpace)) { if (node instanceof LinkNode) { if (!NodeUtils.checkIfReadable(node, user.getName(), user.getGroups())) { throw PermissionDeniedException.forPath(relativePath); } node = this.followLink((LinkNode) node); } } return node; } else { } else { switch (jobType) { switch (jobType) { case pullFromVoSpace: case pullFromVoSpace: Loading @@ -152,8 +162,8 @@ public class UriService { List<String> groups = user.getGroups(); List<String> groups = user.getGroups(); // Check privileges write or read according to job type // Check privileges write or read according to job type 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) { Loading Loading @@ -266,4 +276,11 @@ public class UriService { return (Transfer) job.getJobInfo().getAny().get(0); return (Transfer) job.getJobInfo().getAny().get(0); } } private Node followLink(LinkNode linkNode) { String targetPath = URIUtils.returnVosPathFromNodeURI(linkNode.getTarget(), authority); Optional<Node> targetNode = nodeDao.listNode(targetPath); return targetNode.orElseThrow(() -> new InternalFaultException("Broken Link to target: " + targetPath)); } } }