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" | #pragma ide diagnostic ignored "readability-convert-member-functions-to-static" | ||||||
|  |  | ||||||
| #include <chrono> | #include <chrono> | ||||||
| #include <iomanip> | #include <filesystem> | ||||||
|  | #include <fstream> | ||||||
|  |  | ||||||
| #include <botan/argon2.h> |  | ||||||
| #include <botan/uuid.h> | #include <botan/uuid.h> | ||||||
| #include <botan/totp.h> | #include <botan/totp.h> | ||||||
|  |  | ||||||
| @@ -76,7 +76,7 @@ namespace api { | |||||||
|                 .set_payload_claim("jti", picojson::value((int64_t)new_token.getValueOfId())) |                 .set_payload_claim("jti", picojson::value((int64_t)new_token.getValueOfId())) | ||||||
|                 .set_issued_at(std::chrono::system_clock::from_time_t(iat.count())) |                 .set_issued_at(std::chrono::system_clock::from_time_t(iat.count())) | ||||||
|                 .set_expires_at(std::chrono::system_clock::from_time_t(exp.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) { |     void auth::generate_root(db::User& user) { | ||||||
| @@ -91,6 +91,20 @@ namespace api { | |||||||
|         db::MapperToken token_mapper(drogon::app().getDbClient()); |         db::MapperToken token_mapper(drogon::app().getDbClient()); | ||||||
|          token_mapper.deleteBy(db::Criteria(db::Token::Cols::_owner_id, db::CompareOps::EQ, user.getValueOfId())); |          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 | #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; |         std::stringstream ss; | ||||||
|         ss << config::get_url() << "/oauth/authorize" |         ss << config::get_url() << "/oauth/authorize" | ||||||
|            << "?redirect_uri=" << get_redirect_uri() |            << "?redirect_uri=" << get_redirect_uri() | ||||||
| @@ -91,7 +91,7 @@ namespace api { | |||||||
|         cbk(drogon::HttpResponse::newRedirectionResponse(ss.str())); |         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); |         auto tokens =  get_gitlab_tokens(code, false); | ||||||
|         if (!tokens.has_value()) |         if (!tokens.has_value()) | ||||||
|             return cbk(dto::Responses::get_unauth_res("Invalid code")); |             return cbk(dto::Responses::get_unauth_res("Invalid code")); | ||||||
|   | |||||||
| @@ -67,6 +67,7 @@ public: | |||||||
|     static std::string get_token(const db::User&); |     static std::string get_token(const db::User&); | ||||||
|     static void generate_root(db::User&); |     static void generate_root(db::User&); | ||||||
|     static void revoke_all(const db::User&); |     static void revoke_all(const db::User&); | ||||||
|  |     static std::string get_jwt_secret(); | ||||||
|  |  | ||||||
|     void gitlab(req_type, cbk_type); |     void gitlab(req_type, cbk_type); | ||||||
|     void gitlab_callback(req_type, cbk_type, std::string code); |     void gitlab_callback(req_type, cbk_type, std::string code); | ||||||
|   | |||||||
| @@ -10,8 +10,6 @@ | |||||||
| #include "Tokens.h" | #include "Tokens.h" | ||||||
| #include "User.h" | #include "User.h" | ||||||
|  |  | ||||||
| const std::string jwt_secret = "CUM"; |  | ||||||
|  |  | ||||||
| namespace db { | namespace db { | ||||||
|     enum UserRole : int { |     enum UserRole : int { | ||||||
|         ADMIN = 2, |         ADMIN = 2, | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ void Login::doFilter(const drogon::HttpRequestPtr& req, drogon::FilterCallback&& | |||||||
|     try { |     try { | ||||||
|         auto token = jwt::decode<jwt::traits::kazuho_picojson>(token_str); |         auto token = jwt::decode<jwt::traits::kazuho_picojson>(token_str); | ||||||
|         jwt::verify<jwt::traits::kazuho_picojson>() |         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); |                 .verify(token); | ||||||
|         uint64_t token_id = token.get_payload_claim("jti").as_int(); |         uint64_t token_id = token.get_payload_claim("jti").as_int(); | ||||||
|         uint64_t user_id = token.get_payload_claim("sub").as_int(); |         uint64_t user_id = token.get_payload_claim("sub").as_int(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user