chore: bootstrap independent git workflow
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
13
crates/db-config/Cargo.toml
Normal file
13
crates/db-config/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "db-config"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
db-core.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
123
crates/db-config/src/lib.rs
Normal file
123
crates/db-config/src/lib.rs
Normal file
@@ -0,0 +1,123 @@
|
||||
use db_core::{ConnectionTarget, CoreError};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct ConnectionProfile {
|
||||
pub name: String,
|
||||
pub target: ConnectionTarget,
|
||||
pub password_env_var: Option<String>,
|
||||
}
|
||||
|
||||
impl ConnectionProfile {
|
||||
pub fn new(
|
||||
name: impl Into<String>,
|
||||
target: ConnectionTarget,
|
||||
password_env_var: Option<String>,
|
||||
) -> Result<Self, CoreError> {
|
||||
let profile = Self {
|
||||
name: name.into(),
|
||||
target,
|
||||
password_env_var,
|
||||
};
|
||||
|
||||
profile.validate()?;
|
||||
Ok(profile)
|
||||
}
|
||||
|
||||
pub fn validate(&self) -> Result<(), CoreError> {
|
||||
if self.name.trim().is_empty() {
|
||||
return Err(CoreError::InvalidConnection("profile name is empty"));
|
||||
}
|
||||
|
||||
self.target.validate()
|
||||
}
|
||||
|
||||
pub fn redacted_summary(&self) -> String {
|
||||
match &self.password_env_var {
|
||||
Some(password_env_var) => format!(
|
||||
"{} via password env {}",
|
||||
self.target.redacted_endpoint(),
|
||||
password_env_var
|
||||
),
|
||||
None => self.target.redacted_endpoint(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_password(mut self, password: Option<String>) -> Self {
|
||||
self.target.password = password;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use db_core::{ConnectionTarget, ConnectionTransport, DatabaseKind};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn rejects_empty_profile_name() {
|
||||
let target = ConnectionTarget::new(
|
||||
DatabaseKind::Sqlite,
|
||||
ConnectionTransport::File {
|
||||
path: "demo.sqlite".into(),
|
||||
},
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.expect("target should be valid");
|
||||
|
||||
let result = ConnectionProfile::new(" ", target, None);
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
Err(CoreError::InvalidConnection("profile name is empty"))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn summary_mentions_password_env_without_secret() {
|
||||
let target = ConnectionTarget::new(
|
||||
DatabaseKind::Postgres,
|
||||
ConnectionTransport::Tcp {
|
||||
host: String::from("127.0.0.1"),
|
||||
port: 55432,
|
||||
},
|
||||
Some(String::from("dbtool_demo")),
|
||||
Some(String::from("dbtool")),
|
||||
)
|
||||
.expect("target should be valid");
|
||||
let profile =
|
||||
ConnectionProfile::new("local", target, Some(String::from("DBTOOL_PASSWORD")))
|
||||
.expect("profile should be valid");
|
||||
|
||||
assert_eq!(
|
||||
profile.redacted_summary(),
|
||||
"postgres://dbtool@127.0.0.1:55432/dbtool_demo via password env DBTOOL_PASSWORD"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn injects_password_without_changing_redacted_output() {
|
||||
let target = ConnectionTarget::new(
|
||||
DatabaseKind::Postgres,
|
||||
ConnectionTransport::Tcp {
|
||||
host: String::from("127.0.0.1"),
|
||||
port: 55432,
|
||||
},
|
||||
Some(String::from("dbtool_demo")),
|
||||
Some(String::from("dbtool")),
|
||||
)
|
||||
.expect("target should be valid");
|
||||
|
||||
let profile =
|
||||
ConnectionProfile::new("local", target, Some(String::from("DBTOOL_PASSWORD")))
|
||||
.expect("profile should be valid")
|
||||
.with_password(Some(String::from("secret")));
|
||||
|
||||
assert_eq!(profile.target.password.as_deref(), Some("secret"));
|
||||
assert_eq!(
|
||||
profile.redacted_summary(),
|
||||
"postgres://dbtool@127.0.0.1:55432/dbtool_demo via password env DBTOOL_PASSWORD"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user