ntopng/scripts/lua/admin/change_user_mfa.lua
2026-03-13 09:06:43 +01:00

85 lines
2.6 KiB
Lua

--
-- (C) 2013-26 - ntop.org
--
-- REST endpoint to manage TOTP/MFA settings for a user.
-- POST parameters:
-- action = "enable" | "disable" | "generate_secret"
-- username = target username
--
-- Only an admin or the user themselves may change their own MFA settings.
--
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"]
local username = _POST["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 == "generate_secret" then
-- Generate a new TOTP secret and store it (does not enable MFA yet)
local secret = ntop.generateTOTPSecret()
if not secret then
print(json.encode({ result = -1, message = "Failed to generate secret" }))
return
end
if not ntop.setUserTOTPSecret(username, secret) then
print(json.encode({ result = -1, message = "Failed to save secret" }))
return
end
local uri = ntop.getTOTPProvisioningUri(username)
print(json.encode({
result = 0,
secret = secret,
provisioning_uri = uri or ""
}))
elseif action == "enable" then
-- Verify the provided TOTP code before enabling (confirm setup is correct)
local code = _POST["totp"]
if isEmptyString(code) then
print(json.encode({ result = -1, message = "Missing TOTP code" }))
return
end
if not ntop.validateTOTP(username, code) then
print(json.encode({ result = -1, message = "Invalid TOTP code" }))
return
end
if not ntop.setUserTOTPEnabled(username, true) then
print(json.encode({ result = -1, message = "Failed to enable MFA" }))
return
end
print(json.encode({ result = 0, message = "MFA enabled" }))
elseif action == "disable" then
-- Admins can disable without a code; users must supply current code
if not isAdministrator() then
local code = _POST["totp"]
if isEmptyString(code) or not ntop.validateTOTP(username, code) then
print(json.encode({ result = -1, message = "Invalid TOTP code" }))
return
end
end
ntop.setUserTOTPEnabled(username, false)
print(json.encode({ result = 0, message = "MFA disabled" }))
else
print(json.encode({ result = -1, message = "Unknown action" }))
end