terminal-web-server/src/auth/resources.cpp

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;