diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c9e9f1..046ecb0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,8 @@ add_executable(terminal-web-server src/terminal_api_driver.cpp src/auth/resources.cpp src/auth/resources.h + src/auth/jwt.cpp + src/auth/jwt.h ) find_package(Boost 1.53.0 COMPONENTS system thread filesystem log log_setup REQUIRED) diff --git a/src/auth/jwt.cpp b/src/auth/jwt.cpp new file mode 100644 index 0000000..31910a0 --- /dev/null +++ b/src/auth/jwt.cpp @@ -0,0 +1,5 @@ +// +// Created by vlad on 04.11.2024. +// + +#include "jwt.h" diff --git a/src/auth/jwt.h b/src/auth/jwt.h new file mode 100644 index 0000000..d0c6cf6 --- /dev/null +++ b/src/auth/jwt.h @@ -0,0 +1,23 @@ +#ifndef JWT_H +#define JWT_H +#include +#include "resources.h" + +namespace http::auth::jwt { + class Jwt { + public: + static Jwt fromCookies(const std::string& cookie); + static Jwt fromString(const std::string& cookie); + static Jwt fromUser(const std::string& User); + + bool isValid(); + + std::string getUsername(); + + std::string asCookie(); + + ~Jwt(); + }; +} + +#endif //JWT_H diff --git a/src/auth/resources.h b/src/auth/resources.h index f36bd5b..d5f445e 100644 --- a/src/auth/resources.h +++ b/src/auth/resources.h @@ -4,25 +4,74 @@ namespace http::auth { /** - * Класс пользовательских разрешений, - */ - class UserPremision{}; + * Класс пользователя, содержит логин/хеш_пароля/настройки пользователя/права. + * Хеш пароля представляется в виде строки + */ + class User { + private: + uint32_t perms; - /** - * Класс пользователя, содержит логин/хеш_пароля/настройки пользователя/права - */ - class User{}; + public: + const std::string username; + std::string passwordHash; - /** - * Класс аутентификации. Управляет всеми сессиями, создает новые при логине, удаляет при логауте. - * @note Класс устанавливает заголовок 'Set-Cookie' в ответе, и этот заголовок должен дойти до пользователя! - */ - class AuthProvider { + User(const std::string& username, const std::string& passwordHash); + /** + * Проверить пароль на соответствие хешу + * @param pass + * @return + */ + bool checkPassword(const std::string& pass); + + /** + * Установка пароля + * @param pass строка с исходным паролем + */ + void setPassword(const std::string& pass); + + + static constexpr uint32_t SUPERUSER = 0x0001; + static constexpr uint32_t WATCH_STATISTICS = 0x0002; // мониторинг модема + static constexpr uint32_t RESET_PACKET_STATISTICS = 0x0004; // сброс статистики пакетов + static constexpr uint32_t WATCH_SETTINGS = 0x0008; // просмотр настроек , если недоступно, то вкладки с настройками не будет + static constexpr uint32_t EDIT_SETTINGS = 0x0010; // редактирование настроек, установка параметров модулятора/демодулятора/dma/cinc + static constexpr uint32_t UPDATE_FIRMWARE = 0x0020; // обновление прошивки + + /** + * Проверить, что у пользователя есть нужное право. Если это суперпользователь, то у него по умолчанию все права есть. + * @param p набор прав, из констант данного класса. + * @return + */ + bool checkPremisions(uint32_t p); + + void setPremisions(uint32_t p); + void resetPremisions(uint32_t p); + + ~User(); }; - class NeedAuentificationResource: public resource::BasicResource {}; + /** + * Класс аутентификации. Управляет всеми сессиями, создает новые при логине, удаляет при логауте. + * @note Класс устанавливает заголовок 'Set-Cookie' в ответе, и этот заголовок должен дойти до пользователя! + */ + class AuthProvider { + public: + AuthProvider(); + /** + * Авторизовать пользователя. + * + * @param rep + * @return true, в случае успешной авторизации + */ + bool doAuth(const std::string& username, const std::string& password, server::Reply& rep); + + ~AuthProvider(); + }; + + class NeedAuentificationResource : public resource::BasicResource { + }; } #endif //RESOURCES_H diff --git a/src/server/connection.hpp b/src/server/connection.hpp index eecda3f..1fbb986 100644 --- a/src/server/connection.hpp +++ b/src/server/connection.hpp @@ -13,7 +13,7 @@ namespace http::server { - using request_handler = std::function; + using request_handler = std::function; class ConnectionManager; /// Represents a single Connection from a client. Base class @@ -71,7 +71,7 @@ namespace http::server { RequestParser request_parser_; /// The reply to be sent back to the client. - reply reply_; + Reply reply_; }; class SslConnection final : public ConnectionBase, public std::enable_shared_from_this { @@ -113,7 +113,7 @@ namespace http::server { RequestParser request_parser_; /// The reply to be sent back to the client. - reply reply_; + Reply reply_; }; typedef std::shared_ptr connection_ptr; diff --git a/src/server/reply.cpp b/src/server/reply.cpp index b37cfe0..a259770 100644 --- a/src/server/reply.cpp +++ b/src/server/reply.cpp @@ -68,7 +68,7 @@ namespace http::server { const char crlf[] = {'\r', '\n'}; } // namespace misc_strings - std::vector reply::to_buffers() const { + std::vector Reply::to_buffers() const { std::vector buffers; buffers.push_back(status_strings::to_buffer(status)); for (const auto & h : headers) { @@ -206,7 +206,7 @@ namespace http::server { } } // namespace stock_replies - void stockReply(status_type status, reply& rep) { + void stockReply(status_type status, Reply& rep) { rep.status = status; rep.headers.clear(); rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::text_html)}); diff --git a/src/server/reply.hpp b/src/server/reply.hpp index 9243dbb..e84536d 100644 --- a/src/server/reply.hpp +++ b/src/server/reply.hpp @@ -28,7 +28,7 @@ namespace http::server { }; /// A reply to be sent to a client. - struct reply { + struct Reply { status_type status; /// The headers to be included in the reply. @@ -44,7 +44,7 @@ namespace http::server { }; /// Get a stock reply. - void stockReply(status_type status, reply& rep); + void stockReply(status_type status, Reply& rep); } // namespace http::Server diff --git a/src/server/resource.cpp b/src/server/resource.cpp index 53874a8..f7e0e5c 100644 --- a/src/server/resource.cpp +++ b/src/server/resource.cpp @@ -30,7 +30,7 @@ http::resource::StaticFileResource::StaticFileResource(const std::string &path, #endif } -void http::resource::StaticFileResource::handle(const server::Request &req, server::reply &rep) { +void http::resource::StaticFileResource::handle(const server::Request &req, server::Reply &rep) { if (req.method != "GET") { stockReply(server::bad_request, rep); return; @@ -56,7 +56,7 @@ http::resource::GenericResource::GenericResource(const std::string &path, const this->path = path; } -void http::resource::GenericResource::handle(const server::Request &req, server::reply &rep) { +void http::resource::GenericResource::handle(const server::Request &req, server::Reply &rep) { this->generator_(req, rep); } diff --git a/src/server/resource.h b/src/server/resource.h index 77f3dd7..8545a93 100644 --- a/src/server/resource.h +++ b/src/server/resource.h @@ -14,7 +14,7 @@ namespace http::resource { public: std::string path; - virtual void handle(const server::Request &req, server::reply &rep) = 0; + virtual void handle(const server::Request &req, server::Reply &rep) = 0; virtual ~BasicResource() = default; }; @@ -34,12 +34,12 @@ namespace http::resource { public: StaticFileResource(const std::string& path, const std::string& filePath, server::mime_types::Mime type); - void handle(const server::Request &req, server::reply &rep) override; + void handle(const server::Request &req, server::Reply &rep) override; ~StaticFileResource() override; }; - using respGenerator = std::function; + using respGenerator = std::function; /** * Класс ресурса для POST-запросов @@ -51,7 +51,7 @@ namespace http::resource { public: GenericResource(const std::string& path, const respGenerator& generator); - void handle(const server::Request &req, server::reply &rep) override; + void handle(const server::Request &req, server::Reply &rep) override; ~GenericResource() override; }; diff --git a/src/server/server.cpp b/src/server/server.cpp index 4148466..a4dcff2 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -111,7 +111,7 @@ namespace http::server { }); } - void Server::requestHandler(const Request &req, reply &rep) { + void Server::requestHandler(const Request &req, Reply &rep) { // Request path must be absolute and not contain "..". if (req.url->path.empty() || req.url->path[0] != '/' || req.url->path.find("..") != std::string::npos) { stockReply(bad_request, rep); diff --git a/src/server/server.hpp b/src/server/server.hpp index 0736a60..0ad4f5b 100644 --- a/src/server/server.hpp +++ b/src/server/server.hpp @@ -74,7 +74,7 @@ namespace http::server { ConnectionManager connection_manager_; /// Handle a request and produce a reply. - void requestHandler(const Request &req, reply &rep); + void requestHandler(const Request &req, Reply &rep); }; } // namespace http::Server