mirror of
https://github.com/ntop/ntopng.git
synced 2026-05-03 09:20:10 +00:00
101 lines
3.5 KiB
Lua
101 lines
3.5 KiB
Lua
--
|
|
-- (C) 2013-26 - ntop.org
|
|
--
|
|
-- REST endpoint for WebAuthn/Passkey credential management.
|
|
-- Actions:
|
|
-- get_registration_options -> generate challenge for registration
|
|
-- complete_registration -> verify and store a new credential
|
|
-- delete -> remove a credential
|
|
-- list -> list credentials
|
|
--
|
|
|
|
local dirs = ntop.getDirs()
|
|
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
|
require "lua_utils"
|
|
local json = require "dkjson"
|
|
|
|
sendHTTPHeader('application/json')
|
|
|
|
local action = _POST["action"] or _GET["action"]
|
|
local username = _POST["username"] or _GET["username"]
|
|
|
|
if isEmptyString(username) then
|
|
print(json.encode({ result = -1, message = "Missing username" }))
|
|
return
|
|
end
|
|
|
|
username = string.lower(username)
|
|
|
|
-- Authorization: admin or the logged-in user themselves
|
|
local curr_user = _SESSION and _SESSION["user"] or ""
|
|
if (not isAdministrator()) and (curr_user ~= username) then
|
|
print(json.encode({ result = -1, message = "Not authorized" }))
|
|
return
|
|
end
|
|
|
|
if action == "get_registration_options" then
|
|
local opts = ntop.generateWebAuthnRegistrationOptions(username)
|
|
if not opts then
|
|
print(json.encode({ result = -1, message = "Failed to generate challenge" }))
|
|
return
|
|
end
|
|
-- Return options for navigator.credentials.create()
|
|
-- rp.id is intentionally empty here; the client fills it with window.location.hostname
|
|
print(json.encode({
|
|
result = 0,
|
|
challenge = opts.challenge,
|
|
rp = { name = "ntopng", id = "" },
|
|
user = { id = username, name = username, displayName = username },
|
|
pubKeyCredParams = {{ type = "public-key", alg = -7 }},
|
|
authenticatorSelection = { userVerification = "preferred", residentKey = "preferred" },
|
|
attestation = "none",
|
|
timeout = 60000
|
|
}))
|
|
|
|
elseif action == "complete_registration" then
|
|
local cred_name = _POST["cred_name"] or "Passkey"
|
|
local cred_id = _POST["cred_id"]
|
|
local client_data = _POST["client_data"]
|
|
local att_obj = _POST["att_obj"]
|
|
local challenge = _POST["challenge"]
|
|
local origin = _POST["origin"]
|
|
local rp_id = _POST["rp_id"]
|
|
|
|
if isEmptyString(cred_id) or isEmptyString(client_data) or
|
|
isEmptyString(att_obj) or isEmptyString(challenge) or
|
|
isEmptyString(origin) or isEmptyString(rp_id) then
|
|
print(json.encode({ result = -1, message = "Missing registration data" }))
|
|
return
|
|
end
|
|
|
|
local ok = ntop.completeWebAuthnRegistration(
|
|
username, cred_name, cred_id, client_data, att_obj, challenge, origin, rp_id
|
|
)
|
|
if ok then
|
|
print(json.encode({ result = 0, message = "Passkey registered successfully" }))
|
|
else
|
|
print(json.encode({ result = -1, message = "Registration verification failed" }))
|
|
end
|
|
|
|
elseif action == "delete" then
|
|
local cred_id = _POST["cred_id"]
|
|
if isEmptyString(cred_id) then
|
|
print(json.encode({ result = -1, message = "Missing credential ID" }))
|
|
return
|
|
end
|
|
local ok = ntop.deleteWebAuthnCredential(username, cred_id)
|
|
if ok then
|
|
print(json.encode({ result = 0, message = "Passkey removed" }))
|
|
else
|
|
print(json.encode({ result = -1, message = "Credential not found" }))
|
|
end
|
|
|
|
elseif action == "list" then
|
|
local creds_json = ntop.getWebAuthnCredentials(username)
|
|
-- Parse and re-encode to ensure valid JSON output
|
|
local creds = json.decode(creds_json) or {}
|
|
print(json.encode({ result = 0, credentials = creds }))
|
|
|
|
else
|
|
print(json.encode({ result = -1, message = "Unknown action" }))
|
|
end
|