]> git.lizzy.rs Git - minetest.git/blob - src/script/lua_api/l_auth.cpp
Joystick: Remap joystick-specific KeyTypes to generic ones
[minetest.git] / src / script / lua_api / l_auth.cpp
1 /*
2 Minetest
3 Copyright (C) 2018 bendeutsch, Ben Deutsch <ben@bendeutsch.de>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "lua_api/l_auth.h"
21 #include "lua_api/l_internal.h"
22 #include "common/c_converter.h"
23 #include "common/c_content.h"
24 #include "cpp_api/s_base.h"
25 #include "server.h"
26 #include "environment.h"
27 #include "database/database.h"
28 #include <algorithm>
29
30 // common start: ensure auth db
31 AuthDatabase *ModApiAuth::getAuthDb(lua_State *L)
32 {
33         ServerEnvironment *server_environment =
34                         dynamic_cast<ServerEnvironment *>(getEnv(L));
35         if (!server_environment)
36                 return nullptr;
37         return server_environment->getAuthDatabase();
38 }
39
40 void ModApiAuth::pushAuthEntry(lua_State *L, const AuthEntry &authEntry)
41 {
42         lua_newtable(L);
43         int table = lua_gettop(L);
44         // id
45         lua_pushnumber(L, authEntry.id);
46         lua_setfield(L, table, "id");
47         // name
48         lua_pushstring(L, authEntry.name.c_str());
49         lua_setfield(L, table, "name");
50         // password
51         lua_pushstring(L, authEntry.password.c_str());
52         lua_setfield(L, table, "password");
53         // privileges
54         lua_newtable(L);
55         int privtable = lua_gettop(L);
56         for (const std::string &privs : authEntry.privileges) {
57                 lua_pushboolean(L, true);
58                 lua_setfield(L, privtable, privs.c_str());
59         }
60         lua_setfield(L, table, "privileges");
61         // last_login
62         lua_pushnumber(L, authEntry.last_login);
63         lua_setfield(L, table, "last_login");
64
65         lua_pushvalue(L, table);
66 }
67
68 // auth_read(name)
69 int ModApiAuth::l_auth_read(lua_State *L)
70 {
71         NO_MAP_LOCK_REQUIRED;
72         AuthDatabase *auth_db = getAuthDb(L);
73         if (!auth_db)
74                 return 0;
75         AuthEntry authEntry;
76         const char *name = luaL_checkstring(L, 1);
77         bool success = auth_db->getAuth(std::string(name), authEntry);
78         if (!success)
79                 return 0;
80
81         pushAuthEntry(L, authEntry);
82         return 1;
83 }
84
85 // auth_save(table)
86 int ModApiAuth::l_auth_save(lua_State *L)
87 {
88         NO_MAP_LOCK_REQUIRED;
89         AuthDatabase *auth_db = getAuthDb(L);
90         if (!auth_db)
91                 return 0;
92         luaL_checktype(L, 1, LUA_TTABLE);
93         int table = 1;
94         AuthEntry authEntry;
95         bool success;
96         success = getintfield(L, table, "id", authEntry.id);
97         success = success && getstringfield(L, table, "name", authEntry.name);
98         success = success && getstringfield(L, table, "password", authEntry.password);
99         lua_getfield(L, table, "privileges");
100         if (lua_istable(L, -1)) {
101                 lua_pushnil(L);
102                 while (lua_next(L, -2)) {
103                         authEntry.privileges.emplace_back(
104                                         lua_tostring(L, -2)); // the key, not the value
105                         lua_pop(L, 1);
106                 }
107         } else {
108                 success = false;
109         }
110         lua_pop(L, 1); // the table
111         success = success && getintfield(L, table, "last_login", authEntry.last_login);
112
113         if (!success) {
114                 lua_pushboolean(L, false);
115                 return 1;
116         }
117
118         lua_pushboolean(L, auth_db->saveAuth(authEntry));
119         return 1;
120 }
121
122 // auth_create(table)
123 int ModApiAuth::l_auth_create(lua_State *L)
124 {
125         NO_MAP_LOCK_REQUIRED;
126         AuthDatabase *auth_db = getAuthDb(L);
127         if (!auth_db)
128                 return 0;
129         luaL_checktype(L, 1, LUA_TTABLE);
130         int table = 1;
131         AuthEntry authEntry;
132         bool success;
133         // no meaningful id field, we assume
134         success = getstringfield(L, table, "name", authEntry.name);
135         success = success && getstringfield(L, table, "password", authEntry.password);
136         lua_getfield(L, table, "privileges");
137         if (lua_istable(L, -1)) {
138                 lua_pushnil(L);
139                 while (lua_next(L, -2)) {
140                         authEntry.privileges.emplace_back(
141                                         lua_tostring(L, -2)); // the key, not the value
142                         lua_pop(L, 1);
143                 }
144         } else {
145                 success = false;
146         }
147         lua_pop(L, 1); // the table
148         success = success && getintfield(L, table, "last_login", authEntry.last_login);
149
150         if (!success)
151                 return 0;
152
153         if (auth_db->createAuth(authEntry)) {
154                 pushAuthEntry(L, authEntry);
155                 return 1;
156         }
157
158         return 0;
159 }
160
161 // auth_delete(name)
162 int ModApiAuth::l_auth_delete(lua_State *L)
163 {
164         NO_MAP_LOCK_REQUIRED;
165         AuthDatabase *auth_db = getAuthDb(L);
166         if (!auth_db)
167                 return 0;
168         std::string name(luaL_checkstring(L, 1));
169         lua_pushboolean(L, auth_db->deleteAuth(name));
170         return 1;
171 }
172
173 // auth_list_names()
174 int ModApiAuth::l_auth_list_names(lua_State *L)
175 {
176         NO_MAP_LOCK_REQUIRED;
177         AuthDatabase *auth_db = getAuthDb(L);
178         if (!auth_db)
179                 return 0;
180         std::vector<std::string> names;
181         auth_db->listNames(names);
182         lua_createtable(L, names.size(), 0);
183         int table = lua_gettop(L);
184         int i = 1;
185         for (const std::string &name : names) {
186                 lua_pushstring(L, name.c_str());
187                 lua_rawseti(L, table, i++);
188         }
189         return 1;
190 }
191
192 // auth_reload()
193 int ModApiAuth::l_auth_reload(lua_State *L)
194 {
195         NO_MAP_LOCK_REQUIRED;
196         AuthDatabase *auth_db = getAuthDb(L);
197         if (auth_db)
198                 auth_db->reload();
199         return 0;
200 }
201
202 void ModApiAuth::Initialize(lua_State *L, int top)
203 {
204
205         lua_newtable(L);
206         int auth_top = lua_gettop(L);
207
208         registerFunction(L, "read", l_auth_read, auth_top);
209         registerFunction(L, "save", l_auth_save, auth_top);
210         registerFunction(L, "create", l_auth_create, auth_top);
211         registerFunction(L, "delete", l_auth_delete, auth_top);
212         registerFunction(L, "list_names", l_auth_list_names, auth_top);
213         registerFunction(L, "reload", l_auth_reload, auth_top);
214
215         lua_setfield(L, top, "auth");
216 }