+ Update + refactor KvSecret struct

+ Update Secretmeta + default()
This commit is contained in:
sam 2024-05-01 16:52:37 +02:00
parent 79130d39e8
commit 2f570a7a9d
7 changed files with 48 additions and 37 deletions

1
Cargo.lock generated
View file

@ -1579,7 +1579,6 @@ dependencies = [
"sha2", "sha2",
"sqlx-core", "sqlx-core",
"sqlx-mysql", "sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite", "sqlx-sqlite",
"syn 1.0.109", "syn 1.0.109",
"tempfile", "tempfile",

View file

@ -23,7 +23,7 @@ json-patch = "1.2.0"
# utoipa = { version = "4.2.0", features = ["axum_extras"] } # utoipa = { version = "4.2.0", features = ["axum_extras"] }
sqlx = { version = "0.7.4", features = [ sqlx = { version = "0.7.4", features = [
"sqlite", "sqlite",
"postgres", # "postgres",
"any", "any",
"macros", "macros",
"runtime-tokio", "runtime-tokio",

View file

@ -43,8 +43,8 @@ func TestWriteSecret(t *testing.T) {
// Path foo // Path foo
_, err := client.Secrets.KvV2Write(ctx, "foo", schema.KvV2WriteRequest{ _, err := client.Secrets.KvV2Write(ctx, "foo", schema.KvV2WriteRequest{
Data: map[string]any{ Data: map[string]any{
"password1": "abc123", "password1": "123abc",
"version": 1, "password2": "horse horse horse battery staple correct",
}}, }},
vault.WithMountPath(mountpath), vault.WithMountPath(mountpath),
) )
@ -56,8 +56,8 @@ func TestWriteSecret(t *testing.T) {
// Path bar // Path bar
_, err = client.Secrets.KvV2Write(ctx, "bar", schema.KvV2WriteRequest{ _, err = client.Secrets.KvV2Write(ctx, "bar", schema.KvV2WriteRequest{
Data: map[string]any{ Data: map[string]any{
"password1": "secure123", "password1": "abc123",
"password2": "second password", "password2": "correct horse battery staple",
}}, }},
vault.WithMountPath(mountpath), vault.WithMountPath(mountpath),
) )

View file

@ -1,7 +1,5 @@
pub mod kv; pub mod kv;
use std::string;
use crate::engines::kv::logic::body_to_json; use crate::engines::kv::logic::body_to_json;
use crate::engines::kv::structs::KvSecret; use crate::engines::kv::structs::KvSecret;
use axum::{ use axum::{
@ -19,8 +17,8 @@ pub fn secrets_router(pool: Pool<Any>) -> Router<Pool<Any>> {
// Router::new().layer(map_request(handler)) // Router::new().layer(map_request(handler))
Router::new() Router::new()
.route("/:mount_path/data/:kv_path", post(baz)) .route("/:mount_path/data/:kv_path", post(baz))
.with_state(pool) .with_state(pool)
} }
/// Routing handler for path "/v1/kv-v2/data/foo" /// Routing handler for path "/v1/kv-v2/data/foo"
@ -29,14 +27,16 @@ pub fn secrets_router(pool: Pool<Any>) -> Router<Pool<Any>> {
async fn baz(Path(mount_path): Path<String>, Path(kv_path): Path<String>, body: String) -> String { async fn baz(Path(mount_path): Path<String>, Path(kv_path): Path<String>, body: String) -> String {
let mut body_json = body_to_json(body); let mut body_json = body_to_json(body);
// TODO: If version field provided during a read, the value at the version number will be returned
let secret: KvSecret = KvSecret { let secret: KvSecret = KvSecret {
content: body_json["data"]["password1"].take().to_string(), data: body_json.to_string(),
version: body_json["data"]["version"].take().as_i64().unwrap(), // content: body_json["data"]["password1"].take().to_string(),
version: body_json["data"]["version"].take().as_i64(),
}; };
log::debug!( log::debug!(
"Secret: {}, Content: {}, Version: {}, path: {}", "Secret: {}, Content: {}, Version: {:?}, path: {}",
kv_path, kv_path,
secret.content, secret.data,
secret.version, secret.version,
mount_path, mount_path,
); );

View file

@ -39,6 +39,9 @@ async fn post_data() -> &'static str {
todo!("not implemented") todo!("not implemented")
} }
/// TODO soft delete the secret version at path. can be undone with undelete_secret
// https://developer.hashicorp.com/vault/api-docs/secret/kv/kv-v2#delete-latest-version-of-secret
// https://developer.hashicorp.com/vault/api-docs/secret/kv/kv-v2#delete-secret-versions
async fn delete_data() -> &'static str { async fn delete_data() -> &'static str {
todo!("not implemented") todo!("not implemented")
} }

View file

@ -1,11 +1,14 @@
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::{collections::HashMap, hash::Hash, vec};
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct KvSecret { pub struct KvSecret {
pub content: String, // TODO: maybe change later for field validation etc.
pub version: i64, pub data: String,
// TODO: options for secrets
// pub options: HashMap<String, String>,
pub version: Option<i64>,
// TODO add all fields // TODO add all fields
} }
@ -20,12 +23,34 @@ pub struct VersionMeta {
pub struct SecretMeta { pub struct SecretMeta {
pub cas_required: bool, pub cas_required: bool,
pub created_time: DateTime<Utc>, pub created_time: DateTime<Utc>,
pub current_version: u32, pub current_version: i64,
/// In Hashicorp:
/// If not set, the backend's configured delete_version_after is used.
/// Cannot be greater than the backend's delete_version_after
// TODO: implement duration type
pub delete_version_after: String, pub delete_version_after: String,
// TODO https://developer.hashicorp.com/vault/docs/concepts/duration-format // TODO https://developer.hashicorp.com/vault/docs/concepts/duration-format
pub max_versions: u32, pub max_versions: i64,
pub oldest_version: u32, pub oldest_version: i64,
pub updated_time: DateTime<Utc>, pub updated_time: DateTime<Utc>,
pub custom_metadata: HashMap<String, String>, /// User-provided key-value pairs that are used to describe arbitrary and version-agnostic information about a secret.
pub custom_metadata: Option<HashMap<String, String>>,
pub versions: Vec<VersionMeta>, pub versions: Vec<VersionMeta>,
} }
impl Default for SecretMeta {
fn default() -> Self {
let current = Utc::now();
SecretMeta {
cas_required: false,
created_time: current,
current_version: 1,
delete_version_after: "24h00m00s".to_string(),
max_versions: 10,
oldest_version: 1,
updated_time: current,
custom_metadata: None,
versions: vec![],
}
}
}

View file

@ -53,19 +53,3 @@ fn test_patching() {
panic!("patched was not initialized"); panic!("patched was not initialized");
} }
} }
pub fn create_mock_meta() -> SecretMeta {
SecretMeta {
cas_required: false,
created_time: DateTime::parse_from_rfc3339("2018-03-22T02:24:06.945319214Z")
.unwrap()
.with_timezone(&Utc),
current_version: 3,
delete_version_after: "3h25m19s".to_string(),
max_versions: 0,
oldest_version: 0,
updated_time: Utc::now(),
custom_metadata: HashMap::new(),
versions: vec![],
}
}