computercraft/packages/lns_server.lua
2023-10-08 05:44:23 -04:00

184 lines
4.7 KiB
Lua

settings.define("lns_server.modem_location", {
description = "Modem location",
type = "string",
default = "right"
})
modem_location = settings.get("lns_server.modem_location")
settings.define("lns_server.rednet_hostname", {
description = "Rednet hostname",
type = "string",
default = "test"
})
settings.define("lns_server.require_auth", {
description = "Require authentication",
type = "boolean",
default = false
})
require_auth = settings.get("lns_server.require_auth")
settings.define("lns_server.auth_group", {
description = "Authentication group",
type = "string",
default = "admin"
})
local auth_group = settings.get("lns_server.auth_group")
settings.define("lns_server.auth_server", {
description = "Authentication server",
type = "string",
default = "auth.box"
})
auth_server = settings.get("lns_server.auth_server")
settings.define("lns_server.log_level", {
description = "Log Level",
type = "string",
default = "info"
})
log_level = settings.get("lns_server.log_level")
rednet.host("lns", settings.get("lns_server.rednet_hostname"))
rednet.open(modem_location)
local data = {}
function log(str)
io.write("[" .. os.time() .. "] " .. str .. "\n")
end
function log_debug(str)
if log_level == "debug" then
log(str)
end
end
function save_data()
db = fs.open("lns.db", "w")
db.write(textutils.serialize(data))
db.close()
end
function load_data()
if fs.exists("lns.db") then
db = fs.open("lns.db", "r")
db_contents = db.readAll()
db.close()
data = textutils.unserialize(db_contents)
end
end
function split (inputstr, sep)
if sep == nil then
sep = "%s"
end
local t={}
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
table.insert(t, str)
end
return t
end
function check_user_in_group(username, group)
local package = {
["action"] = "check_group",
["username"] = username,
["group"] = group
}
local authID = data[auth_server]
rednet.send(authID, package, "auth")
while true do
id, msg = rednet.receive("auth")
if id == authID then
if msg == "invalid request" then
io.write("Invalid request\n")
return false
elseif msg == true then
return true
else
return false
end
end
end
end
load_data()
while true do
client_id, msg = rednet.receive("lns")
request = msg
if request.action == nil or request.hostname == nil then
rednet.send(client_id, "invalid request", "lns")
end
if request.action == "lookup" then
-- check if hostname in data
if request.hostname == nil then
rednet.send(client_id, nil, "lns")
log("Sent nil to " .. client_id)
else
rednet.send(client_id, data[request.hostname], "lns")
log("Sent " .. request.hostname .. " to " .. client_id)
end
end
if request.action == "reload" then
load_data()
rednet.send(client_id, "ok", "lns")
log("Reloaded data")
end
if request.action == "register" then
local auth_passed = false
if require_auth then
local authID = data[auth_server]
if request.token == nil then
rednet.send(client_id, "invalid auth", "lns")
elseif authID ~= nil then
rednet.send(authID, {
["action"] = "token",
["token"] = request.token
}, "auth")
local responseServerID = nil
while responseServerID ~= authID do
responseServerID, auth_response = rednet.receive("auth")
end
local errorPos, errorEnd = string.find(auth_response, "invalid")
if errorPos then
log("Error: " .. auth_response)
else
if check_user_in_group(auth_response, auth_group) then
auth_passed = true
else
rednet.send(client_id, "invalid auth", "lns")
end
end
else
log("Error: Auth server not found to " .. client_id)
end
else
auth_passed = true
end
if auth_passed then
data[request.hostname] = client_id
log("Registered " .. request.hostname .. " as " .. client_id)
save_data()
rednet.send(client_id, "ok", "lns")
else
rednet.send(client_id, "auth required", "lns")
end
end
end