use serde::{Deserialize, Serialize};
use crate::client::{get_owner, Client, PostBody};
use crate::enforcer::Enforcer;
use crate::error::Result;
use crate::serde_util::null_to_default;
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase", default)]
pub struct CasbinRule {
pub id: i64,
pub ptype: String,
pub v0: String,
pub v1: String,
pub v2: String,
pub v3: String,
pub v4: String,
pub v5: String,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct PolicyFilter {
pub ptype: String,
pub field_index: Option<i32>,
#[serde(deserialize_with = "null_to_default")]
pub field_values: Vec<String>,
}
impl Client {
pub async fn get_policies(
&self,
enforcer_name: &str,
adapter_id: &str,
) -> Result<Vec<CasbinRule>> {
self.get_list(
"get-policies",
&[
("id", &self.get_id(enforcer_name)),
("adapterId", adapter_id),
],
)
.await
}
pub async fn get_filtered_policies(
&self,
enforcer_id: &str,
filters: &[PolicyFilter],
) -> Result<Vec<CasbinRule>> {
let post_bytes = serde_json::to_vec(filters)?;
let response = self
.do_post(
"get-filtered-policies",
&[("id", enforcer_id)],
PostBody::Raw(post_bytes),
)
.await?;
if response.data.is_null() {
return Ok(Vec::new());
}
Ok(serde_json::from_value(response.data)?)
}
pub async fn add_policy(&self, enforcer: &Enforcer, policy: &CasbinRule) -> Result<bool> {
self.modify_policy("add-policy", enforcer, policy).await
}
pub async fn update_policy(
&self,
enforcer: &Enforcer,
old_policy: &CasbinRule,
new_policy: &CasbinRule,
) -> Result<bool> {
self.modify_policy(
"update-policy",
enforcer,
&[old_policy.clone(), new_policy.clone()],
)
.await
}
pub async fn remove_policy(&self, enforcer: &Enforcer, policy: &CasbinRule) -> Result<bool> {
self.modify_policy("remove-policy", enforcer, policy).await
}
async fn modify_policy<T: Serialize>(
&self,
action: &str,
enforcer: &Enforcer,
policies: &T,
) -> Result<bool> {
let owner = get_owner(&enforcer.owner, &self.config.organization_name);
let id = format!("{}/{}", owner, enforcer.name);
Ok(self.modify_object(action, &id, policies, &[]).await?.1)
}
}