Merged postData, deleteData, postMeta

This commit is contained in:
someone 2024-06-02 20:17:21 +02:00
commit 075f13777a
3 changed files with 169 additions and 18 deletions

View file

@ -13,6 +13,7 @@ import (
var client *vault.Client
var ctx context.Context
// Apparently used as a default if mountpath is an empty string (client library)
var mountpath = "/kv-v2"
var mountpath2 = "/some"
@ -106,14 +107,54 @@ func TestDeleteSecret(t *testing.T) {
func TestReadSecret(t *testing.T) {
_, err := client.Secrets.KvV2Read(ctx, "bar")
if err != nil {
log.Fatal("kv2: Failed to read secret:\n\t", err)
}
}
func TestReadSecret2(t *testing.T) {
_, err := client.Secrets.KvV2Read(ctx, "ba")
func TestReadMeta(t *testing.T) {
_, err := client.Secrets.KvV2ReadMetadata(ctx, "bar")
if err != nil {
log.Fatal("kv2: Failed to read secret:\n\t", err)
log.Fatal("kv2: Failed to read metadata:\n\t", err)
}
}
}
func TestWriteAndReadMeta(t *testing.T) {
meta := schema.KvV2WriteMetadataRequest{
MaxVersions: 5,
CasRequired: false,
DeleteVersionAfter: "3h25m19s",
CustomMetadata: map[string]interface{}{
"foo": "abc",
"bar": "123",
"baz": "5c07d823-3810-48f6-a147-4c06b5219e84",
},
}
_, err := client.Secrets.KvV2WriteMetadata(ctx, "newMeta", meta)
if err != nil {
log.Fatal("kv2: Failed to write metadata:\n\t", err)
}
// read the metadata
_, err2 := client.Secrets.KvV2ReadMetadata(ctx, "newMeta")
if err2 != nil {
log.Fatal("kv2: Failed to read metadata:\n\t", err)
}
}
// does NOT revert destruction
func TestDestroySecret(t *testing.T) {
_, err := client.Secrets.KvV2DestroyVersions(ctx, "bar", schema.KvV2DestroyVersionsRequest{Versions: []int32{1}})
if err != nil {
log.Fatal("kv2: Failed to destroy secret:\n\t", err)
}
}
// does NOT revert destruction
func TestDestroySecret2(t *testing.T) {
_, err := client.Secrets.KvV2DestroyVersions(ctx, "bar", schema.KvV2DestroyVersionsRequest{Versions: []int32{1, 2}})
if err != nil {
log.Fatal("kv2: Failed to destroy secret:\n\t", err)
}
}

View file

@ -8,10 +8,7 @@ pub mod http_structs;
// #[cfg(test)]
// mod tests;
use crate::{
engines::kv::{self, http_structs::*},
storage::DatabaseDriver,
};
use crate::{engines::kv::http_structs::*, storage::DatabaseDriver};
use axum::{
extract::{self, Path, State},
http::StatusCode,
@ -24,7 +21,8 @@ use chrono::{DateTime, Utc};
use db_structs::*;
use log::{error, info};
use serde_json;
use sqlx::Row;
use sqlx::{Row, Sqlite};
use std::{collections::HashMap, convert::Infallible};
pub fn kv_router(pool: DatabaseDriver) -> Router {
@ -206,8 +204,48 @@ async fn delete_path() -> &'static str {
todo!("not implemented")
}
async fn destroy_path() -> &'static str {
todo!("not implemented")
async fn destroy_path(
State(pool): State<DatabaseDriver>,
Path(kv_path): Path<String>,
Json(body): Json<KvSecretDestrReq>,
) -> Result<impl IntoResponse, Infallible> {
let versions = body.versions;
for ver in versions {
let res_wrapper = sqlx::query::<Sqlite>(
"DELETE FROM secret_versions where secret_path = $1 AND version_number = $2",
)
.bind(&kv_path)
.bind(ver)
.execute(&pool)
.await;
match res_wrapper {
Ok(result) => {
if result.rows_affected() == 0 {
log::debug!(
"No rows were deleted for version {} at path {}",
ver,
kv_path
);
} else {
log::debug!("Deleted version {} at path {}", ver, kv_path);
}
}
Err(e) => {
log::error!(
"Failed to delete version {} at path {}: {}",
ver,
kv_path,
e
);
}
}
}
// check if all are gone
Ok(StatusCode::NO_CONTENT)
}
async fn get_meta(
@ -302,14 +340,59 @@ async fn get_meta(
Ok((StatusCode::OK, Json(metadata_res)).into_response())
}
// currently only writes the metadata - No case if already exists
async fn post_meta(
State(pool): State<DatabaseDriver>,
Path((mount_path, kv_path)): Path<(String, String)>,
body: String,
) -> &'static str {
// let mut body_json = body_to_json(body);
// let meta_data: SecretMeta = Default::default();
todo!("not implemented")
Path(kv_path): Path<String>,
Json(body): Json<KvMetaReq>,
// extract::Json(body): extract::Json<http_structs::KvMetaReq>,
) -> Result<impl IntoResponse, Infallible> {
let now = Utc::now();
let custom_metadata: String = match serde_json::to_string(&body.custom_metadata) {
Ok(data) => data,
Err(_) => {
log::error!(
"could not serialize custom_metadata: {:?}\ndropping data",
body.custom_metadata
);
String::new()
}
};
let new_metadata = DbSecretMeta {
cas_required: body.cas_required.unwrap_or(false),
secret_path: kv_path,
created_time: now,
delete_version_after: Some("30d".to_string()),
max_versions: body.max_versions,
updated_time: now,
custom_data: Some(custom_metadata),
};
match sqlx::query("INSERT INTO metadata (cas_required, secret_path, created_time, delete_version_after, max_versions, updated_time, custom_data) VALUES ($1, $2, $3, $4, $5, $6, $7)")
.bind(new_metadata.cas_required)
.bind(new_metadata.secret_path)
.bind(new_metadata.created_time)
.bind(new_metadata.delete_version_after.unwrap())
.bind(new_metadata.max_versions)
.bind(new_metadata.updated_time)
.bind(new_metadata.custom_data.unwrap())
.execute(&pool)
.await
{
Ok(result) => {
info!("{:?}", result);
if result.rows_affected() == 0 {
log::error!("Failed to insert metadata");
}
}
Err(e) => {
error!("{:?}", e);
}
};
Ok(StatusCode::NO_CONTENT)
}
async fn delete_meta() -> &'static str {

View file

@ -59,6 +59,12 @@ impl ErrorStruct {
}
}
#[derive(Deserialize)]
/// HTTP Request to destroy secret versions
pub struct KvSecretDestrReq {
pub versions: Vec<i64>,
}
#[derive(Serialize, Debug)]
/// HTTP Response to Reading a Secret metadata
/// Container of [`KvMetaResData`]
@ -105,8 +111,29 @@ pub struct KvMetaResData {
pub max_versions: i64,
pub oldest_version: i64,
pub updated_time: DateTime<Utc>,
// pub custom_metadata: Option<String>, // TODO as hashmap
pub custom_metadata: Option<HashMap<String, String>>,
pub versions: HashMap<i64, KvMetaResVersionData>,
// the key to a version is the version number
}
// Example
// {
// "max_versions": 5,
// "cas_required": false,
// "delete_version_after": "3h25m19s",
// "custom_metadata": {
// "foo": "abc",
// "bar": "123",
// "baz": "5c07d823-3810-48f6-a147-4c06b5219e84"
// }
// }
#[derive(Serialize, Debug, Deserialize)]
/// HTTP Request to post metadatas
pub struct KvMetaReq {
pub cas_required: Option<bool>,
// pub cas_required: bool,
pub delete_version_after: Option<String>,
pub max_versions: i64,
// pub updated_time: Option<DateTime<Utc>>,
pub custom_metadata: Option<HashMap<String, String>>,
}