#include "resources.h" #include #include #include #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::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::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;