Add token validation filter based on token signature and expiration date
- changed login request from GET to POST - implement json body conversion to DTO objects - set `user_id` and `role` attributes for HttpRequest inside filter
This commit is contained in:
@@ -32,6 +32,10 @@ add_executable(${PROJECT_NAME}
|
|||||||
src/utils/JsonConversion.h
|
src/utils/JsonConversion.h
|
||||||
src/controllers/AuthController.cpp
|
src/controllers/AuthController.cpp
|
||||||
src/controllers/AuthController.h
|
src/controllers/AuthController.h
|
||||||
|
src/controllers/filters/TokenValidationFilter.cpp
|
||||||
|
src/controllers/filters/TokenValidationFilter.h
|
||||||
|
src/dto/LoginRequestDto.h
|
||||||
|
src/dto/RegisterRequestDto.h
|
||||||
src/models/Entity.h
|
src/models/Entity.h
|
||||||
src/models/User.h
|
src/models/User.h
|
||||||
src/services/AuthService.cpp
|
src/services/AuthService.cpp
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
#include "dependency_injection/DependencyContainer.h"
|
#include "dependency_injection/DependencyContainer.h"
|
||||||
|
#include "dto/LoginRequestDto.h"
|
||||||
|
#include "dto/RegisterRequestDto.h"
|
||||||
#include "services/AuthService.h"
|
#include "services/AuthService.h"
|
||||||
#include "utils/JsonConversion.h"
|
#include "utils/JsonConversion.h"
|
||||||
|
|
||||||
@@ -13,37 +15,57 @@ api::v1::Auth::Auth()
|
|||||||
m_logger->info("[api::v1::Auth::Auth] Registered Auth controller");
|
m_logger->info("[api::v1::Auth::Auth] Registered Auth controller");
|
||||||
}
|
}
|
||||||
|
|
||||||
void api::v1::Auth::login(
|
void api::v1::Auth::loginUser(
|
||||||
const drogon::HttpRequestPtr& req,
|
const drogon::HttpRequestPtr& req,
|
||||||
std::function<void(const drogon::HttpResponsePtr&)>&& callback,
|
std::function<void(const drogon::HttpResponsePtr&)>&& callback
|
||||||
const std::string& username,
|
|
||||||
std::string&& password
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
m_logger->info("[api::v1::Auth::login] User `{}` tries to login", username);
|
auto body = req->getBody();
|
||||||
|
auto j = nlohmann::json::parse(body);
|
||||||
|
auto loginDataDto = j.get<LoginRequestDto>();
|
||||||
|
|
||||||
std::string token{};
|
std::string token{};
|
||||||
bool result = m_authService->authenticateUser(username, std::move(password), token);
|
bool result = m_authService->authenticateUser(loginDataDto, token);
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
m_logger->info("[api::v1::Auth::login] User `{}` successfully logged in", username);
|
m_logger->info("[api::v1::Auth::loginUser] User `{}` successfully logged in", loginDataDto.username);
|
||||||
nlohmann::json json;
|
auto resp = drogon::HttpResponse::newHttpResponse();
|
||||||
json["result"] = "ok";
|
|
||||||
|
|
||||||
auto resp = drogon::HttpResponse::newHttpJsonResponse(nlohmannToJsonValue(json));
|
|
||||||
resp->addHeader("Authorization", "Bearer " + token);
|
resp->addHeader("Authorization", "Bearer " + token);
|
||||||
callback(resp);
|
callback(resp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_logger->info("[api::v1::Auth::login] User `{}` failed to login", username);
|
m_logger->info("[api::v1::Auth::loginUser] User `{}` failed to login", loginDataDto.username);
|
||||||
nlohmann::json json;
|
auto resp = drogon::HttpResponse::newHttpResponse(drogon::k401Unauthorized, drogon::ContentType::CT_TEXT_PLAIN);
|
||||||
json["result"] = "error";
|
resp->setBody("Invalid username or password");
|
||||||
json["message"] = "Invalid username or password";
|
callback(resp);
|
||||||
|
}
|
||||||
auto resp = drogon::HttpResponse::newHttpJsonResponse(nlohmannToJsonValue(json));
|
}
|
||||||
resp->setStatusCode(drogon::k401Unauthorized);
|
|
||||||
|
void api::v1::Auth::registerUser(
|
||||||
|
const drogon::HttpRequestPtr& req,
|
||||||
|
std::function<void(const drogon::HttpResponsePtr&)>&& callback)
|
||||||
|
{
|
||||||
|
auto body = req->getBody();
|
||||||
|
auto j = nlohmann::json::parse(body);
|
||||||
|
auto registerDataDto = j.get<RegisterRequestDto>();
|
||||||
|
|
||||||
|
std::string token{};
|
||||||
|
bool result = m_authService->registerUser(registerDataDto, token);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
m_logger->info("[api::v1::Auth::registerUser] User `{}` successfully registered", registerDataDto.username);
|
||||||
|
auto resp = drogon::HttpResponse::newHttpResponse();
|
||||||
|
resp->addHeader("Authorization", "Bearer " + token);
|
||||||
|
callback(resp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nlohmann::json json;
|
||||||
|
auto resp = drogon::HttpResponse::newHttpResponse(drogon::k406NotAcceptable, drogon::ContentType::CT_TEXT_PLAIN);
|
||||||
|
resp->setBody("Failed to register new account");
|
||||||
callback(resp);
|
callback(resp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,15 +12,18 @@ class Auth : public drogon::HttpController<Auth>
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
METHOD_LIST_BEGIN
|
METHOD_LIST_BEGIN
|
||||||
METHOD_ADD(Auth::login, "/login?username={}&password={}", drogon::Get);
|
METHOD_ADD(Auth::loginUser, "/login", drogon::Post);
|
||||||
|
METHOD_ADD(Auth::registerUser, "/register", drogon::Post);
|
||||||
METHOD_LIST_END
|
METHOD_LIST_END
|
||||||
|
|
||||||
Auth();
|
Auth();
|
||||||
|
|
||||||
void login(const drogon::HttpRequestPtr& req,
|
void loginUser(const drogon::HttpRequestPtr& req,
|
||||||
std::function<void(const drogon::HttpResponsePtr&)>&& callback,
|
std::function<void(const drogon::HttpResponsePtr&)>&& callback);
|
||||||
const std::string& username,
|
|
||||||
std::string&& password);
|
void registerUser(const drogon::HttpRequestPtr& req,
|
||||||
|
std::function<void(const drogon::HttpResponsePtr&)>&& callback
|
||||||
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<spdlog::logger> m_logger;
|
std::shared_ptr<spdlog::logger> m_logger;
|
||||||
|
|||||||
47
src/controllers/filters/TokenValidationFilter.cpp
Normal file
47
src/controllers/filters/TokenValidationFilter.cpp
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include "TokenValidationFilter.h"
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include "dependency_injection/DependencyContainer.h"
|
||||||
|
#include "services/UserManager.h"
|
||||||
|
|
||||||
|
TokenValidationFilter::TokenValidationFilter()
|
||||||
|
{
|
||||||
|
m_userManager = DependencyContainer::Resolve<UserManager>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TokenValidationFilter::doFilter(
|
||||||
|
const drogon::HttpRequestPtr& req,
|
||||||
|
drogon::FilterCallback&& fcb,
|
||||||
|
drogon::FilterChainCallback&& fccb
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto authHeader = req->getHeader("Authorization");
|
||||||
|
if (authHeader.empty() || authHeader.find("Bearer ") != 0)
|
||||||
|
{
|
||||||
|
auto res = drogon::HttpResponse::newHttpResponse();
|
||||||
|
res->setStatusCode(drogon::k401Unauthorized);
|
||||||
|
res->setBody("Missing or invalid Authorization header");
|
||||||
|
return fcb(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string token = authHeader.substr(7);
|
||||||
|
bool validated = m_userManager->validateToken(token);
|
||||||
|
|
||||||
|
if (validated)
|
||||||
|
{
|
||||||
|
// TODO: set role and user_id attributes here
|
||||||
|
auto payloadString = m_userManager->getPayloadFromToken(token);
|
||||||
|
auto payload = nlohmann::json::parse(payloadString);
|
||||||
|
|
||||||
|
int user_id = payload["user_id"];
|
||||||
|
std::string role = payload["role"];
|
||||||
|
req->attributes()->insert("user_id", user_id);
|
||||||
|
req->attributes()->insert("role", role);
|
||||||
|
|
||||||
|
return fccb();
|
||||||
|
}
|
||||||
|
auto res = drogon::HttpResponse::newHttpResponse();
|
||||||
|
res->setStatusCode(drogon::k401Unauthorized);
|
||||||
|
res->setBody("Invalid token");
|
||||||
|
return fcb(res);
|
||||||
|
}
|
||||||
18
src/controllers/filters/TokenValidationFilter.h
Normal file
18
src/controllers/filters/TokenValidationFilter.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <drogon/drogon.h>
|
||||||
|
|
||||||
|
class UserManager;
|
||||||
|
|
||||||
|
class TokenValidationFilter : public drogon::HttpFilter<TokenValidationFilter>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TokenValidationFilter();
|
||||||
|
|
||||||
|
virtual void doFilter(const drogon::HttpRequestPtr& req,
|
||||||
|
drogon::FilterCallback&& fcb,
|
||||||
|
drogon::FilterChainCallback&& fccb) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<UserManager> m_userManager;
|
||||||
|
};
|
||||||
13
src/dto/LoginRequestDto.h
Normal file
13
src/dto/LoginRequestDto.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
class LoginRequestDto
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string username;
|
||||||
|
std::string password;
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(LoginRequestDto, username, password);
|
||||||
|
};
|
||||||
15
src/dto/RegisterRequestDto.h
Normal file
15
src/dto/RegisterRequestDto.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
class RegisterRequestDto
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string username;
|
||||||
|
std::string password;
|
||||||
|
std::string firstName;
|
||||||
|
std::string lastName;
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(RegisterRequestDto, username, password, firstName, lastName);
|
||||||
|
};
|
||||||
@@ -12,3 +12,8 @@ std::optional<User> MockUserStorage::getUserByUsername(const std::string& userna
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MockUserStorage::insertUser(const User& user)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ class MockUserStorage : public IUserStorage
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual std::optional<User> getUserByUsername(const std::string& username) override;
|
virtual std::optional<User> getUserByUsername(const std::string& username) override;
|
||||||
|
virtual bool insertUser(const User& user) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include "UserManager.h"
|
#include "UserManager.h"
|
||||||
#include "dependency_injection/DependencyContainer.h"
|
#include "dependency_injection/DependencyContainer.h"
|
||||||
|
#include "dto/LoginRequestDto.h"
|
||||||
|
#include "dto/RegisterRequestDto.h"
|
||||||
#include "storages/IUserStorage.h"
|
#include "storages/IUserStorage.h"
|
||||||
|
|
||||||
AuthService::AuthService()
|
AuthService::AuthService()
|
||||||
@@ -12,27 +14,45 @@ AuthService::AuthService()
|
|||||||
m_userManager = DependencyContainer::Resolve<UserManager>();
|
m_userManager = DependencyContainer::Resolve<UserManager>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthService::authenticateUser(
|
bool AuthService::authenticateUser(LoginRequestDto& loginData, std::string& outToken)
|
||||||
const std::string& username,
|
|
||||||
std::string&& password,
|
|
||||||
std::string& outToken
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
auto foundUser = m_userStorage->getUserByUsername(username);
|
auto foundUser = m_userStorage->getUserByUsername(loginData.username);
|
||||||
if (!foundUser.has_value())
|
if (!foundUser.has_value())
|
||||||
{
|
{
|
||||||
m_logger->info("Failed to find user with username `{}`", username);
|
m_logger->info("Failed to find user with username `{}`", loginData.username);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_userManager->validateCredentials(*foundUser, std::move(loginData.password)))
|
||||||
|
{
|
||||||
|
outToken = m_userManager->generateToken(*foundUser);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return m_userManager->validateCredentials(foundUser.value(), std::move(password));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AuthService::registerUser(
|
|
||||||
const std::string& username,
|
|
||||||
const std::string& password,
|
|
||||||
const std::string& firstName,
|
|
||||||
const std::string& lastName,
|
|
||||||
std::string& outToken
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AuthService::registerUser(RegisterRequestDto& registerData, std::string& outToken)
|
||||||
|
{
|
||||||
|
if (!m_userManager->validateRegisterData(registerData))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto hashedPassword = m_userManager->hashPassword(std::move(registerData.password));
|
||||||
|
|
||||||
|
User user;
|
||||||
|
user.username = registerData.username;
|
||||||
|
user.passwordHash = hashedPassword;
|
||||||
|
user.firstName = registerData.firstName;
|
||||||
|
user.lastName = registerData.lastName;
|
||||||
|
user.role = "LIVER";
|
||||||
|
|
||||||
|
bool insertResult = m_userStorage->insertUser(user);
|
||||||
|
if (!insertResult)
|
||||||
|
{
|
||||||
|
m_logger->error("Failed to create new user");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
outToken = m_userManager->generateToken(user);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,25 +6,16 @@
|
|||||||
|
|
||||||
class IUserStorage;
|
class IUserStorage;
|
||||||
class UserManager;
|
class UserManager;
|
||||||
|
class LoginRequestDto;
|
||||||
|
class RegisterRequestDto;
|
||||||
|
|
||||||
class AuthService
|
class AuthService
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AuthService();
|
AuthService();
|
||||||
|
|
||||||
bool authenticateUser(
|
bool authenticateUser(LoginRequestDto& loginData, std::string& outToken);
|
||||||
const std::string& username,
|
bool registerUser(RegisterRequestDto& registerData, std::string& outToken);
|
||||||
std::string&& password,
|
|
||||||
std::string& outToken
|
|
||||||
);
|
|
||||||
|
|
||||||
bool registerUser(
|
|
||||||
const std::string& username,
|
|
||||||
const std::string& password,
|
|
||||||
const std::string& firstName,
|
|
||||||
const std::string& lastName,
|
|
||||||
std::string& outToken
|
|
||||||
);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<spdlog::logger> m_logger;
|
std::shared_ptr<spdlog::logger> m_logger;
|
||||||
|
|||||||
@@ -1,23 +1,99 @@
|
|||||||
#include "UserManager.h"
|
#include "UserManager.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <vector>
|
||||||
#include <drogon/utils/Utilities.h>
|
#include <drogon/utils/Utilities.h>
|
||||||
|
#include <jwt-cpp/jwt.h>
|
||||||
|
#include <jwt-cpp/traits/nlohmann-json/defaults.h>
|
||||||
#include "dependency_injection/DependencyContainer.h"
|
#include "dependency_injection/DependencyContainer.h"
|
||||||
#include "models/User.h"
|
#include "models/User.h"
|
||||||
#include "services/encryption/PasswordEncryptor.h"
|
#include "services/encryption/PasswordEncryptor.h"
|
||||||
|
|
||||||
|
std::string PUBLIC_KEY{
|
||||||
|
R"(-----BEGIN PUBLIC KEY-----
|
||||||
|
MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgGlyZf3ilQWS862UM0wPL9t+B/La
|
||||||
|
E4QiLOWULVmiHvtg6ly5erX4LeKX9og0LYgdUyialjPRElutRq1dTEJ4x9kgDkT4
|
||||||
|
o+hwcem+OHKkdbIfGSIdrI1SzWPYq8F9JjL9elPghD8Rul1US+2HWyrJkw3YiAjU
|
||||||
|
gmZ8mUpu5Hkq+LjzAgMBAAE=
|
||||||
|
-----END PUBLIC KEY-----)"
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string PRIVATE_KEY{
|
||||||
|
R"(-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIICWgIBAAKBgGlyZf3ilQWS862UM0wPL9t+B/LaE4QiLOWULVmiHvtg6ly5erX4
|
||||||
|
LeKX9og0LYgdUyialjPRElutRq1dTEJ4x9kgDkT4o+hwcem+OHKkdbIfGSIdrI1S
|
||||||
|
zWPYq8F9JjL9elPghD8Rul1US+2HWyrJkw3YiAjUgmZ8mUpu5Hkq+LjzAgMBAAEC
|
||||||
|
gYATCsimV5OnxQjiUMAOvTNcRN80mPMrSmynLOIfrKpBpRfNlOU3FVFb+StZH2sV
|
||||||
|
iI4q5/e19cyF5726sv2Bh4Q3Uob6eJZfpcReScUtbhFLhikCSTvWf6g+6ebCBF9m
|
||||||
|
HoXQBvJhthRo+9BSoweZjxNZirxO1DaqbrxIdufpBJL9aQJBAL/iyzb7mQ/oq8/j
|
||||||
|
BcVnPlOBK6R3q5ZcynJTgyLMTldAwTB4WZrUPBWt51WUL7LoZhMtQIGNaqApSwyp
|
||||||
|
ehaRKscCQQCMre5E5QXDvAITYIoGNs1x5qVUzKCYXYIv0hdko21V9GLNaYWLL5ux
|
||||||
|
BAZsvNLBE2DMbl4mJiL198qJItYk0nR1AkAIXjGSgkJYiUME29eiljAHoDhxAa7/
|
||||||
|
7af+eFndqJ85+t7x6C2wLNU59M2D0+SIns3kxDJt8+bUeTiGotVqKoZ9AkAELNFK
|
||||||
|
eCWQpo7FNnNCNfQo8jhr6NrHStcnRivtj7AaAfPAtuYAuHv9Z+os5fm3QzT3PDtN
|
||||||
|
FIqrFByNr1v9ocVVAkAWvQ4q4Mkw8u/zCAuPiK9NJn377nc4bENQkcn6ZJ4dbMgt
|
||||||
|
yV8QswCTqtfaXKyOEs46WNYhEtMahiLPeL7V23Mr
|
||||||
|
-----END RSA PRIVATE KEY-----)"
|
||||||
|
};
|
||||||
|
|
||||||
UserManager::UserManager()
|
UserManager::UserManager()
|
||||||
{
|
{
|
||||||
|
m_logger = DependencyContainer::Resolve<spdlog::logger>();
|
||||||
m_passwordEncryptor = DependencyContainer::Resolve<PasswordEncryptor>();
|
m_passwordEncryptor = DependencyContainer::Resolve<PasswordEncryptor>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UserManager::validateCredentials(const User& userData, std::string&& rawPassword)
|
bool UserManager::validateCredentials(const User& userData, std::string&& rawPassword)
|
||||||
{
|
{
|
||||||
auto hashedPassword = hashPassword(std::move(rawPassword));
|
auto hashedPassword = hashPassword(std::move(rawPassword));
|
||||||
auto base64Hash = drogon::utils::base64Encode(hashedPassword.data(), hashedPassword.size());
|
return hashedPassword == userData.passwordHash;
|
||||||
return base64Hash == userData.passwordHash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> UserManager::hashPassword(std::string&& rawPassword)
|
bool UserManager::validateRegisterData(const RegisterRequestDto& registerData)
|
||||||
{
|
{
|
||||||
return m_passwordEncryptor->encryptPassword(std::move(rawPassword));
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UserManager::generateToken(const User& userData)
|
||||||
|
{
|
||||||
|
return jwt::create()
|
||||||
|
.set_type("JWT")
|
||||||
|
.set_payload_claim("user_id", jwt::claim(userData.id))
|
||||||
|
.set_payload_claim("role", jwt::claim(userData.role))
|
||||||
|
.set_expires_in(std::chrono::seconds{ 3600 })
|
||||||
|
.sign(jwt::algorithm::rs256{ "", PRIVATE_KEY });
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UserManager::hashPassword(std::string&& rawPassword)
|
||||||
|
{
|
||||||
|
auto hashData = m_passwordEncryptor->encryptPassword(std::move(rawPassword));
|
||||||
|
return drogon::utils::base64Encode(hashData.data(), hashData.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UserManager::validateToken(const std::string& token)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto decoded = jwt::decode(token);
|
||||||
|
|
||||||
|
auto verifier = jwt::verify()
|
||||||
|
.allow_algorithm(jwt::algorithm::rs256{ PUBLIC_KEY, "" });
|
||||||
|
verifier.verify(decoded);
|
||||||
|
}
|
||||||
|
catch (const jwt::error::token_verification_exception& ex)
|
||||||
|
{
|
||||||
|
m_logger->info("Failed to validate token: {}", ex.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UserManager::getPayloadFromToken(const std::string& token)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto decoded = jwt::decode(token);
|
||||||
|
return decoded.get_payload();
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{ }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <spdlog/logger.h>
|
||||||
|
|
||||||
class User;
|
|
||||||
|
|
||||||
class PasswordEncryptor;
|
class PasswordEncryptor;
|
||||||
|
class RegisterRequestDto;
|
||||||
|
class User;
|
||||||
|
|
||||||
class UserManager
|
class UserManager
|
||||||
{
|
{
|
||||||
@@ -14,10 +14,15 @@ public:
|
|||||||
UserManager();
|
UserManager();
|
||||||
|
|
||||||
bool validateCredentials(const User& userData, std::string&& rawPassword);
|
bool validateCredentials(const User& userData, std::string&& rawPassword);
|
||||||
|
bool validateRegisterData(const RegisterRequestDto& registerData);
|
||||||
|
|
||||||
|
std::string generateToken(const User& userData);
|
||||||
|
std::string hashPassword(std::string&& rawPassword);
|
||||||
|
|
||||||
|
bool validateToken(const std::string& token);
|
||||||
|
std::string getPayloadFromToken(const std::string& token);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint8_t> hashPassword(std::string&& rawPassword);
|
std::shared_ptr<spdlog::logger> m_logger;
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<PasswordEncryptor> m_passwordEncryptor;
|
std::shared_ptr<PasswordEncryptor> m_passwordEncryptor;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ class IUserStorage
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual std::optional<User> getUserByUsername(const std::string& username) = 0;
|
virtual std::optional<User> getUserByUsername(const std::string& username) = 0;
|
||||||
|
virtual bool insertUser(const User& user) = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user