Skip to content
Draft
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
11 changes: 6 additions & 5 deletions src/credentials.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@ impl CredentialRegistry {

/// Bootstrap administrator credentials plus an optional PostgreSQL DSN.
///
/// Precedence is per key: a non-empty JSON credentials-file value wins,
/// otherwise the corresponding environment bootstrap value is used. Empty
/// values are omitted. PostgreSQL connection material remains in this
/// process-local secret registry and does not affect [`CredentialSource`],
/// Precedence is per key: a non-blank JSON credentials-file value wins,
/// otherwise the corresponding environment bootstrap value is used. Blank
/// PostgreSQL values are omitted. PostgreSQL connection material remains in
/// this process-local secret registry and does not affect [`CredentialSource`],
/// which is intentionally limited to administrator-auth provenance exposed
/// by health/support surfaces.
pub fn bootstrap_secrets_with_postgres(
Expand Down Expand Up @@ -156,6 +156,7 @@ impl CredentialRegistry {
}
if let Some(raw) = file_map.get(CRED_POSTGRES_DSN)
&& let Some(text) = json_value_as_nonempty_string(raw)
.filter(|text| !text.trim().is_empty())
{
values.insert(CRED_POSTGRES_DSN.to_string(), text);
}
Expand Down Expand Up @@ -183,7 +184,7 @@ impl CredentialRegistry {
admin_from_env = true;
}
if !values.contains_key(CRED_POSTGRES_DSN)
&& let Some(dsn) = env_postgres_dsn.filter(|value| !value.is_empty())
&& let Some(dsn) = env_postgres_dsn.filter(|value| !value.trim().is_empty())
{
values.insert(CRED_POSTGRES_DSN.to_string(), dsn);
}
Expand Down
46 changes: 46 additions & 0 deletions tests/postgres_credential_boundary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,49 @@ fn empty_postgres_dsn_is_not_registered() {

assert_eq!(registry.get_credential(POSTGRES_DSN_KEY), None);
}

#[test]
fn blank_environment_postgres_dsn_is_not_registered() {
let registry = CredentialRegistry::bootstrap_secrets_with_postgres(
None,
None,
None,
Some(" \t ".to_string()),
)
.unwrap();

assert_eq!(registry.get_credential(POSTGRES_DSN_KEY), None);
assert_eq!(registry.source(), CredentialSource::None);
assert!(!registry.has_admin_auth());
}

#[test]
fn blank_credentials_file_postgres_dsn_is_not_registered() {
let path = temp_credentials_path("blank-postgres-dsn");
std::fs::write(&path, r#"{"postgres_dsn":" \t "}"#).unwrap();

let registry =
CredentialRegistry::bootstrap_secrets_with_postgres(Some(&path), None, None, None).unwrap();

assert_eq!(registry.get_credential(POSTGRES_DSN_KEY), None);
assert_eq!(registry.source(), CredentialSource::None);
assert!(!registry.has_admin_auth());

let _ = std::fs::remove_file(path);
}

#[test]
fn nonblank_postgres_dsn_is_preserved_byte_for_byte() {
let dsn = "host=db.internal dbname=wardnet user=wardnet";
let registry = CredentialRegistry::bootstrap_secrets_with_postgres(
None,
None,
None,
Some(dsn.to_string()),
)
.unwrap();

assert_eq!(registry.get_credential(POSTGRES_DSN_KEY), Some(dsn));
assert_eq!(registry.source(), CredentialSource::None);
assert!(!registry.has_admin_auth());
}
Loading