Rewrote backend in c++

This commit is contained in:
2022-08-28 17:37:09 +02:00
parent d199ecae87
commit 2e8877837a
98 changed files with 14078 additions and 1433 deletions

View File

@@ -0,0 +1,82 @@
#include "filters.h"
#include <drogon/utils/coroutine.h>
#include <jwt-cpp/traits/kazuho-picojson/traits.h>
#include <jwt-cpp/jwt.h>
#include "db/db.h"
#include "dto/dto.h"
#include "controllers/controllers.h"
void cleanup_tokens(db::MapperToken& mapper) {
const uint64_t now = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
mapper.deleteBy(
db::Criteria(db::Token::Cols::_exp, db::CompareOps::LE, now)
);
}
void Login::doFilter(const drogon::HttpRequestPtr& req, drogon::FilterCallback&& cb, drogon::FilterChainCallback&& ccb) {
std::string token_str;
if (req->path() == "/api/fs/download") {
token_str = req->getParameter("jwtToken");
} else {
std::string auth_header = req->getHeader("Authorization");
if (auth_header.empty() || (!auth_header.starts_with("Bearer ")))
return cb(dto::Responses::get_unauth_res("Unauthorized"));
token_str = auth_header.substr(7);
}
try {
auto token = jwt::decode<jwt::traits::kazuho_picojson>(token_str);
jwt::verify<jwt::traits::kazuho_picojson>()
.allow_algorithm(jwt::algorithm::hs256{jwt_secret})
.verify(token);
uint64_t token_id = token.get_payload_claim("jti").as_int();
uint64_t user_id = token.get_payload_claim("sub").as_int();
auto db = drogon::app().getDbClient();
db::MapperUser user_mapper(db);
db::MapperToken token_mapper(db);
cleanup_tokens(token_mapper);
db::Token db_token = token_mapper.findByPrimaryKey(token_id);
db::User db_user = user_mapper.findByPrimaryKey(db_token.getValueOfOwnerId());
if (db_user.getValueOfId() != user_id) throw std::exception();
if (db::User_getEnumRole(db_user) == db::UserRole::DISABLED) throw std::exception();
if (db_user.getValueOfGitlab() != 0) {
auto info = api::auth::get_gitlab_user(db_user.getValueOfGitlabAt());
if (!info.has_value()) {
auto tokens = api::auth::get_gitlab_tokens(req, db_user.getValueOfGitlabRt(), true);
info = api::auth::get_gitlab_user(tokens->at);
if (!tokens.has_value() || !info.has_value()) {
api::auth::revoke_all(db_user);
throw std::exception();
}
db_user.setGitlabAt(tokens->at);
db_user.setGitlabRt(tokens->rt);
user_mapper.update(db_user);
}
if (info->name != db_user.getValueOfName()) {
api::auth::revoke_all(db_user);
throw std::exception();
}
}
req->attributes()->insert("token", db_token);
req->attributes()->insert("user", db_user);
ccb();
} catch (const std::exception&) {
cb(dto::Responses::get_unauth_res("Unauthorized"));
}
}
void Admin::doFilter(const drogon::HttpRequestPtr& req, drogon::FilterCallback&& cb, drogon::FilterChainCallback&& ccb) {
db::User user = dto::get_user(req);
if (db::User_getEnumRole(user) != db::UserRole::ADMIN)
cb(dto::Responses::get_forbdn_res("Forbidden"));
else
ccb();
}

View File

@@ -0,0 +1,14 @@
#ifndef BACKEND_FILTERS_H
#define BACKEND_FILTERS_H
#include <drogon/HttpFilter.h>
struct Login : public drogon::HttpFilter<Login> {
void doFilter(const drogon::HttpRequestPtr&, drogon::FilterCallback&&, drogon::FilterChainCallback&&) override;
};
struct Admin : public drogon::HttpFilter<Admin> {
void doFilter(const drogon::HttpRequestPtr&, drogon::FilterCallback&&, drogon::FilterChainCallback&&) override;
};
#endif //BACKEND_FILTERS_H