Loading src/main/java/it/inaf/oats/vospace/CreateNodeController.java +84 −0 Original line number Diff line number Diff line Loading @@ -8,7 +8,11 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.beans.factory.annotation.Autowired; import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.List; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PutMapping; import it.inaf.oats.vospace.exception.*; import java.util.stream.Collectors; import java.util.Arrays; @RestController public class CreateNodeController extends BaseNodeController { Loading @@ -16,6 +20,9 @@ public class CreateNodeController extends BaseNodeController { @Autowired private NodeDAO nodeDao; @Value("${vospace-authority}") private String authority; @PutMapping(value = {"/nodes", "/nodes/**"}, consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}) Loading @@ -25,7 +32,84 @@ public class CreateNodeController extends BaseNodeController { List<String> userGroups = principal.getGroups(); if (!isValidURI(node.getUri())) throw new InvalidURIException(node.getUri()); if(!isUrlConsistentWithPayloadURI(node.getUri(), path)) { throw new InvalidURIException(node.getUri(), path); } // This checks if the user is trying to insert the root node at "/" too if (nodeDao.listNode(path).isPresent()) { throw new DuplicateNodeException(path); } // Retrieve parent node Node parentNode = nodeDao.listNode(getParentPath(path)) .orElseThrow(() -> new ContainerNotFoundException(getParentPath(path))); List<String> groupWritePropValues = parentNode.getProperties().stream() .filter((i) -> i.getUri() .equals("ivo://ivoa.net/vospace/core#groupwrite")) .map((i) -> i.getValue()) .collect(Collectors.toList()); if (groupWritePropValues.isEmpty()) { throw new PermissionDeniedException(path); } List<String> nodeGroups = Arrays.asList(groupWritePropValues.get(0).split(",",-1)); if (!nodeGroups.stream().anyMatch((i) -> userGroups.contains(i))) { throw new PermissionDeniedException(path); } // Check if parent node is a LinkNode and if so throw exception if (parentNode.getType().equals("vos:LinkNode")) { throw new LinkFoundException(getParentPath(path)); } nodeDao.createNode(node); return node; } // Assuming that this service implementation uses only ! as a separator // in the authority part of the URI private boolean isValidURI(String nodeURI) { String parsedAuthority; if(!nodeURI.startsWith("vos://")) { return false; } else { parsedAuthority = nodeURI.replaceAll("vos://", "").split("/",-1)[0]; } if(parsedAuthority.isEmpty() || !parsedAuthority.replace("~","!").equals(authority)) return false; return true; } private boolean isUrlConsistentWithPayloadURI(String nodeURI, String path) { // It's assumed that nodeURI has been validated to be in the expected // form vos://authority[!~]somepath/mynode..." return nodeURI.replaceAll("vos://[^/]+", "").equals(path); } private String getParentPath(String path) { String[] parsedPath = path.split("/"); StringBuilder sb = new StringBuilder(); for (int i = 0; i < parsedPath.length - 1; i++) { sb.append("/").append(parsedPath[i]); } return sb.toString(); } } src/main/java/it/inaf/oats/vospace/exception/ContainerNotFoundException.java 0 → 100644 +12 −0 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.NOT_FOUND) public class ContainerNotFoundException extends VoSpaceException { public ContainerNotFoundException(String path) { super("Container Not Found at path: " + path); } } src/main/java/it/inaf/oats/vospace/exception/DuplicateNodeException.java 0 → 100644 +12 −0 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.CONFLICT) public class DuplicateNodeException extends VoSpaceException { public DuplicateNodeException(String path) { super("Duplicate Node at path: " + path); } } src/main/java/it/inaf/oats/vospace/exception/InvalidURIException.java 0 → 100644 +18 −0 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.BAD_REQUEST) public class InvalidURIException extends VoSpaceException { public InvalidURIException(String URI, String path) { super("InvalidURI. Payload node URI: " + URI + " is not consistent with request path: " + path); } public InvalidURIException(String URI) { super("InvalidURI. URI: "+URI+ " is not in a valid format"); } } src/main/java/it/inaf/oats/vospace/exception/LinkFoundException.java 0 → 100644 +12 −0 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.BAD_REQUEST) public class LinkFoundException extends VoSpaceException { public LinkFoundException(String path) { super("Link Found at path: " + path); } } Loading
src/main/java/it/inaf/oats/vospace/CreateNodeController.java +84 −0 Original line number Diff line number Diff line Loading @@ -8,7 +8,11 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.beans.factory.annotation.Autowired; import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.List; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PutMapping; import it.inaf.oats.vospace.exception.*; import java.util.stream.Collectors; import java.util.Arrays; @RestController public class CreateNodeController extends BaseNodeController { Loading @@ -16,6 +20,9 @@ public class CreateNodeController extends BaseNodeController { @Autowired private NodeDAO nodeDao; @Value("${vospace-authority}") private String authority; @PutMapping(value = {"/nodes", "/nodes/**"}, consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}) Loading @@ -25,7 +32,84 @@ public class CreateNodeController extends BaseNodeController { List<String> userGroups = principal.getGroups(); if (!isValidURI(node.getUri())) throw new InvalidURIException(node.getUri()); if(!isUrlConsistentWithPayloadURI(node.getUri(), path)) { throw new InvalidURIException(node.getUri(), path); } // This checks if the user is trying to insert the root node at "/" too if (nodeDao.listNode(path).isPresent()) { throw new DuplicateNodeException(path); } // Retrieve parent node Node parentNode = nodeDao.listNode(getParentPath(path)) .orElseThrow(() -> new ContainerNotFoundException(getParentPath(path))); List<String> groupWritePropValues = parentNode.getProperties().stream() .filter((i) -> i.getUri() .equals("ivo://ivoa.net/vospace/core#groupwrite")) .map((i) -> i.getValue()) .collect(Collectors.toList()); if (groupWritePropValues.isEmpty()) { throw new PermissionDeniedException(path); } List<String> nodeGroups = Arrays.asList(groupWritePropValues.get(0).split(",",-1)); if (!nodeGroups.stream().anyMatch((i) -> userGroups.contains(i))) { throw new PermissionDeniedException(path); } // Check if parent node is a LinkNode and if so throw exception if (parentNode.getType().equals("vos:LinkNode")) { throw new LinkFoundException(getParentPath(path)); } nodeDao.createNode(node); return node; } // Assuming that this service implementation uses only ! as a separator // in the authority part of the URI private boolean isValidURI(String nodeURI) { String parsedAuthority; if(!nodeURI.startsWith("vos://")) { return false; } else { parsedAuthority = nodeURI.replaceAll("vos://", "").split("/",-1)[0]; } if(parsedAuthority.isEmpty() || !parsedAuthority.replace("~","!").equals(authority)) return false; return true; } private boolean isUrlConsistentWithPayloadURI(String nodeURI, String path) { // It's assumed that nodeURI has been validated to be in the expected // form vos://authority[!~]somepath/mynode..." return nodeURI.replaceAll("vos://[^/]+", "").equals(path); } private String getParentPath(String path) { String[] parsedPath = path.split("/"); StringBuilder sb = new StringBuilder(); for (int i = 0; i < parsedPath.length - 1; i++) { sb.append("/").append(parsedPath[i]); } return sb.toString(); } }
src/main/java/it/inaf/oats/vospace/exception/ContainerNotFoundException.java 0 → 100644 +12 −0 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.NOT_FOUND) public class ContainerNotFoundException extends VoSpaceException { public ContainerNotFoundException(String path) { super("Container Not Found at path: " + path); } }
src/main/java/it/inaf/oats/vospace/exception/DuplicateNodeException.java 0 → 100644 +12 −0 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.CONFLICT) public class DuplicateNodeException extends VoSpaceException { public DuplicateNodeException(String path) { super("Duplicate Node at path: " + path); } }
src/main/java/it/inaf/oats/vospace/exception/InvalidURIException.java 0 → 100644 +18 −0 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.BAD_REQUEST) public class InvalidURIException extends VoSpaceException { public InvalidURIException(String URI, String path) { super("InvalidURI. Payload node URI: " + URI + " is not consistent with request path: " + path); } public InvalidURIException(String URI) { super("InvalidURI. URI: "+URI+ " is not in a valid format"); } }
src/main/java/it/inaf/oats/vospace/exception/LinkFoundException.java 0 → 100644 +12 −0 Original line number Diff line number Diff line package it.inaf.oats.vospace.exception; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.BAD_REQUEST) public class LinkFoundException extends VoSpaceException { public LinkFoundException(String path) { super("Link Found at path: " + path); } }