Skip to main content

casdoor_rust_sdk/
permission.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, Response};
18use crate::error::Result;
19use crate::serde_util::null_to_default;
20
21/// Permission has the same definition as
22/// <https://github.com/casdoor/casdoor/blob/master/object/permission.go>.
23#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
24#[serde(rename_all = "camelCase", default)]
25pub struct Permission {
26    pub owner: String,
27    pub name: String,
28    pub created_time: String,
29    pub display_name: String,
30    pub description: String,
31
32    #[serde(deserialize_with = "null_to_default")]
33    pub users: Vec<String>,
34    #[serde(deserialize_with = "null_to_default")]
35    pub groups: Vec<String>,
36    #[serde(deserialize_with = "null_to_default")]
37    pub roles: Vec<String>,
38    #[serde(deserialize_with = "null_to_default")]
39    pub domains: Vec<String>,
40
41    #[serde(deserialize_with = "null_to_default")]
42    pub source_groups: Vec<String>,
43    #[serde(deserialize_with = "null_to_default")]
44    pub source_roles: Vec<String>,
45
46    pub model: String,
47    pub adapter: String,
48    pub resource_type: String,
49    #[serde(deserialize_with = "null_to_default")]
50    pub resources: Vec<String>,
51    #[serde(deserialize_with = "null_to_default")]
52    pub actions: Vec<String>,
53    pub effect: String,
54    pub is_enabled: bool,
55
56    /// An optional RFC3339 timestamp. When set and reached, the permission is
57    /// automatically revoked (its Casbin policies are removed and it is disabled) by the
58    /// permission expiration job, providing time-limited access as required by standards
59    /// such as ISO/IEC 27001 control 5.18. An empty value means the permission never
60    /// expires.
61    pub expire_time: String,
62
63    pub submitter: String,
64    pub approver: String,
65    pub approve_time: String,
66    pub state: String,
67}
68
69impl Client {
70    /// Get the permissions of the client's organization.
71    pub async fn get_permissions(&self) -> Result<Vec<Permission>> {
72        self.get_list(
73            "get-permissions",
74            &[("owner", &self.config.organization_name)],
75        )
76        .await
77    }
78
79    /// Get the permissions of a role.
80    pub async fn get_permissions_by_role(&self, name: &str) -> Result<Vec<Permission>> {
81        self.get_list("get-permissions-by-role", &[("id", &self.get_id(name))])
82            .await
83    }
84
85    /// Get one page of the permissions of the client's organization, together with the
86    /// total number of the permissions.
87    pub async fn get_pagination_permissions(
88        &self,
89        p: i32,
90        page_size: i32,
91        query: &[(&str, &str)],
92    ) -> Result<(Vec<Permission>, i32)> {
93        self.get_pagination(
94            "get-permissions",
95            &self.config.organization_name,
96            p,
97            page_size,
98            query,
99        )
100        .await
101    }
102
103    /// Get one permission by name.
104    pub async fn get_permission(&self, name: &str) -> Result<Option<Permission>> {
105        self.get_object("get-permission", &[("id", &self.get_id(name))])
106            .await
107    }
108
109    /// Add a permission.
110    pub async fn add_permission(&self, permission: &Permission) -> Result<bool> {
111        Ok(self
112            .modify_permission("add-permission", permission, &[])
113            .await?
114            .1)
115    }
116
117    /// Update a permission.
118    pub async fn update_permission(&self, permission: &Permission) -> Result<bool> {
119        Ok(self
120            .modify_permission("update-permission", permission, &[])
121            .await?
122            .1)
123    }
124
125    /// Update only the given columns of a permission.
126    pub async fn update_permission_for_columns(
127        &self,
128        permission: &Permission,
129        columns: &[&str],
130    ) -> Result<bool> {
131        Ok(self
132            .modify_permission("update-permission", permission, columns)
133            .await?
134            .1)
135    }
136
137    /// Delete a permission.
138    pub async fn delete_permission(&self, permission: &Permission) -> Result<bool> {
139        Ok(self
140            .modify_permission("delete-permission", permission, &[])
141            .await?
142            .1)
143    }
144
145    async fn modify_permission(
146        &self,
147        action: &str,
148        permission: &Permission,
149        columns: &[&str],
150    ) -> Result<(Response, bool)> {
151        let mut permission = permission.clone();
152        permission.owner = get_owner(&permission.owner, &self.config.organization_name);
153
154        let id = format!("{}/{}", permission.owner, permission.name);
155        self.modify_object(action, &id, &permission, columns).await
156    }
157}