This repository has been archived on 2026-02-10. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Web2OAC/src/main/java/org/openautonomousconnection/oac2web/frontend/dashboard.java

170 lines
7.4 KiB
Java
Raw Normal View History

2026-01-19 17:02:46 +01:00
package org.openautonomousconnection.oac2web.frontend;
import org.openautonomousconnection.oac2web.utils.Oac2WebApp;
import org.openautonomousconnection.oac2web.utils.RegistrarDao;
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.web.WebResponsePacket;
import org.openautonomousconnection.protocol.side.web.ProtocolWebServer;
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.WebRequestMethod;
import org.openautonomousconnection.webserver.api.Route;
import org.openautonomousconnection.webserver.api.SessionContext;
import org.openautonomousconnection.webserver.api.WebPage;
import org.openautonomousconnection.webserver.api.WebPageContext;
import org.openautonomousconnection.webserver.utils.Html;
import org.openautonomousconnection.webserver.utils.RequestParams;
import java.util.HashMap;
import java.util.Map;
/**
* Dashboard page: lists owned infonames and allows modifications.
*
* Requires valid session.
*
* POST headers (action-based):
* - action=create_infoname, tln, infoname
* - action=delete_infoname, id
* - action=add_record, id (infoname_id), sub, type, value, ttl, priority, port, weight
*/
2026-02-06 22:51:56 +01:00
@Route(path = "/ins/dashboard")
2026-01-19 17:02:46 +01:00
public final class dashboard implements WebPage {
@Override
public WebResponsePacket handle(WebPageContext ctx) throws Exception {
SessionContext session = SessionContext.from(ctx.client, (ProtocolWebServer) ctx.client.getServer(), ctx.request.getHeaders());
if (!session.isValid() || session.getUser() == null) {
return new WebResponsePacket(401, "text/plain", new HashMap<>(), Html.utf8("Authentication required (session)."));
}
int userId;
try {
userId = Integer.parseInt(session.getUser());
} catch (Exception e) {
return new WebResponsePacket(401, "text/plain", new HashMap<>(), Html.utf8("Invalid session user."));
}
2026-01-19 17:49:05 +01:00
Oac2WebApp app = Oac2WebApp.get();
RegistrarDao dao = app.dao();
2026-01-19 17:02:46 +01:00
String msg = null;
String err = null;
if (ctx.request.getMethod() == WebRequestMethod.POST) {
RequestParams p = new RequestParams(ctx.request);
String action = p.getOr("action", "").trim();
try {
if ("create_infoname".equalsIgnoreCase(action)) {
String tln = p.get("tln");
String info = p.get("infoname");
if (tln == null || tln.isBlank() || info == null || info.isBlank()) {
err = "Missing tln / infoname.";
} else {
Integer tlnId = dao.findTlnId(tln.trim()).orElse(null);
if (tlnId == null) {
err = "Unknown TLN: " + tln;
} else {
int newId = dao.createInfoName(tlnId, info.trim(), userId);
msg = "Created infoname id=" + newId + " (" + info + "." + tln + ")";
}
}
} else if ("delete_infoname".equalsIgnoreCase(action)) {
int id = p.getInt("id", -1);
if (id <= 0) {
err = "Invalid id.";
} else if (!dao.isOwnerOfInfoName(id, userId)) {
err = "Not owner (edit/delete requires ownership).";
} else {
dao.deleteInfoName(id);
msg = "Deleted infoname id=" + id;
}
} else if ("add_record".equalsIgnoreCase(action)) {
int infonameId = p.getInt("id", -1);
if (infonameId <= 0) {
err = "Invalid infoname id.";
} else if (!dao.isOwnerOfInfoName(infonameId, userId)) {
err = "Not owner (edit/delete requires ownership).";
} else {
String sub = p.get("sub");
String type = p.getOr("type", "").trim().toUpperCase();
String value = p.get("value");
int ttl = p.getInt("ttl", 3600);
2026-01-19 17:49:05 +01:00
2026-01-19 17:02:46 +01:00
Integer priority = (p.get("priority") == null) ? null : p.getInt("priority", 0);
Integer port = (p.get("port") == null) ? null : p.getInt("port", 0);
Integer weight = (p.get("weight") == null) ? null : p.getInt("weight", 0);
if (type.isBlank() || value == null || value.isBlank()) {
err = "Missing type/value.";
} else {
Integer subId = dao.ensureSubname(infonameId, sub);
int rid = dao.addRecord(infonameId, subId, type, value.trim(), ttl, priority, port, weight);
msg = "Added record id=" + rid + " type=" + type;
}
}
} else if (!action.isBlank()) {
err = "Unknown action: " + action;
}
} catch (Exception e) {
err = "Action failed: " + e.getMessage();
}
}
2026-01-19 17:49:05 +01:00
return render(userId, msg, err, dao);
2026-01-19 17:02:46 +01:00
}
2026-01-19 17:49:05 +01:00
private WebResponsePacket render(int userId, String msg, String err, RegistrarDao dao) throws Exception {
RegistrarDao.InfoNameRow[] owned = dao.listOwnedInfoNames(userId);
2026-01-19 17:02:46 +01:00
StringBuilder list = new StringBuilder();
if (owned.length == 0) {
list.append("<p class='muted'>No infonames yet.</p>");
} else {
list.append("<ul>");
for (RegistrarDao.InfoNameRow r : owned) {
list.append("<li>")
.append("<code>").append(Html.esc(r.info())).append(".").append(Html.esc(r.tln())).append("</code>")
.append(" (id=").append(r.id()).append(")")
.append("</li>");
}
list.append("</ul>");
}
String body = """
<div class="card">
<h2>Dashboard</h2>
<p class="muted">Owned by users.id = <code>%d</code></p>
%s
%s
<h3>Create InfoName</h3>
<p class="muted">POST headers: <code>action=create_infoname</code>, <code>tln</code>, <code>infoname</code></p>
<h3>Add Record</h3>
<p class="muted">POST headers: <code>action=add_record</code>, <code>id</code> (infoname id), optional <code>sub</code>, <code>type</code>, <code>value</code>, optional <code>ttl</code>, <code>priority</code>, <code>port</code>, <code>weight</code></p>
<h3>Delete InfoName</h3>
<p class="muted">POST headers: <code>action=delete_infoname</code>, <code>id</code></p>
<h3>Your InfoNames</h3>
%s
<div class="row">
2026-01-19 17:49:05 +01:00
<div class="col"><a href="/ins/index.html">Home</a></div>
2026-01-19 17:02:46 +01:00
</div>
</div>
""".formatted(
userId,
msg == null ? "" : "<p class='ok'>" + Html.esc(msg) + "</p>",
err == null ? "" : "<p class='err'>" + Html.esc(err) + "</p>",
list
);
String html = Html.page("Dashboard", body);
Map<String, String> headers = new HashMap<>();
return new WebResponsePacket(200, "text/html", headers, Html.utf8(html));
}
}