diff --git a/src/db/auth.cpp b/src/db/auth.cpp index 6030e69..494b53a 100644 --- a/src/db/auth.cpp +++ b/src/db/auth.cpp @@ -7,26 +7,13 @@ #include #include +#include + using leveldb_ptr = leveldb::DB*; auto user_db = leveldb_ptr{nullptr}; auto iter_round = 10000; -auto filter(const std::string_view id) -> bool -{ - return id.contains(':'); -} - -auto mangle_user_id(const std::string_view id) -> std::string -{ - return std::format("{}:user_id", id); -} - -auto mangle_permission(const std::string_view id) -> std::string -{ - return std::format("{}:permission", id); -} - extern "C" { auto open_user_db() -> int @@ -35,7 +22,7 @@ extern "C" opts.create_if_missing = true; - auto status = leveldb::DB::Open(opts, "db/user", &user_db); + auto status = leveldb::DB::Open(opts, "db/users", &user_db); if (!status.ok()) { std::println(stderr, "Failed to open user database: {}", status.ToString()); @@ -51,10 +38,8 @@ extern "C" auto check_user_exists(const char* user_id, int* result) -> int { - if (filter(user_id)) return 0; - auto value = std::string{}; - auto status = user_db->Get(leveldb::ReadOptions{}, mangle_user_id(user_id), &value); + auto status = user_db->Get(leveldb::ReadOptions{}, user_id, &value); if (status.ok()) { *result = 1; } else if (status.IsNotFound()) { @@ -68,10 +53,16 @@ extern "C" auto set_user_password(const char* user_id, const char* password) -> int { - if (filter(user_id)) return 0; + auto value = std::string{}; + auto status = user_db->Get(leveldb::ReadOptions{}, user_id, &value); + if (!status.ok()) { + std::println(stderr, "Failed to set user password: {}", status.ToString()); + return 0; + } + auto json = nlohmann::json::parse(value); + json["hash"] = generate_hash(password, iter_round); - auto hash = generate_hash(password, iter_round); - auto status = user_db->Put(leveldb::WriteOptions{}, mangle_user_id(user_id), hash); + status = user_db->Put(leveldb::WriteOptions{}, user_id, json.dump()); if (!status.ok()) { std::println(stderr, "Failed to set user password: {}", status.ToString()); return 0; @@ -81,26 +72,24 @@ extern "C" auto login(const char* user_id, const char* password, int* result) -> int { - if (filter(user_id)) return 0; - auto value = std::string{}; - auto status = user_db->Get(leveldb::ReadOptions{}, mangle_user_id(user_id), &value); + auto status = user_db->Get(leveldb::ReadOptions{}, user_id, &value); if (!status.ok()) { if (!status.IsNotFound()) std::println(stderr, "Failed to login: {}", status.ToString()); return 0; } - *result = validate_password(password, value.data()); + auto json = nlohmann::json::parse(value); + *result = validate_password(password, json["hash"]); return 1; } int registe(const char* user_id, const char* password) { - if (filter(user_id)) return 0; - - auto batch = leveldb::WriteBatch{}; - batch.Put(mangle_user_id(user_id), generate_hash(password, iter_round)); - batch.Put(mangle_permission(user_id), "2"); - auto status = user_db->Write(leveldb::WriteOptions{}, &batch); + auto json = nlohmann::json{ + {"hash", generate_hash(password, iter_round)}, + {"permission", 2} + }; + auto status = user_db->Put(leveldb::WriteOptions{}, user_id, json.dump()); if (!status.ok()) { std::println(stderr, "Failed to register: {}", status.ToString()); return 0; @@ -110,12 +99,7 @@ extern "C" auto delete_user(const char* user_id) -> int { - if (filter(user_id)) return 0; - - auto batch = leveldb::WriteBatch{}; - batch.Delete(mangle_user_id(user_id)); - batch.Delete(mangle_permission(user_id)); - auto status = user_db->Write(leveldb::WriteOptions{}, &batch); + auto status = user_db->Delete(leveldb::WriteOptions{}, user_id); if (!status.ok()) { std::println(stderr, "Failed to delete: {}", status.ToString()); return 0; @@ -125,24 +109,29 @@ extern "C" int get_user_permission(const char* user_id, int* result) { - if (filter(user_id)) return 0; - auto value = std::string{}; - auto status = user_db->Get(leveldb::ReadOptions{}, mangle_permission(user_id), &value); - if (status.ok()) { - *result = std::stoi(value); - } else { + auto status = user_db->Get(leveldb::ReadOptions{}, user_id, &value); + if (!status.ok()) { if (!status.IsNotFound()) std::println(stderr, "Failed to get user permission: {}", status.ToString()); return 0; } + auto json = nlohmann::json::parse(value); + json["permission"].get_to(*result); return 1; } int set_user_permission(const char* user_id, int permission) { - if (filter(user_id)) return 0; + auto value = std::string{}; + auto status = user_db->Get(leveldb::ReadOptions{}, user_id, &value); + if (!status.ok()) { + std::println(stderr, "Failed to set user password: {}", status.ToString()); + return 0; + } + auto json = nlohmann::json::parse(value); + json["permission"] = permission; - auto status = user_db->Put(leveldb::WriteOptions{}, mangle_permission(user_id), std::to_string(permission)); + status = user_db->Put(leveldb::WriteOptions{}, user_id, json.dump()); if (!status.ok()) { std::println(stderr, "Failed to set user permission: {}", status.ToString()); return 0; @@ -152,8 +141,10 @@ extern "C" int set_admin_password(const char* password) { - auto hash = generate_hash(password, iter_round); - auto status = user_db->Put(leveldb::WriteOptions{}, "admin_password_hash", hash); + auto json = nlohmann::json{ + {"admin_password_hash", generate_hash(password, iter_round)} + }; + auto status = user_db->Put(leveldb::WriteOptions{}, "@", json.dump()); if (!status.ok()) { std::println(stderr, "Failed to set admin password: {}", status.ToString()); return 0; @@ -164,19 +155,21 @@ extern "C" int admin_login(const char* password, int* result) { auto value = std::string{}; - auto status = user_db->Get(leveldb::ReadOptions{}, "admin_password_hash", &value); + auto status = user_db->Get(leveldb::ReadOptions{}, "@", &value); if (!status.ok()) { std::println(stderr, "Failed to login admin: {}", status.ToString()); return 0; } - *result = validate_password(password, value.data()); + auto json = nlohmann::json::parse(value); + json["admin_password_hash"].get_to(value); + *result = validate_password(password, value); return 1; } int has_admin_password(int* result) { auto value = std::string{}; - auto status = user_db->Get(leveldb::ReadOptions{}, "admin_password_hash", &value); + auto status = user_db->Get(leveldb::ReadOptions{}, "@", &value); if (status.ok()) { *result = 1; } else if (status.IsNotFound()) {