Skip to content

Commit c747321

Browse files
committed
Merge #951: Config overhaul: remove secrets when final config is printed to console
4673514 fix: [#948] mask secrets in logs (Jose Celano) 16aa652 chore(deps): add url dependency (Jose Celano) Pull request description: When the tracker is started, the final configuration is printed out. This feature was added in #935. This PR masks the secrets with asterics. ACKs for top commit: josecelano: ACK 4673514 Tree-SHA512: 59d064ac361333cbb089a7a72ab95cb579c17a41dc9efe67a44290d7a1c44a002e9d7d541808e881b9e274a555da432579e937a7d0db12eb5122840e263229e5
2 parents 1e891f1 + 4673514 commit c747321

File tree

7 files changed

+64
-5
lines changed

7 files changed

+64
-5
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/configuration/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ thiserror = "1"
2525
toml = "0"
2626
torrust-tracker-located-error = { version = "3.0.0-alpha.12-develop", path = "../located-error" }
2727
torrust-tracker-primitives = { version = "3.0.0-alpha.12-develop", path = "../primitives" }
28+
url = "2.5.2"
2829

2930
[dev-dependencies]
3031
uuid = { version = "1", features = ["v4"] }

packages/configuration/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub type AccessTokens = HashMap<String, String>;
4848
pub const LATEST_VERSION: &str = "2";
4949

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

7272
/// The configuration version.
73-
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Display)]
73+
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Display, Clone)]
7474
pub struct Version {
7575
#[serde(default = "Version::default_semver")]
7676
version: String,

packages/configuration/src/v2/database.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use serde::{Deserialize, Serialize};
22
use torrust_tracker_primitives::DatabaseDriver;
3+
use url::Url;
34

45
#[allow(clippy::struct_excessive_bools)]
56
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
@@ -13,7 +14,7 @@ pub struct Database {
1314
/// For `Sqlite3`, the format is `path/to/database.db`, for example:
1415
/// `./storage/tracker/lib/database/sqlite3.db`.
1516
/// For `Mysql`, the format is `mysql://db_user:db_user_password:port/db_name`, for
16-
/// example: `root:password@localhost:3306/torrust`.
17+
/// example: `mysql://root:password@localhost:3306/torrust`.
1718
#[serde(default = "Database::default_path")]
1819
pub path: String,
1920
}
@@ -35,4 +36,42 @@ impl Database {
3536
fn default_path() -> String {
3637
String::from("./storage/tracker/lib/database/sqlite3.db")
3738
}
39+
40+
/// Masks secrets in the configuration.
41+
///
42+
/// # Panics
43+
///
44+
/// Will panic if the database path for `MySQL` is not a valid URL.
45+
pub fn mask_secrets(&mut self) {
46+
match self.driver {
47+
DatabaseDriver::Sqlite3 => {
48+
// Nothing to mask
49+
}
50+
DatabaseDriver::MySQL => {
51+
let mut url = Url::parse(&self.path).expect("path for MySQL driver should be a valid URL");
52+
url.set_password(Some("***")).expect("url password should be changed");
53+
self.path = url.to_string();
54+
}
55+
}
56+
}
57+
}
58+
59+
#[cfg(test)]
60+
mod tests {
61+
62+
use torrust_tracker_primitives::DatabaseDriver;
63+
64+
use super::Database;
65+
66+
#[test]
67+
fn it_should_allow_masking_the_mysql_user_password() {
68+
let mut database = Database {
69+
driver: DatabaseDriver::MySQL,
70+
path: "mysql://root:password@localhost:3306/torrust".to_string(),
71+
};
72+
73+
database.mask_secrets();
74+
75+
assert_eq!(database.path, "mysql://root:***@localhost:3306/torrust".to_string());
76+
}
3877
}

packages/configuration/src/v2/mod.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ const CONFIG_OVERRIDE_PREFIX: &str = "TORRUST_TRACKER_CONFIG_OVERRIDE_";
263263
const CONFIG_OVERRIDE_SEPARATOR: &str = "__";
264264

265265
/// Core configuration for the tracker.
266-
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default)]
266+
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default, Clone)]
267267
pub struct Configuration {
268268
/// Configuration metadata.
269269
#[serde(flatten)]
@@ -380,6 +380,18 @@ impl Configuration {
380380
// code-review: do we need to use Figment also to serialize into json?
381381
serde_json::to_string_pretty(self).expect("Could not encode JSON value")
382382
}
383+
384+
/// Masks secrets in the configuration.
385+
#[must_use]
386+
pub fn mask_secrets(mut self) -> Self {
387+
self.core.database.mask_secrets();
388+
389+
if let Some(ref mut api) = self.http_api {
390+
api.mask_secrets();
391+
}
392+
393+
self
394+
}
383395
}
384396

385397
#[cfg(test)]

packages/configuration/src/v2/tracker_api.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ impl HttpApi {
6161
pub fn override_admin_token(&mut self, api_admin_token: &str) {
6262
self.access_tokens.insert("admin".to_string(), api_admin_token.to_string());
6363
}
64+
65+
pub fn mask_secrets(&mut self) {
66+
for token in self.access_tokens.values_mut() {
67+
*token = "***".to_string();
68+
}
69+
}
6470
}
6571

6672
#[cfg(test)]

src/bootstrap/app.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub fn setup() -> (Configuration, Arc<Tracker>) {
3030

3131
let tracker = initialize_with_configuration(&configuration);
3232

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

3535
(configuration, tracker)
3636
}

0 commit comments

Comments
 (0)