hardware-enclave 0.1.5

Hardware-backed key management — macOS Secure Enclave, Windows TPM 2.0, Linux TPM/keyring — plus in-process memory protection
Documentation
#![allow(dead_code, unused_imports, unused_qualifications, unreachable_patterns)]
use std::collections::BTreeMap;
use std::path::Path;

use anyhow::Result;
use serde::{Deserialize, Serialize};

use super::types::BindingRecord;

const INSTALL_PROVENANCE_KEY: &str = "install_provenance";

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct InstallProvenance {
    pub config_line_origin: String,
    pub installed_from_npmrc: bool,
    pub original_line_kind: Option<String>,
}

pub fn applies_to_config_path(record: &BindingRecord, path: &str) -> bool {
    provenance_for_path(record, path).is_some()
}

pub fn has_any_install_provenance(record: &BindingRecord) -> bool {
    !load_install_provenance(record).is_empty()
        || record.metadata.contains_key("original_config_path")
        || record.metadata.contains_key("config_line_origin")
        || record.metadata.contains_key("installed_from_npmrc")
}

pub fn provenance_for_path(record: &BindingRecord, path: &str) -> Option<InstallProvenance> {
    load_install_provenance(record)
        .get(path)
        .cloned()
        .or_else(|| legacy_provenance_for_path(record, path))
}

pub fn set_provenance_for_path(
    record: &mut BindingRecord,
    path: &Path,
    provenance: InstallProvenance,
) -> Result<()> {
    let path_string = path.to_string_lossy().into_owned();
    let mut all = load_install_provenance(record);
    all.insert(path_string.clone(), provenance.clone());
    store_install_provenance(record, &all)?;
    set_legacy_provenance(record, &path_string, &provenance);
    Ok(())
}

pub fn remove_provenance_for_path(record: &mut BindingRecord, path: &str) -> Result<bool> {
    let mut all = load_install_provenance(record);
    let removed_from_map = all.remove(path).is_some();
    if removed_from_map {
        if all.is_empty() {
            record.metadata.remove(INSTALL_PROVENANCE_KEY);
            clear_legacy_provenance(record);
            return Ok(false);
        }

        store_install_provenance(record, &all)?;
        if let Some((remaining_path, remaining)) = all.iter().next() {
            set_legacy_provenance(record, remaining_path, remaining);
        }
        return Ok(true);
    }

    if record
        .metadata
        .get("original_config_path")
        .is_some_and(|stored| stored == path)
    {
        clear_legacy_provenance(record);
        return Ok(false);
    }

    Ok(!all.is_empty())
}

fn load_install_provenance(record: &BindingRecord) -> BTreeMap<String, InstallProvenance> {
    record
        .metadata
        .get(INSTALL_PROVENANCE_KEY)
        .and_then(|serialized| serde_json::from_str(serialized).ok())
        .unwrap_or_default()
}

fn store_install_provenance(
    record: &mut BindingRecord,
    all: &BTreeMap<String, InstallProvenance>,
) -> Result<()> {
    record.metadata.insert(
        INSTALL_PROVENANCE_KEY.to_string(),
        serde_json::to_string(all)?,
    );
    Ok(())
}

fn legacy_provenance_for_path(record: &BindingRecord, path: &str) -> Option<InstallProvenance> {
    let original_path = record.metadata.get("original_config_path")?;
    if original_path != path {
        return None;
    }

    let config_line_origin = record.metadata.get("config_line_origin")?.clone();
    let installed_from_npmrc = record
        .metadata
        .get("installed_from_npmrc")
        .is_some_and(|value| value == "true");
    let original_line_kind = record.metadata.get("original_line_kind").cloned();
    Some(InstallProvenance {
        config_line_origin,
        installed_from_npmrc,
        original_line_kind,
    })
}

fn set_legacy_provenance(record: &mut BindingRecord, path: &str, provenance: &InstallProvenance) {
    record.metadata.insert(
        "config_line_origin".to_string(),
        provenance.config_line_origin.clone(),
    );
    record
        .metadata
        .insert("original_config_path".to_string(), path.to_string());
    record.metadata.insert(
        "installed_from_npmrc".to_string(),
        provenance.installed_from_npmrc.to_string(),
    );
    match &provenance.original_line_kind {
        Some(kind) => {
            record
                .metadata
                .insert("original_line_kind".to_string(), kind.clone());
        }
        None => {
            record.metadata.remove("original_line_kind");
        }
    }
}

