From 1c34f5ac5b99df71a8fb9e32fe4556f86a7d3e9f Mon Sep 17 00:00:00 2001 From: mrplesk2 Date: Thu, 22 Jan 2026 10:52:43 +0300 Subject: [PATCH] Task done v1 --- auth.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++- auth.hpp | 37 +++++++++++++++++++++- server.cpp | 44 ++++++++++++++++++++------ 3 files changed, 161 insertions(+), 12 deletions(-) diff --git a/auth.cpp b/auth.cpp index f6cfe5c..84b7d32 100644 --- a/auth.cpp +++ b/auth.cpp @@ -5,7 +5,97 @@ namespace auth namespace core { -// TODO: добавьте определения классов/функций + AuthManager::AuthManager() = default; + void AuthManager::AddAdmin(std::string username, std::string password) + { + users_.emplace(std::move(username), User{std::move(password), true}); + } + + std::optional AuthManager::Login(const std::string& username, const std::string& password) + { + const auto it = users_.find(username); + if (it == users_.end() || + it->second.password != password) + return std::nullopt; + + const uint64_t id = AcquireSessionId(); + + sessions_[id] = username; + return id; + } + + bool AuthManager::Logout(uint64_t sessionId) + { + const auto erased = sessions_.erase(sessionId); + if (erased == 0) return false; + + ReleaseSessionId(sessionId); + return true; + } + + bool AuthManager::AddUser(uint64_t sessionId, const std::string& username, const std::string& password) + { + if (!SessionIsAdmin(sessionId) || users_.count(username) != 0) return false; + + users_.emplace(username, User{password, false}); + return true; + } + + bool AuthManager::DelUser(uint64_t sessionId, const std::string& username) + { + if (!SessionIsAdmin(sessionId)) return false; + + const auto erased = users_.erase(username); + if (erased == 0) return false; + + for (auto it = sessions_.begin(); it != sessions_.end(); ) + { + if (it->second == username) + { + ReleaseSessionId(it->first); + it = sessions_.erase(it); + } + else + { + ++it; + } + } + + return true; + } + + bool AuthManager::SessionExists(uint64_t sessionId) + { + return sessions_.count(sessionId) != 0; + } + + bool AuthManager::SessionIsAdmin(uint64_t sessionId) + { + auto sit = sessions_.find(sessionId); + if (sit == sessions_.end()) return false; + + auto uit = users_.find(sit->second); + if (uit == users_.end()) return false; + + return uit->second.isAdmin; + } + + uint64_t AuthManager::AcquireSessionId() + { + if (!freeSessions_.empty()) + { + const uint64_t id = freeSessions_.top(); + freeSessions_.pop(); + return id; + } + + return nextSessionId_++; + } + + void AuthManager::ReleaseSessionId(uint64_t id) + { + freeSessions_.push(id); + } } // namespace core } // namespace auth diff --git a/auth.hpp b/auth.hpp index 1e81d9c..310810a 100644 --- a/auth.hpp +++ b/auth.hpp @@ -1,11 +1,46 @@ #pragma once +#include +#include +#include +#include +#include namespace auth { namespace core { + struct User + { + std::string password; + bool isAdmin = false; + }; -// TODO: добавьте объявления классов/функций + class AuthManager + { + public: + AuthManager(); + void AddAdmin(std::string username, std::string password); + + std::optional Login(const std::string& username, const std::string& password); + + bool Logout(uint64_t sessionId); + + bool AddUser(uint64_t sessionId, const std::string& username, const std::string& password); + + bool DelUser(uint64_t sessionId, const std::string& username); + + bool SessionExists(uint64_t sessionId); + bool SessionIsAdmin(uint64_t sessionId); + private: + uint64_t AcquireSessionId(); + void ReleaseSessionId(uint64_t id); + + std::unordered_map users_; + std::unordered_map sessions_; + + std::stack freeSessions_; + uint64_t nextSessionId_ = 1; + }; } // namespace core } // namespace auth diff --git a/server.cpp b/server.cpp index ec1cec6..30bf494 100644 --- a/server.cpp +++ b/server.cpp @@ -12,12 +12,16 @@ #include "udp_session.hpp" #include "udp_socket.hpp" #include "command.hpp" +#include "auth.hpp" namespace auth { namespace server { +static auth::core::AuthManager authManager; + + namespace { @@ -50,23 +54,43 @@ std::string process_command(std::string_view income) const auto vargs = command.GetArgs(); if (std::holds_alternative(vargs)) { - // TODO: обработайте команду login - [[maybe_unused]] const auto args = std::get(vargs); + const auto args = std::get(vargs); + const auto session = authManager.Login(std::string(args.username), std::string(args.password)); + + if (!session) + return "error: invalud username or password\n"; + + return "session_id=" + std::to_string(*session) + "\n"; } else if (std::holds_alternative(vargs)) { - // TODO: обработайте команду logout - [[maybe_unused]] const auto args = std::get(vargs); + const auto args = std::get(vargs); + + if (!authManager.Logout(std::stoull(std::string(args.sessionId)))) + return "error: invalid session\n"; + + return "ok\n"; } else if (std::holds_alternative(vargs)) { - // TODO: обработайте команду adduser - [[maybe_unused]] const auto args = std::get(vargs); + const auto args = std::get(vargs); + + if (!authManager.AddUser(std::stoull(std::string(args.sessionId)), + std::string(args.username), + std::string(args.password))) + return "error: access denied or user exists\n"; + + return "ok\n"; } else if (std::holds_alternative(vargs)) { - // TODO: обработайте команда deluser - [[maybe_unused]] const auto args = std::get(vargs); + const auto args = std::get(vargs); + + if (!authManager.DelUser(std::stoull(std::string(args.sessionId)), + std::string(args.username))) + return "error: access denied or user not found\n"; + + return "ok\n"; } } catch (const std::exception& err) @@ -83,8 +107,8 @@ Server::Server(std::string_view adminUsername, const std::atomic& running) : running_(running), socket_(port), session_(socket_) { - // TODO: добавьте администратора с именем и паролем - // из параметров конструктора + authManager.AddAdmin(std::string(adminUsername), std::string(adminPassword)); + std::cout << "Add administrator user '" << adminUsername << "/***'\n"; std::cout << "Listening on port " << port << '\n'; }