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 in authentication table, return nil
88 if not minetest.auth_table[name] then
91 -- Figure out what privileges the player should have.
92 -- Take a copy of the privilege table
94 for priv, _ in pairs(minetest.auth_table[name].privileges) do
95 privileges[priv] = true
97 -- If singleplayer, give all privileges except those marked as give_to_singleplayer = false
98 if minetest.is_singleplayer() then
99 for priv, def in pairs(minetest.registered_privileges) do
100 if def.give_to_singleplayer then
101 privileges[priv] = true
104 -- For the admin, give everything
105 elseif name == minetest.setting_get("name") then
106 for priv, def in pairs(minetest.registered_privileges) do
107 privileges[priv] = true
112 password = minetest.auth_table[name].password,
113 privileges = privileges,
116 create_auth = function(name, password)
117 assert(type(name) == "string")
118 assert(type(password) == "string")
119 minetest.log('info', "Built-in authentication handler adding player '"..name.."'")
120 minetest.auth_table[name] = {
122 privileges = minetest.string_to_privs(minetest.setting_get("default_privs")),
126 set_password = function(name, password)
127 assert(type(name) == "string")
128 assert(type(password) == "string")
129 if not minetest.auth_table[name] then
130 minetest.builtin_auth_handler.create_auth(name, password)
132 minetest.log('info', "Built-in authentication handler setting password of player '"..name.."'")
133 minetest.auth_table[name].password = password
138 set_privileges = function(name, privileges)
139 assert(type(name) == "string")
140 assert(type(privileges) == "table")
141 if not minetest.auth_table[name] then
142 minetest.builtin_auth_handler.create_auth(name, minetest.get_password_hash(name, minetest.setting_get("default_password")))
144 minetest.auth_table[name].privileges = privileges
145 minetest.notify_authentication_modified(name)
154 function minetest.register_authentication_handler(handler)
155 if minetest.registered_auth_handler then
156 error("Add-on authentication handler already registered by "..minetest.registered_auth_handler_modname)
158 minetest.registered_auth_handler = handler
159 minetest.registered_auth_handler_modname = minetest.get_current_modname()
162 function minetest.get_auth_handler()
163 if minetest.registered_auth_handler then
164 return minetest.registered_auth_handler
166 return minetest.builtin_auth_handler
169 function minetest.set_player_password(name, password)
170 if minetest.get_auth_handler().set_password then
171 minetest.get_auth_handler().set_password(name, password)
175 function minetest.set_player_privs(name, privs)
176 if minetest.get_auth_handler().set_privileges then
177 minetest.get_auth_handler().set_privileges(name, privs)
181 function minetest.auth_reload()
182 if minetest.get_auth_handler().reload then
183 return minetest.get_auth_handler().reload()