mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2025-07-01 23:46:59 +00:00
rework identity to be more modular and less shit
This commit is contained in:
parent
d141bf346c
commit
874f381d43
@ -73,6 +73,7 @@ set(PRJ_LIBRARIES
|
|||||||
Boost::iostreams
|
Boost::iostreams
|
||||||
Boost::thread
|
Boost::thread
|
||||||
Boost::filesystem
|
Boost::filesystem
|
||||||
|
Boost::outcome
|
||||||
cryptopp::cryptopp
|
cryptopp::cryptopp
|
||||||
ZLIB::ZLIB
|
ZLIB::ZLIB
|
||||||
OpenSSL::SSL
|
OpenSSL::SSL
|
||||||
@ -86,7 +87,7 @@ find_package(fmt CONFIG REQUIRED)
|
|||||||
find_package(doctest CONFIG REQUIRED)
|
find_package(doctest CONFIG REQUIRED)
|
||||||
find_package(spdlog CONFIG REQUIRED)
|
find_package(spdlog CONFIG REQUIRED)
|
||||||
find_package(httplib CONFIG REQUIRED)
|
find_package(httplib CONFIG REQUIRED)
|
||||||
find_package(Boost REQUIRED COMPONENTS system iostreams thread filesystem)
|
find_package(Boost REQUIRED COMPONENTS system iostreams thread filesystem outcome)
|
||||||
find_package(cryptopp CONFIG REQUIRED)
|
find_package(cryptopp CONFIG REQUIRED)
|
||||||
find_package(ZLIB REQUIRED)
|
find_package(ZLIB REQUIRED)
|
||||||
find_package(OpenSSL REQUIRED)
|
find_package(OpenSSL REQUIRED)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
#include "Http.h"
|
#include "Http.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <fmt/core.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
@ -113,3 +114,95 @@ std::string Identity::login(const std::string& fields) {
|
|||||||
d.erase("public_key");
|
d.erase("public_key");
|
||||||
return d.dump();
|
return d.dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<ident::Identity, std::string> ident::login_cached() noexcept {
|
||||||
|
std::string private_key;
|
||||||
|
try {
|
||||||
|
std::ifstream key_file(ident::KEYFILE);
|
||||||
|
if (key_file.is_open()) {
|
||||||
|
auto size = fs::file_size(ident::KEYFILE);
|
||||||
|
key_file.read(&private_key[0], static_cast<long>(size));
|
||||||
|
key_file.close();
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
return fmt::format("Failed to read cached key: {}", e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string pk_json {};
|
||||||
|
|
||||||
|
try {
|
||||||
|
pk_json = nlohmann::json {
|
||||||
|
{ "pk", private_key }
|
||||||
|
}.dump();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
spdlog::error("Private key had invalid format, please log in again.");
|
||||||
|
return std::string("Invalid login saved, please log in again.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return detail::login(pk_json);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ident::is_login_cached() noexcept {
|
||||||
|
return std::filesystem::exists(KEYFILE) && std::filesystem::is_regular_file(KEYFILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<ident::Identity, std::string> ident::login(const std::string& username_or_email, const std::string& password) {
|
||||||
|
std::string login_json {};
|
||||||
|
|
||||||
|
try {
|
||||||
|
login_json = nlohmann::json {
|
||||||
|
{ "username", username_or_email },
|
||||||
|
{ "password", password },
|
||||||
|
}
|
||||||
|
.dump();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
spdlog::error("Username or password has invalid format, please try again.");
|
||||||
|
return std::string("Username or password contain illegal characters, please try again.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return detail::login(login_json);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ident::detail::cache_key(const std::string& private_key) noexcept {
|
||||||
|
try {
|
||||||
|
std::ofstream key_file(ident::KEYFILE, std::ios::trunc);
|
||||||
|
key_file << private_key;
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
spdlog::warn("Failed to cache key - login will not be remembered: {}", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Result<ident::Identity, std::string> ident::detail::login(const std::string& json_params, bool remember) noexcept {
|
||||||
|
auto result = HTTP::Post("https://auth.beammp.com/userlogin", json_params);
|
||||||
|
|
||||||
|
nlohmann::json json = nlohmann::json::parse(result, nullptr, false);
|
||||||
|
|
||||||
|
if (result == "-1" || result.at(0) != '{' || json.is_discarded()) {
|
||||||
|
spdlog::error("auth.beammp.com failed to respond with valid user details");
|
||||||
|
spdlog::trace("auth.beammp.com/userlogin responded with: {}", result);
|
||||||
|
return std::string("Invalid answer from auth server. Please check your internet connection and see if you can reach https://beammp.com.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (json["success"].get<bool>()) {
|
||||||
|
spdlog::info("{}", json["message"].get<std::string>());
|
||||||
|
ident::Identity id {
|
||||||
|
.PublicKey = json["public_key"].get<std::string>(),
|
||||||
|
.PrivateKey = json["private_key"].get<std::string>(),
|
||||||
|
.Role = json["role"].get<std::string>(),
|
||||||
|
.Username = json["username"].get<std::string>(),
|
||||||
|
.Message = json["message"].get<std::string>(),
|
||||||
|
};
|
||||||
|
if (remember) {
|
||||||
|
cache_key(id.PrivateKey);
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
} else {
|
||||||
|
spdlog::info("Auto-Authentication unsuccessful please re-login!");
|
||||||
|
return std::string("Failed to auto-login with saved details, please login again.");
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
spdlog::error("Incomplete or invalid answer from auth servers. Please try logging in again.");
|
||||||
|
spdlog::trace("auth.beammp.com/userlogin responded with incomplete data: {}", result);
|
||||||
|
return std::string("Failed to auto-login with saved details, because the auth server responded with invalid details.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,19 +1,34 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <filesystem>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "Result.h"
|
||||||
|
|
||||||
|
namespace ident {
|
||||||
|
|
||||||
|
constexpr const char* KEYFILE = "key";
|
||||||
|
|
||||||
struct Identity {
|
struct Identity {
|
||||||
Identity();
|
|
||||||
|
|
||||||
void check_local_key();
|
|
||||||
|
|
||||||
bool LoginAuth { false };
|
|
||||||
std::string PublicKey {};
|
std::string PublicKey {};
|
||||||
std::string PrivateKey {};
|
std::string PrivateKey {};
|
||||||
std::string Role {};
|
std::string Role {};
|
||||||
std::string Username {};
|
std::string Username {};
|
||||||
|
std::string Message {};
|
||||||
std::string login(const std::string& fields);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void update_key(const char* newKey);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Whether a login is cached / remembered
|
||||||
|
bool is_login_cached() noexcept;
|
||||||
|
|
||||||
|
Result<Identity, std::string> login_cached() noexcept;
|
||||||
|
|
||||||
|
Result<Identity, std::string> login(const std::string& username_or_email, const std::string& password);
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
Result<Identity, std::string> login(const std::string& json_params, bool remember) noexcept;
|
||||||
|
|
||||||
|
void cache_key(const std::string& private_key) noexcept;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
"boost-iostreams",
|
"boost-iostreams",
|
||||||
"boost-process",
|
"boost-process",
|
||||||
"boost-thread",
|
"boost-thread",
|
||||||
|
"boost-outcome",
|
||||||
"nlohmann-json",
|
"nlohmann-json",
|
||||||
"cryptopp",
|
"cryptopp",
|
||||||
"zstd"
|
"zstd"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user