]> git.lizzy.rs Git - dragonfireclient.git/blob - builtin/game/auth.lua
Merge pull request #59 from PrairieAstronomer/readme_irrlicht_change
[dragonfireclient.git] / builtin / game / auth.lua
1 -- Minetest: builtin/auth.lua
2
3 --
4 -- Builtin authentication handler
5 --
6
7 -- Make the auth object private, deny access to mods
8 local core_auth = core.auth
9 core.auth = nil
10
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
17                         return nil
18                 end
19                 -- Figure out what privileges the player should have.
20                 -- Take a copy of the privilege table
21                 local privileges = {}
22                 for priv, _ in pairs(auth_entry.privileges) do
23                         privileges[priv] = true
24                 end
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
30                                 end
31                         end
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
37                                 end
38                         end
39                 end
40                 -- All done
41                 return {
42                         password = auth_entry.password,
43                         privileges = privileges,
44                         last_login = auth_entry.last_login,
45                 }
46         end,
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({
52                         name = name,
53                         password = password,
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)
56                 })
57         end,
58         delete_auth = function(name)
59                 assert(type(name) == "string")
60                 local auth_entry = core_auth.read(name)
61                 if not auth_entry then
62                         return false
63                 end
64                 core.log('info', "Built-in authentication handler deleting player '"..name.."'")
65                 return core_auth.delete(name)
66         end,
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)
73                 else
74                         core.log('info', "Built-in authentication handler setting password of player '"..name.."'")
75                         auth_entry.password = password
76                         core_auth.save(auth_entry)
77                 end
78                 return true
79         end,
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")))
88                 end
89
90                 auth_entry.privileges = privileges
91
92                 core_auth.save(auth_entry)
93
94                 -- Run grant callbacks
95                 for priv, _ in pairs(privileges) do
96                         if not auth_entry.privileges[priv] then
97                                 core.run_priv_callbacks(name, priv, nil, "grant")
98                         end
99                 end
100
101                 -- Run revoke callbacks
102                 for priv, _ in pairs(auth_entry.privileges) do
103                         if not privileges[priv] then
104                                 core.run_priv_callbacks(name, priv, nil, "revoke")
105                         end
106                 end
107                 core.notify_authentication_modified(name)
108         end,
109         reload = function()
110                 core_auth.reload()
111                 return true
112         end,
113         record_login = function(name)
114                 assert(type(name) == "string")
115                 local auth_entry = core_auth.read(name)
116                 assert(auth_entry)
117                 auth_entry.last_login = os.time()
118                 core_auth.save(auth_entry)
119         end,
120         iterate = function()
121                 local names = {}
122                 local nameslist = core_auth.list_names()
123                 for k,v in pairs(nameslist) do
124                         names[v] = true
125                 end
126                 return pairs(names)
127         end,
128 }
129
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
133         end
134         local auth_entry = core_auth.read(name)
135         if auth_entry ~= nil then
136                 return
137         end
138
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)
146                 end
147         end
148 end)
149
150 --
151 -- Authentication API
152 --
153
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)
157         end
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
161 end
162
163 function core.get_auth_handler()
164         return core.registered_auth_handler or core.builtin_auth_handler
165 end
166
167 local function auth_pass(name)
168         return function(...)
169                 local auth_handler = core.get_auth_handler()
170                 if auth_handler[name] then
171                         return auth_handler[name](...)
172                 end
173                 return false
174         end
175 end
176
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")
181
182 local record_login = auth_pass("record_login")
183 core.register_on_joinplayer(function(player)
184         record_login(player:get_player_name())
185 end)