← back to jdx__fnox

Function bodies 391 total

All specs Real LLM only Function bodies
put_secret_value function · rust · L72-L79 (8 LOC)
src/providers/gcp_sm.rs
    async fn put_secret_value(&self, _secret_id: &str, _secret_value: &str) -> Result<()> {
        Err(FnoxError::ProviderApiError {
            provider: "GCP Secret Manager".to_string(),
            details: "put_secret not yet implemented".to_string(),
            hint: "Contributions welcome to implement payload data setting".to_string(),
            url: URL.to_string(),
        })
    }
get_secret function · rust · L87-L140 (54 LOC)
src/providers/gcp_sm.rs
    async fn get_secret(&self, value: &str) -> Result<String> {
        let client = self.create_client().await?;
        let secret_name = self.build_secret_name(value);

        let response = client
            .access_secret_version()
            .set_name(secret_name)
            .send()
            .await
            .map_err(|e| {
                let err_str = e.to_string();
                if err_str.contains("NOT_FOUND") || err_str.contains("not found") {
                    FnoxError::ProviderSecretNotFound {
                        provider: "GCP Secret Manager".to_string(),
                        secret: value.to_string(),
                        hint: "Check that the secret exists in the GCP project".to_string(),
                        url: URL.to_string(),
                    }
                } else if err_str.contains("PERMISSION_DENIED") || err_str.contains("permission") {
                    FnoxError::ProviderAuthFailed {
                        provider: "GCP Sec
test_connection function · rust · L141-L174 (34 LOC)
src/providers/gcp_sm.rs
    async fn test_connection(&self) -> Result<()> {
        let client = self.create_client().await?;

        // Try to list secrets to verify access
        client
            .list_secrets()
            .set_parent(format!("projects/{}", self.project))
            .send()
            .await
            .map_err(|e| {
                let err_str = e.to_string();
                if err_str.contains("PERMISSION_DENIED") || err_str.contains("permission") {
                    FnoxError::ProviderAuthFailed {
                        provider: "GCP Secret Manager".to_string(),
                        details: err_str,
                        hint: "Check IAM permissions for secretmanager.secrets.list".to_string(),
                        url: URL.to_string(),
                    }
                } else {
                    FnoxError::ProviderApiError {
                        provider: "GCP Secret Manager".to_string(),
                        details: format!(
                          
put_secret function · rust · L175-L181 (7 LOC)
src/providers/gcp_sm.rs
    async fn put_secret(&self, key: &str, value: &str) -> Result<String> {
        let secret_id = self.get_secret_id(key);
        self.put_secret_value(&secret_id, value).await?;
        // Return the key name (without prefix) to store in config
        Ok(key.to_string())
    }
new function · rust · L15-L25 (11 LOC)
src/providers/infisical.rs
    pub fn new(
        project_id: Option<String>,
        environment: Option<String>,
        path: Option<String>,
    ) -> Self {
        Self {
            project_id,
            environment,
            path,
        }
    }
execute_infisical_command function · rust · L140-L203 (64 LOC)
src/providers/infisical.rs
    fn execute_infisical_command(&self, args: &[&str]) -> Result<String> {
        tracing::debug!("Executing infisical command with args: {:?}", args);

        let token = self.get_auth_token()?;

        let mut cmd = Command::new("infisical");
        cmd.args(args);

        // Add authentication token
        cmd.arg("--token");
        cmd.arg(&token);

        // Add custom domain if specified, stripping /api suffix if present
        // The CLI's --domain flag expects base URL (some commands append /api automatically)
        if let Some(api_url) = infisical_api_url() {
            let base_url = api_url.trim_end_matches("/api").trim_end_matches('/');
            cmd.arg("--domain");
            cmd.arg(base_url);
        }

        // Add silent flag to reduce noise
        cmd.arg("--silent");

        cmd.stdin(std::process::Stdio::null());

        let output = cmd.output().map_err(|e| {
            if e.kind() == std::io::ErrorKind::NotFound {
                FnoxError::P
get_secret function · rust · L207-L289 (83 LOC)
src/providers/infisical.rs
    async fn get_secret(&self, value: &str) -> Result<String> {
        tracing::debug!("Getting secret '{}' from Infisical", value);

        // Build the command: infisical secrets get <name> --output json
        // Using JSON format allows us to distinguish between "not found" and "empty value"
        let mut args = vec!["secrets", "get", value, "--output", "json"];

        // Add project ID if specified
        let project_arg;
        if let Some(ref project_id) = self.project_id {
            project_arg = format!("--projectId={}", project_id);
            args.push(&project_arg);
        }

        // Add environment if specified (otherwise CLI uses its default: "dev")
        let env_arg;
        if let Some(ref environment) = self.environment {
            env_arg = format!("--env={}", environment);
            args.push(&env_arg);
        }

        // Add path if specified (otherwise CLI uses its default: "/")
        let path_arg;
        if let Some(ref path) = self.pat
Want this analysis on your repo? https://repobility.com/scan/
test_connection function · rust · L414-L424 (11 LOC)
src/providers/infisical.rs
    async fn test_connection(&self) -> Result<()> {
        tracing::debug!("Testing connection to Infisical");

        // Try to authenticate and get a token
        let _token = self.get_auth_token()?;

        tracing::debug!("Infisical connection test successful");

        Ok(())
    }
env_dependencies function · rust · L426-L438 (13 LOC)
src/providers/infisical.rs
pub fn env_dependencies() -> &'static [&'static str] {
    &[
        "INFISICAL_TOKEN",
        "FNOX_INFISICAL_TOKEN",
        "INFISICAL_CLIENT_ID",
        "FNOX_INFISICAL_CLIENT_ID",
        "INFISICAL_CLIENT_SECRET",
        "FNOX_INFISICAL_CLIENT_SECRET",
        "INFISICAL_API_URL",
        "FNOX_INFISICAL_API_URL",
    ]
}
infisical_token function · rust · L439-L444 (6 LOC)
src/providers/infisical.rs
fn infisical_token() -> Option<String> {
    env::var("FNOX_INFISICAL_TOKEN")
        .or_else(|_| env::var("INFISICAL_TOKEN"))
        .ok()
}
infisical_client_id function · rust · L445-L450 (6 LOC)
src/providers/infisical.rs
fn infisical_client_id() -> Option<String> {
    env::var("FNOX_INFISICAL_CLIENT_ID")
        .or_else(|_| env::var("INFISICAL_CLIENT_ID"))
        .ok()
}
infisical_client_secret function · rust · L451-L456 (6 LOC)
src/providers/infisical.rs
fn infisical_client_secret() -> Option<String> {
    env::var("FNOX_INFISICAL_CLIENT_SECRET")
        .or_else(|_| env::var("INFISICAL_CLIENT_SECRET"))
        .ok()
}
infisical_api_url function · rust · L457-L462 (6 LOC)
src/providers/infisical.rs
fn infisical_api_url() -> Option<String> {
    env::var("FNOX_INFISICAL_API_URL")
        .or_else(|_| env::var("INFISICAL_API_URL"))
        .ok()
}
new function · rust · L19-L25 (7 LOC)
src/providers/keepass.rs
    pub fn new(database: String, keyfile: Option<String>, password: Option<String>) -> Self {
        Self {
            database_path: PathBuf::from(shellexpand::tilde(&database).to_string()),
            keyfile_path: keyfile.map(|k| PathBuf::from(shellexpand::tilde(&k).to_string())),
            password,
        }
    }
get_password function · rust · L28-L117 (90 LOC)
src/providers/keepass.rs
    fn get_password(&self) -> Result<String> {
        // Priority: env var > config
        if let Some(password) = keepass_password() {
            return Ok(password);
        }

        if let Some(password) = &self.password {
            return Ok(password.clone());
        }

        Err(FnoxError::ProviderAuthFailed {
            provider: "KeePass".to_string(),
            details: "Database password not set".to_string(),
            hint: "Set FNOX_KEEPASS_PASSWORD or KEEPASS_PASSWORD environment variable, or configure password in provider config".to_string(),
            url: "https://fnox.jdx.dev/providers/keepass".to_string(),
        })
    }

    /// Build the database key from password and optional keyfile
    fn build_key(&self) -> Result<DatabaseKey> {
        let password = self.get_password()?;
        let mut key = DatabaseKey::new();

        // Add password
        key = key.with_password(&password);

        // Add keyfile if configured
        if let Some(keyfil
Repobility · open methodology · https://repobility.com/research/
build_key function · rust · L47-L74 (28 LOC)
src/providers/keepass.rs
    fn build_key(&self) -> Result<DatabaseKey> {
        let password = self.get_password()?;
        let mut key = DatabaseKey::new();

        // Add password
        key = key.with_password(&password);

        // Add keyfile if configured
        if let Some(keyfile_path) = &self.keyfile_path {
            let mut keyfile =
                File::open(keyfile_path).map_err(|e| FnoxError::ProviderApiError {
                    provider: "KeePass".to_string(),
                    details: format!("Failed to open keyfile '{}': {}", keyfile_path.display(), e),
                    hint: "Check that the keyfile exists and is readable".to_string(),
                    url: "https://fnox.jdx.dev/providers/keepass".to_string(),
                })?;
            key = key
                .with_keyfile(&mut keyfile)
                .map_err(|e| FnoxError::ProviderApiError {
                    provider: "KeePass".to_string(),
                    details: format!("Failed to read keyfile: {}", e)
open_database function · rust · L77-L97 (21 LOC)
src/providers/keepass.rs
    fn open_database(&self) -> Result<Database> {
        let file = File::open(&self.database_path).map_err(|e| FnoxError::ProviderApiError {
            provider: "KeePass".to_string(),
            details: format!(
                "Failed to open database '{}': {}",
                self.database_path.display(),
                e
            ),
            hint: "Check that the database file exists and is readable".to_string(),
            url: "https://fnox.jdx.dev/providers/keepass".to_string(),
        })?;
        let mut reader = BufReader::new(file);
        let key = self.build_key()?;

        Database::open(&mut reader, key).map_err(|e| FnoxError::ProviderAuthFailed {
            provider: "KeePass".to_string(),
            details: format!("Failed to decrypt database: {}", e),
            hint: "Check that the password and/or keyfile are correct".to_string(),
            url: "https://fnox.jdx.dev/providers/keepass".to_string(),
        })
    }
parse_reference function · rust · L198-L225 (28 LOC)
src/providers/keepass.rs
    fn parse_reference(value: &str) -> (Vec<&str>, &str) {
        let parts: Vec<&str> = value.split('/').collect();

        // Known field names (case-insensitive check, but return proper casing)
        let known_fields = ["password", "username", "url", "notes", "title"];

        if parts.len() == 1 {
            // Just entry name, default to password
            (parts, "Password")
        } else {
            // Check if the last part is a known field
            let last = parts.last().unwrap().to_lowercase();
            if known_fields.contains(&last.as_str()) {
                let field = match last.as_str() {
                    "password" => "Password",
                    "username" => "UserName",
                    "url" => "URL",
                    "notes" => "Notes",
                    "title" => "Title",
                    _ => "Password",
                };
                (parts[..parts.len() - 1].to_vec(), field)
            } else {
                // Last pa
find_entry function · rust · L230-L249 (20 LOC)
src/providers/keepass.rs
    fn find_entry<'a>(group: &'a Group, path: &[&str]) -> Option<&'a Entry> {
        if path.is_empty() {
            return None;
        }

        if path.len() == 1 {
            // Search for entry by title in this group and all subgroups
            let entry_name = path[0];
            Self::find_entry_by_title(group, entry_name)
        } else {
            // Navigate to subgroup first
            let group_name = path[0];
            for subgroup in &group.groups {
                if subgroup.name == group_name {
                    return Self::find_entry(subgroup, &path[1..]);
                }
            }
            None
        }
    }
find_entry_by_title function · rust · L252-L264 (13 LOC)
src/providers/keepass.rs
    fn find_entry_by_title<'a>(group: &'a Group, title: &str) -> Option<&'a Entry> {
        for entry in &group.entries {
            if entry.get_title() == Some(title) {
                return Some(entry);
            }
        }
        for subgroup in &group.groups {
            if let Some(entry) = Self::find_entry_by_title(subgroup, title) {
                return Some(entry);
            }
        }
        None
    }
find_entry_by_title_mut function · rust · L267-L289 (23 LOC)
src/providers/keepass.rs
    fn find_entry_by_title_mut<'a>(group: &'a mut Group, title: &str) -> Option<&'a mut Entry> {
        // First check if entry is in this group's direct entries
        let found_entry_idx = group
            .entries
            .iter()
            .position(|e| e.get_title() == Some(title));

        if let Some(idx) = found_entry_idx {
            return Some(&mut group.entries[idx]);
        }

        // Check subgroups
        let found_in_subgroup_idx = group
            .groups
            .iter()
            .position(|sg| Self::find_entry_by_title(sg, title).is_some());

        if let Some(idx) = found_in_subgroup_idx {
            return Self::find_entry_by_title_mut(&mut group.groups[idx], title);
        }

        None
    }
find_or_create_entry function · rust · L293-L362 (70 LOC)
src/providers/keepass.rs
    fn find_or_create_entry(
        group: &mut Group,
        path: &[&str],
        value: &str,
        field: &str,
    ) -> Result<String> {
        if path.is_empty() {
            return Err(FnoxError::ProviderInvalidResponse {
                provider: "KeePass".to_string(),
                details: "Empty path for entry".to_string(),
                hint: "Provide an entry name or path".to_string(),
                url: "https://fnox.jdx.dev/providers/keepass".to_string(),
            });
        }

        // Reject writing to Title field as it's used for entry lookups
        if field == "Title" {
            return Err(FnoxError::ProviderInvalidResponse {
                provider: "KeePass".to_string(),
                details: "Cannot write to 'Title' field".to_string(),
                hint: "The 'Title' field is used for entry identification. Use a different field name.".to_string(),
                url: "https://fnox.jdx.dev/providers/keepass".to_string(),
            
put_secret function · rust · L406-L443 (38 LOC)
src/providers/keepass.rs
    async fn put_secret(&self, key: &str, value: &str) -> Result<String> {
        // Parse the key to determine entry path and field
        let (entry_path, field) = Self::parse_reference(key);

        tracing::debug!(
            "Storing KeePass secret '{}' field '{}' in '{}'",
            entry_path.join("/"),
            field,
            self.database_path.display()
        );

        // Check if database exists; if not, create a new one
        let mut db = if self.database_path.exists() {
            self.open_database()?
        } else {
            // Create new KDBX4 database
            tracing::info!(
                "Creating new KeePass database at '{}'",
                self.database_path.display()
            );
            Database::new(keepass::config::DatabaseConfig::default())
        };

        // Find or create the entry
        let entry_name = Self::find_or_create_entry(&mut db.root, &entry_path, value, field)?;

        // Save the database
        self.
Same scanner, your repo: https://repobility.com — Repobility
test_parse_reference_with_field function · rust · L505-L521 (17 LOC)
src/providers/keepass.rs
    fn test_parse_reference_with_field() {
        let (path, field) = KeePassProvider::parse_reference("my-entry/username");
        assert_eq!(path, vec!["my-entry"]);
        assert_eq!(field, "UserName");

        let (path, field) = KeePassProvider::parse_reference("my-entry/password");
        assert_eq!(path, vec!["my-entry"]);
        assert_eq!(field, "Password");

        let (path, field) = KeePassProvider::parse_reference("my-entry/url");
        assert_eq!(path, vec!["my-entry"]);
        assert_eq!(field, "URL");

        let (path, field) = KeePassProvider::parse_reference("my-entry/notes");
        assert_eq!(path, vec!["my-entry"]);
        assert_eq!(field, "Notes");
    }
test_parse_reference_with_group function · rust · L524-L532 (9 LOC)
src/providers/keepass.rs
    fn test_parse_reference_with_group() {
        let (path, field) = KeePassProvider::parse_reference("group/my-entry");
        assert_eq!(path, vec!["group", "my-entry"]);
        assert_eq!(field, "Password");

        let (path, field) = KeePassProvider::parse_reference("group/subgroup/my-entry");
        assert_eq!(path, vec!["group", "subgroup", "my-entry"]);
        assert_eq!(field, "Password");
    }
test_parse_reference_with_group_and_field function · rust · L535-L543 (9 LOC)
src/providers/keepass.rs
    fn test_parse_reference_with_group_and_field() {
        let (path, field) = KeePassProvider::parse_reference("group/my-entry/username");
        assert_eq!(path, vec!["group", "my-entry"]);
        assert_eq!(field, "UserName");

        let (path, field) = KeePassProvider::parse_reference("group/subgroup/my-entry/password");
        assert_eq!(path, vec!["group", "subgroup", "my-entry"]);
        assert_eq!(field, "Password");
    }
build_key_name function · rust · L20-L25 (6 LOC)
src/providers/keychain.rs
    fn build_key_name(&self, key: &str) -> String {
        match &self.prefix {
            Some(prefix) => format!("{}{}", prefix, key),
            None => key.to_string(),
        }
    }
create_entry function · rust · L28-L71 (44 LOC)
src/providers/keychain.rs
    fn create_entry(&self, key: &str) -> Result<Entry> {
        let full_key = self.build_key_name(key);
        Entry::new(&self.service, &full_key).map_err(|e| FnoxError::ProviderApiError {
            provider: "Keychain".to_string(),
            details: format!(
                "Failed to create entry for service '{}', key '{}': {}",
                self.service, full_key, e
            ),
            hint: "Check that the keychain is accessible".to_string(),
            url: "https://fnox.jdx.dev/providers/keychain".to_string(),
        })
    }

    /// Store a secret in the OS keychain
    pub async fn put_secret(&self, key: &str, value: &str) -> Result<()> {
        let entry = self.create_entry(key)?;
        let full_key = self.build_key_name(key);

        tracing::debug!(
            "Storing secret '{}' in OS keychain (service: '{}', key: '{}')",
            full_key,
            self.service,
            full_key
        );

        entry
            .set_password(value
put_secret function · rust · L42-L108 (67 LOC)
src/providers/keychain.rs
    pub async fn put_secret(&self, key: &str, value: &str) -> Result<()> {
        let entry = self.create_entry(key)?;
        let full_key = self.build_key_name(key);

        tracing::debug!(
            "Storing secret '{}' in OS keychain (service: '{}', key: '{}')",
            full_key,
            self.service,
            full_key
        );

        entry
            .set_password(value)
            .map_err(|e| FnoxError::ProviderApiError {
                provider: "Keychain".to_string(),
                details: format!(
                    "Failed to store secret '{}' (service: '{}'): {}",
                    full_key, self.service, e
                ),
                hint: "Check that the keychain is accessible and writable".to_string(),
                url: "https://fnox.jdx.dev/providers/keychain".to_string(),
            })?;

        tracing::debug!(
            "Successfully stored secret '{}' in OS keychain (service: '{}')",
            full_key,
            self.s
test_connection function · rust · L131-L167 (37 LOC)
src/providers/keychain.rs
    async fn test_connection(&self) -> Result<()> {
        // Try to create an entry with a test key to verify keychain access
        let test_key = "__fnox_test__";
        let entry = self.create_entry(test_key)?;

        // Try to set a test value to verify we have keychain access
        entry
            .set_password("test")
            .map_err(|e| FnoxError::ProviderAuthFailed {
                provider: "Keychain".to_string(),
                details: format!(
                    "Failed to access keychain (service: '{}'): {}",
                    self.service, e
                ),
                hint: "Check that you have permission to access the OS keychain".to_string(),
                url: "https://fnox.jdx.dev/providers/keychain".to_string(),
            })?;

        // Try to read it back to verify it worked
        entry
            .get_password()
            .map_err(|e| FnoxError::ProviderAuthFailed {
                provider: "Keychain".to_string(),
          
put_secret function · rust · L168-L173 (6 LOC)
src/providers/keychain.rs
    async fn put_secret(&self, key: &str, value: &str) -> Result<String> {
        self.put_secret(key, value).await?;
        // Return the key name to store in config
        Ok(key.to_string())
    }
Powered by Repobility — scan your code at https://repobility.com
test_keychain_set_and_get function · rust · L182-L197 (16 LOC)
src/providers/keychain.rs
    async fn test_keychain_set_and_get() {
        let provider = KeychainProvider::new("fnox-unit-test".to_string(), None);

        // Set a secret
        let result = provider.put_secret("test_key", "test_value").await;
        assert!(result.is_ok(), "Failed to set secret: {:?}", result.err());

        // Get it back
        let result = provider.get_secret("test_key").await;
        assert!(result.is_ok(), "Failed to get secret: {:?}", result.err());
        assert_eq!(result.unwrap(), "test_value");

        // Clean up
        let entry = provider.create_entry("test_key").unwrap();
        let _ = entry.delete_credential();
    }
display_name function · rust · L55-L63 (9 LOC)
src/providers/mod.rs
    pub fn display_name(&self) -> &'static str {
        match self {
            Self::Local => "Local (easy to start)",
            Self::PasswordManager => "Password Manager",
            Self::CloudKms => "Cloud KMS",
            Self::CloudSecretsManager => "Cloud Secrets Manager",
            Self::OsKeychain => "OS Keychain",
        }
    }
description function · rust · L66-L78 (13 LOC)
src/providers/mod.rs
    pub fn description(&self) -> &'static str {
        match self {
            Self::Local => "Plain text or local encryption - no external dependencies",
            Self::PasswordManager => {
                "1Password, Bitwarden, Infisical - use your existing password manager"
            }
            Self::CloudKms => "AWS KMS, Azure Key Vault, GCP KMS - encrypt with cloud keys",
            Self::CloudSecretsManager => {
                "AWS, Azure, GCP, HashiCorp Vault - store secrets remotely"
            }
            Self::OsKeychain => "Use your operating system's secure keychain",
        }
    }
all function · rust · L81-L89 (9 LOC)
src/providers/mod.rs
    pub fn all() -> &'static [WizardCategory] {
        &[
            Self::Local,
            Self::PasswordManager,
            Self::CloudKms,
            Self::CloudSecretsManager,
            Self::OsKeychain,
        ]
    }
encrypt function · rust · L182-L187 (6 LOC)
src/providers/mod.rs
    async fn encrypt(&self, _value: &str) -> Result<String> {
        // Default implementation for non-encryption providers
        Err(crate::error::FnoxError::Provider(
            "This provider does not support encryption".to_string(),
        ))
    }
put_secret function · rust · L197-L214 (18 LOC)
src/providers/mod.rs
    async fn put_secret(&self, _key: &str, value: &str) -> Result<String> {
        let capabilities = self.capabilities();

        if capabilities.contains(&ProviderCapability::Encryption) {
            // Encryption provider - encrypt and return ciphertext
            self.encrypt(value).await
        } else if capabilities.contains(&ProviderCapability::RemoteStorage) {
            // Remote storage provider - should override this method
            Err(crate::error::FnoxError::Provider(
                "Remote storage provider must implement put_secret".to_string(),
            ))
        } else {
            // Read-only provider
            Err(crate::error::FnoxError::Provider(
                "This provider does not support storing secrets".to_string(),
            ))
        }
    }
wizard_info_by_category function · rust · L258-L263 (6 LOC)
src/providers/mod.rs
    pub fn wizard_info_by_category(category: WizardCategory) -> Vec<&'static WizardInfo> {
        ALL_WIZARD_INFO
            .iter()
            .filter(|info| info.category == category)
            .collect()
    }
get_provider_resolved function · rust · L273-L281 (9 LOC)
src/providers/mod.rs
pub async fn get_provider_resolved(
    config: &crate::config::Config,
    profile: &str,
    provider_name: &str,
    provider_config: &ProviderConfig,
) -> Result<Box<dyn Provider>> {
    let resolved = resolve_provider_config(config, profile, provider_name, provider_config).await?;
    get_provider_from_resolved(&resolved)
}
Want this analysis on your repo? https://repobility.com/scan/
new function · rust · L22-L28 (7 LOC)
src/providers/onepassword.rs
    pub fn new(vault: Option<String>, account: Option<String>, token: Option<String>) -> Self {
        Self {
            vault,
            account,
            token,
        }
    }
get_token function · rust · L31-L36 (6 LOC)
src/providers/onepassword.rs
    fn get_token(&self) -> Option<String> {
        self.token
            .as_ref()
            .cloned()
            .or_else(op_service_account_token)
    }
value_to_reference function · rust · L39-L105 (67 LOC)
src/providers/onepassword.rs
    fn value_to_reference(&self, value: &str) -> Result<String> {
        // Check if value is already a full op:// reference
        if value.starts_with("op://") {
            return Ok(value.to_string());
        }

        if self.vault.is_none() {
            return Err(FnoxError::ProviderInvalidResponse {
                provider: "1Password".to_string(),
                details: format!("Unknown secret vault for: '{}'", value),
                hint: "Specify a vault in the provider config or use a full 'op://' reference"
                    .to_string(),
                url: "https://fnox.jdx.dev/providers/1password".to_string(),
            });
        }

        // Parse value as "item/field" or just "item"
        // Default field is "password" if not specified
        let parts: Vec<&str> = value.split('/').collect();
        match parts.len() {
            1 => Ok(format!(
                "op://{}/{}/password",
                self.vault.as_ref().unwrap(),
                p
execute_op_command function · rust · L80-L239 (160 LOC)
src/providers/onepassword.rs
    fn execute_op_command(&self, args: &[&str]) -> Result<String> {
        tracing::debug!("Executing op command with args: {:?}", args);

        let mut cmd = Command::new("op");
        if let Some(token) = self.get_token() {
            tracing::debug!(
                "Setting OP_SERVICE_ACCOUNT_TOKEN (token length: {})",
                token.len()
            );
            cmd.env("OP_SERVICE_ACCOUNT_TOKEN", token);
        }
        cmd.args(args);

        // Add account flag if specified
        if let Some(account) = &self.account {
            cmd.arg("--account").arg(account);
        }

        let output = cmd.output().map_err(|e| {
            if e.kind() == std::io::ErrorKind::NotFound {
                FnoxError::ProviderCliNotFound {
                    provider: "1Password".to_string(),
                    cli: "op".to_string(),
                    install_hint: "brew install 1password-cli".to_string(),
                    url: "https://fnox.jdx.dev/providers/1pas
get_secret function · rust · L263-L271 (9 LOC)
src/providers/onepassword.rs
    async fn get_secret(&self, value: &str) -> Result<String> {
        tracing::debug!("Getting secret '{}' from 1Password", value);

        let reference = self.value_to_reference(value)?;
        tracing::debug!("Reading 1Password secret: {}", reference);

        // Use 'op read' to fetch the secret
        self.execute_op_command(&["read", &reference])
    }
test_connection function · rust · L390-L400 (11 LOC)
src/providers/onepassword.rs
    async fn test_connection(&self) -> Result<()> {
        tracing::debug!("Testing connection to 1Password");

        // Try to get the current user as a basic connectivity test
        let output = self.execute_op_command(&["whoami"])?;

        tracing::debug!("1Password whoami output: {}", output);

        Ok(())
    }
op_service_account_token function · rust · L406-L411 (6 LOC)
src/providers/onepassword.rs
fn op_service_account_token() -> Option<String> {
    env::var("FNOX_OP_SERVICE_ACCOUNT_TOKEN")
        .or_else(|_| env::var("OP_SERVICE_ACCOUNT_TOKEN"))
        .ok()
}
new function · rust · L44-L65 (22 LOC)
src/providers/passwordstate.rs
    pub fn new(
        base_url: String,
        api_key: Option<String>,
        password_list_id: String,
        verify_ssl: Option<String>,
    ) -> Self {
        let api_key = api_key.or_else(passwordstate_api_key).unwrap_or_default();

        let verify_ssl = verify_ssl
            .map(|v| v.to_lowercase() != "false")
            .unwrap_or(true);

        // Normalize base_url (remove trailing slash)
        let base_url = base_url.trim_end_matches('/').to_string();

        Self {
            base_url,
            api_key,
            password_list_id,
            verify_ssl,
        }
    }
Repobility · open methodology · https://repobility.com/research/
create_client function · rust · L68-L105 (38 LOC)
src/providers/passwordstate.rs
    fn create_client(&self) -> Result<reqwest::Client> {
        reqwest::Client::builder()
            .danger_accept_invalid_certs(!self.verify_ssl)
            .build()
            .map_err(|e| FnoxError::ProviderApiError {
                provider: "Passwordstate".to_string(),
                details: format!("Failed to create HTTP client: {}", e),
                hint: "Check your network configuration".to_string(),
                url: "https://fnox.jdx.dev/providers/overview".to_string(),
            })
    }

    /// Parse value reference into (identifier, field, is_id)
    ///
    /// Supported formats:
    /// - `123` (numeric) - Password ID, returns password field
    /// - `123/field` - Password ID with specific field
    /// - `title` (non-numeric) - Search by title, returns password field
    /// - `title/field` - Search by title, get specific field
    fn parse_reference(&self, value: &str) -> Result<(String, String, bool)> {
        let parts: Vec<&str> = value.split('/
get_by_id function · rust · L109-L138 (30 LOC)
src/providers/passwordstate.rs
    async fn get_by_id(&self, password_id: &str) -> Result<PasswordEntry> {
        let client = self.create_client()?;
        let url = format!("{}/api/passwords/{}", self.base_url, password_id);

        tracing::debug!("Fetching password by ID from: {}", url);

        let response = client
            .get(&url)
            .header("APIKey", &self.api_key)
            .send()
            .await
            .map_err(|e| FnoxError::ProviderApiError {
                provider: "Passwordstate".to_string(),
                details: format!("HTTP request failed: {}", e),
                hint: "Check network connectivity to the Passwordstate server".to_string(),
                url: "https://fnox.jdx.dev/providers/overview".to_string(),
            })?;

        if !response.status().is_success() {
            let status = response.status();
            let body = response.text().await.unwrap_or_default();
            if status.as_u16() == 401 || status.as_u16() == 403 {
                
extract_field function · rust · L172-L266 (95 LOC)
src/providers/passwordstate.rs
    fn extract_field(entry: &PasswordEntry, field: &str) -> Result<String> {
        let value = match field {
            "password" => entry.password.clone(),
            "username" | "user" => entry.user_name.clone(),
            "title" => entry.title.clone(),
            "url" => entry.url.clone(),
            "description" => entry.description.clone(),
            "notes" => entry.notes.clone(),
            _ => None,
        };

        value.ok_or_else(|| FnoxError::ProviderInvalidResponse {
            provider: "Passwordstate".to_string(),
            details: format!("Field '{}' not found or empty in password entry", field),
            hint: "Available fields: password, username, title, url, description, notes"
                .to_string(),
            url: "https://fnox.jdx.dev/providers/overview".to_string(),
        })
    }

    /// Search for a password by title within the configured list
    async fn search_by_title(&self, title: &str) -> Result<PasswordEntry> {
     
‹ prevpage 5 / 8next ›