computercraft/packages/auth_server.lua

233 lines
6.7 KiB
Lua
Raw Permalink Normal View History

2023-10-08 06:19:55 +02:00
2023-10-09 12:54:35 +02:00
settings.define("auth_server.salt", {
description = "Salt for hashing passwords",
type = "string",
default = "3m&LmNm7"
})
2023-10-08 06:19:55 +02:00
2023-10-08 11:11:52 +02:00
local data = {
2023-10-08 11:15:17 +02:00
users = {}
2023-10-08 06:19:55 +02:00
}
2023-10-08 11:15:17 +02:00
-- Schema:
-- data = {
-- users = {
-- ["username"] = {
2023-10-09 12:54:35 +02:00
-- token = "token",
2023-10-08 11:15:17 +02:00
-- password = "hashed password",
-- groups = {
-- ["group"] = true
-- },
-- },
-- }
2023-10-08 06:19:55 +02:00
function save_data()
db = fs.open("auth.db", "w")
db.write(textutils.serialize(data))
db.close()
end
function load_data()
if fs.exists("auth.db") then
db = fs.open("auth.db", "r")
db_contents = db.readAll()
db.close()
data = textutils.unserialize(db_contents)
end
end
function generate_token(user)
2023-10-09 12:54:35 +02:00
local token = sha256.sha256(user .. os.time() .. math.random())
2023-10-08 06:19:55 +02:00
data.users[user].token = token
return token
end
function convert_password(password)
2023-10-09 12:54:35 +02:00
local salt = settings.get("auth_server.salt")
return sha256.sha256(password .. salt)
2023-10-08 06:19:55 +02:00
end
2023-10-08 07:09:44 +02:00
function log(str)
io.write("[" .. os.time() .. "] " .. str .. "\n")
end
2023-10-08 11:11:52 +02:00
function countElements(table)
local count = 0
for key, value in pairs(table) do
count = count + 1
end
return count
end
2023-10-08 06:19:55 +02:00
load_data()
math.randomseed(os.time())
while true do
2023-10-08 08:44:20 +02:00
client_id, msg = rednet.receive("auth")
2023-10-08 06:19:55 +02:00
request = msg
if request.action == nil then
2023-10-08 08:44:20 +02:00
rednet.send(client_id, "invalid request", "auth")
2023-10-08 06:19:55 +02:00
end
if request.action == "register" then
if request.username == nil or request.password == nil then
2023-10-08 08:44:20 +02:00
rednet.send(client_id, "invalid request", "auth")
2023-10-08 06:19:55 +02:00
end
if data.users[request.username] ~= nil then
2023-10-08 08:44:20 +02:00
rednet.send(client_id, "user already exists", "auth")
2023-10-08 06:19:55 +02:00
end
data.users[request.username] = {
password = convert_password(request.password)
}
2023-10-08 10:59:38 +02:00
2023-10-08 11:11:52 +02:00
local user_count = countElements(data.users)
2023-10-08 11:07:48 +02:00
if user_count == 1 then
2023-10-08 11:15:17 +02:00
log("Promoting " .. request.username .. " to admin")
2023-10-08 11:07:48 +02:00
data.users[request.username].groups = {
["admin"] = true
}
2023-10-08 10:59:38 +02:00
end
2023-10-08 06:19:55 +02:00
save_data()
2023-10-08 08:44:20 +02:00
rednet.send(client_id, "ok", "auth")
2023-10-08 07:09:44 +02:00
log(request.username .. " registered")
2023-10-08 06:19:55 +02:00
end
if request.action == "login" then
if request.username == nil or request.password == nil then
2023-10-08 08:44:20 +02:00
rednet.send(client_id, "invalid request", "auth")
2023-10-08 07:09:44 +02:00
2023-10-08 08:25:17 +02:00
elseif data.users[request.username] == nil then
2023-10-08 08:44:20 +02:00
rednet.send(client_id, "user not found", "auth")
2023-10-08 06:19:55 +02:00
2023-10-08 07:09:44 +02:00
log(request.username .. " failed log in attempt")
2023-10-08 08:25:17 +02:00
elseif convert_password(request.password) == data.users[request.username].password then
2023-10-08 06:19:55 +02:00
local token = generate_token(request.username)
2023-10-08 08:54:58 +02:00
rednet.send(client_id, token, "auth")
2023-10-08 07:09:44 +02:00
log(request.username .. " logged in")
2023-10-08 06:19:55 +02:00
else
2023-10-08 08:44:20 +02:00
rednet.send(client_id, "invalid password", "auth")
2023-10-08 06:19:55 +02:00
end
end
if request.action == "token" then
2023-10-08 08:57:56 +02:00
if request.token == nil or request.token == "" or request.token == -1 then
2023-10-08 08:44:20 +02:00
rednet.send(client_id, "invalid request", "auth")
2023-10-08 07:09:44 +02:00
else
2023-10-08 06:19:55 +02:00
2023-10-08 09:01:39 +02:00
local found = false
2023-10-08 07:09:44 +02:00
for user, userdata in pairs(data.users) do
if userdata.token == request.token then
2023-10-08 09:12:06 +02:00
rednet.send(client_id, user, "auth")
2023-10-08 09:01:39 +02:00
found = true
2023-10-08 07:09:44 +02:00
end
2023-10-08 06:19:55 +02:00
end
2023-10-08 09:01:39 +02:00
if not found then
rednet.send(client_id, "invalid token", "auth")
end
2023-10-08 07:09:44 +02:00
end
2023-10-08 06:19:55 +02:00
end
if request.action == "profile" then
if request.username == nil then
2023-10-08 08:44:20 +02:00
rednet.send(client_id, "invalid request", "auth")
2023-10-08 06:19:55 +02:00
end
local profile = {}
if data.users[request.username].profile_data ~= nil then
profile = data.users[request.username].profile_data
else
profile.display_name = request.username
end
profile.username = request.username
2023-10-08 08:44:20 +02:00
rednet.send(client_id, data.users[request.username], "auth")
2023-10-08 06:19:55 +02:00
end
if request.action == "update_profile" then
if request.username == nil or request.token == nil then
2023-10-08 08:44:20 +02:00
rednet.send(client_id, "invalid request", "auth")
2023-10-08 06:19:55 +02:00
end
if data.users[request.username].token == request.token then
if request.profile_data ~= nil then
data.users[request.username].profile_data = request.profile_data
end
save_data()
rednet.send(client_id, "ok")
2023-10-08 08:44:20 +02:00
log(request.username .. " updated their profile", "auth")
2023-10-08 06:19:55 +02:00
else
2023-10-08 08:44:20 +02:00
rednet.send(client_id, "invalid token", "auth")
2023-10-08 06:19:55 +02:00
end
end
2023-10-08 10:44:58 +02:00
if request.action == "check_group" then
if request.username == nil or request.group == nil then
rednet.send(client_id, "invalid request", "auth")
end
2023-10-08 11:34:38 +02:00
if data.users[request.username].groups == nil or data.users[request.username].groups[request.group] == nil or data.users[request.username].groups[request.group] == false then
2023-10-08 10:44:58 +02:00
rednet.send(client_id, false, "auth")
else
2023-10-08 11:33:00 +02:00
rednet.send(client_id, true, "auth")
2023-10-08 10:44:58 +02:00
end
end
if request.action == "list_groups" then
if request.username == nil then
rednet.send(client_id, "invalid request", "auth")
end
if data.users[request.username].groups == nil then
rednet.send(client_id, {}, "auth")
else
rednet.send(client_id, data.users[request.username].groups, "auth")
end
end
-- Only if in group admin
if request.action == "add_group" then
if request.username == nil or request.group == nil or request.token == nil then
rednet.send(client_id, "invalid request", "auth")
else
local found = false
local acting_user = nil
for user, userdata in pairs(data.users) do
if userdata.token == request.token then
acting_user = user
found = true
end
end
if not found then
rednet.send(client_id, "invalid token", "auth")
2023-10-08 10:57:53 +02:00
elseif data.users[acting_user]["groups"] == nil or data.users[acting_user].groups["admin"] == nil then
2023-10-08 10:44:58 +02:00
rednet.send(client_id, "invalid privileges", "auth")
else
if data.users[request.username].groups == nil then
data.users[request.username].groups = {}
end
data.users[request.username].groups[request.group] = true
save_data()
rednet.send(client_id, "ok", "auth")
log(request.username .. " added to group " .. request.group, "auth")
end
end
end
2023-10-08 06:19:55 +02:00
end