From 914dbeaa0be4b5ef87506b605ef4e241cd3732dc Mon Sep 17 00:00:00 2001 From: luk3yx Date: Thu, 23 Apr 2020 23:07:19 +1200 Subject: [PATCH] Add LevelDB auth database. (#9476) * Add leveldb auth database. --- src/database/database-leveldb.cpp | 98 ++++++++++++++++++++++++++++++- src/database/database-leveldb.h | 17 ++++++ src/serverenvironment.cpp | 8 +++ 3 files changed, 122 insertions(+), 1 deletion(-) diff --git a/src/database/database-leveldb.cpp b/src/database/database-leveldb.cpp index 4a4904c6..1aab4c43 100644 --- a/src/database/database-leveldb.cpp +++ b/src/database/database-leveldb.cpp @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "filesys.h" #include "exceptions.h" +#include "util/serialize.h" #include "util/string.h" #include "leveldb/db.h" @@ -97,5 +98,100 @@ void Database_LevelDB::listAllLoadableBlocks(std::vector &dst) delete it; } -#endif // USE_LEVELDB +AuthDatabaseLevelDB::AuthDatabaseLevelDB(const std::string &savedir) +{ + leveldb::Options options; + options.create_if_missing = true; + leveldb::Status status = leveldb::DB::Open(options, + savedir + DIR_DELIM + "auth.db", &m_database); + ENSURE_STATUS_OK(status); +} +AuthDatabaseLevelDB::~AuthDatabaseLevelDB() +{ + delete m_database; +} + +bool AuthDatabaseLevelDB::getAuth(const std::string &name, AuthEntry &res) +{ + std::string raw; + leveldb::Status s = m_database->Get(leveldb::ReadOptions(), name, &raw); + if (!s.ok()) + return false; + std::istringstream is(raw); + + /* + u8 version = 1 + std::string password + u16 number of privileges + for each privilege { + std::string privilege + } + s64 last_login + */ + + if (readU8(is) > 1) + return false; + + res.id = 1; + res.name = name; + res.password = deSerializeString(is); + + u16 privilege_count = readU16(is); + res.privileges.clear(); + res.privileges.reserve(privilege_count); + for (u16 i = 0; i < privilege_count; i++) { + res.privileges.push_back(deSerializeString(is)); + } + + res.last_login = readS64(is); + return true; +} + +bool AuthDatabaseLevelDB::saveAuth(const AuthEntry &authEntry) +{ + std::ostringstream os; + writeU8(os, 1); + os << serializeString(authEntry.password); + + size_t privilege_count = authEntry.privileges.size(); + FATAL_ERROR_IF(privilege_count > U16_MAX, + "Unsupported number of privileges"); + writeU16(os, privilege_count); + for (const std::string &privilege : authEntry.privileges) { + os << serializeString(privilege); + } + + writeS64(os, authEntry.last_login); + leveldb::Status s = m_database->Put(leveldb::WriteOptions(), + authEntry.name, os.str()); + return s.ok(); +} + +bool AuthDatabaseLevelDB::createAuth(AuthEntry &authEntry) +{ + return saveAuth(authEntry); +} + +bool AuthDatabaseLevelDB::deleteAuth(const std::string &name) +{ + leveldb::Status s = m_database->Delete(leveldb::WriteOptions(), name); + return s.ok(); +} + +void AuthDatabaseLevelDB::listNames(std::vector &res) +{ + leveldb::Iterator* it = m_database->NewIterator(leveldb::ReadOptions()); + res.clear(); + for (it->SeekToFirst(); it->Valid(); it->Next()) { + res.emplace_back(it->key().ToString()); + } + delete it; +} + +void AuthDatabaseLevelDB::reload() +{ + // No-op for LevelDB. +} + +#endif // USE_LEVELDB diff --git a/src/database/database-leveldb.h b/src/database/database-leveldb.h index d30f9f8f..a9bd0faa 100644 --- a/src/database/database-leveldb.h +++ b/src/database/database-leveldb.h @@ -45,4 +45,21 @@ private: leveldb::DB *m_database; }; +class AuthDatabaseLevelDB : public AuthDatabase +{ +public: + AuthDatabaseLevelDB(const std::string &savedir); + virtual ~AuthDatabaseLevelDB(); + + virtual bool getAuth(const std::string &name, AuthEntry &res); + virtual bool saveAuth(const AuthEntry &authEntry); + virtual bool createAuth(AuthEntry &authEntry); + virtual bool deleteAuth(const std::string &name); + virtual void listNames(std::vector &res); + virtual void reload(); + +private: + leveldb::DB *m_database; +}; + #endif // USE_LEVELDB diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index 27f0c1e3..08d79611 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -44,6 +44,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #if USE_POSTGRESQL #include "database/database-postgresql.h" #endif +#if USE_LEVELDB +#include "database/database-leveldb.h" +#endif #include "server/luaentity_sao.h" #include "server/player_sao.h" @@ -2187,6 +2190,11 @@ AuthDatabase *ServerEnvironment::openAuthDatabase( if (name == "files") return new AuthDatabaseFiles(savedir); +#if USE_LEVELDB + if (name == "leveldb") + return new AuthDatabaseLevelDB(savedir); +#endif + throw BaseException(std::string("Database backend ") + name + " not supported."); }