tsafe-cli 1.0.28

Secrets runtime for developers — inject credentials into processes via exec, never into shell history or .env files
Documentation
//! Runtime configuration for the KeePass pull provider.

use tsafe_core::pullconfig::PullSource;

use super::error::KeePassError;

/// Resolved runtime configuration for a KeePass pull operation.
#[derive(Debug)]
///
/// `password` is resolved at construction time from the environment variable
/// named by `PullSource::Keepass::password_env`.  It is never stored in the
/// manifest file.
pub struct KeePassConfig {
    /// Absolute path to the `.kdbx` file.
    pub path: String,
    /// Resolved master password (from the env var named by `password_env`).
    /// `None` means no password was requested — the database must be opened
    /// with a key file only.
    pub password: Option<String>,
    /// Absolute path to a KeePass key file, if configured.
    pub keyfile_path: Option<String>,
    /// Only import entries from this group name (case-insensitive direct match).
    /// `None` imports from the root group directly.
    pub group: Option<String>,
    /// When `true`, traverse descendant groups under the matched group.
    pub recursive: bool,
}

impl KeePassConfig {
    /// Build a [`KeePassConfig`] from a [`PullSource::Keepass`] variant.
    ///
    /// Resolves `password_env` against the current process environment.
    /// Returns an error if `password_env` is set but the variable is absent.
    pub fn from_pull_source(src: &PullSource) -> Result<Self, KeePassError> {
        let PullSource::Keepass {
            path,
            password_env,
            keyfile_path,
            group,
            recursive,
            ..
        } = src
        else {
            // Safety: callers are responsible for passing the correct variant.
            panic!("KeePassConfig::from_pull_source called with non-Keepass PullSource");
        };

        let password = match password_env {
            Some(env_var) => {
                let val = std::env::var(env_var)
                    .map_err(|_| KeePassError::PasswordRequired(env_var.clone()))?;
                Some(val)
            }
            None => None,
        };

        // Either a password or a key file must be provided; an empty
        // DatabaseKey is rejected by the keepass crate.
        if password.is_none() && keyfile_path.is_none() {
            // Default env var name matches the design doc convention.
            return Err(KeePassError::PasswordRequired(
                "TSAFE_KP_PASSWORD".to_string(),
            ));
        }

        Ok(KeePassConfig {
            path: path.clone(),
            password,
            keyfile_path: keyfile_path.clone(),
            group: group.clone(),
            recursive: recursive.unwrap_or(false),
        })
    }
}