сделал систему прав, теперь все действия с апи выполняются только при наличии прав (и в целом авторизации)
This commit is contained in:
parent
857a01528b
commit
5175362d1b
@ -1,6 +1,7 @@
|
|||||||
#include "resources.h"
|
#include "resources.h"
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <utility>
|
||||||
#include "jwt.h"
|
#include "jwt.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
@ -8,6 +9,9 @@
|
|||||||
http::auth::User::User(const std::string &username, const std::string &passwordHash): username(username),
|
http::auth::User::User(const std::string &username, const std::string &passwordHash): username(username),
|
||||||
passwordHash(passwordHash.empty() ? utils::sha256(username) : passwordHash) {}
|
passwordHash(passwordHash.empty() ? utils::sha256(username) : passwordHash) {}
|
||||||
|
|
||||||
|
http::auth::User::User(const std::string &username, const std::string &passwordHash, uint32_t perms): perms(perms),
|
||||||
|
username(username), passwordHash(passwordHash.empty() ? utils::sha256(username) : passwordHash) {}
|
||||||
|
|
||||||
bool http::auth::User::checkPassword(const std::string &pass) const {
|
bool http::auth::User::checkPassword(const std::string &pass) const {
|
||||||
return utils::sha256(pass) == passwordHash;
|
return utils::sha256(pass) == passwordHash;
|
||||||
}
|
}
|
||||||
@ -19,9 +23,8 @@ void http::auth::User::setPassword(const std::string &pass) {
|
|||||||
bool http::auth::User::checkPremisions(uint32_t p) const {
|
bool http::auth::User::checkPremisions(uint32_t p) const {
|
||||||
if (this->perms & SUPERUSER) {
|
if (this->perms & SUPERUSER) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return (this->perms & p) == p;
|
|
||||||
}
|
}
|
||||||
|
return (this->perms & p) == p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void http::auth::User::setPremisions(uint32_t p) {
|
void http::auth::User::setPremisions(uint32_t p) {
|
||||||
@ -73,3 +76,23 @@ std::shared_ptr<http::auth::User> http::auth::AuthProvider::getSession(const ser
|
|||||||
}
|
}
|
||||||
|
|
||||||
http::auth::AuthProvider::~AuthProvider() = default;
|
http::auth::AuthProvider::~AuthProvider() = default;
|
||||||
|
|
||||||
|
http::auth::AuthRequiredResource::AuthRequiredResource(const std::string &path, AuthProvider& provider, resource::respGenerator generator):
|
||||||
|
BasicResource(path), provider_(provider), generator_(std::move(generator)), perms(User::SUPERUSER) {}
|
||||||
|
|
||||||
|
http::auth::AuthRequiredResource::AuthRequiredResource(const std::string &path, AuthProvider& provider, uint32_t perms, resource::respGenerator generator):
|
||||||
|
BasicResource(path), provider_(provider), generator_(std::move(generator)), perms(perms) {}
|
||||||
|
|
||||||
|
void http::auth::AuthRequiredResource::handle(const server::Request &req, server::Reply &rep) {
|
||||||
|
if (auto user = this->provider_.getSession(req)) {
|
||||||
|
if (user->checkPremisions(this->perms)) {
|
||||||
|
this->generator_(req, rep);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
stockReply(server::forbidden, rep);
|
||||||
|
} else {
|
||||||
|
stockReply(server::unauthorized, rep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
http::auth::AuthRequiredResource::~AuthRequiredResource() = default;
|
||||||
|
@ -16,12 +16,20 @@ namespace http::auth {
|
|||||||
std::string passwordHash;
|
std::string passwordHash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Конструктор пользователя.
|
* Конструктор пользователя. По-умолчанию пользователь создается без прав, их нужно задать отдельной функцией.
|
||||||
* @param username Имя пользователя, он же - логин.
|
* @param username Имя пользователя, он же - логин.
|
||||||
* @param passwordHash Хеш sha256 пароля пользователя. Если передать пустой, то пароль будет сгенерирован такой же, как и имя пользователя.
|
* @param passwordHash Хеш sha256 пароля пользователя. Если передать пустой, то пароль будет сгенерирован такой же, как и имя пользователя.
|
||||||
*/
|
*/
|
||||||
explicit User(const std::string& username, const std::string& passwordHash = "");
|
explicit User(const std::string& username, const std::string& passwordHash = "");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Конструктор пользователя с указанными правами. Аналогично первому конструктору.
|
||||||
|
* @param username Имя пользователя, он же - логин.
|
||||||
|
* @param passwordHash Хеш sha256 пароля пользователя. Если передать пустой, то пароль будет сгенерирован такой же, как и имя пользователя.
|
||||||
|
* @param perms Права пользователя
|
||||||
|
*/
|
||||||
|
explicit User(const std::string& username, const std::string& passwordHash, uint32_t perms);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Проверить пароль на соответствие хешу
|
* Проверить пароль на соответствие хешу
|
||||||
* @param pass
|
* @param pass
|
||||||
@ -42,6 +50,7 @@ namespace http::auth {
|
|||||||
static constexpr uint32_t WATCH_SETTINGS = 0x0008; // просмотр настроек , если недоступно, то вкладки с настройками не будет
|
static constexpr uint32_t WATCH_SETTINGS = 0x0008; // просмотр настроек , если недоступно, то вкладки с настройками не будет
|
||||||
static constexpr uint32_t EDIT_SETTINGS = 0x0010; // редактирование настроек, установка параметров модулятора/демодулятора/dma/cinc
|
static constexpr uint32_t EDIT_SETTINGS = 0x0010; // редактирование настроек, установка параметров модулятора/демодулятора/dma/cinc
|
||||||
static constexpr uint32_t UPDATE_FIRMWARE = 0x0020; // обновление прошивки
|
static constexpr uint32_t UPDATE_FIRMWARE = 0x0020; // обновление прошивки
|
||||||
|
static constexpr uint32_t SETUP_QOS = 0x0040; // управление профилем QoS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Проверить, что у пользователя есть нужное право. Если это суперпользователь, то у него по умолчанию все права есть.
|
* Проверить, что у пользователя есть нужное право. Если это суперпользователь, то у него по умолчанию все права есть.
|
||||||
@ -79,17 +88,19 @@ namespace http::auth {
|
|||||||
~AuthProvider();
|
~AuthProvider();
|
||||||
};
|
};
|
||||||
|
|
||||||
class AuentificationRequiredResource final: public resource::BasicResource {
|
class AuthRequiredResource final: public resource::BasicResource {
|
||||||
public:
|
public:
|
||||||
explicit AuentificationRequiredResource(const std::string& path, std::shared_ptr<AuthProvider> provider, resource::respGenerator generator);
|
explicit AuthRequiredResource(const std::string& path, AuthProvider& provider, resource::respGenerator generator);
|
||||||
|
explicit AuthRequiredResource(const std::string& path, AuthProvider& provider, uint32_t perms, resource::respGenerator generator);
|
||||||
|
|
||||||
void handle(const server::Request &req, server::Reply &rep) override;
|
void handle(const server::Request &req, server::Reply &rep) override;
|
||||||
|
|
||||||
~AuentificationRequiredResource() override;
|
~AuthRequiredResource() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uint32_t perms;
|
||||||
resource::respGenerator generator_;
|
resource::respGenerator generator_;
|
||||||
std::shared_ptr<AuthProvider> provider_;
|
AuthProvider& provider_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
src/main.cpp
12
src/main.cpp
@ -98,7 +98,7 @@ public:
|
|||||||
|
|
||||||
ServerResources(): sf(std::make_unique<http::resource::StaticFileFactory>()), api(std::make_unique<api_driver::ApiDriver>()) {
|
ServerResources(): sf(std::make_unique<http::resource::StaticFileFactory>()), api(std::make_unique<api_driver::ApiDriver>()) {
|
||||||
api->startDaemon();
|
api->startDaemon();
|
||||||
auth.users.emplace_back(std::make_shared<http::auth::User>("admin"));
|
auth.users.emplace_back(std::make_shared<http::auth::User>("admin", "", http::auth::User::SUPERUSER));
|
||||||
|
|
||||||
sf->registerFile(FAVICON_ICO, mime_types::image_png, true);
|
sf->registerFile(FAVICON_ICO, mime_types::image_png, true);
|
||||||
sf->registerFile(KROKODIL_GIF, mime_types::image_gif, true);
|
sf->registerFile(KROKODIL_GIF, mime_types::image_gif, true);
|
||||||
@ -176,7 +176,7 @@ public:
|
|||||||
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/js/vue.js", [this](const auto& req, auto& rep) { boost::ignore_unused(req); sf->serve(VUE_JS, rep); }));
|
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/js/vue.js", [this](const auto& req, auto& rep) { boost::ignore_unused(req); sf->serve(VUE_JS, rep); }));
|
||||||
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/vid/video_2024-11-06_15-49-35.mp4", [this](const auto& req, auto& rep) { boost::ignore_unused(req); sf->serve(KB_MP4, rep); }));
|
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/vid/video_2024-11-06_15-49-35.mp4", [this](const auto& req, auto& rep) { boost::ignore_unused(req); sf->serve(KB_MP4, rep); }));
|
||||||
|
|
||||||
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/api/get/statistics", [this](const auto& req, auto& rep) {
|
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/get/statistics", this->auth, http::auth::User::WATCH_STATISTICS, [this](const auto& req, auto& rep) {
|
||||||
if (req.method != "GET") {
|
if (req.method != "GET") {
|
||||||
http::server::stockReply(http::server::bad_request, rep);
|
http::server::stockReply(http::server::bad_request, rep);
|
||||||
}
|
}
|
||||||
@ -190,7 +190,7 @@ public:
|
|||||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||||
}));
|
}));
|
||||||
|
|
||||||
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/api/get/settings", [this](const auto& req, auto& rep) {
|
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/get/settings", this->auth, http::auth::User::WATCH_SETTINGS, [this](const auto& req, auto& rep) {
|
||||||
if (req.method != "GET") {
|
if (req.method != "GET") {
|
||||||
http::server::stockReply(http::server::bad_request, rep);
|
http::server::stockReply(http::server::bad_request, rep);
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ public:
|
|||||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||||
}));
|
}));
|
||||||
|
|
||||||
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/api/resetPacketStatistics", [this](const auto& req, auto& rep) {
|
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/resetPacketStatistics", this->auth, http::auth::User::RESET_PACKET_STATISTICS, [this](const auto& req, auto& rep) {
|
||||||
if (req.method != "POST") {
|
if (req.method != "POST") {
|
||||||
http::server::stockReply(http::server::bad_request, rep);
|
http::server::stockReply(http::server::bad_request, rep);
|
||||||
}
|
}
|
||||||
@ -217,7 +217,7 @@ public:
|
|||||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||||
}));
|
}));
|
||||||
|
|
||||||
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/api/set/qos", [this](const auto& req, auto& rep) {
|
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/qos", this->auth, http::auth::User::SETUP_QOS, [this](const auto& req, auto& rep) {
|
||||||
if (req.method != "POST") {
|
if (req.method != "POST") {
|
||||||
http::server::stockReply(http::server::bad_request, rep);
|
http::server::stockReply(http::server::bad_request, rep);
|
||||||
}
|
}
|
||||||
@ -245,7 +245,7 @@ public:
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/api/set/bucLnb", [this](const auto& req, auto& rep) {
|
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/bucLnb", this->auth, http::auth::User::SUPERUSER, [this](const auto& req, auto& rep) {
|
||||||
if (req.method != "POST") {
|
if (req.method != "POST") {
|
||||||
http::server::stockReply(http::server::bad_request, rep);
|
http::server::stockReply(http::server::bad_request, rep);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user