diff options
Diffstat (limited to 'central/src/main/java/moe/yuuta/dn42peering/admin/nodes/NodeAdminUI.java')
-rw-r--r-- | central/src/main/java/moe/yuuta/dn42peering/admin/nodes/NodeAdminUI.java | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/central/src/main/java/moe/yuuta/dn42peering/admin/nodes/NodeAdminUI.java b/central/src/main/java/moe/yuuta/dn42peering/admin/nodes/NodeAdminUI.java new file mode 100644 index 0000000..dd625cc --- /dev/null +++ b/central/src/main/java/moe/yuuta/dn42peering/admin/nodes/NodeAdminUI.java @@ -0,0 +1,142 @@ +package moe.yuuta.dn42peering.admin.nodes; + +import edazdarevic.commons.net.CIDRUtils; +import io.vertx.core.Future; +import io.vertx.core.json.JsonObject; +import io.vertx.ext.web.RoutingContext; +import io.vertx.ext.web.common.template.TemplateEngine; +import moe.yuuta.dn42peering.RPC; +import moe.yuuta.dn42peering.node.INodeService; +import moe.yuuta.dn42peering.node.Node; +import moe.yuuta.dn42peering.portal.FormException; +import moe.yuuta.dn42peering.portal.RenderingUtils; +import org.apache.commons.validator.routines.InetAddressValidator; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.IOException; +import java.net.Inet6Address; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +class NodeAdminUI { + public static void renderForm(@Nonnull TemplateEngine engine, + @Nonnull INodeService nodeService, + @Nonnull String asn, + boolean newForm, + @Nullable Node node, + @Nullable List<String> errors, + @Nonnull RoutingContext ctx) { + final Map<String, Object> root = new HashMap<>(); + root.put("asn", asn); + root.put("tunneling_method_wireguard", true); + if (node != null) { + root.put("id", node.getId()); + root.put("input_asn", node.getAsn()); + root.put("name", node.getName()); + root.put("ipv4", node.getDn42Ip4()); + root.put("ipv6", node.getDn42Ip6()); + root.put("ipv6_non_ll", node.getDn42Ip6NonLL()); + root.put("public_ip", node.getPublicIp()); + root.put("internal_ip", node.getInternalIp()); + root.put("internal_port", node.getInternalPort()); + root.put("notice", node.getNotice()); + root.put("tunneling_method_wireguard", node.isWireguard()); + } + if(!newForm && node != null) + root.put("action", "/admin/nodes/edit?id=" + node.getId()); + else + root.put("action", "/admin/nodes/new"); + root.put("errors", errors); + engine.render(root, newForm ? "admin/nodes/new.ftlh" : "admin/nodes/edit.ftlh", + RenderingUtils.getGeneralRenderingHandler(ctx)); + } + + @Nonnull + public static Future<Node> parseForm(@Nonnull INodeService nodeService, + @Nonnull String authAsn, + @Nonnull JsonObject form) { + final List<String> errors = new ArrayList<>(10); + final Node node = new Node(); + node.setAsn(form.getString("asn", authAsn)); + node.setName(form.getString("name")); + node.setNotice(form.getString("notice")); + node.setDn42Ip4(form.getString("ipv4")); + node.setDn42Ip6(form.getString("ipv6")); + node.setDn42Ip6NonLL(form.getString("ipv6_non_ll")); + node.setInternalIp(form.getString("internal_ip")); + node.setPublicIp(form.getString("public_ip")); + try { + String raw = form.getString("internal_port"); + if(raw == null || raw.isEmpty()) { + node.setInternalPort(RPC.AGENT_PORT); + } else { + node.setInternalPort(Integer.parseInt(raw)); + } + } catch (NumberFormatException e) { + errors.add("Invalid internal port"); + } + node.setWireguard(form.containsKey("tunneling_method_wireguard")); + + if(!node.getAsn().matches("[aA][sS]424242[0-9][0-9][0-9][0-9]")) + errors.add("ASN is invalid"); + if(node.getName() == null || node.getName().trim().isEmpty()) + errors.add("No name supplied"); + try { + if(node.getDn42Ip4() != null) { + if (InetAddressValidator.getInstance().isValidInet4Address(node.getDn42Ip4())) { + if (!new CIDRUtils("172.20.0.0/14").isInRange(node.getDn42Ip4())) { + errors.add("DN42 IPv4 address is illegal. It must be a dn42 IPv4 address (172.20.x.x to 172.23.x.x)."); + } + } else + errors.add("DN42 IPv4 address is illegal. Cannot parse your address."); + } else { + errors.add("DN42 IPv4 address is not supplied"); + } + if(node.getDn42Ip6() != null) { + if (InetAddressValidator.getInstance().isValidInet6Address(node.getDn42Ip6())) { + if (new CIDRUtils("fd00::/8").isInRange(node.getDn42Ip6())) { + errors.add("DN42 IPv6 address is illegal. It must be a link-local IPv6 address."); + } + } else + errors.add("DN42 Link Local IPv6 address is illegal. Cannot parse your address."); + } else { + errors.add("DN42 IPv6 Link Local address is not supplied"); + } + if(node.getDn42Ip6NonLL() != null) { + if (InetAddressValidator.getInstance().isValidInet6Address(node.getDn42Ip6NonLL())) { + if (!new CIDRUtils("fd00::/8").isInRange(node.getDn42Ip6NonLL()) || + Inet6Address.getByName(node.getDn42Ip6NonLL()).isLinkLocalAddress()) { + errors.add("DN42 IPv6 address is illegal. It must be a dn42 IPv6 address."); + } + } else + errors.add("IPv6 address is illegal. Cannot parse your address."); + } else { + errors.add("DN42 IPv6 address is not supplied"); + } + } catch (IOException e) { + return Future.failedFuture(e); + } + + if(node.getInternalIp() == null) { + errors.add("Internal IP is not supplied."); + } + + if(node.getInternalPort() < 0 || + node.getInternalPort() > 65535) { + errors.add("Internal Port is out of range. Supported range: [0, 65535]."); + } + + if(node.getPublicIp() == null || node.getPublicIp().isEmpty()) { + errors.add("Public IP is not supplied."); + } + + if(errors.isEmpty()) { + return Future.succeededFuture(node); + } else { + return Future.failedFuture(new FormException(node, errors.toArray(new String[]{}))); + } + } +} |