From 914dbeaa0be4b5ef87506b605ef4e241cd3732dc Mon Sep 17 00:00:00 2001 From: luk3yx Date: Thu, 23 Apr 2020 23:07:19 +1200 Subject: Add LevelDB auth database. (#9476) * Add leveldb auth database. --- src/database/database-leveldb.cpp | 98 ++++++++++++++++++++++++++++++++++++++- src/database/database-leveldb.h | 17 +++++++ 2 files changed, 114 insertions(+), 1 deletion(-) (limited to 'src/database') diff --git a/src/database/database-leveldb.cpp b/src/database/database-leveldb.cpp index 4a4904c6a..1aab4c43d 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 d30f9f8f5..a9bd0faa4 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 -- cgit v1.2.3