Merge branch '23-config-file' into 'main'

Resolve "Config file"

Closes #23

See merge request root/fileserver!10
This commit is contained in:
Mutzi 2022-09-04 08:35:51 +00:00
commit e0c52ad645
6 changed files with 101 additions and 25 deletions

View File

@ -0,0 +1,11 @@
{
"gitlab_id": "",
"gitlab_secret": "",
"gitlab_url": "",
"gitlab_api_url": "",
"gitlab_redirect_url": "",
"smtp_server": "",
"smtp_port": 25,
"smtp_user": "",
"smtp_password": ""
}

View File

@ -21,7 +21,6 @@
#include "controllers/controllers.h" #include "controllers/controllers.h"
#include "db/db.h" #include "db/db.h"
#include "dto/dto.h"
namespace api { namespace api {
@ -43,15 +42,17 @@ namespace api {
char totp[16]; char totp[16];
std::snprintf(totp, 16, "%06d", Botan::TOTP(Botan::OctetString(totp_secret)).generate_totp(t)); std::snprintf(totp, 16, "%06d", Botan::TOTP(Botan::OctetString(totp_secret)).generate_totp(t));
auto config = drogon::app().getCustomConfig();
drogon::app().getPlugin<SMTPMail>()->sendEmail( drogon::app().getPlugin<SMTPMail>()->sendEmail(
"mail.mattv.de", config["smtp_server"].asString(),
587, (uint16_t)config["smtp_port"].asUInt64(),
"fileserver@mattv.de", "fileserver@mattv.de",
user.getValueOfName(), user.getValueOfName(),
"MFileserver - Email 2fa code", "MFileserver - Email 2fa code",
"Your code is: " + std::string(totp) +"\r\nIt is valid for 5 Minutes", "Your code is: " + std::string(totp) +"\r\nIt is valid for 5 Minutes",
"no-reply@mattv.de", config["smtp_user"].asString(),
"noreplyLONGPASS123", config["smtp_password"].asString(),
false false
); );
} }

View File

@ -6,34 +6,49 @@
#include "controllers/controllers.h" #include "controllers/controllers.h"
#include "dto/dto.h" #include "dto/dto.h"
const std::string GITLAB_ID = "98bcbad78cb1f880d1d1de62291d70a791251a7bea077bfe7df111ef3c115760"; namespace config {
const std::string GITLAB_SECRET = "7ee01d2b204aff3a05f9d028f004d169b6d381ec873e195f314b3935fa150959"; std::string get_id() {
const std::string GITLAB_URL = "https://gitlab.mattv.de"; static std::string val = drogon::app().getCustomConfig()["gitlab_id"].asString();
const std::string GITLAB_API_URL = "https://ssh.gitlab.mattv.de"; return val;
}
std::string get_secret() {
static std::string val = drogon::app().getCustomConfig()["gitlab_secret"].asString();
return val;
}
std::string get_url() {
static std::string val = drogon::app().getCustomConfig()["gitlab_url"].asString();
return val;
}
std::string get_api_url() {
static std::string val = drogon::app().getCustomConfig()["gitlab_api_url"].asString();
return val;
}
std::string get_redirect_url() {
static std::string val = drogon::app().getCustomConfig()["gitlab_redirect_url"].asString();
return val;
}
}
std::string get_redirect_uri(req_type req) { std::string get_redirect_uri() {
auto host_header = req->headers().find("host");
std::stringstream ss; std::stringstream ss;
ss << (req->path().starts_with("127") ? (req->isOnSecureConnection() ? "https" : "http") : "https") ss << config::get_redirect_url()
<< "://"
<< (host_header != req->headers().end() ? host_header->second : "127.0.0.1:2345")
<< "/api/auth/gitlab_callback"; << "/api/auth/gitlab_callback";
return drogon::utils::urlEncode(ss.str()); return drogon::utils::urlEncode(ss.str());
} }
const drogon::HttpClientPtr& get_gitlab_client() { const drogon::HttpClientPtr& get_gitlab_client() {
static drogon::HttpClientPtr client = drogon::HttpClient::newHttpClient(GITLAB_API_URL, drogon::app().getLoop(), false, false); static drogon::HttpClientPtr client = drogon::HttpClient::newHttpClient(config::get_api_url(), drogon::app().getLoop(), false, false);
return client; return client;
} }
namespace api { namespace api {
std::optional<auth::gitlab_tokens> auth::get_gitlab_tokens(req_type req, const std::string& code_or_token, bool token) { std::optional<auth::gitlab_tokens> auth::get_gitlab_tokens(const std::string& code_or_token, bool token) {
std::stringstream ss; std::stringstream ss;
ss << "/oauth/token" ss << "/oauth/token"
<< "?redirect_uri=" << get_redirect_uri(req) << "?redirect_uri=" << get_redirect_uri()
<< "&client_id=" << GITLAB_ID << "&client_id=" << config::get_id()
<< "&client_secret=" << GITLAB_SECRET << "&client_secret=" << config::get_secret()
<< (token ? "&refresh_token=" : "&code=") << code_or_token << (token ? "&refresh_token=" : "&code=") << code_or_token
<< "&grant_type=" << (token ? "refresh_token" : "authorization_code"); << "&grant_type=" << (token ? "refresh_token" : "authorization_code");
auto gitlab_req = drogon::HttpRequest::newHttpRequest(); auto gitlab_req = drogon::HttpRequest::newHttpRequest();
@ -69,15 +84,15 @@ namespace api {
void auth::gitlab(req_type req, cbk_type cbk) { void auth::gitlab(req_type req, cbk_type cbk) {
std::stringstream ss; std::stringstream ss;
ss << GITLAB_URL << "/oauth/authorize" ss << config::get_url() << "/oauth/authorize"
<< "?redirect_uri=" << get_redirect_uri(req) << "?redirect_uri=" << get_redirect_uri()
<< "&client_id=" << GITLAB_ID << "&client_id=" << config::get_id()
<< "&scope=read_user&response_type=code"; << "&scope=read_user&response_type=code";
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 req, cbk_type cbk, std::string code) {
auto tokens = get_gitlab_tokens(req, 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"));
auto info = get_gitlab_user(tokens->at); auto info = get_gitlab_user(tokens->at);

View File

@ -60,7 +60,7 @@ public:
static std::unique_ptr<Botan::RNG> rng; static std::unique_ptr<Botan::RNG> rng;
static std::optional<gitlab_tokens> get_gitlab_tokens(req_type, const std::string&, bool token); static std::optional<gitlab_tokens> get_gitlab_tokens(const std::string&, bool token);
static std::optional<gitlab_user> get_gitlab_user(const std::string&); static std::optional<gitlab_user> get_gitlab_user(const std::string&);
static bool verify2fa(const db::User&, uint32_t totp); static bool verify2fa(const db::User&, uint32_t totp);
static void send_mail(const db::User&); static void send_mail(const db::User&);

View File

@ -48,7 +48,7 @@ void Login::doFilter(const drogon::HttpRequestPtr& req, drogon::FilterCallback&&
if (db_user.getValueOfGitlab() != 0) { if (db_user.getValueOfGitlab() != 0) {
auto info = api::auth::get_gitlab_user(db_user.getValueOfGitlabAt()); auto info = api::auth::get_gitlab_user(db_user.getValueOfGitlabAt());
if (!info.has_value()) { if (!info.has_value()) {
auto tokens = api::auth::get_gitlab_tokens(req, db_user.getValueOfGitlabRt(), true); auto tokens = api::auth::get_gitlab_tokens(db_user.getValueOfGitlabRt(), true);
info = api::auth::get_gitlab_user(tokens->at); info = api::auth::get_gitlab_user(tokens->at);
if (!tokens.has_value() || !info.has_value()) { if (!tokens.has_value() || !info.has_value()) {
api::auth::revoke_all(db_user); api::auth::revoke_all(db_user);

View File

@ -121,6 +121,55 @@ int main(int argc, char* argv[]) {
config["plugins"].append(access_logger); config["plugins"].append(access_logger);
config["plugins"].append(smtp_mail); config["plugins"].append(smtp_mail);
if (!std::filesystem::exists("config.json")) {
std::cerr << "config.json missing" << std::endl;
return 1;
}
std::ifstream config_file("config.json");
config_file >> config["custom_config"];
if (!config["custom_config"].isObject()) {
std::cerr << "config.json must be an object" << std::endl;
return 1;
}
if (!config["custom_config"].isMember("gitlab_id")) {
std::cerr << "config.json missing gitlab_id" << std::endl;
return 1;
}
if (!config["custom_config"].isMember("gitlab_secret")) {
std::cerr << "config.json missing gitlab_secret" << std::endl;
return 1;
}
if (!config["custom_config"].isMember("gitlab_url")) {
std::cerr << "config.json missing gitlab_url" << std::endl;
return 1;
}
if (!config["custom_config"].isMember("gitlab_api_url")) {
std::cerr << "config.json missing gitlab_api_url" << std::endl;
return 1;
}
if (!config["custom_config"].isMember("gitlab_redirect_url")) {
std::cerr << "config.json missing gitlab_redirect_url" << std::endl;
return 1;
}
if (!config["custom_config"].isMember("smtp_server")) {
std::cerr << "config.json missing smtp_server" << std::endl;
return 1;
}
if (!config["custom_config"].isMember("smtp_port")) {
std::cerr << "config.json missing smtp_port" << std::endl;
return 1;
}
if (!config["custom_config"].isMember("smtp_user")) {
std::cerr << "config.json missing smtp_user" << std::endl;
return 1;
}
if (!config["custom_config"].isMember("smtp_password")) {
std::cerr << "config.json missing smtp_password" << std::endl;
return 1;
}
drogon::app() drogon::app()
.setClientMaxBodySize(std::numeric_limits<size_t>::max()) .setClientMaxBodySize(std::numeric_limits<size_t>::max())