- Split library (db/crypto/service) and MCP/Web/OAuth binary - Add deploy examples and CI/docs updates Made-with: Cursor
80 lines
2.1 KiB
Rust
80 lines
2.1 KiB
Rust
use anyhow::Result;
|
|
use serde_json::Value;
|
|
use sqlx::PgPool;
|
|
use std::collections::HashMap;
|
|
use uuid::Uuid;
|
|
|
|
use crate::crypto;
|
|
use crate::service::search::{fetch_entries, fetch_secrets_for_entries};
|
|
|
|
/// Decrypt a single named field from an entry.
|
|
pub async fn get_secret_field(
|
|
pool: &PgPool,
|
|
namespace: &str,
|
|
kind: &str,
|
|
name: &str,
|
|
field_name: &str,
|
|
master_key: &[u8; 32],
|
|
user_id: Option<Uuid>,
|
|
) -> Result<Value> {
|
|
let entries = fetch_entries(
|
|
pool,
|
|
Some(namespace),
|
|
Some(kind),
|
|
Some(name),
|
|
&[],
|
|
None,
|
|
user_id,
|
|
)
|
|
.await?;
|
|
let entry = entries
|
|
.first()
|
|
.ok_or_else(|| anyhow::anyhow!("Not found: [{}/{}] {}", namespace, kind, name))?;
|
|
|
|
let entry_ids = vec![entry.id];
|
|
let secrets_map = fetch_secrets_for_entries(pool, &entry_ids).await?;
|
|
let fields = secrets_map.get(&entry.id).map(Vec::as_slice).unwrap_or(&[]);
|
|
|
|
let field = fields
|
|
.iter()
|
|
.find(|f| f.field_name == field_name)
|
|
.ok_or_else(|| anyhow::anyhow!("Secret field '{}' not found", field_name))?;
|
|
|
|
crypto::decrypt_json(master_key, &field.encrypted)
|
|
}
|
|
|
|
/// Decrypt all secret fields from an entry. Returns a map field_name → decrypted Value.
|
|
pub async fn get_all_secrets(
|
|
pool: &PgPool,
|
|
namespace: &str,
|
|
kind: &str,
|
|
name: &str,
|
|
master_key: &[u8; 32],
|
|
user_id: Option<Uuid>,
|
|
) -> Result<HashMap<String, Value>> {
|
|
let entries = fetch_entries(
|
|
pool,
|
|
Some(namespace),
|
|
Some(kind),
|
|
Some(name),
|
|
&[],
|
|
None,
|
|
user_id,
|
|
)
|
|
.await?;
|
|
let entry = entries
|
|
.first()
|
|
.ok_or_else(|| anyhow::anyhow!("Not found: [{}/{}] {}", namespace, kind, name))?;
|
|
|
|
let entry_ids = vec![entry.id];
|
|
let secrets_map = fetch_secrets_for_entries(pool, &entry_ids).await?;
|
|
let fields = secrets_map.get(&entry.id).map(Vec::as_slice).unwrap_or(&[]);
|
|
|
|
let mut map = HashMap::new();
|
|
for f in fields {
|
|
let decrypted = crypto::decrypt_json(master_key, &f.encrypted)?;
|
|
map.insert(f.field_name.clone(), decrypted);
|
|
}
|
|
Ok(map)
|
|
}
|