aboutsummaryrefslogtreecommitdiff
path: root/src/script
diff options
context:
space:
mode:
authorBen Deutsch <ben@bendeutsch.de>2018-08-05 13:13:38 +0200
committerLoïc Blot <nerzhul@users.noreply.github.com>2018-08-05 13:13:38 +0200
commit153fb211ac2342907eb766a79c1f41824f981ab5 (patch)
tree58a927bbf9a7d3d3811df6a703de02362b6474fb /src/script
parent18368824958139f1428d534082852d778982b4c9 (diff)
downloadminetest-153fb211ac2342907eb766a79c1f41824f981ab5.tar.gz
minetest-153fb211ac2342907eb766a79c1f41824f981ab5.tar.bz2
minetest-153fb211ac2342907eb766a79c1f41824f981ab5.zip
Replace auth.txt with SQLite auth database (#7279)
* Replace auth.txt with SQLite auth database
Diffstat (limited to 'src/script')
-rw-r--r--src/script/lua_api/CMakeLists.txt1
-rw-r--r--src/script/lua_api/l_auth.cpp216
-rw-r--r--src/script/lua_api/l_auth.h54
-rw-r--r--src/script/scripting_server.cpp2
4 files changed, 273 insertions, 0 deletions
diff --git a/src/script/lua_api/CMakeLists.txt b/src/script/lua_api/CMakeLists.txt
index 97c3786ec..32f6a2793 100644
--- a/src/script/lua_api/CMakeLists.txt
+++ b/src/script/lua_api/CMakeLists.txt
@@ -1,5 +1,6 @@
set(common_SCRIPT_LUA_API_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/l_areastore.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/l_auth.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_base.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_craft.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_env.cpp
diff --git a/src/script/lua_api/l_auth.cpp b/src/script/lua_api/l_auth.cpp
new file mode 100644
index 000000000..0fc57ba3a
--- /dev/null
+++ b/src/script/lua_api/l_auth.cpp
@@ -0,0 +1,216 @@
+/*
+Minetest
+Copyright (C) 2018 bendeutsch, Ben Deutsch <ben@bendeutsch.de>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "lua_api/l_auth.h"
+#include "lua_api/l_internal.h"
+#include "common/c_converter.h"
+#include "common/c_content.h"
+#include "cpp_api/s_base.h"
+#include "server.h"
+#include "environment.h"
+#include "database/database.h"
+#include <algorithm>
+
+// common start: ensure auth db
+AuthDatabase *ModApiAuth::getAuthDb(lua_State *L)
+{
+ ServerEnvironment *server_environment =
+ dynamic_cast<ServerEnvironment *>(getEnv(L));
+ if (!server_environment)
+ return nullptr;
+ return server_environment->getAuthDatabase();
+}
+
+void ModApiAuth::pushAuthEntry(lua_State *L, const AuthEntry &authEntry)
+{
+ lua_newtable(L);
+ int table = lua_gettop(L);
+ // id
+ lua_pushnumber(L, authEntry.id);
+ lua_setfield(L, table, "id");
+ // name
+ lua_pushstring(L, authEntry.name.c_str());
+ lua_setfield(L, table, "name");
+ // password
+ lua_pushstring(L, authEntry.password.c_str());
+ lua_setfield(L, table, "password");
+ // privileges
+ lua_newtable(L);
+ int privtable = lua_gettop(L);
+ for (const std::string &privs : authEntry.privileges) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, privtable, privs.c_str());
+ }
+ lua_setfield(L, table, "privileges");
+ // last_login
+ lua_pushnumber(L, authEntry.last_login);
+ lua_setfield(L, table, "last_login");
+
+ lua_pushvalue(L, table);
+}
+
+// auth_read(name)
+int ModApiAuth::l_auth_read(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ AuthDatabase *auth_db = getAuthDb(L);
+ if (!auth_db)
+ return 0;
+ AuthEntry authEntry;
+ const char *name = luaL_checkstring(L, 1);
+ bool success = auth_db->getAuth(std::string(name), authEntry);
+ if (!success)
+ return 0;
+
+ pushAuthEntry(L, authEntry);
+ return 1;
+}
+
+// auth_save(table)
+int ModApiAuth::l_auth_save(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ AuthDatabase *auth_db = getAuthDb(L);
+ if (!auth_db)
+ return 0;
+ luaL_checktype(L, 1, LUA_TTABLE);
+ int table = 1;
+ AuthEntry authEntry;
+ bool success;
+ success = getintfield(L, table, "id", authEntry.id);
+ success = success && getstringfield(L, table, "name", authEntry.name);
+ success = success && getstringfield(L, table, "password", authEntry.password);
+ lua_getfield(L, table, "privileges");
+ if (lua_istable(L, -1)) {
+ lua_pushnil(L);
+ while (lua_next(L, -2)) {
+ authEntry.privileges.emplace_back(
+ lua_tostring(L, -2)); // the key, not the value
+ lua_pop(L, 1);
+ }
+ } else {
+ success = false;
+ }
+ lua_pop(L, 1); // the table
+ success = success && getintfield(L, table, "last_login", authEntry.last_login);
+
+ if (!success) {
+ lua_pushboolean(L, false);
+ return 1;
+ }
+
+ lua_pushboolean(L, auth_db->saveAuth(authEntry));
+ return 1;
+}
+
+// auth_create(table)
+int ModApiAuth::l_auth_create(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ AuthDatabase *auth_db = getAuthDb(L);
+ if (!auth_db)
+ return 0;
+ luaL_checktype(L, 1, LUA_TTABLE);
+ int table = 1;
+ AuthEntry authEntry;
+ bool success;
+ // no meaningful id field, we assume
+ success = getstringfield(L, table, "name", authEntry.name);
+ success = success && getstringfield(L, table, "password", authEntry.password);
+ lua_getfield(L, table, "privileges");
+ if (lua_istable(L, -1)) {
+ lua_pushnil(L);
+ while (lua_next(L, -2)) {
+ authEntry.privileges.emplace_back(
+ lua_tostring(L, -2)); // the key, not the value
+ lua_pop(L, 1);
+ }
+ } else {
+ success = false;
+ }
+ lua_pop(L, 1); // the table
+ success = success && getintfield(L, table, "last_login", authEntry.last_login);
+
+ if (!success)
+ return 0;
+
+ if (auth_db->createAuth(authEntry)) {
+ pushAuthEntry(L, authEntry);
+ return 1;
+ }
+
+ return 0;
+}
+
+// auth_delete(name)
+int ModApiAuth::l_auth_delete(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ AuthDatabase *auth_db = getAuthDb(L);
+ if (!auth_db)
+ return 0;
+ std::string name(luaL_checkstring(L, 1));
+ lua_pushboolean(L, auth_db->deleteAuth(name));
+ return 1;
+}
+
+// auth_list_names()
+int ModApiAuth::l_auth_list_names(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ AuthDatabase *auth_db = getAuthDb(L);
+ if (!auth_db)
+ return 0;
+ std::vector<std::string> names;
+ auth_db->listNames(names);
+ lua_createtable(L, names.size(), 0);
+ int table = lua_gettop(L);
+ int i = 1;
+ for (const std::string &name : names) {
+ lua_pushstring(L, name.c_str());
+ lua_rawseti(L, table, i++);
+ }
+ return 1;
+}
+
+// auth_reload()
+int ModApiAuth::l_auth_reload(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ AuthDatabase *auth_db = getAuthDb(L);
+ if (auth_db)
+ auth_db->reload();
+ return 0;
+}
+
+void ModApiAuth::Initialize(lua_State *L, int top)
+{
+
+ lua_newtable(L);
+ int auth_top = lua_gettop(L);
+
+ registerFunction(L, "read", l_auth_read, auth_top);
+ registerFunction(L, "save", l_auth_save, auth_top);
+ registerFunction(L, "create", l_auth_create, auth_top);
+ registerFunction(L, "delete", l_auth_delete, auth_top);
+ registerFunction(L, "list_names", l_auth_list_names, auth_top);
+ registerFunction(L, "reload", l_auth_reload, auth_top);
+
+ lua_setfield(L, top, "auth");
+}
diff --git a/src/script/lua_api/l_auth.h b/src/script/lua_api/l_auth.h
new file mode 100644
index 000000000..fb9a9875b
--- /dev/null
+++ b/src/script/lua_api/l_auth.h
@@ -0,0 +1,54 @@
+/*
+Minetest
+Copyright (C) 2018 bendeutsch, Ben Deutsch <ben@bendeutsch.de>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+
+#include "lua_api/l_base.h"
+
+class AuthDatabase;
+struct AuthEntry;
+
+class ModApiAuth : public ModApiBase
+{
+private:
+ // auth_read(name)
+ static int l_auth_read(lua_State *L);
+
+ // auth_save(table)
+ static int l_auth_save(lua_State *L);
+
+ // auth_create(table)
+ static int l_auth_create(lua_State *L);
+
+ // auth_delete(name)
+ static int l_auth_delete(lua_State *L);
+
+ // auth_list_names()
+ static int l_auth_list_names(lua_State *L);
+
+ // auth_reload()
+ static int l_auth_reload(lua_State *L);
+
+ // helper for auth* methods
+ static AuthDatabase *getAuthDb(lua_State *L);
+ static void pushAuthEntry(lua_State *L, const AuthEntry &authEntry);
+
+public:
+ static void Initialize(lua_State *L, int top);
+};
diff --git a/src/script/scripting_server.cpp b/src/script/scripting_server.cpp
index 93b28b61b..2204c6884 100644
--- a/src/script/scripting_server.cpp
+++ b/src/script/scripting_server.cpp
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "cpp_api/s_internal.h"
#include "lua_api/l_areastore.h"
+#include "lua_api/l_auth.h"
#include "lua_api/l_base.h"
#include "lua_api/l_craft.h"
#include "lua_api/l_env.h"
@@ -106,6 +107,7 @@ void ServerScripting::InitializeModApi(lua_State *L, int top)
ModChannelRef::Register(L);
// Initialize mod api modules
+ ModApiAuth::Initialize(L, top);
ModApiCraft::Initialize(L, top);
ModApiEnvMod::Initialize(L, top);
ModApiInventory::Initialize(L, top);