From 22e3a1e50cbfd7245b80abb08344b0ce41c89abd Mon Sep 17 00:00:00 2001 From: Ruslan Pislari Date: Tue, 17 Dec 2024 12:58:47 +0200 Subject: [PATCH] feat: adding secret get_effective_at method --- examples/secret/src/lib.rs | 34 +++++++++++++++++++++++++++-- src/lib.rs | 3 +++ src/proxywasm.rs | 44 +++++++++++++++++++++++++++++++++++--- wit/secret.wit | 6 +++++- 4 files changed, 81 insertions(+), 6 deletions(-) diff --git a/examples/secret/src/lib.rs b/examples/secret/src/lib.rs index 9ca7628..866cab9 100644 --- a/examples/secret/src/lib.rs +++ b/examples/secret/src/lib.rs @@ -1,4 +1,4 @@ - +use std::time::SystemTime; use anyhow::{Error, Result}; use fastedge::body::Body; @@ -37,8 +37,38 @@ fn main(_req: Request) -> Result> { .map_err(Error::msg); } + let ts = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).expect("Time went backwards").as_secs(); + let effective_at_value = match secret::get_effective_at("SECRET", ts) { + Ok(value) => value, + Err(secret::Error::AccessDenied) => { + return Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::empty()) + .map_err(Error::msg); + }, + Err(secret::Error::Other(msg)) => { + return Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from(msg)) + .map_err(Error::msg); + }, + Err(secret::Error::DecryptError) => { + return Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::empty()) + .map_err(Error::msg); + } + }; + + if effective_at_value.is_none() { + return Response::builder() + .status(StatusCode::NOT_FOUND) + .body(Body::empty()) + .map_err(Error::msg); + } + Response::builder() .status(StatusCode::OK) - .body(Body::from(value.unwrap_or_default())) + .body(Body::from(format!("get={:?}\nget_efective_at={:?}\n", value, effective_at_value))) .map_err(Error::msg) } diff --git a/src/lib.rs b/src/lib.rs index da433a0..6331939 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,6 +43,9 @@ pub mod dictionary { pub mod secret { #[doc(inline)] pub use crate::gcore::fastedge::secret::get; + #[doc(inline)] + pub use crate::gcore::fastedge::secret::get_effective_at; + pub use crate::gcore::fastedge::secret::Error; } /// Error type returned by [`send_request`] diff --git a/src/proxywasm.rs b/src/proxywasm.rs index 8e58ea0..4bde920 100644 --- a/src/proxywasm.rs +++ b/src/proxywasm.rs @@ -5,15 +5,23 @@ extern "C" { return_value_data: *mut *mut u8, return_value_size: *mut usize, ) -> u32; + + fn proxy_get_effective_at_secret( + key_data: *const u8, + key_size: usize, + at: u64, + return_value_data: *mut *mut u8, + return_value_size: *mut usize, + ) -> u32; } /// ProxyWasm secret interface pub mod secret { - use crate::proxywasm::proxy_get_secret; + use crate::proxywasm::{proxy_get_secret, proxy_get_effective_at_secret}; use std::ptr::null_mut; - /// Get secret method. - /// return None if secret not found for given key + /// Returns a secret value to the corresponding key effective now. + /// If the value does not exist returns `None`. pub fn get(key: &str) -> Result>, u32> { let mut return_data: *mut u8 = null_mut(); let mut return_size: usize = 0; @@ -40,4 +48,34 @@ pub mod secret { } } } + + /// Returns a secret value to the corresponding key effective at given timestamp (in sec). + /// If the value does not exist returns `None`. + pub fn get_effective_at(key: &str, at: u64) -> Result>, u32> { + let mut return_data: *mut u8 = null_mut(); + let mut return_size: usize = 0; + unsafe { + match proxy_get_effective_at_secret( + key.as_ptr(), + key.len(), + at, + &mut return_data, + &mut return_size, + ) { + 0 => { + if !return_data.is_null() { + Ok(Some(Vec::from_raw_parts( + return_data, + return_size, + return_size, + ))) + } else { + Ok(None) + } + } + 1 => Ok(None), + status => panic!("unexpected status: {}", status), + } + } + } } \ No newline at end of file diff --git a/wit/secret.wit b/wit/secret.wit index a13b263..cfe4dba 100644 --- a/wit/secret.wit +++ b/wit/secret.wit @@ -1,8 +1,12 @@ interface secret { - /// Get the secret associated with the specified `key` + /// Get the secret associated with the specified `key` efective at current timestamp. /// Returns `ok(none)` if the key does not exist. get: func(key: string) -> result, error>; + /// Get the secret associated with the specified `key` effective `at` given timestamp in seconds. + /// Returns `ok(none)` if the key does not exist. + get-effective-at: func(key: string, at: u64) -> result, error>; + /// The set of errors which may be raised by functions in this interface variant error { /// The requesting component does not have access to the specified key