From 9d3bbdcd28c46c9ab04ad3b3b1185f95335af6f3 Mon Sep 17 00:00:00 2001 From: sanbei101 Date: Sun, 6 Oct 2024 02:12:44 +0000 Subject: [PATCH] feat: add StringAdapter to file adapter module --- src/adapter/mod.rs | 4 + src/adapter/string_adapater.rs | 156 +++++++++++++++++++++++++++++++++ src/lib.rs | 3 +- 3 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 src/adapter/string_adapater.rs diff --git a/src/adapter/mod.rs b/src/adapter/mod.rs index ad27afd2..cadaee7a 100644 --- a/src/adapter/mod.rs +++ b/src/adapter/mod.rs @@ -4,11 +4,15 @@ use async_trait::async_trait; pub mod file_adapter; pub mod memory_adapter; pub mod null_adapter; +#[cfg(not(target_arch = "wasm32"))] +pub mod string_adapater; #[cfg(not(target_arch = "wasm32"))] pub use file_adapter::FileAdapter; pub use memory_adapter::MemoryAdapter; pub use null_adapter::NullAdapter; +#[cfg(not(target_arch = "wasm32"))] +pub use string_adapater::StringAdapter; use crate::{model::Model, Result}; diff --git a/src/adapter/string_adapater.rs b/src/adapter/string_adapater.rs new file mode 100644 index 00000000..fe56decd --- /dev/null +++ b/src/adapter/string_adapater.rs @@ -0,0 +1,156 @@ +pub struct StringAdapter { + policy_string: String, + is_filtered: bool, +} + +impl StringAdapter { + pub fn new(policy_string: String) -> Self { + StringAdapter { + policy_string, + is_filtered: false, + } + } + + pub fn new_filtered_adapter(policy_string: String) -> Self { + StringAdapter { + policy_string, + is_filtered: true, + } + } + + fn load_policy_from_string( + &mut self, + m: &mut dyn Model, + handler: LoadPolicyFileHandler, + ) -> Result<()> { + let lines = self.policy_string.lines(); + for line in lines { + handler(line.to_string(), m); + } + Ok(()) + } + + fn load_filtered_policy_from_string<'a>( + &mut self, + m: &mut dyn Model, + filter: Filter<'a>, + handler: LoadFilteredPolicyFileHandler<'a>, + ) -> Result { + let mut is_filtered = false; + let lines = self.policy_string.lines(); + for line in lines { + if handler(line.to_string(), m, &filter) { + is_filtered = true; + } + } + Ok(is_filtered) + } + + fn save_policy_to_string(&mut self, policies: String) -> Result<()> { + self.policy_string = policies; + Ok(()) + } +} + +#[async_trait] +impl Adapter for StringAdapter { + async fn load_policy(&mut self, m: &mut dyn Model) -> Result<()> { + self.is_filtered = false; + self.load_policy_from_string(m, load_policy_line)?; + Ok(()) + } + + async fn load_filtered_policy<'a>( + &mut self, + m: &mut dyn Model, + f: Filter<'a>, + ) -> Result<()> { + self.is_filtered = self.load_filtered_policy_from_string( + m, + f, + load_filtered_policy_line, + )?; + Ok(()) + } + + async fn save_policy(&mut self, m: &mut dyn Model) -> Result<()> { + let mut policies = String::new(); + let ast_map = m.get_model().get("p").ok_or_else(|| { + ModelError::P("Missing policy definition in conf file".to_owned()) + })?; + + for (ptype, ast) in ast_map { + for rule in ast.get_policy() { + writeln!(policies, "{},{}", ptype, rule.join(",")) + .map_err(|e| AdapterError(e.into()))?; + } + } + + if let Some(ast_map) = m.get_model().get("g") { + for (ptype, ast) in ast_map { + for rule in ast.get_policy() { + writeln!(policies, "{},{}", ptype, rule.join(",")) + .map_err(|e| AdapterError(e.into()))?; + } + } + } + + self.save_policy_to_string(policies)?; + Ok(()) + } + + async fn clear_policy(&mut self) -> Result<()> { + self.save_policy_to_string(String::new())?; + Ok(()) + } + + async fn add_policy( + &mut self, + _sec: &str, + _ptype: &str, + _rule: Vec, + ) -> Result { + Ok(true) + } + + async fn add_policies( + &mut self, + _sec: &str, + _ptype: &str, + _rules: Vec>, + ) -> Result { + Ok(true) + } + + async fn remove_policy( + &mut self, + _sec: &str, + _ptype: &str, + _rule: Vec, + ) -> Result { + Ok(true) + } + + async fn remove_policies( + &mut self, + _sec: &str, + _ptype: &str, + _rules: Vec>, + ) -> Result { + Ok(true) + } + + async fn remove_filtered_policy( + &mut self, + _sec: &str, + _ptype: &str, + _field_index: usize, + _field_values: Vec, + ) -> Result { + Ok(true) + } + + fn is_filtered(&self) -> bool { + self.is_filtered + } +} diff --git a/src/lib.rs b/src/lib.rs index 0ed2bc93..0c89db52 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,8 +34,9 @@ pub mod prelude; #[cfg(not(target_arch = "wasm32"))] pub use adapter::FileAdapter; +#[cfg(not(target_arch = "wasm32"))] +pub use adapter::StringAdapter; pub use adapter::{Adapter, Filter, MemoryAdapter, NullAdapter}; - #[cfg(feature = "cached")] pub use cache::{Cache, DefaultCache}; #[cfg(feature = "cached")]