From 9ef6b9430c0795fc6e46ef6307a9660f162a691c Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sun, 24 Mar 2024 15:17:19 +0200 Subject: [PATCH] feat(secret): hide db password --- Cargo.lock | 11 +++++++++++ Cargo.toml | 1 + src/configuation.rs | 32 +++++++++++++++++--------------- src/main.rs | 3 ++- tests/health_check.rs | 8 ++++---- 5 files changed, 35 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6107a16..c993b12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1653,6 +1653,16 @@ dependencies = [ "untrusted", ] +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "serde", + "zeroize", +] + [[package]] name = "security-framework" version = "2.9.2" @@ -2867,6 +2877,7 @@ dependencies = [ "config", "once_cell", "reqwest", + "secrecy", "serde", "sqlx", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 69f1c95..1ccefab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ tracing-subscriber = { version = "0.3", features = ["registry", "env-filter"] } tower-http = { version = "0.5", features = ["trace"] } tracing-bunyan-formatter = "0.3" tracing-log = "0.2" +secrecy = { version = "0.8", features = ["serde"] } [dev-dependencies] reqwest = "0.12" diff --git a/src/configuation.rs b/src/configuation.rs index 660f9af..0010c41 100644 --- a/src/configuation.rs +++ b/src/configuation.rs @@ -1,5 +1,4 @@ -use std::fmt::Display; - +use secrecy::{ExposeSecret, Secret}; use serde::Deserialize; #[derive(Debug, Deserialize)] @@ -11,28 +10,31 @@ pub struct Settings { #[derive(Debug, Deserialize)] pub struct DatabaseSettings { pub username: String, - pub password: String, + pub password: Secret, pub port: u16, pub host: String, pub database_name: String, } impl DatabaseSettings { - pub fn to_string_no_db(&self) -> String { - format!( + pub fn to_string_no_db(&self) -> Secret { + Secret::new(format!( "postgres://{}:{}@{}:{}", - self.username, self.password, self.host, self.port - ) + self.username, + self.password.expose_secret(), + self.host, + self.port + )) } -} - -impl Display for DatabaseSettings { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, + pub fn to_string(&self) -> Secret { + Secret::new(format!( "postgres://{}:{}@{}:{}/{}", - self.username, self.password, self.host, self.port, self.database_name - ) + self.username, + self.password.expose_secret(), + self.host, + self.port, + self.database_name + )) } } diff --git a/src/main.rs b/src/main.rs index bcfb6f1..0f0e5fe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ use std::net::SocketAddr; +use secrecy::ExposeSecret; use sqlx::postgres::PgPoolOptions; use tokio::net::TcpListener; use zero2prod::{ @@ -14,7 +15,7 @@ async fn main() -> Result<(), std::io::Error> { init_subscriber(subscriber); let configuation = get_configuration().expect("Failed to read configuation."); let pool = PgPoolOptions::new() - .connect(&configuation.database.to_string()) + .connect(&configuation.database.to_string().expose_secret()) .await .expect("Failed to connect to Postgres."); let addr = SocketAddr::from(([127, 0, 0, 1], configuation.application_port)); diff --git a/tests/health_check.rs b/tests/health_check.rs index 4123564..0508b81 100644 --- a/tests/health_check.rs +++ b/tests/health_check.rs @@ -1,5 +1,6 @@ use once_cell::sync::Lazy; use reqwest::Client; +use secrecy::ExposeSecret; use sqlx::{postgres::PgPoolOptions, Connection, Executor, PgConnection, PgPool}; use tokio::net::TcpListener; use uuid::Uuid; @@ -28,8 +29,7 @@ async fn health_check() { async fn subscribe_returns_200_for_valid_form_data() { let app = spawn_app().await; let configuration = get_configuration().expect("Failed to read configuration."); - let db_url = configuration.database.to_string(); - let mut connection = PgConnection::connect(&db_url) + let mut connection = PgConnection::connect(&configuration.database.to_string().expose_secret()) .await .expect("Failed to connect to Postgres."); let client = Client::new(); @@ -120,7 +120,7 @@ async fn spawn_app() -> TestApp { } async fn configure_database(config: &DatabaseSettings) -> PgPool { - let mut connection = PgConnection::connect(&config.to_string_no_db()) + let mut connection = PgConnection::connect(&config.to_string_no_db().expose_secret()) .await .expect("Failed to connect to Postgres."); @@ -138,7 +138,7 @@ async fn configure_database(config: &DatabaseSettings) -> PgPool { .expect("Failed to create database."); let pool = PgPoolOptions::new() - .connect(&config.to_string()) + .connect(&config.to_string().expose_secret()) .await .expect("Failed to connect to Postgres.");