= big refactor meeting

This commit is contained in:
sam 2024-04-28 14:27:02 +02:00
parent 6e215a99ee
commit aae1225d2d
7 changed files with 159 additions and 155 deletions

View file

@ -1,154 +1 @@
#[cfg(test)] // hello world
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<SecretMeta> = 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<String, serde_json::Error> {
serde_json::to_string(&secret)
}
/// deserialize JSON String to secret
pub fn deserialize_secret_struct(raw: &String) -> Result<TempSecret, serde_json::Error> {
serde_json::from_str(&raw)
}
#[derive(Serialize, Deserialize, Debug)]
pub struct VersionMeta {
pub created_time: DateTime<Utc>,
pub deletion_time: Option<DateTime<Utc>>, // optional deletion time
pub destroyed: bool,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SecretMeta {
pub cas_required: bool,
pub created_time: DateTime<Utc>,
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<Utc>,
pub custom_metadata: HashMap<String, String>,
pub versions: Vec<VersionMeta>,
}
/// serialize metadata to JSON String
pub fn serialize_metadata_json(secret: &SecretMeta) -> Result<String, serde_json::Error> {
serde_json::to_string(&secret)
}
/// deserialize JSON String to metadata
pub fn deserialize_metadata_struct(raw: &String) -> Result<SecretMeta, serde_json::Error> {
serde_json::from_str(&raw)
}
// /// atrocity that currently uses unwrap
// fn patch_metadata(old: &mut SecretMeta, new: &SecretMeta) -> Result<SecretMeta, serde_json::Error>{
// 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<SecretMeta, serde_json::Error> {
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::<serde_json::Value>(body.as_str()) {
Ok(val) => return val,
Err(e) => {
log::debug!("Faulty result from conversion: {:?}", e);
return Into::into("Error converting body");
}
}
}

View file

@ -1,3 +1,5 @@
pub mod kv;
use axum::{ use axum::{
extract::Request, extract::Request,
http::StatusCode, http::StatusCode,

View file

@ -1,3 +1,8 @@
pub mod logic;
pub mod structs;
#[cfg(tests)]
mod tests;
use axum::{routing::*, Router}; use axum::{routing::*, Router};
pub fn kv_router() -> Router { pub fn kv_router() -> Router {

48
src/engines/kv/logic.rs Normal file
View file

@ -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<String, serde_json::Error> {
serde_json::to_string(&secret)
}
/// deserialize JSON String to secret
pub fn deserialize_secret_struct(raw: &String) -> Result<KvSecret, serde_json::Error> {
serde_json::from_str(&raw)
}
/// serialize metadata to JSON String
pub fn serialize_metadata_json(secret: &SecretMeta) -> Result<String, serde_json::Error> {
serde_json::to_string(&secret)
}
/// deserialize JSON String to metadata
pub fn deserialize_metadata_struct(raw: &String) -> Result<SecretMeta, serde_json::Error> {
serde_json::from_str(&raw)
}
pub fn patch_metadata(
old: &mut SecretMeta,
new: &SecretMeta,
) -> Result<SecretMeta, serde_json::Error> {
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::<serde_json::Value>(body.as_str()) {
Ok(val) => return val,
Err(e) => {
log::debug!("Faulty result from conversion: {:?}", e);
return Into::into("Error converting body");
}
}
}

31
src/engines/kv/structs.rs Normal file
View file

@ -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<Utc>,
pub deletion_time: Option<DateTime<Utc>>, // optional deletion time
pub destroyed: bool,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SecretMeta {
pub cas_required: bool,
pub created_time: DateTime<Utc>,
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<Utc>,
pub custom_metadata: HashMap<String, String>,
pub versions: Vec<VersionMeta>,
}

71
src/engines/kv/tests.rs Normal file
View file

@ -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<SecretMeta> = 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![],
}
}

View file

@ -4,7 +4,7 @@ use serde::Deserialize;
use std::{env, net::SocketAddr, str::FromStr}; use std::{env, net::SocketAddr, str::FromStr};
use tokio::net::TcpListener; use tokio::net::TcpListener;
use crate::common::body_to_json; use crate::engines::kv::logic::body_to_json;
mod auth; mod auth;
mod common; mod common;