Newer
Older
Sonia Zorba
committed
import it.inaf.ia2.aa.data.User;
Nicola Fulvio Calabria
committed
import it.inaf.oats.vospace.datamodel.NodeProperties;
import it.inaf.oats.vospace.datamodel.NodeUtils;
import net.ivoa.xml.vospace.v2.Node;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Autowired;
import it.inaf.oats.vospace.persistence.NodeDAO;
Nicola Fulvio Calabria
committed
import org.springframework.beans.factory.annotation.Value;
Sonia Zorba
committed
import org.springframework.web.bind.annotation.PutMapping;
Nicola Fulvio Calabria
committed
import it.inaf.oats.vospace.exception.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Nicola Fulvio Calabria
committed
import net.ivoa.xml.vospace.v2.Property;
Sonia Zorba
committed
public class CreateNodeController extends BaseNodeController {
private static final Logger LOG = LoggerFactory.getLogger(CreateNodeController.class);
Sonia Zorba
committed
@Autowired
private NodeDAO nodeDao;
Nicola Fulvio Calabria
committed
@Value("${vospace-authority}")
private String authority;
Sonia Zorba
committed
@PutMapping(value = {"/nodes", "/nodes/**"},
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})
Sonia Zorba
committed
public Node createNode(@RequestBody Node node, User principal) {
String path = getPath();
LOG.debug("createNode called for path {}", path);
Nicola Fulvio Calabria
committed
// Validate payload node URI
Nicola Fulvio Calabria
committed
if (!isValidURI(node.getUri())) {
Nicola Fulvio Calabria
committed
throw new InvalidURIException(node.getUri());
Nicola Fulvio Calabria
committed
}
Nicola Fulvio Calabria
committed
// Check if payload URI is consistent with http request
Nicola Fulvio Calabria
committed
if (!isUrlConsistentWithPayloadURI(node.getUri(), path)) {
Nicola Fulvio Calabria
committed
throw new InvalidURIException(node.getUri(), path);
}
Nicola Fulvio Calabria
committed
// Check if another node is already present at specified path
Nicola Fulvio Calabria
committed
// 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)));
Nicola Fulvio Calabria
committed
// Check if parent node is not a Container node and in case throw
// appropriate exception
if (!parentNode.getType().equals("vos:ContainerNode")) {
if (parentNode.getType().equals("vos:LinkNode")) {
throw new LinkFoundException(getParentPath(path));
} else {
throw new ContainerNotFoundException(getParentPath(path));
}
}
if(!NodeUtils.checkIfWritable(parentNode, principal.getName(), principal.getGroups())) {
throw new PermissionDeniedException(path);
Nicola Fulvio Calabria
committed
}
Nicola Fulvio Calabria
committed
// Check if node creator property is set. If not set it according to
// token. In case of creator mistmatch between node and token throw
// exception
String creator = NodeProperties.getNodePropertyByURI(
node, NodeProperties.CREATOR_URI);
if(creator == null)
{
Property creatorProperty = new Property();
creatorProperty.setUri(NodeProperties.CREATOR_URI);
creatorProperty.setValue(principal.getName());
node.getProperties().add(creatorProperty);
} else {
if(!creator.equals(principal.getName()))
// maybe a more specific exception would be more appropriate?
throw new PermissionDeniedException(path);
}
Nicola Fulvio Calabria
committed
nodeDao.createNode(node);
Sonia Zorba
committed
return node;
Nicola Fulvio Calabria
committed
Nicola Fulvio Calabria
committed
// Assuming that this service implementation uses only ! as a separator
// in the authority part of the URI
Nicola Fulvio Calabria
committed
private boolean isValidURI(String nodeURI) {
Nicola Fulvio Calabria
committed
String parsedAuthority;
Nicola Fulvio Calabria
committed
if (!nodeURI.startsWith("vos://")) {
Nicola Fulvio Calabria
committed
return false;
} else {
Nicola Fulvio Calabria
committed
parsedAuthority = nodeURI.replaceAll("vos://", "").split("/", -1)[0];
Nicola Fulvio Calabria
committed
}
Nicola Fulvio Calabria
committed
if (parsedAuthority.isEmpty()
|| !parsedAuthority.replace("~", "!").equals(authority)) {
Nicola Fulvio Calabria
committed
return false;
Nicola Fulvio Calabria
committed
}
return true;
Nicola Fulvio Calabria
committed
}
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);
}