From a4aed41ff1f8a2071c4d97f855b769a4f7f8a18b Mon Sep 17 00:00:00 2001 From: keqingmoe Date: Sun, 22 Dec 2024 22:42:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7=E8=AE=A4?= =?UTF-8?q?=E8=AF=81=E5=8A=9F=E8=83=BD=E7=9A=84=E5=88=9D=E6=AD=A5=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/jwt/jwt.h | 6 ++-- include/server/auth.h | 6 ++++ src/db/auth.cpp | 79 +++++++++++++++++++++++++++++++++++++++++++ src/jwt/jwt.cpp | 6 ++-- 4 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 include/server/auth.h create mode 100644 src/db/auth.cpp diff --git a/include/jwt/jwt.h b/include/jwt/jwt.h index dfd7933..643cd53 100644 --- a/include/jwt/jwt.h +++ b/include/jwt/jwt.h @@ -6,11 +6,11 @@ extern "C" { #endif - auto create_token(const char* user_id, const char* secret) noexcept -> char*; + char* create_token(const char* user_id, const char* secret); - auto get_payload(const char* token) noexcept -> char*; + char* get_payload(const char* token); - auto verify_token(const char* token, const char* secret) noexcept -> int; + int verify_token(const char* token, const char* secret); #ifdef __cplusplus } diff --git a/include/server/auth.h b/include/server/auth.h new file mode 100644 index 0000000..675cee5 --- /dev/null +++ b/include/server/auth.h @@ -0,0 +1,6 @@ +#ifndef SERVER_AUTH_H +#define SERVER_AUTH_H + +// Your code here + +#endif // SERVER_AUTH_H \ No newline at end of file diff --git a/src/db/auth.cpp b/src/db/auth.cpp new file mode 100644 index 0000000..5d678c5 --- /dev/null +++ b/src/db/auth.cpp @@ -0,0 +1,79 @@ +#include "auth.h" + +#include "hash/hash.hpp" + +#include + +#include + +using leveldb_ptr = leveldb::DB*; + +auto user_db = leveldb_ptr{nullptr}; +auto iter_round = 10000; + +extern "C" +{ + auto open_user_db() -> int + { + auto opts = leveldb::Options{}; + + opts.create_if_missing = true; + + auto status = leveldb::DB::Open(opts, "db/user", &user_db); + + if (!status.ok()) { + std::println(stderr, "Failed to open user database: {}", status.ToString()); + return 0; + } + return 1; + } + + auto close_user_db() -> void + { + delete user_db; + } + + auto check_user_exists(const char* user_id, int* result) -> int + { + auto value = std::string{}; + auto status = user_db->Get(leveldb::ReadOptions{}, user_id, &value); + if (status.ok()) { + *result = 1; + } else if (status.IsNotFound()) { + *result = 0; + } else { + std::println(stderr, "Failed to check user existence: {}", status.ToString()); + return 0; + } + return 1; + } + + auto set_user_password(const char* user_id, const char* password) -> int + { + auto status = user_db->Put(leveldb::WriteOptions{}, user_id, generate_hash(password, iter_round)); + if (!status.ok()) { + std::println(stderr, "Failed to set user password: {}", status.ToString()); + return 0; + } + return 1; + } + + auto login(const char* user_id, const char* password, int* result) -> int + { + auto value = std::string{}; + auto status = user_db->Get(leveldb::ReadOptions{}, user_id, &value); + if (!status.ok()) { + std::println(stderr, "Failed to login: {}", status.ToString()); + return 0; + } + *result = validate_password(password, value.data()); + return 1; + } + + auto logout(const char* user_id) -> int + { + leveldb::WriteOptions write_options; + leveldb::Status status = user_db->Delete(write_options, user_id); + return status.ok(); + } +} \ No newline at end of file diff --git a/src/jwt/jwt.cpp b/src/jwt/jwt.cpp index 43485f7..d83e6f9 100644 --- a/src/jwt/jwt.cpp +++ b/src/jwt/jwt.cpp @@ -8,7 +8,7 @@ using namespace std::literals::chrono_literals; extern "C" { - auto create_token(const char* user_id, const char* secret) noexcept -> char* + auto create_token(const char* user_id, const char* secret) -> char* { auto token = jwt::create() .set_type("JWS") @@ -21,14 +21,14 @@ extern "C" return strdup(token.c_str()); } - auto get_payload(const char* token) noexcept -> char* + auto get_payload(const char* token) -> char* { auto decoded_token = jwt::decode(token); auto payload = decoded_token.get_payload_claim("user_id").as_string(); return strdup(payload.c_str()); } - auto verify_token(const char* token, const char* secret) noexcept -> int + auto verify_token(const char* token, const char* secret) -> int { try { auto decoded_token = jwt::decode(token);