99 lines
3.6 KiB
C++
99 lines
3.6 KiB
C++
#include "resources.h"
|
|
#include <boost/log/trivial.hpp>
|
|
#include <boost/algorithm/string.hpp>
|
|
#include <utility>
|
|
#include "jwt.h"
|
|
#include "utils.h"
|
|
|
|
|
|
http::auth::User::User(const std::string &username, const std::string &passwordHash): username(username),
|
|
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 {
|
|
return utils::sha256(pass) == passwordHash;
|
|
}
|
|
|
|
void http::auth::User::setPassword(const std::string &pass) {
|
|
this->passwordHash = utils::sha256(pass);
|
|
}
|
|
|
|
bool http::auth::User::checkPremisions(uint32_t p) const {
|
|
if (this->perms & SUPERUSER) {
|
|
return true;
|
|
}
|
|
return (this->perms & p) == p;
|
|
}
|
|
|
|
void http::auth::User::setPremisions(uint32_t p) {
|
|
if (p & SUPERUSER) {
|
|
this->perms = SUPERUSER;
|
|
} else {
|
|
this->perms |= p;
|
|
}
|
|
}
|
|
|
|
void http::auth::User::resetPremisions(uint32_t p) {
|
|
this->perms &= p;
|
|
}
|
|
|
|
http::auth::User::~User() = default;
|
|
|
|
|
|
http::auth::AuthProvider::AuthProvider() = default;
|
|
|
|
std::shared_ptr<http::auth::User> http::auth::AuthProvider::doAuth(const std::string &username, const std::string &password, server::Reply &rep) {
|
|
for (const auto& u: users) {
|
|
if (u->username == username) {
|
|
if (u->checkPassword(password)) {
|
|
auto t = jwt::Jwt::fromUser(u->username);
|
|
rep.headers.push_back({.name = "Set-Cookie", .value = t.asCookie()});
|
|
return u;
|
|
}
|
|
BOOST_LOG_TRIVIAL(warning) << "http::auth::AuthProvider::doAuth(): Failed to login " << username << ", password: " << password << " (incorrect password)";
|
|
return nullptr;
|
|
}
|
|
}
|
|
BOOST_LOG_TRIVIAL(warning) << "http::auth::AuthProvider::doAuth(): Failed to login " << username << ", password: " << password << " (user not found)";
|
|
return nullptr;
|
|
}
|
|
|
|
std::shared_ptr<http::auth::User> http::auth::AuthProvider::getSession(const server::Request &req) {
|
|
auto t = jwt::Jwt::fromCookies(req.getHeaderValue("cookie"));
|
|
if (t.isValid()) {
|
|
const auto name = t.getUsername();
|
|
// токен валидный, ищем юзера
|
|
for (auto& u: users) {
|
|
if (u->username == name) {
|
|
return u;
|
|
}
|
|
}
|
|
BOOST_LOG_TRIVIAL(warning) << "http::auth::AuthProvider::getSession(): Found valid session for a non-existent user " << name;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
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;
|