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 -- Is set to nil if unknown
45 last_login = auth_entry.last_login,
48 create_auth = function(name, password)
49 assert(type(name) == "string")
50 assert(type(password) == "string")
51 core.log('info', "Built-in authentication handler adding player '"..name.."'")
52 return core_auth.create({
55 privileges = core.string_to_privs(core.settings:get("default_privs")),
56 last_login = os.time(),
59 delete_auth = function(name)
60 assert(type(name) == "string")
61 local auth_entry = core_auth.read(name)
62 if not auth_entry then
65 core.log('info', "Built-in authentication handler deleting player '"..name.."'")
66 return core_auth.delete(name)
68 set_password = function(name, password)
69 assert(type(name) == "string")
70 assert(type(password) == "string")
71 local auth_entry = core_auth.read(name)
72 if not auth_entry then
73 core.builtin_auth_handler.create_auth(name, password)
75 core.log('info', "Built-in authentication handler setting password of player '"..name.."'")
76 auth_entry.password = password
77 core_auth.save(auth_entry)
81 set_privileges = function(name, privileges)
82 assert(type(name) == "string")
83 assert(type(privileges) == "table")
84 local auth_entry = core_auth.read(name)
85 if not auth_entry then
86 auth_entry = core.builtin_auth_handler.create_auth(name,
87 core.get_password_hash(name,
88 core.settings:get("default_password")))
91 -- Run grant callbacks
92 for priv, _ in pairs(privileges) do
93 if not auth_entry.privileges[priv] then
94 core.run_priv_callbacks(name, priv, nil, "grant")
98 -- Run revoke callbacks
99 for priv, _ in pairs(auth_entry.privileges) do
100 if not privileges[priv] then
101 core.run_priv_callbacks(name, priv, nil, "revoke")
105 auth_entry.privileges = privileges
106 core_auth.save(auth_entry)
107 core.notify_authentication_modified(name)
113 record_login = function(name)
114 assert(type(name) == "string")
115 local auth_entry = core_auth.read(name)
117 auth_entry.last_login = os.time()
118 core_auth.save(auth_entry)
122 local nameslist = core_auth.list_names()
123 for k,v in pairs(nameslist) do
130 core.register_on_prejoinplayer(function(name, ip)
131 if core.registered_auth_handler ~= nil then
132 return -- Don't do anything if custom auth handler registered
134 local auth_entry = core_auth.read(name)
135 if auth_entry ~= nil then
139 local name_lower = name:lower()
140 for k in core.builtin_auth_handler.iterate() do
141 if k:lower() == name_lower then
142 return string.format("\nCannot create new player called '%s'. "..
143 "Another account called '%s' is already registered. "..
144 "Please check the spelling if it's your account "..
145 "or use a different nickname.", name, k)
151 -- Authentication API
154 function core.register_authentication_handler(handler)
155 if core.registered_auth_handler then
156 error("Add-on authentication handler already registered by "..core.registered_auth_handler_modname)
158 core.registered_auth_handler = handler
159 core.registered_auth_handler_modname = core.get_current_modname()
160 handler.mod_origin = core.registered_auth_handler_modname
163 function core.get_auth_handler()
164 return core.registered_auth_handler or core.builtin_auth_handler
167 local function auth_pass(name)
169 local auth_handler = core.get_auth_handler()
170 if auth_handler[name] then
171 return auth_handler[name](...)
177 core.set_player_password = auth_pass("set_password")
178 core.set_player_privs = auth_pass("set_privileges")
179 core.remove_player_auth = auth_pass("delete_auth")
180 core.auth_reload = auth_pass("reload")
182 local record_login = auth_pass("record_login")
183 core.register_on_joinplayer(function(player)
184 record_login(player:get_player_name())