feat : add structural validation rules to ConfigValidator
This commit is contained in:
parent
4f89a2918c
commit
dbc318cdfa
@ -1,5 +1,4 @@
|
|||||||
#include <webserv/config/validation/ConfigValidator.hpp>
|
#include <webserv/config/validation/ConfigValidator.hpp>
|
||||||
|
|
||||||
#include <webserv/config/validation/ValidationEngine.hpp> // for ValidationEngine
|
#include <webserv/config/validation/ValidationEngine.hpp> // for ValidationEngine
|
||||||
#include <webserv/config/validation/directive_rules/AValidationRule.hpp> // for AValidationRule
|
#include <webserv/config/validation/directive_rules/AValidationRule.hpp> // for AValidationRule
|
||||||
#include <webserv/config/validation/directive_rules/AllowedValuesRule.hpp> // for AllowedValuesRule
|
#include <webserv/config/validation/directive_rules/AllowedValuesRule.hpp> // for AllowedValuesRule
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
#include <webserv/config/validation/ValidationEngine.hpp>
|
|
||||||
|
|
||||||
#include <webserv/config/AConfig.hpp> // for AConfig
|
#include <webserv/config/AConfig.hpp> // for AConfig
|
||||||
#include <webserv/config/GlobalConfig.hpp> // for GlobalConfig
|
#include <webserv/config/GlobalConfig.hpp> // for GlobalConfig
|
||||||
#include <webserv/config/LocationConfig.hpp> // for LocationConfig
|
#include <webserv/config/LocationConfig.hpp> // for LocationConfig
|
||||||
#include <webserv/config/ServerConfig.hpp> // for ServerConfig
|
#include <webserv/config/ServerConfig.hpp> // for ServerConfig
|
||||||
|
#include <webserv/config/validation/ValidationEngine.hpp>
|
||||||
#include <webserv/config/validation/ValidationResult.hpp> // for ValidationResult
|
#include <webserv/config/validation/ValidationResult.hpp> // for ValidationResult
|
||||||
#include <webserv/config/validation/directive_rules/AValidationRule.hpp> // for AValidationRule
|
#include <webserv/config/validation/directive_rules/AValidationRule.hpp> // for AValidationRule
|
||||||
#include <webserv/log/Log.hpp> // for Log, LOCATION
|
#include <webserv/log/Log.hpp> // for Log, LOCATION
|
||||||
@ -31,7 +30,8 @@ void ValidationEngine::addLocationRule(const std::string &directiveName, std::un
|
|||||||
void ValidationEngine::addStructuralRule(std::unique_ptr<AStructuralValidationRule> rule)
|
void ValidationEngine::addStructuralRule(std::unique_ptr<AStructuralValidationRule> rule)
|
||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
if (rule != nullptr) {
|
if (rule != nullptr)
|
||||||
|
{
|
||||||
structuralRules_.push_back(std::move(rule));
|
structuralRules_.push_back(std::move(rule));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ std::vector<ValidationResult> ValidationEngine::getWarnings() const
|
|||||||
|
|
||||||
bool ValidationEngine::hasErrors() const
|
bool ValidationEngine::hasErrors() const
|
||||||
{
|
{
|
||||||
for (const auto &result : results_) //NOLINT(readability-use-anyofallof)
|
for (const auto &result : results_) // NOLINT(readability-use-anyofallof)
|
||||||
{
|
{
|
||||||
if (!result.isValidResult())
|
if (!result.isValidResult())
|
||||||
{
|
{
|
||||||
@ -122,20 +122,25 @@ void ValidationEngine::validateConfig(RuleMap const &rulesMap, const AConfig *co
|
|||||||
void ValidationEngine::validateLocationConfig(const std::string &path, const LocationConfig *config)
|
void ValidationEngine::validateLocationConfig(const std::string &path, const LocationConfig *config)
|
||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
|
|
||||||
// Run location structural validation rules
|
// Run location structural validation rules
|
||||||
for (const auto &rule : structuralRules_) {
|
for (const auto &rule : structuralRules_)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
ValidationResult result = rule->validateLocation(config);
|
ValidationResult result = rule->validateLocation(config);
|
||||||
if (!result.isValidResult()) {
|
if (!result.isValidResult())
|
||||||
|
{
|
||||||
results_.push_back(result);
|
results_.push_back(result);
|
||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
}
|
||||||
results_.push_back(ValidationResult::error(
|
catch (const std::exception &e)
|
||||||
"Structural rule '" + rule->getRuleName() + "' threw exception for location '" + path + "': " + e.what()));
|
{
|
||||||
|
results_.push_back(ValidationResult::error("Structural rule '" + rule->getRuleName() +
|
||||||
|
"' threw exception for location '" + path + "': " + e.what()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run location directive validation rules
|
// Run location directive validation rules
|
||||||
validateConfig(locationRules_, config);
|
validateConfig(locationRules_, config);
|
||||||
}
|
}
|
||||||
@ -143,23 +148,28 @@ void ValidationEngine::validateLocationConfig(const std::string &path, const Loc
|
|||||||
void ValidationEngine::validateServerConfig(const ServerConfig *config)
|
void ValidationEngine::validateServerConfig(const ServerConfig *config)
|
||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
|
|
||||||
// Run server structural validation rules
|
// Run server structural validation rules
|
||||||
for (const auto &rule : structuralRules_) {
|
for (const auto &rule : structuralRules_)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
ValidationResult result = rule->validateServer(config);
|
ValidationResult result = rule->validateServer(config);
|
||||||
if (!result.isValidResult()) {
|
if (!result.isValidResult())
|
||||||
|
{
|
||||||
results_.push_back(result);
|
results_.push_back(result);
|
||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
}
|
||||||
results_.push_back(ValidationResult::error(
|
catch (const std::exception &e)
|
||||||
"Structural rule '" + rule->getRuleName() + "' threw exception: " + e.what()));
|
{
|
||||||
|
results_.push_back(
|
||||||
|
ValidationResult::error("Structural rule '" + rule->getRuleName() + "' threw exception: " + e.what()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run server directive validation rules
|
// Run server directive validation rules
|
||||||
validateConfig(serverRules_, config);
|
validateConfig(serverRules_, config);
|
||||||
|
|
||||||
for (const auto &path : config->getLocationPaths())
|
for (const auto &path : config->getLocationPaths())
|
||||||
{
|
{
|
||||||
const LocationConfig *locationConfig = config->getLocation(path);
|
const LocationConfig *locationConfig = config->getLocation(path);
|
||||||
@ -173,23 +183,28 @@ void ValidationEngine::validateServerConfig(const ServerConfig *config)
|
|||||||
void ValidationEngine::validateGlobalConfig(const GlobalConfig *config)
|
void ValidationEngine::validateGlobalConfig(const GlobalConfig *config)
|
||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
|
|
||||||
// Run global structural validation rules
|
// Run global structural validation rules
|
||||||
for (const auto &rule : structuralRules_) {
|
for (const auto &rule : structuralRules_)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
ValidationResult result = rule->validateGlobal(config);
|
ValidationResult result = rule->validateGlobal(config);
|
||||||
if (!result.isValidResult()) {
|
if (!result.isValidResult())
|
||||||
|
{
|
||||||
results_.push_back(result);
|
results_.push_back(result);
|
||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
}
|
||||||
results_.push_back(ValidationResult::error(
|
catch (const std::exception &e)
|
||||||
"Structural rule '" + rule->getRuleName() + "' threw exception: " + e.what()));
|
{
|
||||||
|
results_.push_back(
|
||||||
|
ValidationResult::error("Structural rule '" + rule->getRuleName() + "' threw exception: " + e.what()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run global directive validation rules
|
// Run global directive validation rules
|
||||||
validateConfig(globalRules_, config);
|
validateConfig(globalRules_, config);
|
||||||
|
|
||||||
for (const auto *serverConfig : config->getServerConfigs())
|
for (const auto *serverConfig : config->getServerConfigs())
|
||||||
{
|
{
|
||||||
validateServerConfig(serverConfig);
|
validateServerConfig(serverConfig);
|
||||||
@ -205,7 +220,7 @@ void ValidationEngine::validate()
|
|||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
results_.clear(); // Clear previous results
|
results_.clear(); // Clear previous results
|
||||||
|
|
||||||
if (globalConfig_ != nullptr)
|
if (globalConfig_ != nullptr)
|
||||||
{
|
{
|
||||||
validateGlobalConfig(globalConfig_);
|
validateGlobalConfig(globalConfig_);
|
||||||
|
|||||||
@ -4,8 +4,8 @@
|
|||||||
#include <webserv/config/GlobalConfig.hpp>
|
#include <webserv/config/GlobalConfig.hpp>
|
||||||
#include <webserv/config/LocationConfig.hpp>
|
#include <webserv/config/LocationConfig.hpp>
|
||||||
#include <webserv/config/ServerConfig.hpp>
|
#include <webserv/config/ServerConfig.hpp>
|
||||||
#include <webserv/config/validation/ValidationResult.hpp> // for ValidationResult
|
#include <webserv/config/validation/ValidationResult.hpp> // for ValidationResult
|
||||||
#include <webserv/config/validation/directive_rules/AValidationRule.hpp> // for AValidationRule
|
#include <webserv/config/validation/directive_rules/AValidationRule.hpp> // for AValidationRule
|
||||||
#include <webserv/config/validation/structural_rules/AStructuralValidationRule.hpp> // for AStructuralValidationRule
|
#include <webserv/config/validation/structural_rules/AStructuralValidationRule.hpp> // for AStructuralValidationRule
|
||||||
|
|
||||||
#include <map> // for map
|
#include <map> // for map
|
||||||
|
|||||||
@ -10,15 +10,17 @@ class LocationConfig;
|
|||||||
|
|
||||||
class AStructuralValidationRule
|
class AStructuralValidationRule
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string ruleName_;
|
std::string ruleName_;
|
||||||
std::string description_;
|
std::string description_;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AStructuralValidationRule(const std::string &ruleName, const std::string &description)
|
AStructuralValidationRule(const std::string &ruleName, const std::string &description)
|
||||||
: ruleName_(ruleName), description_(description) {}
|
: ruleName_(ruleName), description_(description)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~AStructuralValidationRule() = default;
|
virtual ~AStructuralValidationRule() = default;
|
||||||
|
|
||||||
AStructuralValidationRule(const AStructuralValidationRule &other) = delete;
|
AStructuralValidationRule(const AStructuralValidationRule &other) = delete;
|
||||||
@ -29,30 +31,24 @@ public:
|
|||||||
// Virtual validation methods - override as needed
|
// Virtual validation methods - override as needed
|
||||||
[[nodiscard]] virtual ValidationResult validateGlobal(const GlobalConfig *config) const
|
[[nodiscard]] virtual ValidationResult validateGlobal(const GlobalConfig *config) const
|
||||||
{
|
{
|
||||||
static_cast<void>(config); // Suppress unused parameter warning
|
static_cast<void>(config); // Suppress unused parameter warning
|
||||||
return ValidationResult::success(); // Default: no global validation
|
return ValidationResult::success(); // Default: no global validation
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] virtual ValidationResult validateServer(const ServerConfig *config) const
|
[[nodiscard]] virtual ValidationResult validateServer(const ServerConfig *config) const
|
||||||
{
|
{
|
||||||
static_cast<void>(config); // Suppress unused parameter warning
|
static_cast<void>(config); // Suppress unused parameter warning
|
||||||
return ValidationResult::success(); // Default: no server validation
|
return ValidationResult::success(); // Default: no server validation
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] virtual ValidationResult validateLocation(const LocationConfig *config) const
|
[[nodiscard]] virtual ValidationResult validateLocation(const LocationConfig *config) const
|
||||||
{
|
{
|
||||||
static_cast<void>(config); // Suppress unused parameter warning
|
static_cast<void>(config); // Suppress unused parameter warning
|
||||||
return ValidationResult::success(); // Default: no location validation
|
return ValidationResult::success(); // Default: no location validation
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-virtual getters - set in constructor
|
// Non-virtual getters - set in constructor
|
||||||
[[nodiscard]] std::string getRuleName() const
|
[[nodiscard]] std::string getRuleName() const { return ruleName_; }
|
||||||
{
|
|
||||||
return ruleName_;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::string getDescription() const
|
[[nodiscard]] std::string getDescription() const { return description_; }
|
||||||
{
|
|
||||||
return description_;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
@ -6,8 +6,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
MinimumServerBlocksRule::MinimumServerBlocksRule(size_t minimumServers)
|
MinimumServerBlocksRule::MinimumServerBlocksRule(size_t minimumServers)
|
||||||
: AStructuralValidationRule("MinimumServerBlocksRule",
|
: AStructuralValidationRule("MinimumServerBlocksRule", "Ensures global config has at least " +
|
||||||
"Ensures global config has at least " + std::to_string(minimumServers) + " server block(s)"),
|
std::to_string(minimumServers) + " server block(s)"),
|
||||||
minimumServers_(minimumServers)
|
minimumServers_(minimumServers)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -16,16 +16,17 @@ ValidationResult MinimumServerBlocksRule::validateGlobal(const GlobalConfig *con
|
|||||||
{
|
{
|
||||||
Log::trace(LOCATION);
|
Log::trace(LOCATION);
|
||||||
|
|
||||||
if (config == nullptr) {
|
if (config == nullptr)
|
||||||
|
{
|
||||||
return ValidationResult::error("Global config is null");
|
return ValidationResult::error("Global config is null");
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t serverCount = config->getServerConfigs().size();
|
size_t serverCount = config->getServerConfigs().size();
|
||||||
|
|
||||||
if (serverCount < minimumServers_) {
|
if (serverCount < minimumServers_)
|
||||||
return ValidationResult::error(
|
{
|
||||||
"Global configuration must have at least " + std::to_string(minimumServers_) +
|
return ValidationResult::error("Global configuration must have at least " + std::to_string(minimumServers_) +
|
||||||
" server block(s), but found " + std::to_string(serverCount));
|
" server block(s), but found " + std::to_string(serverCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ValidationResult::success();
|
return ValidationResult::success();
|
||||||
|
|||||||
@ -8,10 +8,10 @@ class GlobalConfig;
|
|||||||
|
|
||||||
class MinimumServerBlocksRule : public AStructuralValidationRule
|
class MinimumServerBlocksRule : public AStructuralValidationRule
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
size_t minimumServers_;
|
size_t minimumServers_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MinimumServerBlocksRule(size_t minimumServers = 1);
|
explicit MinimumServerBlocksRule(size_t minimumServers = 1);
|
||||||
|
|
||||||
~MinimumServerBlocksRule() override = default;
|
~MinimumServerBlocksRule() override = default;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user