fediauth/init.lua

100 lines
4.0 KiB
Lua

local MP = minetest.get_modpath("fediauth")
local http = minetest.request_http_api()
-- sanity checks
assert(type(minetest.encode_png) == "function")
fediauth = {
-- mod storage
storage = minetest.get_mod_storage(),
-- baseXX functions
basexx = loadfile(MP.."/basexx.lua")(),
}
if minetest.settings:get_bool("fediauth.use_matterbridge", false) then
fediauth.matterbridge_avalaible = minetest.get_modpath("yl_matterbridge") and true
end
dofile(MP.."/mastoapi.lua")
local instance = minetest.settings:get("fediauth.instance")
local key = minetest.settings:get("fediauth.api_token")
if not instance or not key then
minetest.log("warning", "[fediauth] For working fediauth you should specify fediauth.instance and fediauth.api_token")
else
mastoapi_init(http, instance, key)
dofile(MP.."/functions.lua")
dofile(MP.."/onboard.lua")
dofile(MP.."/join.lua")
dofile(MP.."/privs.lua")
dofile(MP.."/priv_revoke.lua")
dofile(MP.."/password_save.lua")
local protect_chatcommands = minetest.settings:get_bool("fediauth.protect_chatcommands", true)
if protect_chatcommands and not minetest.is_singleplayer() then
local security_unlock_code
minetest.register_on_mods_loaded(function()
security_unlock_code = SecureRandom()
if security_unlock_code ~= nil then
security_unlock_code = security_unlock_code:next_bytes(1024)
local ascii = ""
for i in string.gmatch(security_unlock_code, "[_%a%d%w.%p%x]") do
ascii = i .. ascii
end
security_unlock_code = ascii
else
minetest.log("warning", "[fediauth] secure random device not avalaible on your machine, fallbacking to pseudorandom")
security_unlock_code = ""
local symbols = "@!$%,/:;-_+|<>"
local pseudorand = PcgRandom(math.random(-2147483648, 2147483647) * math.random(2,32))
for i=1,256 do
local randselector = pseudorand:next(1,4)
if randselector == 1 then
local randuppercase = string.char(pseudorand:next(65, 65 + 25))
security_unlock_code = security_unlock_code .. randuppercase
elseif randselector == 2 then
local randlowercase = string.char(pseudorand:next(65, 65 + 25)):lower()
security_unlock_code = security_unlock_code .. randlowercase
elseif randselector == 3 then
local rint = math.random(1, #symbols)
local symbol = symbols:sub(rint, rint)
security_unlock_code = security_unlock_code .. symbol
else
security_unlock_code = security_unlock_code .. pseudorand:next(0,9)
end
end
end
security_unlock_code = tostring(security_unlock_code):sub(1, math.random(64, 128))
print('[!fediauth]: ' .. minetest.settings:get("name") .. ' for unlock chatcommands you should type')
print('[!fediauth]: /fediauth_unlock ' .. security_unlock_code)
print("[!fediauth]: via terminal!!! or security unlock code can be MITM'ed (restart server for change it)")
print("[!fediauth]: or just join to game as admin")
print("[!fediauth]: This needs to be done once if your commands are blocked")
print("[!fediauth]: or you can manage your server via szutil_consocket")
end)
for name, definition in pairs(minetest.registered_chatcommands) do
definition.privs["fediauth_autorized"] = true
minetest.override_chatcommand(name, definition)
end
minetest.register_chatcommand("fediauth_unlock", {
description = "Only for server admin, ",
privs = {},
func = function(name, unlock_code)
if name == minetest.settings:get("name") and security_unlock_code == unlock_code then
local privs = minetest.get_player_privs(name)
privs["fediauth_autorized"] = true
minetest.set_player_privs(name, privs)
return true, "now you can use all commands"
else
local msg_violation = "[fediauth] '" .. name .. "' attempt guess security code!"
minetest.log("warning", msg_violation)
if fediauth.matterbridge_avalaible then
yl_matterbridge.send_to_bridge("!", msg_violation)
end
minetest.kick_player(name)
end
end
})
end
end