diff --git a/src/common.rs b/src/common.rs index 33fe022..31c0aee 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,154 +1 @@ -#[cfg(test)] -mod tests { - use super::*; - #[test] - fn print_serialized_test() { - let temp_secret = TempSecret { - content: String::from("Hallo"), - version: 12, - }; - let serialized = serialize_secret_json(&temp_secret); - println!("string serialized: {:?}", serialized); - let deserialized = deserialize_secret_struct(&serialized.unwrap()); - println!( - "Struct field from deserialized: {}", - deserialized.unwrap().content - ) - } - #[test] - fn test_patching() { - // TODO add more assertions - let mut base = create_mock_meta(); - println!("OLD metadata: {:?}", base); - let overwrite: SecretMeta = SecretMeta { - max_versions: 10, - versions: vec![VersionMeta { - created_time: Utc::now(), - deletion_time: Some(Utc::now()), - destroyed: true, - }], - cas_required: true, - delete_version_after: "10m".to_string(), - current_version: 4, - oldest_version: 2, - updated_time: Utc::now(), - created_time: Utc::now(), - custom_metadata: HashMap::new(), - }; - let mut patched: Option = None; // Laurenz here - match patch_metadata(&mut base, &overwrite) { - Ok(meta) => { - println!("NEW metadata: {:?}", meta); - println!("patched successfully"); - patched = Some(meta); - } - Err(e) => { - log::error!("error patching metadata: {}", e); - panic!("Patching failed"); - } - } - - if let Some(patched_meta) = patched { - assert!(patched_meta.current_version == 4); - assert!(patched_meta.versions[0].destroyed == true); - } else { - 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![], - } -} - -use chrono::{DateTime, Utc}; -use serde::{Deserialize, Serialize}; -use serde_json::Value; -use std::collections::HashMap; - -#[derive(Serialize, Deserialize, Debug)] -pub struct TempSecret { - pub content: String, - pub version: i64, -} - -/// serialize secret to JSON String -pub fn serialize_secret_json(secret: &TempSecret) -> Result { - serde_json::to_string(&secret) -} - -/// deserialize JSON String to secret -pub fn deserialize_secret_struct(raw: &String) -> Result { - serde_json::from_str(&raw) -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct VersionMeta { - pub created_time: DateTime, - pub deletion_time: Option>, // optional deletion time - pub destroyed: bool, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct SecretMeta { - pub cas_required: bool, - pub created_time: DateTime, - pub current_version: u32, - pub delete_version_after: String, - // TODO https://developer.hashicorp.com/vault/docs/concepts/duration-format - pub max_versions: u32, - pub oldest_version: u32, - pub updated_time: DateTime, - pub custom_metadata: HashMap, - pub versions: Vec, -} - -/// serialize metadata to JSON String -pub fn serialize_metadata_json(secret: &SecretMeta) -> Result { - serde_json::to_string(&secret) -} - -/// deserialize JSON String to metadata -pub fn deserialize_metadata_struct(raw: &String) -> Result { - serde_json::from_str(&raw) -} - -// /// atrocity that currently uses unwrap -// fn patch_metadata(old: &mut SecretMeta, new: &SecretMeta) -> Result{ -// let mut patch = serde_json::to_value(serialize_metadata_json(&old).unwrap()).unwrap(); -// let new_json = serde_json::to_value(serialize_metadata_json(&new).unwrap()).unwrap(); -// json_patch::merge(&mut patch, &new_json); -// return deserialize_metadata_struct(&serde_json::to_string(&patch).unwrap()); -// } - -pub fn patch_metadata( - old: &mut SecretMeta, - new: &SecretMeta, -) -> Result { - let mut patch = serde_json::to_value(old)?; // ? operator is cool: returns early if error was detected - let new_json = serde_json::to_value(new)?; - json_patch::merge(&mut patch, &new_json); - serde_json::from_value(patch) -} - -pub fn body_to_json(body: String) -> Value { - match serde_json::from_str::(body.as_str()) { - Ok(val) => return val, - Err(e) => { - log::debug!("Faulty result from conversion: {:?}", e); - return Into::into("Error converting body"); - } - } -} +// hello world \ No newline at end of file diff --git a/src/engines.rs b/src/engines.rs index 1c17ddc..0066d21 100644 --- a/src/engines.rs +++ b/src/engines.rs @@ -1,3 +1,5 @@ +pub mod kv; + use axum::{ extract::Request, http::StatusCode, diff --git a/src/engines/kv2.rs b/src/engines/kv.rs similarity index 96% rename from src/engines/kv2.rs rename to src/engines/kv.rs index b661e2d..e143650 100644 --- a/src/engines/kv2.rs +++ b/src/engines/kv.rs @@ -1,3 +1,8 @@ +pub mod logic; +pub mod structs; +#[cfg(tests)] +mod tests; + use axum::{routing::*, Router}; pub fn kv_router() -> Router { diff --git a/src/engines/kv/logic.rs b/src/engines/kv/logic.rs new file mode 100644 index 0000000..84483c9 --- /dev/null +++ b/src/engines/kv/logic.rs @@ -0,0 +1,48 @@ +use std::collections::HashMap; + +use chrono::{DateTime, Utc}; +use serde_json::Value; + +use super::structs::*; + +// TODO create default function + +/// serialize secret to JSON String +pub fn serialize_secret_json(secret: &KvSecret) -> Result { + serde_json::to_string(&secret) +} + +/// deserialize JSON String to secret +pub fn deserialize_secret_struct(raw: &String) -> Result { + serde_json::from_str(&raw) +} + +/// serialize metadata to JSON String +pub fn serialize_metadata_json(secret: &SecretMeta) -> Result { + serde_json::to_string(&secret) +} + +/// deserialize JSON String to metadata +pub fn deserialize_metadata_struct(raw: &String) -> Result { + serde_json::from_str(&raw) +} + +pub fn patch_metadata( + old: &mut SecretMeta, + new: &SecretMeta, +) -> Result { + let mut patch = serde_json::to_value(old)?; // ? operator is cool: returns early if error was detected + let new_json = serde_json::to_value(new)?; + json_patch::merge(&mut patch, &new_json); + serde_json::from_value(patch) +} + +pub fn body_to_json(body: String) -> Value { + match serde_json::from_str::(body.as_str()) { + Ok(val) => return val, + Err(e) => { + log::debug!("Faulty result from conversion: {:?}", e); + return Into::into("Error converting body"); + } + } +} diff --git a/src/engines/kv/structs.rs b/src/engines/kv/structs.rs new file mode 100644 index 0000000..5e335df --- /dev/null +++ b/src/engines/kv/structs.rs @@ -0,0 +1,31 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +#[derive(Serialize, Deserialize, Debug)] +pub struct KvSecret { + pub content: String, + pub version: i64, + // TODO add all fields +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct VersionMeta { + pub created_time: DateTime, + pub deletion_time: Option>, // optional deletion time + pub destroyed: bool, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct SecretMeta { + pub cas_required: bool, + pub created_time: DateTime, + pub current_version: u32, + pub delete_version_after: String, + // TODO https://developer.hashicorp.com/vault/docs/concepts/duration-format + pub max_versions: u32, + pub oldest_version: u32, + pub updated_time: DateTime, + pub custom_metadata: HashMap, + pub versions: Vec, +} diff --git a/src/engines/kv/tests.rs b/src/engines/kv/tests.rs new file mode 100644 index 0000000..8b06493 --- /dev/null +++ b/src/engines/kv/tests.rs @@ -0,0 +1,71 @@ +use super::*; +#[test] +fn print_serialized_test() { + let temp_secret = TempSecret { + content: String::from("Hallo"), + version: 12, + }; + let serialized = serialize_secret_json(&temp_secret); + println!("string serialized: {:?}", serialized); + let deserialized = deserialize_secret_struct(&serialized.unwrap()); + println!( + "Struct field from deserialized: {}", + deserialized.unwrap().content + ) +} +#[test] +fn test_patching() { + // TODO add more assertions + let mut base = create_mock_meta(); + println!("OLD metadata: {:?}", base); + let overwrite: SecretMeta = SecretMeta { + max_versions: 10, + versions: vec![VersionMeta { + created_time: Utc::now(), + deletion_time: Some(Utc::now()), + destroyed: true, + }], + cas_required: true, + delete_version_after: "10m".to_string(), + current_version: 4, + oldest_version: 2, + updated_time: Utc::now(), + created_time: Utc::now(), + custom_metadata: HashMap::new(), + }; + let mut patched: Option = None; // Laurenz here + match patch_metadata(&mut base, &overwrite) { + Ok(meta) => { + println!("NEW metadata: {:?}", meta); + println!("patched successfully"); + patched = Some(meta); + } + Err(e) => { + log::error!("error patching metadata: {}", e); + panic!("Patching failed"); + } + } + + if let Some(patched_meta) = patched { + assert!(patched_meta.current_version == 4); + assert!(patched_meta.versions[0].destroyed == true); + } else { + 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![], + } +} diff --git a/src/main.rs b/src/main.rs index 3d2d969..a9266d8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use serde::Deserialize; use std::{env, net::SocketAddr, str::FromStr}; use tokio::net::TcpListener; -use crate::common::body_to_json; +use crate::engines::kv::logic::body_to_json; mod auth; mod common;