1 -- Minetest: builtin/auth.lua
4 -- Builtin authentication handler
7 -- Make the auth object private, deny access to mods
8 local core_auth = core.auth
11 core.builtin_auth_handler = {
12 get_auth = function(name)
13 assert(type(name) == "string")
14 local auth_entry = core_auth.read(name)
15 -- If no such auth found, return nil
16 if not auth_entry then
19 -- Figure out what privileges the player should have.
20 -- Take a copy of the privilege table
22 for priv, _ in pairs(auth_entry.privileges) do
23 privileges[priv] = true
25 -- If singleplayer, give all privileges except those marked as give_to_singleplayer = false
26 if core.is_singleplayer() then
27 for priv, def in pairs(core.registered_privileges) do
28 if def.give_to_singleplayer then
29 privileges[priv] = true
32 -- For the admin, give everything
33 elseif name == core.settings:get("name") then
34 for priv, def in pairs(core.registered_privileges) do
35 if def.give_to_admin then
36 privileges[priv] = true
42 password = auth_entry.password,
43 privileges = privileges,
44 last_login = auth_entry.last_login,
47 create_auth = function(name, password)
48 assert(type(name) == "string")
49 assert(type(password) == "string")
50 core.log('info', "Built-in authentication handler adding player '"..name.."'")
51 return core_auth.create({
54 privileges = core.string_to_privs(core.settings:get("default_privs")),
55 last_login = -1, -- Defer login time calculation until record_login (called by on_joinplayer)
58 delete_auth = function(name)
59 assert(type(name) == "string")
60 local auth_entry = core_auth.read(name)
61 if not auth_entry then
64 core.log('info', "Built-in authentication handler deleting player '"..name.."'")
65 return core_auth.delete(name)
67 set_password = function(name, password)
68 assert(type(name) == "string")
69 assert(type(password) == "string")
70 local auth_entry = core_auth.read(name)
71 if not auth_entry then
72 core.builtin_auth_handler.create_auth(name, password)
74 core.log('info', "Built-in authentication handler setting password of player '"..name.."'")
75 auth_entry.password = password
76 core_auth.save(auth_entry)
80 set_privileges = function(name, privileges)
81 assert(type(name) == "string")
82 assert(type(privileges) == "table")
83 local auth_entry = core_auth.read(name)
84 if not auth_entry then
85 auth_entry = core.builtin_auth_handler.create_auth(name,
86 core.get_password_hash(name,
87 core.settings:get("default_password")))
90 -- Run grant callbacks
91 for priv, _ in pairs(privileges) do
92 if not auth_entry.privileges[priv] then
93 core.run_priv_callbacks(name, priv, nil, "grant")
97 -- Run revoke callbacks
98 for priv, _ in pairs(auth_entry.privileges) do
99 if not privileges[priv] then
100 core.run_priv_callbacks(name, priv, nil, "revoke")
104 auth_entry.privileges = privileges
105 core_auth.save(auth_entry)
106 core.notify_authentication_modified(name)
112 record_login = function(name)
113 assert(type(name) == "string")
114 local auth_entry = core_auth.read(name)
116 auth_entry.last_login = os.time()
117 core_auth.save(auth_entry)
121 local nameslist = core_auth.list_names()
122 for k,v in pairs(nameslist) do
129 core.register_on_prejoinplayer(function(name, ip)
130 if core.registered_auth_handler ~= nil then
131 return -- Don't do anything if custom auth handler registered
133 local auth_entry = core_auth.read(name)
134 if auth_entry ~= nil then
138 local name_lower = name:lower()
139 for k in core.builtin_auth_handler.iterate() do
140 if k:lower() == name_lower then
141 return string.format("\nCannot create new player called '%s'. "..
142 "Another account called '%s' is already registered. "..
143 "Please check the spelling if it's your account "..
144 "or use a different nickname.", name, k)
150 -- Authentication API
153 function core.register_authentication_handler(handler)
154 if core.registered_auth_handler then
155 error("Add-on authentication handler already registered by "..core.registered_auth_handler_modname)
157 core.registered_auth_handler = handler
158 core.registered_auth_handler_modname = core.get_current_modname()
159 handler.mod_origin = core.registered_auth_handler_modname
162 function core.get_auth_handler()
163 return core.registered_auth_handler or core.builtin_auth_handler
166 local function auth_pass(name)
168 local auth_handler = core.get_auth_handler()
169 if auth_handler[name] then
170 return auth_handler[name](...)
176 core.set_player_password = auth_pass("set_password")
177 core.set_player_privs = auth_pass("set_privileges")
178 core.remove_player_auth = auth_pass("delete_auth")
179 core.auth_reload = auth_pass("reload")
181 local record_login = auth_pass("record_login")
182 core.register_on_joinplayer(function(player)
183 record_login(player:get_player_name())