diff --git a/.gitignore b/.gitignore index e63cca3..89e5bab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,9 @@ .env.local config.yaml +/secret/* /files/* !/files/.gitkeep +/build/* +!/build/.gitkeep /target +fly.toml diff --git a/build/.gitkeep b/build/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/fedimovies-cli/src/main.rs b/fedimovies-cli/src/main.rs index f8e601e..ff351fd 100644 --- a/fedimovies-cli/src/main.rs +++ b/fedimovies-cli/src/main.rs @@ -25,7 +25,7 @@ async fn main() { } let db_config = config.database_url.parse().unwrap(); - let db_client = &mut create_database_client(&db_config).await; + let db_client = &mut create_database_client(&db_config, config.tls_ca_file.as_ref().map(|p| p.as_path())).await; apply_migrations(db_client).await; match subcmd { diff --git a/fedimovies-config/src/config.rs b/fedimovies-config/src/config.rs index b994f60..0db6280 100644 --- a/fedimovies-config/src/config.rs +++ b/fedimovies-config/src/config.rs @@ -33,6 +33,8 @@ pub struct Config { // Core settings pub database_url: String, + #[serde(default)] + pub tls_ca_file: Option, pub storage_dir: PathBuf, pub web_client_dir: Option, diff --git a/fedimovies-models/Cargo.toml b/fedimovies-models/Cargo.toml index fda98a7..69aae0a 100644 --- a/fedimovies-models/Cargo.toml +++ b/fedimovies-models/Cargo.toml @@ -27,6 +27,8 @@ thiserror = "1.0.37" # Async runtime tokio = { version = "1.20.4", features = [] } # Used for working with Postgresql database +openssl = { version = "0.10", features = ["vendored"] } +postgres-openssl = "0.5.0" tokio-postgres = { version = "0.7.6", features = ["with-chrono-0_4", "with-uuid-1", "with-serde_json-1"] } postgres-types = { version = "0.2.3", features = ["derive", "with-chrono-0_4", "with-uuid-1", "with-serde_json-1"] } postgres-protocol = "0.6.4" @@ -38,7 +40,6 @@ uuid = { version = "1.1.2", features = ["serde", "v4"] } [dev-dependencies] fedimovies-utils = { path = "../fedimovies-utils", features = ["test-utils"] } - serial_test = "0.7.0" [features] diff --git a/fedimovies-models/src/database/mod.rs b/fedimovies-models/src/database/mod.rs index 71caf00..a8b707f 100644 --- a/fedimovies-models/src/database/mod.rs +++ b/fedimovies-models/src/database/mod.rs @@ -1,3 +1,7 @@ +use deadpool_postgres::SslMode; +use openssl::ssl::{SslConnector, SslMethod}; +use postgres_openssl::MakeTlsConnector; +use std::path::Path; use tokio_postgres::config::Config as DatabaseConfig; use tokio_postgres::error::{Error as PgError, SqlState}; @@ -11,6 +15,7 @@ pub mod test_utils; pub type DbPool = deadpool_postgres::Pool; pub use tokio_postgres::GenericClient as DatabaseClient; +use tokio_postgres::NoTls; #[derive(thiserror::Error, Debug)] #[error("database type error")] @@ -37,21 +42,49 @@ pub enum DatabaseError { AlreadyExists(&'static str), // object type } -pub async fn create_database_client(db_config: &DatabaseConfig) -> tokio_postgres::Client { - let (client, connection) = db_config.connect(tokio_postgres::NoTls).await.unwrap(); - tokio::spawn(async move { - if let Err(err) = connection.await { - log::error!("connection error: {}", err); - }; - }); +pub async fn create_database_client( + db_config: &DatabaseConfig, + ca_file_path: Option<&Path>, +) -> tokio_postgres::Client { + let client = if let Some(ca_file_path) = ca_file_path { + let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); + log::debug!("Using TLS CA file: {}", ca_file_path.display()); + builder.set_ca_file(ca_file_path).unwrap(); + let connector = MakeTlsConnector::new(builder.build()); + let (client, connection) = db_config.connect(connector).await.unwrap(); + tokio::spawn(async move { + if let Err(err) = connection.await { + log::error!("connection with tls error: {}", err); + }; + }); + client + } else { + let (client, connection) = db_config.connect(tokio_postgres::NoTls).await.unwrap(); + tokio::spawn(async move { + if let Err(err) = connection.await { + log::error!("connection error: {}", err); + }; + }); + client + }; + client } -pub fn create_pool(database_url: &str, pool_size: usize) -> DbPool { - let manager = deadpool_postgres::Manager::new( - database_url.parse().expect("invalid database URL"), - tokio_postgres::NoTls, - ); +pub fn create_pool(database_url: &str, ca_file_path: Option<&Path>, pool_size: usize) -> DbPool { + let manager = if let Some(ca_file_path) = ca_file_path { + let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); + log::info!("Using TLS CA file: {}", ca_file_path.display()); + builder.set_ca_file(ca_file_path).unwrap(); + let connector = MakeTlsConnector::new(builder.build()); + deadpool_postgres::Manager::new( + database_url.parse().expect("invalid database URL"), + connector, + ) + } else { + deadpool_postgres::Manager::new(database_url.parse().expect("invalid database URL"), NoTls) + }; + DbPool::builder(manager) .max_size(pool_size) .build() diff --git a/src/main.rs b/src/main.rs index 6e05b6d..689374e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,7 +44,11 @@ async fn main() -> std::io::Result<()> { // https://wiki.postgresql.org/wiki/Number_Of_Database_Connections let db_pool_size = num_cpus::get() * 2; - let db_pool = create_pool(&config.database_url, db_pool_size); + let db_pool = create_pool( + &config.database_url, + config.tls_ca_file.as_ref().map(|s| s.as_path()), + db_pool_size, + ); let mut db_client = get_database_client(&db_pool).await.unwrap(); apply_migrations(&mut db_client).await;