Skip to content

Commit d7dfc3b

Browse files
committed
feat: [#978] add semantic validation for configuration
The section [core.provate_mode] can be inlcuded in the configration TOML file only if the tracker is running in private mode (`private = true`). This commits adds that validation and makes it possible to add more semantic validations in the future. Semantic validations are validations that depend on more than one value. Like the one added, it could be any other incompatible combination.
1 parent e8e935c commit d7dfc3b

File tree

6 files changed

+48
-1
lines changed

6 files changed

+48
-1
lines changed

packages/configuration/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//!
66
//! The current version for configuration is [`v2`].
77
pub mod v2;
8+
pub mod validator;
89

910
use std::collections::HashMap;
1011
use std::env;

packages/configuration/src/v2/core.rs

+11
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};
33

44
use super::network::Network;
55
use crate::v2::database::Database;
6+
use crate::validator::{SemanticValidationError, Validator};
67
use crate::{AnnouncePolicy, TrackerPolicy};
78

89
#[allow(clippy::struct_excessive_bools)]
@@ -131,3 +132,13 @@ impl PrivateMode {
131132
true
132133
}
133134
}
135+
136+
impl Validator for Core {
137+
fn validate(&self) -> Result<(), SemanticValidationError> {
138+
if self.private_mode.is_some() && !self.private {
139+
return Err(SemanticValidationError::UselessPrivateModeSection);
140+
}
141+
142+
Ok(())
143+
}
144+
}

packages/configuration/src/v2/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ use self::health_check_api::HealthCheckApi;
251251
use self::http_tracker::HttpTracker;
252252
use self::tracker_api::HttpApi;
253253
use self::udp_tracker::UdpTracker;
254+
use crate::validator::{SemanticValidationError, Validator};
254255
use crate::{Error, Info, Metadata, Version};
255256

256257
/// This configuration version
@@ -394,6 +395,12 @@ impl Configuration {
394395
}
395396
}
396397

398+
impl Validator for Configuration {
399+
fn validate(&self) -> Result<(), SemanticValidationError> {
400+
self.core.validate()
401+
}
402+
}
403+
397404
#[cfg(test)]
398405
mod tests {
399406

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//! Trait to validate semantic errors.
2+
//!
3+
//! Errors could involve more than one configuration option. Some configuration
4+
//! combinations can be incompatible.
5+
use thiserror::Error;
6+
7+
/// Errors that can occur validating the configuration.
8+
#[derive(Error, Debug)]
9+
pub enum SemanticValidationError {
10+
#[error("Private mode section in configuration can only be included when the tracker is running in private mode.")]
11+
UselessPrivateModeSection,
12+
}
13+
14+
pub trait Validator {
15+
/// # Errors
16+
///
17+
/// Will return an error if the configuration is invalid.
18+
fn validate(&self) -> Result<(), SemanticValidationError>;
19+
}

src/bootstrap/app.rs

+9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use std::sync::Arc;
1515

1616
use torrust_tracker_clock::static_time;
17+
use torrust_tracker_configuration::validator::Validator;
1718
use torrust_tracker_configuration::Configuration;
1819
use tracing::info;
1920

@@ -24,10 +25,18 @@ use crate::core::Tracker;
2425
use crate::shared::crypto::ephemeral_instance_keys;
2526

2627
/// It loads the configuration from the environment and builds the main domain [`Tracker`] struct.
28+
///
29+
/// # Panics
30+
///
31+
/// Setup can file if the configuration is invalid.
2732
#[must_use]
2833
pub fn setup() -> (Configuration, Arc<Tracker>) {
2934
let configuration = initialize_configuration();
3035

36+
if let Err(e) = configuration.validate() {
37+
panic!("Configuration error: {e}");
38+
}
39+
3140
let tracker = initialize_with_configuration(&configuration);
3241

3342
info!("Configuration:\n{}", configuration.clone().mask_secrets().to_json());

src/core/auth.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! Tracker keys are tokens used to authenticate the tracker clients when the tracker runs
55
//! in `private` or `private_listed` modes.
66
//!
7-
//! There are services to [`generate_key`] and [`verify_key`] authentication keys.
7+
//! There are services to [`generate_key`] and [`verify_key_expiration`] authentication keys.
88
//!
99
//! Authentication keys are used only by [`HTTP`](crate::servers::http) trackers. All keys have an expiration time, that means
1010
//! they are only valid during a period of time. After that time the expiring key will no longer be valid.

0 commit comments

Comments
 (0)