Bug fixes
This commit is contained in:
@@ -42,6 +42,9 @@ public final class dashboard implements WebPage {
|
|||||||
return new WebResponsePacket(401, "text/plain", new HashMap<>(), Html.utf8("Invalid session user."));
|
return new WebResponsePacket(401, "text/plain", new HashMap<>(), Html.utf8("Invalid session user."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Oac2WebApp app = Oac2WebApp.get();
|
||||||
|
RegistrarDao dao = app.dao();
|
||||||
|
|
||||||
String msg = null;
|
String msg = null;
|
||||||
String err = null;
|
String err = null;
|
||||||
|
|
||||||
@@ -50,9 +53,6 @@ public final class dashboard implements WebPage {
|
|||||||
String action = p.getOr("action", "").trim();
|
String action = p.getOr("action", "").trim();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Oac2WebApp app = Oac2WebApp.get();
|
|
||||||
RegistrarDao dao = app.dao();
|
|
||||||
|
|
||||||
if ("create_infoname".equalsIgnoreCase(action)) {
|
if ("create_infoname".equalsIgnoreCase(action)) {
|
||||||
String tln = p.get("tln");
|
String tln = p.get("tln");
|
||||||
String info = p.get("infoname");
|
String info = p.get("infoname");
|
||||||
@@ -90,6 +90,7 @@ public final class dashboard implements WebPage {
|
|||||||
String value = p.get("value");
|
String value = p.get("value");
|
||||||
|
|
||||||
int ttl = p.getInt("ttl", 3600);
|
int ttl = p.getInt("ttl", 3600);
|
||||||
|
|
||||||
Integer priority = (p.get("priority") == null) ? null : p.getInt("priority", 0);
|
Integer priority = (p.get("priority") == null) ? null : p.getInt("priority", 0);
|
||||||
Integer port = (p.get("port") == null) ? null : p.getInt("port", 0);
|
Integer port = (p.get("port") == null) ? null : p.getInt("port", 0);
|
||||||
Integer weight = (p.get("weight") == null) ? null : p.getInt("weight", 0);
|
Integer weight = (p.get("weight") == null) ? null : p.getInt("weight", 0);
|
||||||
@@ -110,12 +111,11 @@ public final class dashboard implements WebPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(ctx, userId, msg, err);
|
return render(userId, msg, err, dao);
|
||||||
}
|
}
|
||||||
|
|
||||||
private WebResponsePacket render(WebPageContext ctx, int userId, String msg, String err) throws Exception {
|
private WebResponsePacket render(int userId, String msg, String err, RegistrarDao dao) throws Exception {
|
||||||
Oac2WebApp app = Oac2WebApp.get();
|
RegistrarDao.InfoNameRow[] owned = dao.listOwnedInfoNames(userId);
|
||||||
RegistrarDao.InfoNameRow[] owned = app.dao().listOwnedInfoNames(userId);
|
|
||||||
|
|
||||||
StringBuilder list = new StringBuilder();
|
StringBuilder list = new StringBuilder();
|
||||||
if (owned.length == 0) {
|
if (owned.length == 0) {
|
||||||
@@ -151,7 +151,7 @@ public final class dashboard implements WebPage {
|
|||||||
%s
|
%s
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col"><a href="/">Home</a></div>
|
<div class="col"><a href="/ins/index.html">Home</a></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
""".formatted(
|
""".formatted(
|
||||||
@@ -164,12 +164,6 @@ public final class dashboard implements WebPage {
|
|||||||
String html = Html.page("Dashboard", body);
|
String html = Html.page("Dashboard", body);
|
||||||
|
|
||||||
Map<String, String> headers = new HashMap<>();
|
Map<String, String> headers = new HashMap<>();
|
||||||
// keep the same session header visible to client, if needed
|
|
||||||
if (ctx.request.getHeaders() != null) {
|
|
||||||
String sess = ctx.request.getHeaders().get("session");
|
|
||||||
if (sess != null) headers.put("session", sess);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new WebResponsePacket(200, "text/html", headers, Html.utf8(html));
|
return new WebResponsePacket(200, "text/html", headers, Html.utf8(html));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ public final class index implements WebPage {
|
|||||||
<h2>OAC INS Registrar</h2>
|
<h2>OAC INS Registrar</h2>
|
||||||
<p class="muted">Server-side pages (oac2web). No extra endpoints.</p>
|
<p class="muted">Server-side pages (oac2web). No extra endpoints.</p>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col"><a href="/login">Login</a></div>
|
<div class="col"><a href="/ins/login">Login</a></div>
|
||||||
<div class="col"><a href="/register">Register</a></div>
|
<div class="col"><a href="/ins/register">Register</a></div>
|
||||||
<div class="col"><a href="/dashboard">Dashboard</a></div>
|
<div class="col"><a href="/ins/dashboard">Dashboard</a></div>
|
||||||
</div>
|
</div>
|
||||||
<p class="muted">POST parameters are expected via headers (e.g. <code>username</code>, <code>password</code>, <code>action</code>).</p>
|
<p class="muted">POST parameters are expected via headers (e.g. <code>username</code>, <code>password</code>, <code>action</code>).</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.openautonomousconnection.oac2web.frontend;
|
package org.openautonomousconnection.oac2web.frontend;
|
||||||
|
|
||||||
import org.openautonomousconnection.oac2web.utils.*;
|
import org.openautonomousconnection.oac2web.utils.Oac2WebApp;
|
||||||
|
import org.openautonomousconnection.oac2web.utils.RegistrarDao;
|
||||||
|
import org.openautonomousconnection.oac2web.utils.Sha256;
|
||||||
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.web.WebResponsePacket;
|
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.web.WebResponsePacket;
|
||||||
import org.openautonomousconnection.protocol.side.web.ProtocolWebServer;
|
import org.openautonomousconnection.protocol.side.web.ProtocolWebServer;
|
||||||
import org.openautonomousconnection.protocol.side.web.managers.SessionManager;
|
import org.openautonomousconnection.protocol.side.web.managers.SessionManager;
|
||||||
@@ -41,9 +43,9 @@ public final class login implements WebPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Oac2WebApp app = Oac2WebApp.get();
|
Oac2WebApp app = Oac2WebApp.get();
|
||||||
String usernameHash = Sha256.hex(username.trim());
|
|
||||||
|
|
||||||
RegistrarDao.UserRow u = app.dao().findUserByUsernameHash(usernameHash).orElse(null);
|
String usernameHashHex = Sha256.hex(username.trim());
|
||||||
|
RegistrarDao.UserRow u = app.dao().findUserByUsernameHash(usernameHashHex).orElse(null);
|
||||||
if (u == null) return renderForm("Invalid credentials.");
|
if (u == null) return renderForm("Invalid credentials.");
|
||||||
|
|
||||||
boolean ok = app.passwordHasher().verify(password, u.passwordEncoded());
|
boolean ok = app.passwordHasher().verify(password, u.passwordEncoded());
|
||||||
@@ -59,7 +61,7 @@ public final class login implements WebPage {
|
|||||||
|
|
||||||
Map<String, String> headers = new HashMap<>();
|
Map<String, String> headers = new HashMap<>();
|
||||||
headers.put("session", session);
|
headers.put("session", session);
|
||||||
headers.put("location", "/dashboard");
|
headers.put("location", "/ins/dashboard");
|
||||||
return new WebResponsePacket(302, "text/plain", headers, new byte[0]);
|
return new WebResponsePacket(302, "text/plain", headers, new byte[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,8 +72,8 @@ public final class login implements WebPage {
|
|||||||
%s
|
%s
|
||||||
<p class="muted">Send a POST request with headers <code>username</code> and <code>password</code>.</p>
|
<p class="muted">Send a POST request with headers <code>username</code> and <code>password</code>.</p>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col"><a href="/register">Register</a></div>
|
<div class="col"><a href="/ins/register">Register</a></div>
|
||||||
<div class="col"><a href="/">Home</a></div>
|
<div class="col"><a href="/ins/index.html">Home</a></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
""".formatted(err == null ? "" : "<p class='err'>" + Html.esc(err) + "</p>");
|
""".formatted(err == null ? "" : "<p class='err'>" + Html.esc(err) + "</p>");
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import java.util.Map;
|
|||||||
* - password
|
* - password
|
||||||
*
|
*
|
||||||
* Stores:
|
* Stores:
|
||||||
* - users.username = sha256(username)
|
* - users.username = sha256(username) as HEX (64 chars)
|
||||||
* - users.password = PBKDF2$sha256$...
|
* - users.password = PBKDF2$sha256$...
|
||||||
*/
|
*/
|
||||||
@Route(path = "ins/register")
|
@Route(path = "ins/register")
|
||||||
@@ -32,7 +32,7 @@ public final class register implements WebPage {
|
|||||||
@Override
|
@Override
|
||||||
public WebResponsePacket handle(WebPageContext ctx) throws Exception {
|
public WebResponsePacket handle(WebPageContext ctx) throws Exception {
|
||||||
if (ctx.request.getMethod() != WebRequestMethod.POST) {
|
if (ctx.request.getMethod() != WebRequestMethod.POST) {
|
||||||
return renderForm(null, null);
|
return renderForm(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestParams p = new RequestParams(ctx.request);
|
RequestParams p = new RequestParams(ctx.request);
|
||||||
@@ -41,16 +41,16 @@ public final class register implements WebPage {
|
|||||||
String password = p.get("password");
|
String password = p.get("password");
|
||||||
|
|
||||||
if (username == null || username.isBlank() || password == null || password.isBlank()) {
|
if (username == null || username.isBlank() || password == null || password.isBlank()) {
|
||||||
return renderForm("Missing username/password (send via headers).", null);
|
return renderForm("Missing username/password (send via headers).");
|
||||||
}
|
}
|
||||||
|
|
||||||
Oac2WebApp app = Oac2WebApp.get();
|
Oac2WebApp app = Oac2WebApp.get();
|
||||||
|
|
||||||
String usernameHash = Sha256.hex(username.trim());
|
String usernameHashHex = Sha256.hex(username.trim());
|
||||||
String passwordEnc = app.passwordHasher().hash(password);
|
String passwordEnc = app.passwordHasher().hash(password);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int userId = app.dao().createUser(usernameHash, passwordEnc);
|
int userId = app.dao().createUser(usernameHashHex, passwordEnc);
|
||||||
|
|
||||||
String ip = (ctx.client.getConnection().getSocket() != null && ctx.client.getConnection().getSocket().getInetAddress() != null)
|
String ip = (ctx.client.getConnection().getSocket() != null && ctx.client.getConnection().getSocket().getInetAddress() != null)
|
||||||
? ctx.client.getConnection().getSocket().getInetAddress().getHostAddress()
|
? ctx.client.getConnection().getSocket().getInetAddress().getHostAddress()
|
||||||
@@ -58,37 +58,31 @@ public final class register implements WebPage {
|
|||||||
|
|
||||||
String ua = ctx.request.getHeaders() != null ? ctx.request.getHeaders().getOrDefault("user-agent", "") : "";
|
String ua = ctx.request.getHeaders() != null ? ctx.request.getHeaders().getOrDefault("user-agent", "") : "";
|
||||||
|
|
||||||
// SessionManager user string: we store numeric users.id as string.
|
|
||||||
String session = SessionManager.create(String.valueOf(userId), ip, ua, (ProtocolWebServer) ctx.client.getServer());
|
String session = SessionManager.create(String.valueOf(userId), ip, ua, (ProtocolWebServer) ctx.client.getServer());
|
||||||
|
|
||||||
Map<String, String> headers = new HashMap<>();
|
Map<String, String> headers = new HashMap<>();
|
||||||
headers.put("session", session);
|
headers.put("session", session);
|
||||||
headers.put("location", "/dashboard");
|
headers.put("location", "/ins/dashboard");
|
||||||
|
|
||||||
return new WebResponsePacket(302, "text/plain", headers, new byte[0]);
|
return new WebResponsePacket(302, "text/plain", headers, new byte[0]);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// likely UNIQUE violation on users.username (hashed)
|
return renderForm("Register failed: " + e.getMessage());
|
||||||
return renderForm("Register failed: " + e.getMessage(), null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private WebResponsePacket renderForm(String err, String ok) {
|
private WebResponsePacket renderForm(String err) {
|
||||||
String body = """
|
String body = """
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>Register</h2>
|
<h2>Register</h2>
|
||||||
%s
|
%s
|
||||||
%s
|
|
||||||
<p class="muted">Send a POST request with headers <code>username</code> and <code>password</code>.</p>
|
<p class="muted">Send a POST request with headers <code>username</code> and <code>password</code>.</p>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col"><a href="/login">Login</a></div>
|
<div class="col"><a href="/ins/login">Login</a></div>
|
||||||
<div class="col"><a href="/">Home</a></div>
|
<div class="col"><a href="/ins/index.html">Home</a></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
""".formatted(
|
""".formatted(err == null ? "" : "<p class='err'>" + Html.esc(err) + "</p>");
|
||||||
err == null ? "" : "<p class='err'>" + Html.esc(err) + "</p>",
|
|
||||||
ok == null ? "" : "<p class='ok'>" + Html.esc(ok) + "</p>"
|
|
||||||
);
|
|
||||||
|
|
||||||
String html = Html.page("Register", body);
|
String html = Html.page("Register", body);
|
||||||
return new WebResponsePacket(200, "text/html", new HashMap<>(), Html.utf8(html));
|
return new WebResponsePacket(200, "text/html", new HashMap<>(), Html.utf8(html));
|
||||||
|
|||||||
@@ -7,9 +7,8 @@ import java.util.Objects;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* PBKDF2 password hashing (PBKDF2WithHmacSHA256).
|
* PBKDF2 password hashing (PBKDF2WithHmacSHA256).
|
||||||
*
|
|
||||||
* Storage format:
|
* Storage format:
|
||||||
* PBKDF2$sha256$<iterations>$<saltHex>$<hashHex>
|
* {@code PBKDF2$sha256$ITERATIONS$SALT_HEX$HASH_HEX}
|
||||||
*/
|
*/
|
||||||
public final class Pbkdf2PasswordHasher {
|
public final class Pbkdf2PasswordHasher {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user