fix configuration check regresion

This commit is contained in:
Bartosz Wieczorek 2025-06-04 09:05:49 +02:00
parent 19e117e39b
commit 65e3a5a73c
2 changed files with 28 additions and 12 deletions

View File

@ -84,10 +84,10 @@ class ConfigurationReader {
} }
// Load values into Configuration object, with defaults provided // Load values into Configuration object, with defaults provided
tl::expected< bool, ConfigurationError > applyTo(Configuration & config) { tl::expected< bool, ConfigurationError > applyTo(Configuration & config) const {
// Helper lambdas for conversion
using string = std::pmr::string; using string = std::pmr::string;
// Helper lambdas for conversion
auto getStringOpt = [&](const string & key) -> std::optional< std::pmr::string > { auto getStringOpt = [&](const string & key) -> std::optional< std::pmr::string > {
auto it = keyValues.find(key); auto it = keyValues.find(key);
if(it == keyValues.end()) { if(it == keyValues.end()) {
@ -98,8 +98,12 @@ class ConfigurationReader {
auto getStringReq = [&](const string & key) -> tl::expected< std::pmr::string, ConfigurationError > { auto getStringReq = [&](const string & key) -> tl::expected< std::pmr::string, ConfigurationError > {
auto val = getStringOpt(key); auto val = getStringOpt(key);
if(val.has_value()) if(val.has_value()) {
if(val->empty()) {
return tl::unexpected{ConfigurationError::ErrorClass::RequiredValueEmpty};
}
return std::move(val.value()); return std::move(val.value());
}
return tl::unexpected{ConfigurationError::ErrorClass::RequiredValueNotFound}; return tl::unexpected{ConfigurationError::ErrorClass::RequiredValueNotFound};
}; };
@ -145,6 +149,14 @@ class ConfigurationReader {
return std::nullopt; return std::nullopt;
}; };
/// NOTE:
// getStringOpt can return a valid empty string, for example configuration entry like
// option=
// will return a optional<string> val which contains empty string.
// getStringReq on the other hand, returns error in case when
// * configuration is not found -> RequiredValueNotFound
// * configuration value is empty -> RequiredValueEmpty
// Reading required fields // Reading required fields
if(auto val = getStringReq("systemToken"); not val.has_value()) if(auto val = getStringReq("systemToken"); not val.has_value())
return tl::unexpected{val.error()}; return tl::unexpected{val.error()};
@ -161,7 +173,7 @@ class ConfigurationReader {
else else
config.apiServer = std::move(val.value()); config.apiServer = std::move(val.value());
// optional // optional configuration options
config.prompt = getInt("prompt").value_or(1); config.prompt = getInt("prompt").value_or(1);
config.enablePasswdEmail = getBool("enablePasswdEmail").value_or(true); config.enablePasswdEmail = getBool("enablePasswdEmail").value_or(true);
config.logging = getBool("logging").value_or(true); config.logging = getBool("logging").value_or(true);
@ -174,12 +186,12 @@ class ConfigurationReader {
config.proxyType = getStringOpt("proxyType"); config.proxyType = getStringOpt("proxyType");
config.proxyServer = getStringOpt("proxyServer"); config.proxyServer = getStringOpt("proxyServer");
if(config.proxyEnabled) { if(config.proxyEnabled) {
if(not config.proxyType) { if(not config.proxyType or config.proxyType->empty()) {
log(LogLevel::Error, "Proxy is enabled but proxy type is not set"); log(LogLevel::Error, "Proxy is enabled but proxy type is not present or empty");
return tl::unexpected{ConfigurationError::ErrorClass::BadConfiguration}; return tl::unexpected{ConfigurationError::ErrorClass::BadConfiguration};
} }
if(not config.proxyServer) { if(not config.proxyServer or config.proxyServer->empty()) {
log(LogLevel::Error, "Proxy is enabled but proxy server is not set"); log(LogLevel::Error, "Proxy is enabled but proxy server is not present or empty");
return tl::unexpected{ConfigurationError::ErrorClass::BadConfiguration}; return tl::unexpected{ConfigurationError::ErrorClass::BadConfiguration};
} }
} }
@ -187,12 +199,14 @@ class ConfigurationReader {
config.proxyUsername = getStringOpt("proxyUsername"); config.proxyUsername = getStringOpt("proxyUsername");
config.proxyPass = getStringOpt("proxyPass"); config.proxyPass = getStringOpt("proxyPass");
if(config.proxyAuthRequired) { if(config.proxyAuthRequired) {
if(not config.proxyUsername) { if(not config.proxyUsername or config.proxyUsername->empty()) {
log(LogLevel::Error, "Proxy auth is required but proxy proxy username is not set"); log(LogLevel::Error, "Proxy auth is required but proxy proxy username is not present or empty");
return tl::unexpected{ConfigurationError::ErrorClass::BadConfiguration}; return tl::unexpected{ConfigurationError::ErrorClass::BadConfiguration};
} }
if(not config.proxyPass) { if(not config.proxyPass) {
log(LogLevel::Error, "Proxy is enabled but proxy password is not set,"); log(LogLevel::Error,
"Proxy is enabled but proxy password is not present, "
"if no password is required add an empty entry to configuration file");
return tl::unexpected{ConfigurationError::ErrorClass::BadConfiguration}; return tl::unexpected{ConfigurationError::ErrorClass::BadConfiguration};
} }
} }

View File

@ -13,6 +13,7 @@ class ConfigurationError {
public: public:
enum class ErrorClass { // enum class ErrorClass { //
RequiredValueNotFound, RequiredValueNotFound,
RequiredValueEmpty,
BadFailMode, BadFailMode,
BadInput, BadInput,
BadConfiguration, BadConfiguration,
@ -20,6 +21,7 @@ class ConfigurationError {
}; };
constexpr static auto errorClassPrettyName = make_array< std::string_view >( // constexpr static auto errorClassPrettyName = make_array< std::string_view >( //
"RequiredValueNotFound", "RequiredValueNotFound",
"RequiredValueEmpty",
"BadFailMode", "BadFailMode",
"BadInput", "BadInput",
"BadConfiguration", "BadConfiguration",