Loading vospace-ui-backend/pom.xml +5 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,11 @@ <artifactId>auth-lib</artifactId> <version>2.0.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.13.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> Loading vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/controller/NodesController.java +15 −8 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ package it.inaf.ia2.vospace.ui.controller; import it.inaf.ia2.aa.data.User; import it.inaf.ia2.vospace.ui.client.VOSpaceClient; import it.inaf.ia2.vospace.ui.data.ListNodeData; import it.inaf.ia2.vospace.ui.service.NodesService; import it.inaf.ia2.vospace.ui.service.NodesHtmlGenerator; import it.inaf.oats.vospace.datamodel.NodeUtils; import java.util.List; import java.util.Map; Loading @@ -12,6 +12,7 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.vospace.v2.ContainerNode; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Property; import net.ivoa.xml.vospace.v2.Protocol; import net.ivoa.xml.vospace.v2.Transfer; Loading @@ -36,9 +37,6 @@ public class NodesController extends BaseController { @Value("${vospace-authority}") private String authority; @Autowired private NodesService nodesService; @Autowired private VOSpaceClient client; Loading @@ -51,7 +49,16 @@ public class NodesController extends BaseController { String path = getPath("/nodes/"); LOG.debug("listNodes called for path {}", path); return ResponseEntity.ok(nodesService.generateNodesHtml(path, principal)); ListNodeData listNodeData = new ListNodeData(); Node node = client.getNode(path); listNodeData.setWritable(NodeUtils.checkIfWritable(node, principal.getName(), principal.getGroups())); NodesHtmlGenerator htmlGenerator = new NodesHtmlGenerator(node, principal, authority); listNodeData.setHtmlTable(htmlGenerator.generateNodes()); return ResponseEntity.ok(listNodeData); } @GetMapping(value = "/download/**") Loading vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodeInfo.java +17 −3 Original line number Diff line number Diff line package it.inaf.ia2.vospace.ui.service; import it.inaf.ia2.aa.data.User; import it.inaf.ia2.vospace.ui.exception.VOSpaceException; import it.inaf.oats.vospace.datamodel.NodeProperties; import it.inaf.oats.vospace.datamodel.NodeUtils; import java.util.List; import java.util.Optional; import net.ivoa.xml.vospace.v2.DataNode; Loading Loading @@ -29,8 +31,10 @@ public class NodeInfo { private final boolean sticky; private final boolean busy; private final boolean listOfFiles; private final boolean writable; private final boolean deletable; public NodeInfo(Node node, String authority) { public NodeInfo(Node node, User user, String authority) { this.authority = authority; this.path = getPath(node); this.name = path.substring(path.lastIndexOf("/") + 1); Loading @@ -44,6 +48,8 @@ public class NodeInfo { this.sticky = isSticky(node); this.busy = isBusy(node); this.listOfFiles = isListOfFiles(node); this.writable = NodeUtils.checkIfWritable(node, user.getName(), user.getGroups()); this.deletable = writable && !sticky; } private String getPath(Node node) { Loading Loading @@ -189,4 +195,12 @@ public class NodeInfo { public boolean isListOfFiles() { return listOfFiles; } public boolean isWritable() { return writable; } public boolean isDeletable() { return deletable; } } vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodesHtmlGenerator.java 0 → 100644 +223 −0 Original line number Diff line number Diff line package it.inaf.ia2.vospace.ui.service; import it.inaf.ia2.aa.data.User; import static it.inaf.oats.vospace.datamodel.NodeUtils.urlEncodePath; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import net.ivoa.xml.vospace.v2.ContainerNode; import net.ivoa.xml.vospace.v2.Node; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; public class NodesHtmlGenerator { private final Node parentNode; private final User user; private final String authority; private Element tbody; public NodesHtmlGenerator(Node node, User user, String authority) { this.parentNode = node; this.user = user; this.authority = authority; } public String generateNodes() { Document html = Jsoup.parse("<html></html>"); tbody = html.body().appendElement("tbody"); tbody.attr("id", "nodes"); if (parentNode instanceof ContainerNode) { ContainerNode folder = (ContainerNode) parentNode; for (Node child : folder.getNodes()) { addChild(child); } } return tbody.toString(); } private void addChild(Node child) { NodeInfo nodeInfo = new NodeInfo(child, user, authority); if (nodeInfo.isListOfFiles()) { // hidden file return; } Element row = tbody.appendElement("tr"); addSelectionCell(nodeInfo, row); addLinkCell(nodeInfo, row); addSizeCell(nodeInfo, row); addGroupReadCell(nodeInfo, row); addGroupWriteCell(nodeInfo, row); addActionsCell(nodeInfo, row); } private void addSelectionCell(NodeInfo nodeInfo, Element row) { Element cell = row.appendElement("td"); Element input = cell.appendElement("input"); input.attr("type", "checkbox"); input.attr("data-node", nodeInfo.getPath()); if (nodeInfo.isAsyncTrans()) { input.addClass("async"); } else if (nodeInfo.isDeletable()) { input.addClass("deletable"); } } private void addLinkCell(NodeInfo nodeInfo, Element row) { Element cell = row.appendElement("td"); addNodeIcon(nodeInfo, cell); addLink(nodeInfo, cell); } private void addSizeCell(NodeInfo nodeInfo, Element row) { Element cell = row.appendElement("td"); cell.text(nodeInfo.getSize()); } private void addGroupReadCell(NodeInfo nodeInfo, Element row) { Element cell = row.appendElement("td"); fillGroupCell(cell, nodeInfo.getGroupRead()); } private void addGroupWriteCell(NodeInfo nodeInfo, Element row) { Element cell = row.appendElement("td"); fillGroupCell(cell, nodeInfo.getGroupWrite()); } private void fillGroupCell(Element cell, String groups) { String[] values = groups.split(" "); List<String> personGroups = new ArrayList<>(); List<String> peopleGroups = new ArrayList<>(); for (String value : values) { if (value.startsWith("people.")) { personGroups.add(value.substring("people.".length()).replace("\\.", ".")); } else { peopleGroups.add(value); } } if (!personGroups.isEmpty()) { Element personIcon = cell.appendElement("span"); personIcon.attr("class", "icon person-icon"); cell.appendText(String.join(" ", personGroups)); cell.append(" "); } if (!peopleGroups.isEmpty()) { Element personIcon = cell.appendElement("span"); personIcon.attr("class", "icon people-icon"); cell.appendText(String.join(" ", peopleGroups)); } } private void addActionsCell(NodeInfo nodeInfo, Element row) { Element cell = row.appendElement("td"); if (nodeInfo.isWritable()) { Element shareIcon = cell.appendElement("span"); shareIcon.attr("class", "icon share-icon pointer"); shareIcon.attr("onclick", "shareNode(" + makeJsArg(nodeInfo.getPath()) + "," + makeJsArg(nodeInfo.getGroupRead()) + "," + makeJsArg(nodeInfo.getGroupWrite()) + ")"); } if (nodeInfo.isDeletable()) { cell.append(" "); Element deleteIcon = cell.appendElement("span"); deleteIcon.attr("class", "icon trash-icon pointer"); deleteIcon.attr("onclick", "deleteNode(" + makeJsArg(nodeInfo.getPath()) + ")"); } } private String makeJsArg(String arg) { return "'" + arg.replace("\\", "\\\\").replace("'", "\\'") + "'"; } private void addNodeIcon(NodeInfo nodeInfo, Element cell) { Element iconContainer = cell; if (nodeInfo.isBusy()) { Element loadingWrapper = cell.appendElement("span"); iconContainer = loadingWrapper; loadingWrapper.addClass("node-busy"); Element spinner = loadingWrapper.appendElement("span"); spinner.attr("role", "status"); spinner.addClass("spinner-border"); Element srEl = spinner.appendElement("span"); srEl.addClass("sr-only"); srEl.text("Loading..."); } Element icon = cell.appendElement("span"); icon.addClass("icon"); if (nodeInfo.isFolder()) { if (nodeInfo.isAsyncTrans()) { icon.addClass("folder-x-icon"); } else { icon.addClass("folder-icon"); } } else { if (nodeInfo.isAsyncTrans()) { icon.addClass("file-x-icon"); } else { icon.addClass("file-icon"); } } iconContainer.append(" "); } private void addLink(NodeInfo nodeInfo, Element cell) { if (isDownloadable(nodeInfo, user)) { Element link = cell.appendElement("a"); String href; if (nodeInfo.isFolder()) { href = "#/nodes" + urlEncodePath(nodeInfo.getPath()); } else { href = "download" + urlEncodePath(nodeInfo.getPath()); link.attr("target", "blank_"); } link.attr("href", href); link.text(nodeInfo.getName()); } else { cell.text(nodeInfo.getName()); } } private boolean isDownloadable(NodeInfo nodeInfo, User user) { if (nodeInfo.isFile()) { if (nodeInfo.isAsyncTrans() || nodeInfo.isBusy()) { return false; } } if (nodeInfo.isPublic()) { return true; } if (nodeInfo.getCreator().equals(user.getName())) { return true; } if (user.getGroups() != null && !user.getGroups().isEmpty() && !nodeInfo.getGroupRead().isEmpty()) { List<String> groupRead = Arrays.asList(nodeInfo.getGroupRead().split(" ")); for (String group : groupRead) { if (user.getGroups().contains(group)) { return true; } } } return false; } } vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodesService.javadeleted 100644 → 0 +0 −149 Original line number Diff line number Diff line package it.inaf.ia2.vospace.ui.service; import it.inaf.ia2.aa.data.User; import it.inaf.ia2.vospace.ui.client.VOSpaceClient; import it.inaf.ia2.vospace.ui.data.ListNodeData; import it.inaf.oats.vospace.datamodel.NodeUtils; import static it.inaf.oats.vospace.datamodel.NodeUtils.urlEncodePath; import java.io.IOException; import java.io.StringWriter; import java.io.UncheckedIOException; import java.util.Arrays; import java.util.List; import net.ivoa.xml.vospace.v2.ContainerNode; import net.ivoa.xml.vospace.v2.Node; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Service public class NodesService { private static final Logger LOG = LoggerFactory.getLogger(NodesService.class); @Autowired private VOSpaceClient client; @Value("${vospace-authority}") private String authority; public ListNodeData generateNodesHtml(String path, User user) { ListNodeData listNodeData = new ListNodeData(); Node node = client.getNode(path); listNodeData.setWritable(NodeUtils.checkIfWritable(node, user.getName(), user.getGroups())); try (StringWriter sw = new StringWriter()) { if (node instanceof ContainerNode) { ContainerNode folder = (ContainerNode) node; sw.write("<tbody id=\"nodes\">"); for (Node child : folder.getNodes()) { sw.write(getNodeHtml(child, user)); } sw.write("</tbody>"); } listNodeData.setHtmlTable(sw.toString()); return listNodeData; } catch (IOException ex) { throw new UncheckedIOException(ex); } } private String getNodeHtml(Node node, User user) { NodeInfo nodeInfo = new NodeInfo(node, authority); if (nodeInfo.isListOfFiles()) { // hidden file return ""; } boolean deletable = NodeUtils.checkIfWritable(node, user.getName(), user.getGroups()) && !nodeInfo.isSticky(); String html = "<tr>"; html += "<td><input type=\"checkbox\" data-node=\"" + nodeInfo.getPath().replace("\"", "\\\"") + "\" "; if (nodeInfo.isAsyncTrans()) { html += "class=\"async\""; } else if (deletable) { html += "class=\"deletable\""; } html += "/></td>"; html += "<td>" + getIcon(nodeInfo) + getLink(nodeInfo, user) + "</td>"; html += "<td>" + nodeInfo.getSize() + "</td>"; html += "<td>" + nodeInfo.getGroupRead() + "</td>"; html += "<td>" + nodeInfo.getGroupWrite() + "</td>"; html += "<td>"; if (deletable) { html += "<span class=\"icon trash-icon pointer\" onclick=\"deleteNode('" + nodeInfo.getPath() + "')\"></span>"; } html += "</td>"; html += "</tr>"; return html; } private String getIcon(NodeInfo nodeInfo) { String html = ""; if (nodeInfo.isBusy()) { html += "<span class=\"node-busy\"><span role=\"status\" class=\"spinner-border\"><span class=\"sr-only\">Loading...</span></span>"; } html += "<span class=\"icon "; if (nodeInfo.isFolder()) { html += "folder"; } else { html += "file"; } if (nodeInfo.isAsyncTrans()) { html += "-x"; } html += "-icon\"></span>"; if (nodeInfo.isBusy()) { html += "</span>"; } html += " "; return html; } private String getLink(NodeInfo nodeInfo, User user) { if (isDownloadable(nodeInfo, user)) { if (nodeInfo.isFolder()) { return "<a href=\"#/nodes" + urlEncodePath(nodeInfo.getPath()) + "\">" + nodeInfo.getName() + "</a>"; } else { return "<a href=\"download" + urlEncodePath(nodeInfo.getPath()) + "\" target=\"blank_\">" + nodeInfo.getName() + "</a>"; } } return nodeInfo.getName(); } private boolean isDownloadable(NodeInfo nodeInfo, User user) { if (nodeInfo.isFile()) { if (nodeInfo.isAsyncTrans() || nodeInfo.isBusy()) { return false; } } if (nodeInfo.isPublic()) { return true; } if (nodeInfo.getCreator().equals(user.getName())) { return true; } if (user.getGroups() != null && !user.getGroups().isEmpty() && !nodeInfo.getGroupRead().isEmpty()) { List<String> groupRead = Arrays.asList(nodeInfo.getGroupRead().split(" ")); for (String group : groupRead) { if (user.getGroups().contains(group)) { return true; } } } return false; } } Loading
vospace-ui-backend/pom.xml +5 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,11 @@ <artifactId>auth-lib</artifactId> <version>2.0.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.13.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> Loading
vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/controller/NodesController.java +15 −8 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ package it.inaf.ia2.vospace.ui.controller; import it.inaf.ia2.aa.data.User; import it.inaf.ia2.vospace.ui.client.VOSpaceClient; import it.inaf.ia2.vospace.ui.data.ListNodeData; import it.inaf.ia2.vospace.ui.service.NodesService; import it.inaf.ia2.vospace.ui.service.NodesHtmlGenerator; import it.inaf.oats.vospace.datamodel.NodeUtils; import java.util.List; import java.util.Map; Loading @@ -12,6 +12,7 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.vospace.v2.ContainerNode; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Property; import net.ivoa.xml.vospace.v2.Protocol; import net.ivoa.xml.vospace.v2.Transfer; Loading @@ -36,9 +37,6 @@ public class NodesController extends BaseController { @Value("${vospace-authority}") private String authority; @Autowired private NodesService nodesService; @Autowired private VOSpaceClient client; Loading @@ -51,7 +49,16 @@ public class NodesController extends BaseController { String path = getPath("/nodes/"); LOG.debug("listNodes called for path {}", path); return ResponseEntity.ok(nodesService.generateNodesHtml(path, principal)); ListNodeData listNodeData = new ListNodeData(); Node node = client.getNode(path); listNodeData.setWritable(NodeUtils.checkIfWritable(node, principal.getName(), principal.getGroups())); NodesHtmlGenerator htmlGenerator = new NodesHtmlGenerator(node, principal, authority); listNodeData.setHtmlTable(htmlGenerator.generateNodes()); return ResponseEntity.ok(listNodeData); } @GetMapping(value = "/download/**") Loading
vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodeInfo.java +17 −3 Original line number Diff line number Diff line package it.inaf.ia2.vospace.ui.service; import it.inaf.ia2.aa.data.User; import it.inaf.ia2.vospace.ui.exception.VOSpaceException; import it.inaf.oats.vospace.datamodel.NodeProperties; import it.inaf.oats.vospace.datamodel.NodeUtils; import java.util.List; import java.util.Optional; import net.ivoa.xml.vospace.v2.DataNode; Loading Loading @@ -29,8 +31,10 @@ public class NodeInfo { private final boolean sticky; private final boolean busy; private final boolean listOfFiles; private final boolean writable; private final boolean deletable; public NodeInfo(Node node, String authority) { public NodeInfo(Node node, User user, String authority) { this.authority = authority; this.path = getPath(node); this.name = path.substring(path.lastIndexOf("/") + 1); Loading @@ -44,6 +48,8 @@ public class NodeInfo { this.sticky = isSticky(node); this.busy = isBusy(node); this.listOfFiles = isListOfFiles(node); this.writable = NodeUtils.checkIfWritable(node, user.getName(), user.getGroups()); this.deletable = writable && !sticky; } private String getPath(Node node) { Loading Loading @@ -189,4 +195,12 @@ public class NodeInfo { public boolean isListOfFiles() { return listOfFiles; } public boolean isWritable() { return writable; } public boolean isDeletable() { return deletable; } }
vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodesHtmlGenerator.java 0 → 100644 +223 −0 Original line number Diff line number Diff line package it.inaf.ia2.vospace.ui.service; import it.inaf.ia2.aa.data.User; import static it.inaf.oats.vospace.datamodel.NodeUtils.urlEncodePath; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import net.ivoa.xml.vospace.v2.ContainerNode; import net.ivoa.xml.vospace.v2.Node; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; public class NodesHtmlGenerator { private final Node parentNode; private final User user; private final String authority; private Element tbody; public NodesHtmlGenerator(Node node, User user, String authority) { this.parentNode = node; this.user = user; this.authority = authority; } public String generateNodes() { Document html = Jsoup.parse("<html></html>"); tbody = html.body().appendElement("tbody"); tbody.attr("id", "nodes"); if (parentNode instanceof ContainerNode) { ContainerNode folder = (ContainerNode) parentNode; for (Node child : folder.getNodes()) { addChild(child); } } return tbody.toString(); } private void addChild(Node child) { NodeInfo nodeInfo = new NodeInfo(child, user, authority); if (nodeInfo.isListOfFiles()) { // hidden file return; } Element row = tbody.appendElement("tr"); addSelectionCell(nodeInfo, row); addLinkCell(nodeInfo, row); addSizeCell(nodeInfo, row); addGroupReadCell(nodeInfo, row); addGroupWriteCell(nodeInfo, row); addActionsCell(nodeInfo, row); } private void addSelectionCell(NodeInfo nodeInfo, Element row) { Element cell = row.appendElement("td"); Element input = cell.appendElement("input"); input.attr("type", "checkbox"); input.attr("data-node", nodeInfo.getPath()); if (nodeInfo.isAsyncTrans()) { input.addClass("async"); } else if (nodeInfo.isDeletable()) { input.addClass("deletable"); } } private void addLinkCell(NodeInfo nodeInfo, Element row) { Element cell = row.appendElement("td"); addNodeIcon(nodeInfo, cell); addLink(nodeInfo, cell); } private void addSizeCell(NodeInfo nodeInfo, Element row) { Element cell = row.appendElement("td"); cell.text(nodeInfo.getSize()); } private void addGroupReadCell(NodeInfo nodeInfo, Element row) { Element cell = row.appendElement("td"); fillGroupCell(cell, nodeInfo.getGroupRead()); } private void addGroupWriteCell(NodeInfo nodeInfo, Element row) { Element cell = row.appendElement("td"); fillGroupCell(cell, nodeInfo.getGroupWrite()); } private void fillGroupCell(Element cell, String groups) { String[] values = groups.split(" "); List<String> personGroups = new ArrayList<>(); List<String> peopleGroups = new ArrayList<>(); for (String value : values) { if (value.startsWith("people.")) { personGroups.add(value.substring("people.".length()).replace("\\.", ".")); } else { peopleGroups.add(value); } } if (!personGroups.isEmpty()) { Element personIcon = cell.appendElement("span"); personIcon.attr("class", "icon person-icon"); cell.appendText(String.join(" ", personGroups)); cell.append(" "); } if (!peopleGroups.isEmpty()) { Element personIcon = cell.appendElement("span"); personIcon.attr("class", "icon people-icon"); cell.appendText(String.join(" ", peopleGroups)); } } private void addActionsCell(NodeInfo nodeInfo, Element row) { Element cell = row.appendElement("td"); if (nodeInfo.isWritable()) { Element shareIcon = cell.appendElement("span"); shareIcon.attr("class", "icon share-icon pointer"); shareIcon.attr("onclick", "shareNode(" + makeJsArg(nodeInfo.getPath()) + "," + makeJsArg(nodeInfo.getGroupRead()) + "," + makeJsArg(nodeInfo.getGroupWrite()) + ")"); } if (nodeInfo.isDeletable()) { cell.append(" "); Element deleteIcon = cell.appendElement("span"); deleteIcon.attr("class", "icon trash-icon pointer"); deleteIcon.attr("onclick", "deleteNode(" + makeJsArg(nodeInfo.getPath()) + ")"); } } private String makeJsArg(String arg) { return "'" + arg.replace("\\", "\\\\").replace("'", "\\'") + "'"; } private void addNodeIcon(NodeInfo nodeInfo, Element cell) { Element iconContainer = cell; if (nodeInfo.isBusy()) { Element loadingWrapper = cell.appendElement("span"); iconContainer = loadingWrapper; loadingWrapper.addClass("node-busy"); Element spinner = loadingWrapper.appendElement("span"); spinner.attr("role", "status"); spinner.addClass("spinner-border"); Element srEl = spinner.appendElement("span"); srEl.addClass("sr-only"); srEl.text("Loading..."); } Element icon = cell.appendElement("span"); icon.addClass("icon"); if (nodeInfo.isFolder()) { if (nodeInfo.isAsyncTrans()) { icon.addClass("folder-x-icon"); } else { icon.addClass("folder-icon"); } } else { if (nodeInfo.isAsyncTrans()) { icon.addClass("file-x-icon"); } else { icon.addClass("file-icon"); } } iconContainer.append(" "); } private void addLink(NodeInfo nodeInfo, Element cell) { if (isDownloadable(nodeInfo, user)) { Element link = cell.appendElement("a"); String href; if (nodeInfo.isFolder()) { href = "#/nodes" + urlEncodePath(nodeInfo.getPath()); } else { href = "download" + urlEncodePath(nodeInfo.getPath()); link.attr("target", "blank_"); } link.attr("href", href); link.text(nodeInfo.getName()); } else { cell.text(nodeInfo.getName()); } } private boolean isDownloadable(NodeInfo nodeInfo, User user) { if (nodeInfo.isFile()) { if (nodeInfo.isAsyncTrans() || nodeInfo.isBusy()) { return false; } } if (nodeInfo.isPublic()) { return true; } if (nodeInfo.getCreator().equals(user.getName())) { return true; } if (user.getGroups() != null && !user.getGroups().isEmpty() && !nodeInfo.getGroupRead().isEmpty()) { List<String> groupRead = Arrays.asList(nodeInfo.getGroupRead().split(" ")); for (String group : groupRead) { if (user.getGroups().contains(group)) { return true; } } } return false; } }
vospace-ui-backend/src/main/java/it/inaf/ia2/vospace/ui/service/NodesService.javadeleted 100644 → 0 +0 −149 Original line number Diff line number Diff line package it.inaf.ia2.vospace.ui.service; import it.inaf.ia2.aa.data.User; import it.inaf.ia2.vospace.ui.client.VOSpaceClient; import it.inaf.ia2.vospace.ui.data.ListNodeData; import it.inaf.oats.vospace.datamodel.NodeUtils; import static it.inaf.oats.vospace.datamodel.NodeUtils.urlEncodePath; import java.io.IOException; import java.io.StringWriter; import java.io.UncheckedIOException; import java.util.Arrays; import java.util.List; import net.ivoa.xml.vospace.v2.ContainerNode; import net.ivoa.xml.vospace.v2.Node; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Service public class NodesService { private static final Logger LOG = LoggerFactory.getLogger(NodesService.class); @Autowired private VOSpaceClient client; @Value("${vospace-authority}") private String authority; public ListNodeData generateNodesHtml(String path, User user) { ListNodeData listNodeData = new ListNodeData(); Node node = client.getNode(path); listNodeData.setWritable(NodeUtils.checkIfWritable(node, user.getName(), user.getGroups())); try (StringWriter sw = new StringWriter()) { if (node instanceof ContainerNode) { ContainerNode folder = (ContainerNode) node; sw.write("<tbody id=\"nodes\">"); for (Node child : folder.getNodes()) { sw.write(getNodeHtml(child, user)); } sw.write("</tbody>"); } listNodeData.setHtmlTable(sw.toString()); return listNodeData; } catch (IOException ex) { throw new UncheckedIOException(ex); } } private String getNodeHtml(Node node, User user) { NodeInfo nodeInfo = new NodeInfo(node, authority); if (nodeInfo.isListOfFiles()) { // hidden file return ""; } boolean deletable = NodeUtils.checkIfWritable(node, user.getName(), user.getGroups()) && !nodeInfo.isSticky(); String html = "<tr>"; html += "<td><input type=\"checkbox\" data-node=\"" + nodeInfo.getPath().replace("\"", "\\\"") + "\" "; if (nodeInfo.isAsyncTrans()) { html += "class=\"async\""; } else if (deletable) { html += "class=\"deletable\""; } html += "/></td>"; html += "<td>" + getIcon(nodeInfo) + getLink(nodeInfo, user) + "</td>"; html += "<td>" + nodeInfo.getSize() + "</td>"; html += "<td>" + nodeInfo.getGroupRead() + "</td>"; html += "<td>" + nodeInfo.getGroupWrite() + "</td>"; html += "<td>"; if (deletable) { html += "<span class=\"icon trash-icon pointer\" onclick=\"deleteNode('" + nodeInfo.getPath() + "')\"></span>"; } html += "</td>"; html += "</tr>"; return html; } private String getIcon(NodeInfo nodeInfo) { String html = ""; if (nodeInfo.isBusy()) { html += "<span class=\"node-busy\"><span role=\"status\" class=\"spinner-border\"><span class=\"sr-only\">Loading...</span></span>"; } html += "<span class=\"icon "; if (nodeInfo.isFolder()) { html += "folder"; } else { html += "file"; } if (nodeInfo.isAsyncTrans()) { html += "-x"; } html += "-icon\"></span>"; if (nodeInfo.isBusy()) { html += "</span>"; } html += " "; return html; } private String getLink(NodeInfo nodeInfo, User user) { if (isDownloadable(nodeInfo, user)) { if (nodeInfo.isFolder()) { return "<a href=\"#/nodes" + urlEncodePath(nodeInfo.getPath()) + "\">" + nodeInfo.getName() + "</a>"; } else { return "<a href=\"download" + urlEncodePath(nodeInfo.getPath()) + "\" target=\"blank_\">" + nodeInfo.getName() + "</a>"; } } return nodeInfo.getName(); } private boolean isDownloadable(NodeInfo nodeInfo, User user) { if (nodeInfo.isFile()) { if (nodeInfo.isAsyncTrans() || nodeInfo.isBusy()) { return false; } } if (nodeInfo.isPublic()) { return true; } if (nodeInfo.getCreator().equals(user.getName())) { return true; } if (user.getGroups() != null && !user.getGroups().isEmpty() && !nodeInfo.getGroupRead().isEmpty()) { List<String> groupRead = Arrays.asList(nodeInfo.getGroupRead().split(" ")); for (String group : groupRead) { if (user.getGroups().contains(group)) { return true; } } } return false; } }