bios_iam/basic/serv/
iam_config_serv.rs

1use async_trait::async_trait;
2use bios_basic::rbum::{
3    dto::rbum_filer_dto::RbumBasicFilterReq,
4    serv::rbum_crud_serv::{RbumCrudOperation, RbumCrudQueryPackage},
5};
6use tardis::{
7    basic::{dto::TardisContext, result::TardisResult},
8    db::{
9        reldb_client::IdResp,
10        sea_orm::{sea_query::*, EntityName, Set},
11    },
12    TardisFuns, TardisFunsInst,
13};
14
15use crate::{
16    basic::{
17        domain::iam_config,
18        dto::{
19            iam_config_dto::{IamConfigAddReq, IamConfigAggOrModifyReq, IamConfigDetailResp, IamConfigModifyReq, IamConfigSummaryResp},
20            iam_filer_dto::IamConfigFilterReq,
21        },
22    },
23    iam_enumeration::IamConfigKind,
24};
25
26use super::clients::iam_log_client::{IamLogClient, LogParamTag};
27
28pub struct IamConfigServ;
29
30#[async_trait]
31impl RbumCrudOperation<iam_config::ActiveModel, IamConfigAddReq, IamConfigModifyReq, IamConfigSummaryResp, IamConfigDetailResp, IamConfigFilterReq> for IamConfigServ {
32    fn get_table_name() -> &'static str {
33        iam_config::Entity.table_name()
34    }
35
36    async fn package_add(add_req: &IamConfigAddReq, _: &TardisFunsInst, _: &TardisContext) -> TardisResult<iam_config::ActiveModel> {
37        Ok(iam_config::ActiveModel {
38            id: Set(TardisFuns::field.nanoid()),
39            code: Set(add_req.code.to_string()),
40            name: Set(add_req.name.as_ref().unwrap_or(&"".to_string()).to_string()),
41            note: Set(add_req.note.as_ref().unwrap_or(&"".to_string()).to_string()),
42            value1: Set(add_req.value1.as_ref().unwrap_or(&"".to_string()).to_string()),
43            value2: Set(add_req.value2.as_ref().unwrap_or(&"".to_string()).to_string()),
44            ext: Set(add_req.ext.as_ref().unwrap_or(&"".to_string()).to_string()),
45            rel_item_id: Set(add_req.rel_item_id.to_string()),
46            disabled: Set(add_req.disabled.unwrap_or(false)),
47            data_type: Set(add_req.data_type.to_string()),
48            ..Default::default()
49        })
50    }
51
52    async fn before_add_rbum(add_req: &mut IamConfigAddReq, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> {
53        if Self::config_exist(&add_req.code, &add_req.rel_item_id, funs, ctx).await? {
54            return Err(funs.err().conflict(
55                Self::get_table_name(),
56                "add",
57                &format!("{}.{} config already exists", add_req.code, add_req.rel_item_id),
58                "409-iam-config-exist",
59            ));
60        }
61        Ok(())
62    }
63
64    async fn package_modify(id: &str, modify_req: &IamConfigModifyReq, _: &TardisFunsInst, _: &TardisContext) -> TardisResult<iam_config::ActiveModel> {
65        let mut iam_config = iam_config::ActiveModel {
66            id: Set(id.to_string()),
67            ..Default::default()
68        };
69        if let Some(name) = &modify_req.name {
70            iam_config.name = Set(name.to_string());
71        }
72        if let Some(data_type) = &modify_req.data_type {
73            iam_config.data_type = Set(data_type.to_string());
74        }
75        if let Some(note) = &modify_req.note {
76            iam_config.note = Set(note.to_string());
77        }
78        if let Some(value1) = &modify_req.value1 {
79            iam_config.value1 = Set(value1.to_string());
80        }
81        if let Some(value2) = &modify_req.value2 {
82            iam_config.value2 = Set(value2.to_string());
83        }
84        if let Some(ext) = &modify_req.ext {
85            iam_config.ext = Set(ext.to_string());
86        }
87        if let Some(disabled) = &modify_req.disabled {
88            iam_config.disabled = Set(*disabled);
89        }
90        Ok(iam_config)
91    }
92
93    async fn package_query(is_detail: bool, filter: &IamConfigFilterReq, _: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<SelectStatement> {
94        let mut query = Query::select();
95        query
96            .columns(vec![
97                (iam_config::Entity, iam_config::Column::Id),
98                (iam_config::Entity, iam_config::Column::Code),
99                (iam_config::Entity, iam_config::Column::Name),
100                (iam_config::Entity, iam_config::Column::Note),
101                (iam_config::Entity, iam_config::Column::Value1),
102                (iam_config::Entity, iam_config::Column::Value2),
103                (iam_config::Entity, iam_config::Column::Ext),
104                (iam_config::Entity, iam_config::Column::Disabled),
105                (iam_config::Entity, iam_config::Column::DataType),
106                (iam_config::Entity, iam_config::Column::RelItemId),
107                (iam_config::Entity, iam_config::Column::OwnPaths),
108                (iam_config::Entity, iam_config::Column::Owner),
109                (iam_config::Entity, iam_config::Column::CreateTime),
110                (iam_config::Entity, iam_config::Column::UpdateTime),
111            ])
112            .from(iam_config::Entity);
113        if let Some(code) = &filter.code {
114            query.and_where(Expr::col(iam_config::Column::Code).eq(code));
115        }
116        if let Some(rel_item_id) = &filter.rel_item_id {
117            query.and_where(Expr::col(iam_config::Column::RelItemId).eq(rel_item_id));
118        }
119        if let Some(disabled) = &filter.disabled {
120            query.and_where(Expr::col(iam_config::Column::Disabled).eq(*disabled));
121        }
122        query.with_filter(Self::get_table_name(), &filter.basic, is_detail, false, ctx);
123        Ok(query)
124    }
125}
126
127impl IamConfigServ {
128    pub async fn add_or_modify_batch(rel_item_id: &str, reqs: Vec<IamConfigAggOrModifyReq>, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> {
129        for config in reqs {
130            let config_id = Self::get_config_id_by_code_and_item_id(&config.code, rel_item_id, funs).await?;
131            let (op_describe, op_kind) = match &config.code {
132                IamConfigKind::AccountInactivityLock => (
133                    format!("设置{}个月未使用的账号进行锁定或将其转为休眠账号", config.value1.clone().unwrap_or(0.to_string())),
134                    "SetUpUnusedAccountsToLock".to_string(),
135                ),
136                IamConfigKind::TokenExpire => (
137                    format!("设置{}分钟不活动则会话失效", config.value1.clone().unwrap_or(0.to_string())),
138                    "SetUpSessionInvalidation".to_string(),
139                ),
140                IamConfigKind::AccountTemporaryExpire => (
141                    format!("设置临时账号使用期限为{}个月", config.value1.clone().unwrap_or(0.to_string())),
142                    "SetUpUnusedAccountsToLock".to_string(),
143                ),
144                _ => ("".to_string(), "".to_string()),
145            };
146            if !op_describe.is_empty() {
147                let _ = IamLogClient::add_ctx_task(LogParamTag::SecurityAlarm, None, op_describe, Some(op_kind), ctx).await;
148            }
149            if let Some(id) = config_id {
150                Self::modify_rbum(
151                    &id,
152                    &mut IamConfigModifyReq {
153                        name: config.name,
154                        data_type: Some(config.data_type),
155                        note: config.note,
156                        value1: config.value1,
157                        value2: config.value2,
158                        ext: config.ext,
159                        disabled: config.disabled,
160                    },
161                    funs,
162                    ctx,
163                )
164                .await?;
165            } else {
166                Self::add_rbum(
167                    &mut IamConfigAddReq {
168                        code: config.code,
169                        name: config.name,
170                        data_type: config.data_type,
171                        note: config.note,
172                        value1: config.value1,
173                        value2: config.value2,
174                        ext: config.ext,
175                        disabled: config.disabled,
176                        rel_item_id: rel_item_id.to_string(),
177                    },
178                    funs,
179                    ctx,
180                )
181                .await?;
182            }
183        }
184        Ok(())
185    }
186
187    pub async fn get_config_by_code_and_item_id(code: &IamConfigKind, rel_item_id: &str, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<Option<IamConfigSummaryResp>> {
188        if let Some(config_id) = Self::get_config_id_by_code_and_item_id(code, rel_item_id, funs).await? {
189            let resp = Self::peek_rbum(
190                &config_id,
191                &IamConfigFilterReq {
192                    basic: RbumBasicFilterReq {
193                        own_paths: Some("".to_string()),
194                        with_sub_own_paths: true,
195                        ..Default::default()
196                    },
197                    ..Default::default()
198                },
199                funs,
200                ctx,
201            )
202            .await?;
203            Ok(Some(resp))
204        } else {
205            Ok(None)
206        }
207    }
208
209    pub async fn get_config_id_by_code_and_item_id(code: &IamConfigKind, rel_item_id: &str, funs: &TardisFunsInst) -> TardisResult<Option<String>> {
210        let resp = funs
211            .db()
212            .get_dto::<IdResp>(
213                Query::select()
214                    .column(iam_config::Column::Id)
215                    .from(iam_config::Entity)
216                    .and_where(Expr::col(iam_config::Column::Code).eq(code.to_string()))
217                    .and_where(Expr::col(iam_config::Column::RelItemId).eq(rel_item_id)),
218            )
219            .await?
220            .map(|r| r.id);
221        Ok(resp)
222    }
223
224    pub async fn config_exist(code: &IamConfigKind, rel_item_id: &str, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<bool> {
225        Self::exist_rbum(
226            &IamConfigFilterReq {
227                code: Some(code.to_string()),
228                rel_item_id: Some(rel_item_id.to_string()),
229                ..Default::default()
230            },
231            funs,
232            ctx,
233        )
234        .await
235    }
236}