1 -- Minetest: builtin/auth.lua
4 -- Authentication handler
7 function minetest.string_to_privs(str, delim)
8 assert(type(str) == "string")
11 for _, priv in pairs(string.split(str, delim)) do
12 privs[priv:trim()] = true
17 function minetest.privs_to_string(privs, delim)
18 assert(type(privs) == "table")
21 for priv, bool in pairs(privs) do
23 table.insert(list, priv)
26 return table.concat(list, delim)
29 assert(minetest.string_to_privs("a,b").b == true)
30 assert(minetest.privs_to_string({a=true,b=true}) == "a,b")
32 minetest.auth_file_path = minetest.get_worldpath().."/auth.txt"
33 minetest.auth_table = {}
35 local function read_auth_file()
37 local file, errmsg = io.open(minetest.auth_file_path, 'rb')
39 minetest.log("info", minetest.auth_file_path.." could not be opened for reading ("..errmsg.."); assuming new world")
42 for line in file:lines() do
44 local name, password, privilegestring = string.match(line, "([^:]*):([^:]*):([^:]*)")
45 if not name or not password or not privilegestring then
46 error("Invalid line in auth.txt: "..dump(line))
48 local privileges = minetest.string_to_privs(privilegestring)
49 newtable[name] = {password=password, privileges=privileges}
53 minetest.auth_table = newtable
54 minetest.notify_authentication_modified()
57 local function save_auth_file()
59 -- Check table for validness before attempting to save
60 for name, stuff in pairs(minetest.auth_table) do
61 assert(type(name) == "string")
63 assert(type(stuff) == "table")
64 assert(type(stuff.password) == "string")
65 assert(type(stuff.privileges) == "table")
67 local file, errmsg = io.open(minetest.auth_file_path, 'w+b')
69 error(minetest.auth_file_path.." could not be opened for writing: "..errmsg)
71 for name, stuff in pairs(minetest.auth_table) do
72 local privstring = minetest.privs_to_string(stuff.privileges)
73 file:write(name..":"..stuff.password..":"..privstring..'\n')
80 minetest.builtin_auth_handler = {
81 get_auth = function(name)
82 assert(type(name) == "string")
83 -- Figure out what password to use for a new player (singleplayer
84 -- always has an empty password, otherwise use default, which is
86 local new_password_hash = ""
87 if not minetest.is_singleplayer() then
88 new_password_hash = minetest.get_password_hash(name, minetest.setting_get("default_password"))
90 -- Add player to authentication table if not there already
91 if not minetest.auth_table[name] then
92 minetest.builtin_auth_handler.create_auth(name, minetest.get_password_hash(name, minetest.setting_get("default_password")))
94 -- Figure out what privileges the player should have.
95 -- Take a copy of the privilege table
97 for priv, _ in pairs(minetest.auth_table[name].privileges) do
98 privileges[priv] = true
100 -- If singleplayer, give all privileges except those marked as give_to_singleplayer = false
101 if minetest.is_singleplayer() then
102 for priv, def in pairs(minetest.registered_privileges) do
103 if def.give_to_singleplayer then
104 privileges[priv] = true
107 -- For the admin, give everything
108 elseif name == minetest.setting_get("name") then
109 for priv, def in pairs(minetest.registered_privileges) do
110 privileges[priv] = true
115 password = minetest.auth_table[name].password,
116 privileges = privileges,
119 create_auth = function(name, password)
120 assert(type(name) == "string")
121 assert(type(password) == "string")
122 minetest.log('info', "Built-in authentication handler adding player '"..name.."'")
123 minetest.auth_table[name] = {
125 privileges = minetest.string_to_privs(minetest.setting_get("default_privs")),
129 set_password = function(name, password)
130 assert(type(name) == "string")
131 assert(type(password) == "string")
132 if not minetest.auth_table[name] then
133 minetest.builtin_auth_handler.create_auth(name, password)
135 minetest.log('info', "Built-in authentication handler setting password of player '"..name.."'")
136 minetest.auth_table[name].password = password
141 set_privileges = function(name, privileges)
142 assert(type(name) == "string")
143 assert(type(privileges) == "table")
144 if not minetest.auth_table[name] then
145 minetest.builtin_auth_handler.create_auth(name, minetest.get_password_hash(name, minetest.setting_get("default_password")))
147 minetest.auth_table[name].privileges = privileges
148 minetest.notify_authentication_modified(name)
157 function minetest.register_authentication_handler(handler)
158 if minetest.registered_auth_handler then
159 error("Add-on authentication handler already registered by "..minetest.registered_auth_handler_modname)
161 minetest.registered_auth_handler = handler
162 minetest.registered_auth_handler_modname = minetest.get_current_modname()
165 function minetest.get_auth_handler()
166 if minetest.registered_auth_handler then
167 return minetest.registered_auth_handler
169 return minetest.builtin_auth_handler
172 function minetest.set_player_password(name, password)
173 if minetest.get_auth_handler().set_password then
174 minetest.get_auth_handler().set_password(name, password)
178 function minetest.set_player_privs(name, privs)
179 if minetest.get_auth_handler().set_privileges then
180 minetest.get_auth_handler().set_privileges(name, privs)
184 function minetest.auth_reload()
185 if minetest.get_auth_handler().reload then
186 return minetest.get_auth_handler().reload()