1use 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
66pub struct GroupsClient {
68    service_client: Mutex<TeamPermissionsMgmtServiceClient<Channel>>,
69    metadata_map: MetadataMap,
70}
71
72impl GroupsClient {
73    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    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    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    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    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    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    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    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}