cx_sdk/client/
groups.rs

1// Copyright 2024 Coralogix Ltd.
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//     https://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.
14use std::str::FromStr;
15
16use cx_api::proto::com::coralogix::permissions::v1::{
17    AddUsersToTeamGroupRequest,
18    CreateTeamGroupRequest,
19    DeleteTeamGroupRequest,
20    GetTeamGroupRequest,
21    GetTeamGroupResponse,
22    GetTeamGroupsRequest,
23    GetTeamGroupsResponse,
24    RemoveUsersFromTeamGroupRequest,
25    ScopeFilters,
26    UpdateTeamGroupRequest,
27    UpdateTeamGroupResponse,
28    team_permissions_mgmt_service_client::TeamPermissionsMgmtServiceClient,
29};
30use tokio::sync::Mutex;
31use tonic::{
32    metadata::MetadataMap,
33    transport::{
34        Channel,
35        ClientTlsConfig,
36        Endpoint,
37    },
38};
39
40use crate::{
41    CoralogixRegion,
42    auth::AuthContext,
43    error::{
44        Result,
45        SdkApiError,
46    },
47    metadata::CallProperties,
48    util::make_request_with_metadata,
49};
50
51pub use cx_api::proto::com::coralogix::permissions::v1::{
52    CreateTeamGroupResponse,
53    GroupType,
54    RoleId,
55    TeamGroupId,
56    TeamId,
57    UserId,
58    update_team_group_request::{
59        RoleUpdates,
60        UserUpdates,
61    },
62};
63
64const AAA_FEATURE_GROUP_ID: &str = "aaa";
65
66/// GroupsClient is a client for the groups service.
67pub struct GroupsClient {
68    service_client: Mutex<TeamPermissionsMgmtServiceClient<Channel>>,
69    metadata_map: MetadataMap,
70}
71
72impl GroupsClient {
73    /// Creates a new GroupsClient.
74    ///
75    /// # Arguments
76    /// * `api_key' - The [`AuthContext`] to use for authentication.
77    /// * `region` - The [`CoralogixRegion`] to connect to.
78    pub fn new(auth_context: AuthContext, region: CoralogixRegion) -> Result<Self> {
79        let channel: Channel = Endpoint::from_str(region.grpc_endpoint().as_str())?
80            .tls_config(ClientTlsConfig::new().with_native_roots())?
81            .connect_lazy();
82        let request_metadata: CallProperties = (&auth_context.team_level_api_key).into();
83        Ok(Self {
84            metadata_map: request_metadata.to_metadata_map(),
85            service_client: Mutex::new(TeamPermissionsMgmtServiceClient::new(channel)),
86        })
87    }
88
89    #[allow(clippy::too_many_arguments)]
90    /// Creates a new group.
91    ///
92    /// # Arguments
93    /// * `name` - The name of the group.
94    /// * `team_id` - The [`TeamId`] of the team the group belongs to.
95    /// * `description` - The description of the group.
96    /// * `external_id` - The external ID of the group.
97    /// * `role_ids` - The [`RoleId`]s of the roles in the group.
98    /// * `user_ids` - The [`UserId`]s of the users in the group.
99    /// * `scope_filters` - The [`ScopeFilters`] of the group.
100    /// * `next_gen_scope_id` - The next-gen scope ID of the group.
101    /// * `group_type` - Type of group to create
102    pub async fn create(
103        &self,
104        name: String,
105        team_id: TeamId,
106        description: String,
107        external_id: Option<String>,
108        role_ids: Vec<RoleId>,
109        user_ids: Vec<UserId>,
110        scope_filters: Option<ScopeFilters>,
111        next_gen_scope_id: Option<String>,
112        group_type: GroupType,
113    ) -> Result<CreateTeamGroupResponse> {
114        let request = make_request_with_metadata(
115            CreateTeamGroupRequest {
116                name,
117                team_id: Some(team_id),
118                description: Some(description),
119                external_id,
120                role_ids,
121                user_ids,
122                scope_filters,
123                next_gen_scope_id,
124                group_type: group_type.into(),
125            },
126            &self.metadata_map,
127        );
128        Ok(self
129            .service_client
130            .lock()
131            .await
132            .create_team_group(request)
133            .await
134            .map_err(|status| SdkApiError {
135                status,
136                endpoint:
137                    "/com.coralogix.permissions.v1.TeamPermissionsMgmtService/CreateTeamGroup"
138                        .into(),
139                feature_group: AAA_FEATURE_GROUP_ID.into(),
140            })?
141            .into_inner())
142    }
143
144    /// Fetches the groups for an organization.
145    ///
146    /// # Arguments
147    /// * `group_id` - The [`TeamGroupId`] of the group to fetch.
148    pub async fn get(&self, group_id: TeamGroupId) -> Result<GetTeamGroupResponse> {
149        let request = make_request_with_metadata(
150            GetTeamGroupRequest {
151                group_id: Some(group_id),
152            },
153            &self.metadata_map,
154        );
155        Ok(self
156            .service_client
157            .lock()
158            .await
159            .get_team_group(request)
160            .await
161            .map_err(|status| SdkApiError {
162                status,
163                endpoint: "/com.coralogix.permissions.v1.TeamPermissionsMgmtService/GetTeamGroup"
164                    .into(),
165                feature_group: AAA_FEATURE_GROUP_ID.into(),
166            })?
167            .into_inner())
168    }
169
170    /// Fetches all groups for a team.
171    ///
172    /// # Arguments
173    /// * `team_id` - The [`TeamId`] of the team to fetch groups for.
174    pub async fn list(&self, team_id: TeamId) -> Result<GetTeamGroupsResponse> {
175        let request = make_request_with_metadata(
176            GetTeamGroupsRequest {
177                team_id: Some(team_id),
178            },
179            &self.metadata_map,
180        );
181        Ok(self
182            .service_client
183            .lock()
184            .await
185            .get_team_groups(request)
186            .await
187            .map_err(|status| SdkApiError {
188                status,
189                endpoint: "/com.coralogix.permissions.v1.TeamPermissionsMgmtService/GetTeamGroups"
190                    .into(),
191                feature_group: AAA_FEATURE_GROUP_ID.into(),
192            })?
193            .into_inner())
194    }
195
196    /// Adds users to a group.
197    ///
198    /// # Arguments
199    /// * `group_id` - The [`TeamGroupId`] of the group to add roles to.
200    /// * `user_ids` - The [`UserId`]s of the users to add to the group.
201    pub async fn add_users(&self, group_id: TeamGroupId, user_ids: Vec<UserId>) -> Result<()> {
202        let request = make_request_with_metadata(
203            AddUsersToTeamGroupRequest {
204                group_id: Some(group_id),
205                user_ids,
206            },
207            &self.metadata_map,
208        );
209        self.service_client
210            .lock()
211            .await
212            .add_users_to_team_group(request)
213            .await
214            .map_err(|status| SdkApiError {
215                status,
216                endpoint:
217                    "/com.coralogix.permissions.v1.TeamPermissionsMgmtService/AddUsersToTeamGroup"
218                        .into(),
219                feature_group: AAA_FEATURE_GROUP_ID.into(),
220            })?;
221        Ok(())
222    }
223
224    #[allow(clippy::too_many_arguments)]
225    /// Updates a group.
226    /// * `group_id` - The [`TeamGroupId`] of the group to update.
227    /// * `name` - The name of the group.
228    /// * `team_id` - The [`TeamId`] of the team the group belongs to.
229    /// * `description` - The description of the group.
230    /// * `external_id` - The external ID of the group.
231    /// * `role_updates` - The [`RoleUpdates`] to apply to the group.
232    /// * `user_updates` - The [`UserUpdates`] to apply to the group.
233    /// * `scope_filters` - The [`ScopeFilters`] of the group.
234    /// * `next_gen_scope_id` - The next-gen scope ID of the group.
235    /// * `group_type` - Type of group to create
236    pub async fn update(
237        &self,
238        group_id: TeamGroupId,
239        name: String,
240        description: String,
241        external_id: Option<String>,
242        role_updates: Option<RoleUpdates>,
243        user_updates: Option<UserUpdates>,
244        scope_filters: Option<ScopeFilters>,
245        next_gen_scope_id: Option<String>,
246        group_type: Option<GroupType>,
247    ) -> Result<UpdateTeamGroupResponse> {
248        let request = make_request_with_metadata(
249            UpdateTeamGroupRequest {
250                name,
251                description: Some(description),
252                external_id,
253                group_id: Some(group_id),
254                role_updates,
255                user_updates,
256                scope_filters,
257                next_gen_scope_id,
258                group_type: group_type.map(|g| g.into()),
259            },
260            &self.metadata_map,
261        );
262        Ok(self
263            .service_client
264            .lock()
265            .await
266            .update_team_group(request)
267            .await
268            .map_err(|status| SdkApiError {
269                status,
270                endpoint:
271                    "/com.coralogix.permissions.v1.TeamPermissionsMgmtService/UpdateTeamGroup"
272                        .into(),
273                feature_group: AAA_FEATURE_GROUP_ID.into(),
274            })?
275            .into_inner())
276    }
277
278    /// Removes users from a group.
279    ///
280    /// # Arguments
281    /// * `group_id` - The [`TeamGroupId`] of the group to remove roles from.
282    /// * `user_ids` - The [`UserId`]s of the users to remove from the group.
283    pub async fn remove_users(&self, group_id: TeamGroupId, user_ids: Vec<UserId>) -> Result<()> {
284        let request = make_request_with_metadata(
285            RemoveUsersFromTeamGroupRequest {
286                group_id: Some(group_id),
287                user_ids,
288            },
289            &self.metadata_map,
290        );
291        self.service_client
292            .lock()
293            .await
294            .remove_users_from_team_group(request)
295            .await
296            .map_err(|status| SdkApiError{
297                status,
298                endpoint: "/com.coralogix.permissions.v1.TeamPermissionsMgmtService/RemoveUsersFromTeamGroup".into(),
299                feature_group: AAA_FEATURE_GROUP_ID.into(),
300            })?;
301        Ok(())
302    }
303
304    /// Deletes a group.
305    ///
306    /// # Arguments
307    /// * `group_id` - The [`TeamGroupId`] of the group to delete.
308    pub async fn delete(&self, group_id: TeamGroupId) -> Result<()> {
309        let request = make_request_with_metadata(
310            DeleteTeamGroupRequest {
311                group_id: Some(group_id),
312            },
313            &self.metadata_map,
314        );
315        self.service_client
316            .lock()
317            .await
318            .delete_team_group(request)
319            .await
320            .map_err(|status| SdkApiError {
321                status,
322                endpoint:
323                    "/com.coralogix.permissions.v1.TeamPermissionsMgmtService/DeleteTeamGroup"
324                        .into(),
325                feature_group: AAA_FEATURE_GROUP_ID.into(),
326            })?;
327        Ok(())
328    }
329}