#pragma once #include #include #include #include #include "IExecutor.h" #include "../DAO/IUserDAO.h" #include "../exceptions/session_exception.h" namespace uad { template class AuthRegistrationExecutor : public IExecutor { mysqlx::Session& session_; const std::shared_ptr& user_dao_; public: AuthRegistrationExecutor(mysqlx::Session& session, const std::shared_ptr& user_dao) : session_(session), user_dao_(user_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; BOOST_LOG_TRIVIAL(info) << "POST /api/v1/Auth/Registration - Request"; const auto& body = req.body(); value req_json; try { req_json = json::parse(body); } catch (const system::system_error& err) { BOOST_LOG_TRIVIAL(error) << "POST /api/v1/Auth/Registration - Response 400: Cannot deserialize json"; throw session_exception(http::status::bad_request, "Cannot deserialize json"); } 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 (!ValidateLogin(login) || !ValidatePassword(password)) { BOOST_LOG_TRIVIAL(error) << "POST /api/v1/Auth/Registration - Response 422: Validations failed. Login should have length from 3 to 50. Password from 5 characters length."; throw session_exception( http::status::unprocessable_entity, "Validations failed. Login should have length from 3 to 50. Password from 5 characters length."s ); } if (user_dao_->GetByLogin(login).has_value()) { BOOST_LOG_TRIVIAL(error) << "POST /api/v1/Auth/Registration - Response 409: "s + "User with login "s + login + " exists"s; throw session_exception(http::status::conflict, "User with login "s + login + " exists"s); } user_dto user; user.login = login; user.hashed_password = HashPassword(password); const std::string uuid_stringified = user_dao_->Create(user); http::response res{ http::status::created, req.version() }; value response_body; response_body.emplace_object(); response_body.as_object().emplace( "uuid", uuid_stringified ); response_body.as_object().emplace( "login", user.login ); res.body() = serialize(response_body); res.set(http::field::content_type, "application/json"); res.content_length(res.body().size()); return res; } private: bool ValidateLogin(const std::string& login) { if (login.size() < 3 || login.size() > 50) return false; std::regex pattern(std::string("^[A-Za-z0-9_]+$")); return std::regex_match(login, pattern); } bool ValidatePassword(const std::string& password) { return password.size() >= 5; } }; }