fn clear_legacy_provenance(record: &mut BindingRecord) {
    record.metadata.remove("config_line_origin");
    record.metadata.remove("original_config_path");
    record.metadata.remove("installed_from_npmrc");
    record.metadata.remove("original_line_kind");
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeMap;
    use std::path::PathBuf;

    use super::*;
    use crate::internal::app_adapter::types::BindingId;

    fn test_record() -> BindingRecord {
        BindingRecord {
            id: BindingId::new("test:default"),
            label: "default".to_string(),
            target: "https://example.com".to_string(),
            secret_env_var: "TOKEN".to_string(),
            metadata: BTreeMap::new(),
        }
    }

    #[test]
    fn set_and_get_provenance_for_path() {
        let mut record = test_record();
        let path = PathBuf::from("/home/user/.npmrc");
        let provenance = InstallProvenance {
            config_line_origin: "//registry.npmjs.org/:_authToken".to_string(),
            installed_from_npmrc: true,
            original_line_kind: Some("auth_token".to_string()),
        };

        set_provenance_for_path(&mut record, &path, provenance.clone()).expect("set provenance");

        let result = provenance_for_path(&record, "/home/user/.npmrc");
        assert_eq!(result, Some(provenance));
    }

    #[test]
    fn applies_to_config_path_returns_true_when_set() {
        let mut record = test_record();
        let path = PathBuf::from("/home/user/.npmrc");
        let provenance = InstallProvenance {
            config_line_origin: "//registry.npmjs.org/:_authToken".to_string(),
            installed_from_npmrc: true,
            original_line_kind: None,
        };
        set_provenance_for_path(&mut record, &path, provenance).expect("set provenance");

        assert!(applies_to_config_path(&record, "/home/user/.npmrc"));
        assert!(!applies_to_config_path(&record, "/other/path/.npmrc"));
    }

    #[test]
    fn has_any_install_provenance_empty_record() {
        let record = test_record();
        assert!(!has_any_install_provenance(&record));
    }

    #[test]
    fn has_any_install_provenance_with_provenance() {
        let mut record = test_record();
        let path = PathBuf::from("/home/user/.npmrc");
        let provenance = InstallProvenance {
            config_line_origin: "//registry.npmjs.org/:_authToken".to_string(),
            installed_from_npmrc: false,
            original_line_kind: None,
        };
        set_provenance_for_path(&mut record, &path, provenance).expect("set provenance");

        assert!(has_any_install_provenance(&record));
    }

    #[test]
    fn has_any_install_provenance_with_legacy_metadata() {
        let mut record = test_record();
        record.metadata.insert(
            "original_config_path".to_string(),
            "/home/user/.npmrc".to_string(),
        );

        assert!(has_any_install_provenance(&record));
    }

    #[test]
    fn remove_provenance_for_path_single_entry() {
        let mut record = test_record();
        let path = PathBuf::from("/home/user/.npmrc");
        let provenance = InstallProvenance {
            config_line_origin: "//registry.npmjs.org/:_authToken".to_string(),
            installed_from_npmrc: true,
            original_line_kind: None,
        };
        set_provenance_for_path(&mut record, &path, provenance).expect("set provenance");

        let has_remaining =
            remove_provenance_for_path(&mut record, "/home/user/.npmrc").expect("remove");
        assert!(!has_remaining);
        assert!(!has_any_install_provenance(&record));
    }

    #[test]
    fn remove_provenance_for_path_with_multiple_entries() {
        let mut record = test_record();
        let provenance_a = InstallProvenance {
            config_line_origin: "//registry.npmjs.org/:_authToken".to_string(),
            installed_from_npmrc: true,
            original_line_kind: None,
        };
        let provenance_b = InstallProvenance {
            config_line_origin: "//other.registry/:_authToken".to_string(),
            installed_from_npmrc: false,
            original_line_kind: Some("auth_token".to_string()),
        };
        set_provenance_for_path(&mut record, &PathBuf::from("/path/a"), provenance_a)
            .expect("set a");
        set_provenance_for_path(&mut record, &PathBuf::from("/path/b"), provenance_b)
            .expect("set b");

        let has_remaining = remove_provenance_for_path(&mut record, "/path/a").expect("remove a");
        assert!(has_remaining);
        assert!(provenance_for_path(&record, "/path/b").is_some());
        assert!(provenance_for_path(&record, "/path/a").is_none());
    }

    #[test]
    fn remove_provenance_nonexistent_path() {
        let mut record = test_record();

        let has_remaining =
            remove_provenance_for_path(&mut record, "/no/such/path").expect("remove");
        assert!(!has_remaining);
    }

    #[test]
    fn legacy_provenance_fallback() {
        let mut record = test_record();
        record.metadata.insert(
            "original_config_path".to_string(),
            "/home/user/.npmrc".to_string(),
        );
        record.metadata.insert(
            "config_line_origin".to_string(),
            "//registry.npmjs.org/:_authToken".to_string(),
        );
        record
            .metadata
            .insert("installed_from_npmrc".to_string(), "true".to_string());

        let result = provenance_for_path(&record, "/home/user/.npmrc");
        assert!(result.is_some());
        let prov = result.expect("provenance");
        assert_eq!(prov.config_line_origin, "//registry.npmjs.org/:_authToken");
        assert!(prov.installed_from_npmrc);
        assert_eq!(prov.original_line_kind, None);
    }

    #[test]
    fn legacy_provenance_does_not_match_different_path() {
        let mut record = test_record();
        record.metadata.insert(
            "original_config_path".to_string(),
            "/home/user/.npmrc".to_string(),
        );
        record.metadata.insert(
            "config_line_origin".to_string(),
            "//registry.npmjs.org/:_authToken".to_string(),
        );
        record
            .metadata
            .insert("installed_from_npmrc".to_string(), "true".to_string());

        assert!(provenance_for_path(&record, "/other/path").is_none());
    }

    #[test]
    fn remove_legacy_provenance() {
        let mut record = test_record();
        record.metadata.insert(
            "original_config_path".to_string(),
            "/home/user/.npmrc".to_string(),
        );
        record.metadata.insert(
            "config_line_origin".to_string(),
            "//registry.npmjs.org/:_authToken".to_string(),
        );
        record
            .metadata
            .insert("installed_from_npmrc".to_string(), "true".to_string());

        let has_remaining =
            remove_provenance_for_path(&mut record, "/home/user/.npmrc").expect("remove");
        assert!(!has_remaining);
        assert!(!has_any_install_provenance(&record));
    }

    #[test]
    fn install_provenance_serde_round_trip() {
        let provenance = InstallProvenance {
            config_line_origin: "//registry.npmjs.org/:_authToken".to_string(),
            installed_from_npmrc: true,
            original_line_kind: Some("auth_token".to_string()),
        };

        let json = serde_json::to_string(&provenance).expect("serialize");
        let deserialized: InstallProvenance = serde_json::from_str(&json).expect("deserialize");
        assert_eq!(provenance, deserialized);
    }
}