Skip to main content

casdoor_rust_sdk/
policy.rs

1// Copyright 2026 The Casdoor Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use serde::{Deserialize, Serialize};
16
17use crate::client::{get_owner, Client, PostBody};
18use crate::enforcer::Enforcer;
19use crate::error::Result;
20use crate::serde_util::null_to_default;
21
22/// CasbinRule is one policy rule stored by a Casbin adapter. Its JSON fields are
23/// capitalized, as the Casbin xorm adapter defines them without JSON tags.
24#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
25#[serde(rename_all = "PascalCase", default)]
26pub struct CasbinRule {
27    pub id: i64,
28    pub ptype: String,
29    pub v0: String,
30    pub v1: String,
31    pub v2: String,
32    pub v3: String,
33    pub v4: String,
34    pub v5: String,
35}
36
37/// A filter used by [`Client::get_filtered_policies()`].
38#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
39#[serde(rename_all = "camelCase", default)]
40pub struct PolicyFilter {
41    pub ptype: String,
42    pub field_index: Option<i32>,
43    #[serde(deserialize_with = "null_to_default")]
44    pub field_values: Vec<String>,
45}
46
47impl Client {
48    /// Get the policies of an enforcer. `adapter_id` can be empty to use the adapter of
49    /// the enforcer.
50    pub async fn get_policies(
51        &self,
52        enforcer_name: &str,
53        adapter_id: &str,
54    ) -> Result<Vec<CasbinRule>> {
55        self.get_list(
56            "get-policies",
57            &[
58                ("id", &self.get_id(enforcer_name)),
59                ("adapterId", adapter_id),
60            ],
61        )
62        .await
63    }
64
65    /// Get the policies of an enforcer, filtered by the field index and the field values.
66    pub async fn get_filtered_policies(
67        &self,
68        enforcer_id: &str,
69        filters: &[PolicyFilter],
70    ) -> Result<Vec<CasbinRule>> {
71        let post_bytes = serde_json::to_vec(filters)?;
72
73        let response = self
74            .do_post(
75                "get-filtered-policies",
76                &[("id", enforcer_id)],
77                PostBody::Raw(post_bytes),
78            )
79            .await?;
80
81        if response.data.is_null() {
82            return Ok(Vec::new());
83        }
84
85        Ok(serde_json::from_value(response.data)?)
86    }
87
88    /// Add one policy to an enforcer.
89    pub async fn add_policy(&self, enforcer: &Enforcer, policy: &CasbinRule) -> Result<bool> {
90        self.modify_policy("add-policy", enforcer, policy).await
91    }
92
93    /// Update one policy of an enforcer.
94    pub async fn update_policy(
95        &self,
96        enforcer: &Enforcer,
97        old_policy: &CasbinRule,
98        new_policy: &CasbinRule,
99    ) -> Result<bool> {
100        self.modify_policy(
101            "update-policy",
102            enforcer,
103            &[old_policy.clone(), new_policy.clone()],
104        )
105        .await
106    }
107
108    /// Remove one policy from an enforcer.
109    pub async fn remove_policy(&self, enforcer: &Enforcer, policy: &CasbinRule) -> Result<bool> {
110        self.modify_policy("remove-policy", enforcer, policy).await
111    }
112
113    async fn modify_policy<T: Serialize>(
114        &self,
115        action: &str,
116        enforcer: &Enforcer,
117        policies: &T,
118    ) -> Result<bool> {
119        let owner = get_owner(&enforcer.owner, &self.config.organization_name);
120        let id = format!("{}/{}", owner, enforcer.name);
121
122        Ok(self.modify_object(action, &id, policies, &[]).await?.1)
123    }
124}