Skip to main content

casdoor_rust_sdk/
group.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 std::collections::HashMap;
16
17use serde::{Deserialize, Serialize};
18
19use crate::client::{get_owner, Client, Response};
20use crate::error::Result;
21use crate::serde_util::null_to_default;
22
23/// Group has the same definition as
24/// <https://github.com/casdoor/casdoor/blob/master/object/group.go>.
25#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
26#[serde(rename_all = "camelCase", default)]
27pub struct Group {
28    pub owner: String,
29    pub name: String,
30    pub created_time: String,
31    pub updated_time: String,
32
33    pub display_name: String,
34    pub manager: String,
35    pub contact_email: String,
36    pub r#type: String,
37    pub parent_id: String,
38    pub parent_name: String,
39    pub is_top_group: bool,
40    #[serde(deserialize_with = "null_to_default")]
41    pub users: Vec<String>,
42
43    pub title: String,
44    pub key: String,
45    pub have_children: bool,
46    #[serde(deserialize_with = "null_to_default")]
47    pub children: Vec<Group>,
48
49    pub is_enabled: bool,
50    pub gid_number: i32,
51    #[serde(deserialize_with = "null_to_default")]
52    pub properties: HashMap<String, String>,
53}
54
55impl Client {
56    /// Get the groups of the client's organization.
57    pub async fn get_groups(&self) -> Result<Vec<Group>> {
58        self.get_list("get-groups", &[("owner", &self.config.organization_name)])
59            .await
60    }
61
62    /// Get one page of the groups of the client's organization, together with the total
63    /// number of the groups.
64    pub async fn get_pagination_groups(
65        &self,
66        p: i32,
67        page_size: i32,
68        query: &[(&str, &str)],
69    ) -> Result<(Vec<Group>, i32)> {
70        self.get_pagination(
71            "get-groups",
72            &self.config.organization_name,
73            p,
74            page_size,
75            query,
76        )
77        .await
78    }
79
80    /// Get one group by name.
81    pub async fn get_group(&self, name: &str) -> Result<Option<Group>> {
82        self.get_object("get-group", &[("id", &self.get_id(name))])
83            .await
84    }
85
86    /// Add a group.
87    pub async fn add_group(&self, group: &Group) -> Result<bool> {
88        Ok(self.modify_group("add-group", group, &[]).await?.1)
89    }
90
91    /// Update a group.
92    pub async fn update_group(&self, group: &Group) -> Result<bool> {
93        Ok(self.modify_group("update-group", group, &[]).await?.1)
94    }
95
96    /// Delete a group.
97    pub async fn delete_group(&self, group: &Group) -> Result<bool> {
98        Ok(self.modify_group("delete-group", group, &[]).await?.1)
99    }
100
101    async fn modify_group(
102        &self,
103        action: &str,
104        group: &Group,
105        columns: &[&str],
106    ) -> Result<(Response, bool)> {
107        let mut group = group.clone();
108        group.owner = get_owner(&group.owner, &self.config.organization_name);
109
110        let id = format!("{}/{}", group.owner, group.name);
111        self.modify_object(action, &id, &group, columns).await
112    }
113}