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);