diff --git a/CMakeLists.txt b/CMakeLists.txt index 660e793..70aac04 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,9 +45,10 @@ add_executable(App ./src/main.cpp ./src/endpoints_handlers/IExecutor.h ./src/endpoints_handlers/AuthRegistrationExecutor.h ./src/endpoints_handlers/RootExecutor.h - src/DAO/IAuthDAO.h - src/DAO/MemoryAuthDAO.cpp - src/DAO/MemoryAuthDAO.h + ./src/DAO/IAuthDAO.h + ./src/DAO/MemoryAuthDAO.cpp + ./src/DAO/MemoryAuthDAO.h + ./src/endpoints_handlers/AuthLogoutExecutor.h ) target_link_libraries(App PRIVATE Boost::boost Boost::json Threads::Threads mysql::concpp) diff --git a/src/endpoints_handlers/AuthLogoutExecutor.h b/src/endpoints_handlers/AuthLogoutExecutor.h new file mode 100644 index 0000000..1c6b833 --- /dev/null +++ b/src/endpoints_handlers/AuthLogoutExecutor.h @@ -0,0 +1,103 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "IExecutor.h" +#include "../DAO/IUserDAO.h" +#include "../DAO/IAuthDAO.h" +#include "../helpers/helpers.h" + +namespace uad +{ +template +class AuthLogoutExecutor : public IExecutor +{ + mysqlx::Session& session_; + const std::shared_ptr& user_dao_; + const std::shared_ptr& auth_dao_; + +public: + AuthLogoutExecutor(mysqlx::Session& session, + const std::shared_ptr& user_dao, + const std::shared_ptr& auth_dao) + : session_(session), user_dao_(user_dao), auth_dao_(auth_dao) + { + } + + boost::beast::http::response operator ()( + boost::beast::http::request>&& req + ) override + { + using namespace boost; + using namespace boost::json; + using namespace boost::beast; + using namespace std::string_literals; + + auto body = req.body(); + value req_json; + value response_body; + + response_body.emplace_object(); + + try + { + req_json = json::parse(body); + + const std::string login = req_json.as_object().at("login").as_string().c_str(); + const std::string password = req_json.as_object().at("password").as_string().c_str(); + + if (login.empty() || password.empty()) + { + http::response res{http::status::unprocessable_entity, req.version()}; + response_body.as_object().emplace("Result", "Login or password are empty"); + + res.body() = serialize(response_body); + res.set(http::field::content_type, "application/json"); + res.content_length(res.body().size()); + + return res; + } + + std::optional maybe_user = user_dao_->GetByLogin(login); + + if (!maybe_user.has_value() || (maybe_user.value().GetHashedPassword() != HashPassword(password))) + { + http::response res{http::status::unprocessable_entity, req.version()}; + response_body.as_object().emplace("Result", "Incorrect login or password"); + + res.body() = serialize(response_body); + res.set(http::field::content_type, "application/json"); + res.content_length(res.body().size()); + + return res; + } + auto token = GenerateUUID(); + auth_dao_->Login(maybe_user.value().GetUUID(), token); + + http::response res{http::status::ok, req.version()}; + response_body.as_object().emplace("token", token); + + res.body() = serialize(response_body); + res.set(http::field::content_type, "application/json"); + res.content_length(res.body().size()); + + return res; + } + catch (const system::system_error& err) + { + http::response res{http::status::bad_request, req.version()}; + response_body.as_object().emplace("Result", "cannot deserialize json"); + + res.body() = serialize(response_body); + res.set(http::field::content_type, "application/json"); + res.content_length(res.body().size()); + + return res; + } + } +}; +} diff --git a/src/endpoints_handlers/RootExecutor.h b/src/endpoints_handlers/RootExecutor.h index 9adecc8..3efdc3d 100644 --- a/src/endpoints_handlers/RootExecutor.h +++ b/src/endpoints_handlers/RootExecutor.h @@ -3,6 +3,7 @@ #include "Controller.h" #include "AuthRegistrationExecutor.h" #include "AuthLoginExecutor.h" +#include "AuthLogoutExecutor.h" #include "../DAO/IUserDAO.h" #include "../DAO/IAuthDAO.h" #include "./../helpers/helpers.h" @@ -17,6 +18,8 @@ class RootExecutor Body, Allocator, boost::beast::http::string_body>; using RouteAuthLoginExecutor = AuthLoginExecutor< Body, Allocator, boost::beast::http::string_body>; + using RouteAuthLogoutExecutor = AuthLogoutExecutor< + Body, Allocator, boost::beast::http::string_body>; using IRouteController = IController; using RouteController = Controller; using RoutesPathes = std::unordered_map>; @@ -53,6 +56,13 @@ public: std::make_shared(session_, user_dao_, auth_dao_)} } ); + + routes_pathes_["/api/v1/Auth/Logout"] = std::make_unique( + typename RouteController::HTTPMethodsToExecutors{ + {boost::beast::http::verb::post, + std::make_shared(session_, user_dao_, auth_dao_)} + } + ); } void operator ()(