fix(secrets-mcp 0.5.20): code review plan — export secret types, env map, rollback, API key, MCP tools, web session & validation
- Export/import: optional secret_types map; AddResult includes entry_id - env_map: dot→__ segment encoding; collision errors - rollback: FOR UPDATE + txn-consistent snapshot; restore name from history - regenerate_api_key: rows_affected guard - MCP: find count propagates errors; add uses entry_id for relations; rollback no encryption key - Web: load_session_user_strict + JSON handlers key_version; PATCH length limits - Tests: ExportEntry serde, env segment
This commit is contained in:
@@ -345,15 +345,6 @@ impl SecretsService {
|
||||
Self::extract_enc_key(ctx)
|
||||
}
|
||||
|
||||
/// Require both user_id and encryption key (header only, no arg fallback).
|
||||
fn require_user_and_key(
|
||||
ctx: &RequestContext<RoleServer>,
|
||||
) -> Result<(Uuid, [u8; 32]), rmcp::ErrorData> {
|
||||
let user_id = Self::require_user_id(ctx)?;
|
||||
let key = Self::extract_enc_key(ctx)?;
|
||||
Ok((user_id, key))
|
||||
}
|
||||
|
||||
/// Require both user_id and encryption key, preferring an explicit argument
|
||||
/// value over the X-Encryption-Key header.
|
||||
fn require_user_and_key_or_arg(
|
||||
@@ -801,10 +792,7 @@ impl SecretsService {
|
||||
|
||||
let total_count = secrets_core::service::search::count_entries(&self.pool, &count_params)
|
||||
.await
|
||||
.inspect_err(
|
||||
|e| tracing::warn!(tool = "secrets_find", error = %e, "count_entries failed"),
|
||||
)
|
||||
.unwrap_or(0);
|
||||
.map_err(|e| mcp_err_internal_logged("secrets_find", Some(user_id), e))?;
|
||||
let relation_map = get_relations_for_entries(
|
||||
&self.pool,
|
||||
&result
|
||||
@@ -1135,11 +1123,8 @@ impl SecretsService {
|
||||
.await
|
||||
.map_err(|e| mcp_err_from_anyhow("secrets_add", Some(user_id), e))?;
|
||||
|
||||
let created_entry = resolve_entry(&self.pool, &input.name, Some(folder), Some(user_id))
|
||||
.await
|
||||
.map_err(|e| mcp_err_internal_logged("secrets_add", Some(user_id), e))?;
|
||||
for parent_id in parent_ids {
|
||||
add_parent_relation(&self.pool, parent_id, created_entry.id, Some(user_id))
|
||||
add_parent_relation(&self.pool, parent_id, result.entry_id, Some(user_id))
|
||||
.await
|
||||
.map_err(|e| mcp_err_from_anyhow("secrets_add", Some(user_id), e))?;
|
||||
}
|
||||
@@ -1420,7 +1405,7 @@ impl SecretsService {
|
||||
}
|
||||
|
||||
#[tool(
|
||||
description = "Rollback an entry to a previous version. Requires X-Encryption-Key header. \
|
||||
description = "Rollback an entry to a previous version. Requires Bearer API key only (no encryption key). \
|
||||
Omit to_version to restore the most recent snapshot. \
|
||||
Optionally pass 'id' (from secrets_find) to target directly.",
|
||||
annotations(title = "Rollback Secret Entry", destructive_hint = true)
|
||||
@@ -1431,7 +1416,7 @@ impl SecretsService {
|
||||
ctx: RequestContext<RoleServer>,
|
||||
) -> Result<CallToolResult, rmcp::ErrorData> {
|
||||
let t = Instant::now();
|
||||
let (user_id, _user_key) = Self::require_user_and_key(&ctx)?;
|
||||
let user_id = Self::require_user_id(&ctx)?;
|
||||
tracing::info!(
|
||||
tool = "secrets_rollback",
|
||||
?user_id,
|
||||
|
||||
Reference in New Issue
Block a user