Generate jwt secret on first start instead of hardcoded secret
Closes #26
This commit is contained in:
		@@ -3,9 +3,9 @@
 | 
			
		||||
#pragma ide diagnostic ignored "readability-convert-member-functions-to-static"
 | 
			
		||||
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <iomanip>
 | 
			
		||||
#include <filesystem>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
 | 
			
		||||
#include <botan/argon2.h>
 | 
			
		||||
#include <botan/uuid.h>
 | 
			
		||||
#include <botan/totp.h>
 | 
			
		||||
 | 
			
		||||
@@ -76,7 +76,7 @@ namespace api {
 | 
			
		||||
                .set_payload_claim("jti", picojson::value((int64_t)new_token.getValueOfId()))
 | 
			
		||||
                .set_issued_at(std::chrono::system_clock::from_time_t(iat.count()))
 | 
			
		||||
                .set_expires_at(std::chrono::system_clock::from_time_t(exp.count()))
 | 
			
		||||
                .sign(jwt::algorithm::hs256{jwt_secret});
 | 
			
		||||
                .sign(jwt::algorithm::hs256{get_jwt_secret()});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void auth::generate_root(db::User& user) {
 | 
			
		||||
@@ -91,6 +91,20 @@ namespace api {
 | 
			
		||||
        db::MapperToken token_mapper(drogon::app().getDbClient());
 | 
			
		||||
         token_mapper.deleteBy(db::Criteria(db::Token::Cols::_owner_id, db::CompareOps::EQ, user.getValueOfId()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string auth::get_jwt_secret() {
 | 
			
		||||
        static std::string token;
 | 
			
		||||
        if (token.empty()) {
 | 
			
		||||
            if (!std::filesystem::exists("jwt.secret")) {
 | 
			
		||||
                auto new_token = rng->random_vec(128);
 | 
			
		||||
                std::ofstream file("jwt.secret", std::ofstream::binary);
 | 
			
		||||
                file.write((const char*)new_token.data(), (std::streamsize)new_token.size());
 | 
			
		||||
            }
 | 
			
		||||
            std::ifstream file("jwt.secret", std::ifstream::binary);
 | 
			
		||||
            token = {std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()};
 | 
			
		||||
        }
 | 
			
		||||
        return token;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma clang diagnostic pop
 | 
			
		||||
 
 | 
			
		||||
@@ -82,7 +82,7 @@ namespace api {
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void auth::gitlab(req_type req, cbk_type cbk) {
 | 
			
		||||
    void auth::gitlab(req_type, cbk_type cbk) {
 | 
			
		||||
        std::stringstream ss;
 | 
			
		||||
        ss << config::get_url() << "/oauth/authorize"
 | 
			
		||||
           << "?redirect_uri=" << get_redirect_uri()
 | 
			
		||||
@@ -91,7 +91,7 @@ namespace api {
 | 
			
		||||
        cbk(drogon::HttpResponse::newRedirectionResponse(ss.str()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void auth::gitlab_callback(req_type req, cbk_type cbk, std::string code) {
 | 
			
		||||
    void auth::gitlab_callback(req_type, cbk_type cbk, std::string code) {
 | 
			
		||||
        auto tokens =  get_gitlab_tokens(code, false);
 | 
			
		||||
        if (!tokens.has_value())
 | 
			
		||||
            return cbk(dto::Responses::get_unauth_res("Invalid code"));
 | 
			
		||||
 
 | 
			
		||||
@@ -67,6 +67,7 @@ public:
 | 
			
		||||
    static std::string get_token(const db::User&);
 | 
			
		||||
    static void generate_root(db::User&);
 | 
			
		||||
    static void revoke_all(const db::User&);
 | 
			
		||||
    static std::string get_jwt_secret();
 | 
			
		||||
 | 
			
		||||
    void gitlab(req_type, cbk_type);
 | 
			
		||||
    void gitlab_callback(req_type, cbk_type, std::string code);
 | 
			
		||||
 
 | 
			
		||||
@@ -10,8 +10,6 @@
 | 
			
		||||
#include "Tokens.h"
 | 
			
		||||
#include "User.h"
 | 
			
		||||
 | 
			
		||||
const std::string jwt_secret = "CUM";
 | 
			
		||||
 | 
			
		||||
namespace db {
 | 
			
		||||
    enum UserRole : int {
 | 
			
		||||
        ADMIN = 2,
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ void Login::doFilter(const drogon::HttpRequestPtr& req, drogon::FilterCallback&&
 | 
			
		||||
    try {
 | 
			
		||||
        auto token = jwt::decode<jwt::traits::kazuho_picojson>(token_str);
 | 
			
		||||
        jwt::verify<jwt::traits::kazuho_picojson>()
 | 
			
		||||
                .allow_algorithm(jwt::algorithm::hs256{jwt_secret})
 | 
			
		||||
                .allow_algorithm(jwt::algorithm::hs256{api::auth::get_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();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user