Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/configuration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ thiserror = "1"
toml = "0"
torrust-tracker-located-error = { version = "3.0.0-alpha.12-develop", path = "../located-error" }
torrust-tracker-primitives = { version = "3.0.0-alpha.12-develop", path = "../primitives" }
url = "2.5.2"

[dev-dependencies]
uuid = { version = "1", features = ["v4"] }
4 changes: 2 additions & 2 deletions packages/configuration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub type AccessTokens = HashMap<String, String>;
pub const LATEST_VERSION: &str = "2";

/// Info about the configuration specification.
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Display)]
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Display, Clone)]
pub struct Metadata {
#[serde(default = "Metadata::default_version")]
#[serde(flatten)]
Expand All @@ -70,7 +70,7 @@ impl Metadata {
}

/// The configuration version.
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Display)]
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Display, Clone)]
pub struct Version {
#[serde(default = "Version::default_semver")]
version: String,
Expand Down
41 changes: 40 additions & 1 deletion packages/configuration/src/v2/database.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use serde::{Deserialize, Serialize};
use torrust_tracker_primitives::DatabaseDriver;
use url::Url;

#[allow(clippy::struct_excessive_bools)]
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
Expand All @@ -13,7 +14,7 @@ pub struct Database {
/// For `Sqlite3`, the format is `path/to/database.db`, for example:
/// `./storage/tracker/lib/database/sqlite3.db`.
/// For `Mysql`, the format is `mysql://db_user:db_user_password:port/db_name`, for
/// example: `root:password@localhost:3306/torrust`.
/// example: `mysql://root:password@localhost:3306/torrust`.
#[serde(default = "Database::default_path")]
pub path: String,
}
Expand All @@ -35,4 +36,42 @@ impl Database {
fn default_path() -> String {
String::from("./storage/tracker/lib/database/sqlite3.db")
}

/// Masks secrets in the configuration.
///
/// # Panics
///
/// Will panic if the database path for `MySQL` is not a valid URL.
pub fn mask_secrets(&mut self) {
match self.driver {
DatabaseDriver::Sqlite3 => {
// Nothing to mask
}
DatabaseDriver::MySQL => {
let mut url = Url::parse(&self.path).expect("path for MySQL driver should be a valid URL");
url.set_password(Some("***")).expect("url password should be changed");
self.path = url.to_string();
}
}
}
}

#[cfg(test)]
mod tests {

use torrust_tracker_primitives::DatabaseDriver;

use super::Database;

#[test]
fn it_should_allow_masking_the_mysql_user_password() {
let mut database = Database {
driver: DatabaseDriver::MySQL,
path: "mysql://root:password@localhost:3306/torrust".to_string(),
};

database.mask_secrets();

assert_eq!(database.path, "mysql://root:***@localhost:3306/torrust".to_string());
}
}
14 changes: 13 additions & 1 deletion packages/configuration/src/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ const CONFIG_OVERRIDE_PREFIX: &str = "TORRUST_TRACKER_CONFIG_OVERRIDE_";
const CONFIG_OVERRIDE_SEPARATOR: &str = "__";

/// Core configuration for the tracker.
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default)]
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default, Clone)]
pub struct Configuration {
/// Configuration metadata.
#[serde(flatten)]
Expand Down Expand Up @@ -380,6 +380,18 @@ impl Configuration {
// code-review: do we need to use Figment also to serialize into json?
serde_json::to_string_pretty(self).expect("Could not encode JSON value")
}

/// Masks secrets in the configuration.
#[must_use]
pub fn mask_secrets(mut self) -> Self {
self.core.database.mask_secrets();

if let Some(ref mut api) = self.http_api {
api.mask_secrets();
}

self
}
}

#[cfg(test)]
Expand Down
6 changes: 6 additions & 0 deletions packages/configuration/src/v2/tracker_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ impl HttpApi {
pub fn override_admin_token(&mut self, api_admin_token: &str) {
self.access_tokens.insert("admin".to_string(), api_admin_token.to_string());
}

pub fn mask_secrets(&mut self) {
for token in self.access_tokens.values_mut() {
*token = "***".to_string();
}
}
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub fn setup() -> (Configuration, Arc<Tracker>) {

let tracker = initialize_with_configuration(&configuration);

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

(configuration, tracker)
}
Expand Down