diff --git a/Cargo.toml b/Cargo.toml index 265b82d88..dfc759bc9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,7 @@ tardis = { version = "=0.1.0-rc.3" } # tardis = { path = "../tardis/tardis" } # tardis = { git = "https://github.com/ideal-world/tardis.git", rev = "9424e16" } #spacegate -spacegate-kernel = { git = "https://github.com/ideal-world/spacegate.git", rev = "0f03a1b",features = [ +spacegate-kernel = { git = "https://github.com/ideal-world/spacegate.git", rev = "40e7bf8d0b",features = [ "ws", "cache", "k8s", diff --git a/basic/src/rbum/helper/rbum_scope_helper.rs b/basic/src/rbum/helper/rbum_scope_helper.rs index 2cf3006fe..e6b37ae00 100644 --- a/basic/src/rbum/helper/rbum_scope_helper.rs +++ b/basic/src/rbum/helper/rbum_scope_helper.rs @@ -99,6 +99,9 @@ pub fn check_scope(record_own_paths: &str, record_scope_level: Option, filt return false; } if let Some(record_scope_level) = record_scope_level { + if record_scope_level == 0 { + return true; + } if let Some(p1) = get_pre_paths(1, filter_own_paths) { if record_scope_level == 1 { return record_own_paths.is_empty() || record_own_paths.contains(&p1); diff --git a/middleware/flow/src/dto/flow_external_dto.rs b/middleware/flow/src/dto/flow_external_dto.rs index eae94c677..63735641d 100644 --- a/middleware/flow/src/dto/flow_external_dto.rs +++ b/middleware/flow/src/dto/flow_external_dto.rs @@ -19,6 +19,7 @@ pub struct FlowExternalReq { pub original_sys_state: Option, pub owner_paths: String, pub obj_ids: Vec, + pub notify: Option, pub params: Vec, } diff --git a/middleware/flow/src/dto/flow_inst_dto.rs b/middleware/flow/src/dto/flow_inst_dto.rs index f8f240fa2..ba588c792 100644 --- a/middleware/flow/src/dto/flow_inst_dto.rs +++ b/middleware/flow/src/dto/flow_inst_dto.rs @@ -87,6 +87,8 @@ pub struct FlowInstDetailResp { pub current_state_id: String, pub current_state_name: Option, pub current_state_color: Option, + pub current_state_kind: Option, + pub current_state_ext: Option, pub current_assigned: Option, pub current_vars: Option>, diff --git a/middleware/flow/src/dto/flow_model_dto.rs b/middleware/flow/src/dto/flow_model_dto.rs index 90e0c7123..e86610241 100644 --- a/middleware/flow/src/dto/flow_model_dto.rs +++ b/middleware/flow/src/dto/flow_model_dto.rs @@ -122,6 +122,7 @@ pub struct FlowModelFilterReq { pub rel_template_id: Option, pub template: Option, pub own_paths: Option>, + pub specified_state_ids: Option>, } impl RbumItemFilterFetcher for FlowModelFilterReq { diff --git a/middleware/flow/src/flow_initializer.rs b/middleware/flow/src/flow_initializer.rs index 68b7b7216..e7c1cd463 100644 --- a/middleware/flow/src/flow_initializer.rs +++ b/middleware/flow/src/flow_initializer.rs @@ -6,17 +6,9 @@ use bios_basic::rbum::{ }; use bios_sdk_invoke::invoke_initializer; -use itertools::Itertools; -use serde_json::Value; use tardis::{ basic::{dto::TardisContext, field::TrimString, result::TardisResult}, - db::{ - reldb_client::TardisActiveModel, - sea_orm::{ - self, - sea_query::{Query, Table}, - }, - }, + db::{reldb_client::TardisActiveModel, sea_orm::sea_query::Table}, log::info, web::web_server::TardisWebServer, TardisFuns, TardisFunsInst, @@ -32,9 +24,7 @@ use crate::{ dto::{ flow_model_dto::FlowModelFilterReq, flow_state_dto::FlowSysStateKind, - flow_transition_dto::{ - FlowTransitionActionByVarChangeInfoChangedKind, FlowTransitionActionChangeInfo, FlowTransitionActionChangeKind, FlowTransitionDoubleCheckInfo, FlowTransitionInitInfo, - }, + flow_transition_dto::{FlowTransitionDoubleCheckInfo, FlowTransitionInitInfo}, }, flow_config::{BasicInfo, FlowBasicInfoManager, FlowConfig}, flow_constants, @@ -77,7 +67,6 @@ pub async fn init_db(mut funs: TardisFunsInst) -> TardisResult<()> { funs.begin().await?; if check_initialized(&funs, &ctx).await? { init_basic_info(&funs).await?; - // self::modify_post_actions(&funs, &ctx).await?; } else { let db_kind = TardisFuns::reldb().backend(); let compatible_type = TardisFuns::reldb().compatible_type(); @@ -125,49 +114,6 @@ async fn init_basic_info<'a>(funs: &TardisFunsInst) -> TardisResult<()> { Ok(()) } -// @TODO temporary -pub async fn modify_post_actions(funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { - #[derive(sea_orm::FromQueryResult)] - pub struct FlowTransactionPostAction { - id: String, - action_by_post_changes: Value, - } - let transactions = funs - .db() - .find_dtos::( - Query::select() - .columns([ - (flow_transition::Entity, flow_transition::Column::Id), - (flow_transition::Entity, flow_transition::Column::ActionByPostChanges), - ]) - .from(flow_transition::Entity), - ) - .await? - .into_iter() - .filter(|res| !TardisFuns::json.json_to_obj::>(res.action_by_post_changes.clone()).unwrap_or_default().is_empty()) - .collect_vec(); - for transaction in transactions { - let mut post_changes = TardisFuns::json.json_to_obj::>(transaction.action_by_post_changes.clone()).unwrap_or_default(); - for post_change in post_changes.iter_mut() { - if post_change.changed_kind.is_none() && post_change.kind == FlowTransitionActionChangeKind::Var { - if post_change.changed_val.is_some() { - post_change.changed_kind = Some(FlowTransitionActionByVarChangeInfoChangedKind::ChangeContent); - } else { - post_change.changed_kind = Some(FlowTransitionActionByVarChangeInfoChangedKind::Clean); - } - } - } - let flow_transition = flow_transition::ActiveModel { - id: sea_orm::ActiveValue::Set(transaction.id.clone()), - action_by_post_changes: sea_orm::ActiveValue::Set(TardisFuns::json.obj_to_json(&post_changes)?), - ..Default::default() - }; - funs.db().update_one(flow_transition, ctx).await?; - } - - Ok(()) -} - pub async fn init_rbum_data(funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { let kind_state_id = add_kind(flow_constants::RBUM_KIND_STATE_CODE, flow_constants::RBUM_EXT_TABLE_STATE, funs, ctx).await?; let kind_model_id = add_kind(flow_constants::RBUM_KIND_MODEL_CODE, flow_constants::RBUM_EXT_TABLE_MODEL, funs, ctx).await?; diff --git a/middleware/flow/src/serv/flow_config_serv.rs b/middleware/flow/src/serv/flow_config_serv.rs index 271bb4c70..5f55eb5b1 100644 --- a/middleware/flow/src/serv/flow_config_serv.rs +++ b/middleware/flow/src/serv/flow_config_serv.rs @@ -1,3 +1,4 @@ +use bios_basic::rbum::rbum_enumeration::RbumScopeLevelKind; use bios_sdk_invoke::clients::spi_kv_client::{KvItemSummaryResp, SpiKvClient}; use tardis::{ basic::{dto::TardisContext, result::TardisResult}, @@ -12,7 +13,7 @@ pub struct FlowConfigServ; impl FlowConfigServ { pub async fn modify_config(modify_req: &Vec, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { for req in modify_req { - SpiKvClient::add_or_modify_item(&format!("{}:config:{}", flow_constants::DOMAIN_CODE, req.code.clone()), &req.value, None, funs, ctx).await?; + SpiKvClient::add_or_modify_item(&format!("{}:config:{}", flow_constants::DOMAIN_CODE, req.code.clone()), &req.value, None, Some(RbumScopeLevelKind::Root.to_int()), funs, ctx).await?; } Ok(()) } diff --git a/middleware/flow/src/serv/flow_external_serv.rs b/middleware/flow/src/serv/flow_external_serv.rs index 7b0d3c44e..e05de3c64 100644 --- a/middleware/flow/src/serv/flow_external_serv.rs +++ b/middleware/flow/src/serv/flow_external_serv.rs @@ -76,6 +76,7 @@ impl FlowExternalServ { target_sys_state: Option, original_state: Option, original_sys_state: Option, + is_notify: bool, params: Vec, ctx: &TardisContext, funs: &TardisFunsInst, @@ -110,6 +111,7 @@ impl FlowExternalServ { target_sys_state, original_state, original_sys_state, + notify: Some(is_notify), params, ..Default::default() }; @@ -138,6 +140,7 @@ impl FlowExternalServ { target_sys_state: FlowSysStateKind, original_state: String, original_sys_state: FlowSysStateKind, + is_notify: bool, ctx: &TardisContext, funs: &TardisFunsInst, ) -> TardisResult { @@ -156,6 +159,7 @@ impl FlowExternalServ { target_sys_state: Some(target_sys_state), original_state: Some(original_state), original_sys_state: Some(original_sys_state), + notify: Some(is_notify), ..Default::default() }; debug!("do_notify_changes body: {:?}", body); @@ -215,11 +219,7 @@ impl FlowExternalServ { curr_bus_obj_id: "".to_string(), owner_paths: own_paths.to_string(), obj_ids: rel_business_obj_ids, - target_state: None, - target_sys_state: None, - original_state: None, - original_sys_state: None, - params: vec![], + ..Default::default() }; debug!("do_query_field body: {:?}", body); let resp: FlowExternalResp = funs diff --git a/middleware/flow/src/serv/flow_inst_serv.rs b/middleware/flow/src/serv/flow_inst_serv.rs index 8bdeb170d..e8d3d95ea 100644 --- a/middleware/flow/src/serv/flow_inst_serv.rs +++ b/middleware/flow/src/serv/flow_inst_serv.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use async_recursion::async_recursion; use bios_basic::{ @@ -308,6 +308,8 @@ impl FlowInstServ { pub current_state_id: String, pub current_state_name: Option, pub current_state_color: Option, + pub current_state_kind: Option, + pub current_state_ext: Option, pub current_assigned: Option, pub current_vars: Option, @@ -330,6 +332,7 @@ impl FlowInstServ { let rel_state_table = Alias::new("rel_state"); let flow_state_table = Alias::new("flow_state"); let rel_model_table = Alias::new("rel_model"); + let rbum_rel_table = Alias::new("rbum_rel"); let mut query = Query::select(); query .columns([ @@ -351,6 +354,8 @@ impl FlowInstServ { ]) .expr_as(Expr::col((rel_state_table.clone(), NAME_FIELD.clone())).if_null(""), Alias::new("current_state_name")) .expr_as(Expr::col((flow_state_table.clone(), Alias::new("color"))).if_null(""), Alias::new("current_state_color")) + .expr_as(Expr::col((flow_state_table.clone(), Alias::new("sys_state"))).if_null(""), Alias::new("current_state_kind")) + .expr_as(Expr::col((rbum_rel_table.clone(), Alias::new("ext"))).if_null(""), Alias::new("current_state_ext")) .expr_as(Expr::col((rel_model_table.clone(), NAME_FIELD.clone())).if_null(""), Alias::new("rel_flow_model_name")) .from(flow_inst::Entity) .join_as( @@ -377,6 +382,15 @@ impl FlowInstServ { .add(Expr::col((rel_model_table.clone(), REL_KIND_ID_FIELD.clone())).eq(FlowModelServ::get_rbum_kind_id().unwrap())) .add(Expr::col((rel_model_table.clone(), REL_DOMAIN_ID_FIELD.clone())).eq(FlowModelServ::get_rbum_domain_id().unwrap())), ) + .join_as( + JoinType::LeftJoin, + rbum_rel_table.clone(), + rbum_rel_table.clone(), + Cond::all() + .add(Expr::col((rbum_rel_table.clone(), Alias::new("to_rbum_item_id"))).equals((flow_inst::Entity, flow_inst::Column::CurrentStateId))) + .add(Expr::col((rbum_rel_table.clone(), Alias::new("from_rbum_id"))).equals((flow_inst::Entity, flow_inst::Column::RelFlowModelId))) + .add(Expr::col((rbum_rel_table.clone(), Alias::new("tag"))).eq("FlowModelState".to_string())), + ) .and_where(Expr::col((flow_inst::Entity, flow_inst::Column::Id)).is_in(flow_inst_ids)) .and_where(Expr::col((flow_inst::Entity, flow_inst::Column::OwnPaths)).like(format!("{}%", ctx.own_paths))); @@ -399,6 +413,8 @@ impl FlowInstServ { current_state_id: inst.current_state_id, current_state_name: inst.current_state_name, current_state_color: inst.current_state_color, + current_state_kind: inst.current_state_kind, + current_state_ext: inst.current_state_ext, current_assigned: inst.current_assigned, current_vars: inst.current_vars.map(|current_vars| TardisFuns::json.json_to_obj(current_vars).unwrap()), rel_business_obj_id: inst.rel_business_obj_id, @@ -518,11 +534,12 @@ impl FlowInstServ { let flow_models = FlowModelServ::find_detail_items( &FlowModelFilterReq { basic: RbumBasicFilterReq { - ids: Some(flow_insts.iter().map(|inst| inst.rel_flow_model_id.to_string()).collect_vec()), + ids: Some(flow_insts.iter().map(|inst| inst.rel_flow_model_id.to_string()).collect::>().into_iter().collect()), with_sub_own_paths: true, own_paths: Some("".to_string()), ..Default::default() }, + specified_state_ids: Some(flow_insts.iter().map(|inst| inst.current_state_id.clone()).collect::>().into_iter().collect()), ..Default::default() }, None, @@ -662,15 +679,9 @@ impl FlowInstServ { if next_flow_transition.is_none() { return Err(funs.err().not_found("flow_inst", "transfer", "no transferable state", "404-flow-inst-transfer-state-not-found")); } - if FlowModelServ::check_post_action_ring( - flow_model.transitions().into_iter().find(|trans| trans.id == transfer_req.flow_transition_id).unwrap(), - (false, vec![]), - funs, - ctx, - ) - .await? - .0 - { + let model_transition = flow_model.transitions(); + let next_transition_detail = model_transition.iter().find(|trans| trans.id == transfer_req.flow_transition_id).unwrap().to_owned(); + if FlowModelServ::check_post_action_ring(next_transition_detail.clone(), (false, vec![]), funs, ctx).await?.0 { return Err(funs.err().not_found("flow_inst", "transfer", "this post action exist endless loop", "500-flow-transition-endless-loop")); } @@ -724,6 +735,7 @@ impl FlowInstServ { Some(next_flow_state.sys_state.clone()), Some(prev_flow_state.name.clone()), Some(prev_flow_state.sys_state.clone()), + next_transition_detail.is_notify, params, ctx, funs, @@ -776,10 +788,9 @@ impl FlowInstServ { // get updated instance detail let flow_inst_detail = Self::get(flow_inst_id, funs, ctx).await?; - let model_transition = flow_model.transitions(); Self::do_request_webhook( from_transition_id.and_then(|id: String| model_transition.iter().find(|model_transition| model_transition.id == id)), - model_transition.iter().find(|model_transition| model_transition.id == next_flow_transition.next_flow_transition_id), + Some(&next_transition_detail), ) .await?; @@ -793,6 +804,7 @@ impl FlowInstServ { next_flow_state.sys_state, prev_flow_state.name.clone(), prev_flow_state.sys_state, + next_transition_detail.is_notify, ctx, funs, ) @@ -802,7 +814,16 @@ impl FlowInstServ { let post_changes = model_transition.into_iter().find(|model_transition| model_transition.id == next_flow_transition.next_flow_transition_id).unwrap_or_default().action_by_post_changes(); if !post_changes.is_empty() { - Self::do_post_change(&flow_inst_detail, &flow_model, post_changes, updated_instance_list, ctx, funs).await?; + Self::do_post_change( + &flow_inst_detail, + &flow_model, + post_changes, + updated_instance_list, + next_transition_detail.is_notify, + ctx, + funs, + ) + .await?; } let next_flow_transitions = Self::do_find_next_transitions(&flow_inst_detail, &flow_model, None, &None, skip_filter, funs, ctx).await?.next_flow_transitions; @@ -833,6 +854,7 @@ impl FlowInstServ { current_model: &FlowModelDetailResp, post_changes: Vec, updated_instance_list: &mut Vec, + is_notify: bool, ctx: &TardisContext, funs: &TardisFunsInst, ) -> TardisResult<()> { @@ -867,6 +889,7 @@ impl FlowInstServ { None, None, None, + is_notify, vec![FlowExternalParams { rel_kind: None, rel_tag: None, @@ -891,6 +914,7 @@ impl FlowInstServ { None, None, None, + is_notify, vec![FlowExternalParams { rel_kind: None, rel_tag: None, @@ -1107,7 +1131,7 @@ impl FlowInstServ { spec_flow_transition_id: Option, req_vars: &Option>, skip_filter: bool, - funs: &TardisFunsInst, + _funs: &TardisFunsInst, ctx: &TardisContext, ) -> TardisResult { let flow_model_transitions = flow_model.transitions(); @@ -1188,36 +1212,14 @@ impl FlowInstServ { double_check: model_transition.double_check(), }) .collect_vec(); - let current_flow_state = FlowStateServ::find_one_item( - &FlowStateFilterReq { - basic: RbumBasicFilterReq { - ids: Some(vec![flow_inst.current_state_id.to_string()]), - with_sub_own_paths: true, - own_paths: Some("".to_string()), - ..Default::default() - }, - ..Default::default() - }, - funs, - ctx, - ) - .await? - .ok_or_else(|| funs.err().not_found("flow_inst", "do_find_next_transitions", "flow state is not found", "404-flow-state-not-found"))?; let state_and_next_transitions = FlowInstFindStateAndTransitionsResp { flow_inst_id: flow_inst.id.to_string(), finish_time: flow_inst.finish_time, current_flow_state_name: flow_inst.current_state_name.as_ref().unwrap_or(&"".to_string()).to_string(), - current_flow_state_kind: current_flow_state.sys_state.clone(), - current_flow_state_color: current_flow_state.color.clone(), - current_flow_state_ext: TardisFuns::json.str_to_obj::( - &FlowRelServ::find_from_simple_rels(&FlowRelKind::FlowModelState, &flow_inst.rel_flow_model_id, None, None, funs, ctx) - .await? - .into_iter() - .find(|rel| current_flow_state.id == rel.rel_id) - .ok_or_else(|| funs.err().not_found("flow_inst", "do_find_next_transitions", "flow state is not found", "404-flow-state-not-found"))? - .ext, - )?, + current_flow_state_color: flow_inst.current_state_color.as_ref().unwrap_or(&"".to_string()).to_string(), + current_flow_state_kind: flow_inst.current_state_kind.as_ref().unwrap_or(&FlowSysStateKind::Start).clone(), + current_flow_state_ext: TardisFuns::json.str_to_obj::(&flow_inst.current_state_ext.clone().unwrap_or_default())?, next_flow_transitions: next_transitions, }; Ok(state_and_next_transitions) diff --git a/middleware/flow/src/serv/flow_model_serv.rs b/middleware/flow/src/serv/flow_model_serv.rs index 61fdda4df..d1051733f 100644 --- a/middleware/flow/src/serv/flow_model_serv.rs +++ b/middleware/flow/src/serv/flow_model_serv.rs @@ -200,7 +200,7 @@ impl RbumItemCrudOperation TardisResult { let mut flow_model = Self::do_get_item(flow_model_id, filter, funs, ctx).await?; - let flow_transitions = Self::find_transitions(flow_model_id, funs, ctx).await?; + let flow_transitions = Self::find_transitions(flow_model_id, filter.specified_state_ids.as_deref(), funs, ctx).await?; flow_model.transitions = Some(TardisFuns::json.obj_to_json(&flow_transitions)?); Ok(flow_model) } @@ -216,7 +216,7 @@ impl RbumItemCrudOperation TardisResult> { let mut flow_models = Self::do_paginate_detail_items(filter, page_number, page_size, desc_sort_by_create, desc_sort_by_update, funs, ctx).await?; for flow_model in &mut flow_models.records { - let flow_transitions = Self::find_transitions(&flow_model.id, funs, ctx).await?; + let flow_transitions = Self::find_transitions(&flow_model.id, filter.specified_state_ids.as_deref(), funs, ctx).await?; flow_model.transitions = Some(TardisFuns::json.obj_to_json(&flow_transitions)?); } Ok(flow_models) @@ -231,7 +231,7 @@ impl RbumItemCrudOperation TardisResult> { let mut flow_models = Self::do_find_detail_items(filter, desc_sort_by_create, desc_sort_by_update, funs, ctx).await?; for flow_model in &mut flow_models { - let flow_transitions = Self::find_transitions(&flow_model.id, funs, ctx).await?; + let flow_transitions = Self::find_transitions(&flow_model.id, filter.specified_state_ids.as_deref(), funs, ctx).await?; flow_model.transitions = Some(TardisFuns::json.obj_to_json(&flow_transitions)?); } Ok(flow_models) @@ -555,7 +555,7 @@ impl FlowModelServ { Ok(()) } - async fn find_transitions(flow_model_id: &str, funs: &TardisFunsInst, _ctx: &TardisContext) -> TardisResult> { + async fn find_transitions(flow_model_id: &str, specified_state_ids: Option<&[String]>, funs: &TardisFunsInst, _ctx: &TardisContext) -> TardisResult> { let from_state_rbum_table = Alias::new("from_state_rbum"); let from_state_table = Alias::new("from_state"); let to_state_rbum_table = Alias::new("to_state_rbum"); @@ -624,7 +624,11 @@ impl FlowModelServ { to_state_table.clone(), Cond::all().add(Expr::col((to_state_table.clone(), ID_FIELD.clone())).equals((flow_transition::Entity, flow_transition::Column::FromFlowStateId))), ) - .and_where(Expr::col((flow_transition::Entity, flow_transition::Column::RelFlowModelId)).eq(flow_model_id)) + .and_where(Expr::col((flow_transition::Entity, flow_transition::Column::RelFlowModelId)).eq(flow_model_id)); + if let Some(specified_state_ids) = specified_state_ids { + query.and_where(Expr::col((flow_transition::Entity, flow_transition::Column::FromFlowStateId)).is_in(specified_state_ids)); + } + query .order_by((flow_transition::Entity, flow_transition::Column::Sort), Order::Asc) .order_by((flow_transition::Entity, flow_transition::Column::CreateTime), Order::Asc) .order_by((flow_transition::Entity, flow_transition::Column::Id), Order::Asc); @@ -1174,7 +1178,7 @@ impl FlowModelServ { funs: &TardisFunsInst, ctx: &TardisContext, ) -> TardisResult> { - Ok(Self::find_transitions(flow_model_id, funs, ctx) + Ok(Self::find_transitions(flow_model_id, None, funs, ctx) .await? .into_iter() .filter(|tran_detail| { diff --git a/sdk/invoke/src/clients/spi_kv_client.rs b/sdk/invoke/src/clients/spi_kv_client.rs index 7eaa0b512..4df8c8331 100644 --- a/sdk/invoke/src/clients/spi_kv_client.rs +++ b/sdk/invoke/src/clients/spi_kv_client.rs @@ -34,13 +34,14 @@ pub struct KvItemDetailResp { } impl SpiKvClient { - pub async fn add_or_modify_item(key: &str, value: &T, info: Option, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { + pub async fn add_or_modify_item(key: &str, value: &T, info: Option, scope_level: Option, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { let kv_url: String = BaseSpiClient::module_url(InvokeModuleKind::Kv, funs).await?; let headers = BaseSpiClient::headers(None, funs, ctx).await?; let json = json!({ "key":key.to_string(), "value":value, - "info":info + "info":info, + "scope_level":scope_level, }); funs.web_client().put_obj_to_str(&format!("{kv_url}/ci/item"), &json, headers.clone()).await?; Ok(()) diff --git a/services/bios-all/config/locale/zh-cn.basic b/services/bios-all/config/locale/zh-cn.basic index b6bbd395a..d5c182c83 100644 --- a/services/bios-all/config/locale/zh-cn.basic +++ b/services/bios-all/config/locale/zh-cn.basic @@ -36,6 +36,7 @@ 400-rbum-cert-sk-vcode-only-one 凭证密钥与动态码只能二选一 400-rbum-cert-reset-sk-duplicate 重置密钥不能重复 400-rbum-cert-sk-contains-ak 密码不能包含用户名 +400-rbum-cert-lock 账号已锁定 401-rbum-cert-lock 账号已锁定 409-rbum-cert-sk-expire 凭证密钥已过期 404-rbum-cert-conf-not-exist 找不到对应的凭证配置 diff --git a/spi/spi-conf/src/api/ci/conf_auth.rs b/spi/spi-conf/src/api/ci/conf_auth.rs index c6d18d696..97f0ab2ee 100644 --- a/spi/spi-conf/src/api/ci/conf_auth.rs +++ b/spi/spi-conf/src/api/ci/conf_auth.rs @@ -16,7 +16,6 @@ use bios_basic::{ }; use poem::web::RealIp; use tardis::{ - basic::error::TardisError, serde_json, web::{ context_extractor::TardisContextExtractor, @@ -27,7 +26,10 @@ use tardis::{ }; use crate::{conf_constants::DOMAIN_CODE, serv::*}; -use crate::{dto::conf_auth_dto::*, serv::placehodler::has_placeholder_auth}; +use crate::{ + dto::{conf_auth_dto::*, conf_namespace_dto::*}, + serv::placehodler::has_placeholder_auth, +}; #[derive(Default, Clone, Copy, Debug)] @@ -88,37 +90,47 @@ impl ConfCiAuthApi { .ok_or_else(|| funs.err().not_found(&SpiBsServ::get_obj_name(), "register", "not found backend service", "404-spi-bs-not-exist"))?; bs.id } - BackendServiceSource::New { name, conn_uri, kind_code } => { + BackendServiceSource::New { name } => { // #TODO // this should be determined by url, but now we only support spi-pg - let kind_code = kind_code.unwrap_or(spi_constants::SPI_PG_KIND_CODE.to_string()); + let kind_code = spi_constants::SPI_PG_KIND_CODE.to_string(); let kind_id = RbumKindServ::get_rbum_kind_id_by_code(&kind_code, &funs) .await? .ok_or_else(|| funs.err().not_found(&SpiBsServ::get_obj_name(), "register", "db spi kind not found", "404-spi-bs-not-exist"))?; - let conn_uri = conn_uri.parse::().map_err(|_| TardisError::bad_request("invalid conn url", "400-spi_conf-bad-request"))?; - let ak = conn_uri.username(); - let sk = conn_uri.password().unwrap_or(""); - SpiBsServ::add_item( - &mut SpiBsAddReq { - name: name.into(), - conn_uri: conn_uri.to_string(), - ext: "{\"max_connections\":20,\"min_connections\":10}".to_string(), - private: false, - disabled: None, - ak: ak.into(), - sk: sk.into(), - kind_id: kind_id.into(), - }, - &funs, - &default_ctx, - ) - .await? + let conn_uri = tardis::TardisFuns::fw_config().db().default.url.clone(); + let mut req = SpiBsAddReq { + name: name.unwrap_or(format!("spi-conf-{}", tardis::crypto::crypto_key::TardisCryptoKey.rand_8_hex())).into(), + conn_uri: conn_uri.to_string(), + ext: "{\"max_connections\":20,\"min_connections\":10}".to_string(), + private: false, + disabled: None, + ak: "".into(), + sk: "".into(), + kind_id: kind_id.into(), + }; + if let Ok(conn_uri) = Url::parse(&conn_uri) { + req.ak = conn_uri.username().into(); + req.sk = conn_uri.password().unwrap_or("").into(); + } + SpiBsServ::add_item(&mut req, &funs, &default_ctx).await? } }; let app_tenant_id = req.app_tenant_id.as_deref().unwrap_or(ctx.owner.as_str()); SpiBsServ::add_rel(&bs_id, app_tenant_id, &funs, &ctx).await?; ctx.owner = app_tenant_id.to_string(); let resp = register(req.register_request, &funs, &ctx).await?; + if let Some((_, app)) = ctx.own_paths.split_once('/') { + create_namespace( + &mut NamespaceAttribute { + namespace: app.to_string(), + namespace_show_name: app.to_string(), + namespace_desc: None, + }, + &funs, + &ctx, + ) + .await?; + } funs.commit().await?; TardisResp::ok(resp) } diff --git a/spi/spi-conf/src/conf_config.rs b/spi/spi-conf/src/conf_config.rs index 39b27ebcb..fedc15b8a 100644 --- a/spi/spi-conf/src/conf_config.rs +++ b/spi/spi-conf/src/conf_config.rs @@ -1,7 +1,7 @@ -use std::net::IpAddr; -use ipnet::IpNet; use bios_basic::rbum::rbum_config::RbumConfig; +use ipnet::IpNet; use serde::{Deserialize, Serialize}; +use std::net::IpAddr; use tardis::consts::{IP_LOCALHOST, IP_UNSPECIFIED}; use crate::dto::conf_auth_dto::RegisterRequest; diff --git a/spi/spi-conf/src/dto/conf_auth_dto.rs b/spi/spi-conf/src/dto/conf_auth_dto.rs index 9182748ce..550d5a8ec 100644 --- a/spi/spi-conf/src/dto/conf_auth_dto.rs +++ b/spi/spi-conf/src/dto/conf_auth_dto.rs @@ -53,7 +53,7 @@ derive_into_nacos_auth! { pub struct RegisterRequest { #[oai(validator(pattern = r"^[a-zA-Z\d_]{5,16}$"))] pub username: Option, - #[oai(validator(pattern = r"^[a-zA-Z\d~!@#$%^&*\(\)_+]{8,16}$"))] + #[oai(validator(pattern = r"^[a-zA-Z\d~!@#$%^&*\(\)_+\.]{8,16}$"))] pub password: Option, } @@ -73,10 +73,10 @@ pub enum BackendServiceSource { #[default] Default, New { - name: String, - conn_uri: String, + name: Option, + // conn_uri: String, // - kind_code: Option, + // kind_code: Option, }, } @@ -84,9 +84,9 @@ pub enum BackendServiceSource { pub struct ChangePasswordRequest { #[oai(validator(pattern = r"^[a-zA-Z\d_]{5,16}$"))] pub username: TrimString, - #[oai(validator(pattern = r"^[a-zA-Z\d~!@#$%^&*\(\)_+]{8,16}$"))] + #[oai(validator(pattern = r"^[a-zA-Z\d~!@#$%^&*\(\)_+\.]{8,16}$"))] pub old_password: TrimString, - #[oai(validator(pattern = r"^[a-zA-Z\d~!@#$%^&*\(\)_+]{8,16}$"))] + #[oai(validator(pattern = r"^[a-zA-Z\d~!@#$%^&*\(\)_+\.]{8,16}$"))] pub password: Option, } diff --git a/spi/spi-conf/tests/spi_conf_api_test.rs b/spi/spi-conf/tests/spi_conf_api_test.rs index a28541341..c37886096 100644 --- a/spi/spi-conf/tests/spi_conf_api_test.rs +++ b/spi/spi-conf/tests/spi_conf_api_test.rs @@ -30,7 +30,14 @@ async fn spi_conf_namespace_test() -> TardisResult<()> { start_web_server().await?; let tardis_ctx = TardisContext::default(); let mut client = TestHttpClient::new("https://localhost:8080/spi-conf".to_string()); - client.set_auth(&tardis_ctx)?; + client.set_auth(&TardisContext { + own_paths: "t1/app001".to_string(), + ak: "".to_string(), + roles: vec![], + groups: vec![], + owner: "app001".to_string(), + ..Default::default() + })?; let funs = TardisFuns::inst_with_db_conn(DOMAIN_CODE.to_string(), None); let RegisterResponse { username, password } = client .put( @@ -49,14 +56,7 @@ async fn spi_conf_namespace_test() -> TardisResult<()> { ) .await; log::info!("username: {username}, password: {password}"); - client.set_auth(&TardisContext { - own_paths: "t1/app001".to_string(), - ak: "".to_string(), - roles: vec![], - groups: vec![], - owner: "app001".to_string(), - ..Default::default() - })?; + test_register(&mut client).await?; test_curd(&mut client).await?; test_tags(&mut client).await?; @@ -123,7 +123,7 @@ pub async fn test_curd(client: &mut TestHttpClient) -> TardisResult<()> { assert_eq!(_response.config_count, 1); // 4.1 get namespace list let _response = client.get::>("/ci/namespace/list").await; - assert_eq!(_response.len(), 3); + assert_eq!(_response.len(), 4); // since we have published a config, the config_count should be 1 // 5. delete config client.delete("/ci/cs/config?namespace_id=public&group=DEFAULT-GROUP&data_id=conf-default").await; diff --git a/spi/spi-kv/src/dto/kv_item_dto.rs b/spi/spi-kv/src/dto/kv_item_dto.rs index 535cf61a2..92646813c 100644 --- a/spi/spi-kv/src/dto/kv_item_dto.rs +++ b/spi/spi-kv/src/dto/kv_item_dto.rs @@ -13,6 +13,7 @@ pub struct KvItemAddOrModifyReq { pub key: TrimString, pub value: Value, pub info: Option, + pub scope_level: Option, } #[derive(poem_openapi::Object, Serialize, Deserialize, Debug, sea_orm::FromQueryResult)] @@ -21,6 +22,9 @@ pub struct KvItemDetailResp { pub key: String, pub value: Value, pub info: String, + pub owner: String, + pub own_paths: String, + pub scope_level: i16, pub create_time: DateTime, pub update_time: DateTime, } @@ -31,6 +35,9 @@ pub struct KvItemSummaryResp { pub key: String, pub value: Value, pub info: String, + pub owner: String, + pub own_paths: String, + pub scope_level: i16, pub create_time: DateTime, pub update_time: DateTime, } @@ -54,6 +61,7 @@ pub struct KvNameAddOrModifyReq { #[oai(validator(min_length = "2"))] pub key: TrimString, pub name: String, + pub scope_level: Option, } #[derive(poem_openapi::Object, Serialize, Deserialize, Debug)] @@ -69,6 +77,7 @@ pub struct KvTagAddOrModifyReq { #[oai(validator(min_length = "2"))] pub key: TrimString, pub items: Vec, + pub scope_level: Option, } #[derive(poem_openapi::Object, Serialize, Deserialize, Debug)] diff --git a/spi/spi-kv/src/serv/kv_item_serv.rs b/spi/spi-kv/src/serv/kv_item_serv.rs index d5e225496..9ac8ef2df 100644 --- a/spi/spi-kv/src/serv/kv_item_serv.rs +++ b/spi/spi-kv/src/serv/kv_item_serv.rs @@ -35,6 +35,7 @@ pub async fn add_or_modify_key_name(add_or_modify_req: &mut KvNameAddOrModifyReq let req = KvItemAddOrModifyReq { key: format!("{}{}", kv_constants::KEY_PREFIX_BY_KEY_NAME, add_or_modify_req.key).into(), value: json!(add_or_modify_req.name), + scope_level: add_or_modify_req.scope_level, info: None, }; let inst = funs.init(ctx, true, kv_initializer::init_fun).await?; @@ -72,6 +73,7 @@ pub async fn add_or_modify_tag(add_or_modify_req: &mut KvTagAddOrModifyReq, funs let req = KvItemAddOrModifyReq { key: format!("{}{}", kv_constants::KEY_PREFIX_BY_TAG, add_or_modify_req.key).into(), value: TardisFuns::json.obj_to_json(&add_or_modify_req.items)?, + scope_level: add_or_modify_req.scope_level, info: None, }; let inst = funs.init(ctx, true, kv_initializer::init_fun).await?; diff --git a/spi/spi-kv/src/serv/pg/kv_pg_initializer.rs b/spi/spi-kv/src/serv/pg/kv_pg_initializer.rs index ea7c17b7f..93daf7c4f 100644 --- a/spi/spi-kv/src/serv/pg/kv_pg_initializer.rs +++ b/spi/spi-kv/src/serv/pg/kv_pg_initializer.rs @@ -14,6 +14,9 @@ pub async fn init_table_and_conn(bs_inst: TypedSpiBsInst<'_, TardisRelDBClient>, r#"k character varying NOT NULL PRIMARY KEY, v jsonb NOT NULL, info character varying NOT NULL, + own_paths VARCHAR(255) NULL, + owner VARCHAR(255) NULL, + scope_level SMALLINT NULL, create_time timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP"#, vec![("k", "btree"), ("v", "gin")], diff --git a/spi/spi-kv/src/serv/pg/kv_pg_item_serv.rs b/spi/spi-kv/src/serv/pg/kv_pg_item_serv.rs index 35b683c95..3ad5125f3 100644 --- a/spi/spi-kv/src/serv/pg/kv_pg_item_serv.rs +++ b/spi/spi-kv/src/serv/pg/kv_pg_item_serv.rs @@ -1,4 +1,7 @@ -use bios_basic::spi::spi_funs::{SpiBsInst, SpiBsInstExtractor}; +use bios_basic::{ + rbum::{dto::rbum_filer_dto::RbumBasicFilterReq, helper::rbum_scope_helper}, + spi::spi_funs::{SpiBsInst, SpiBsInstExtractor}, +}; use tardis::{ basic::{dto::TardisContext, result::TardisResult}, db::{reldb_client::TardisRelDBClient, sea_orm::Value}, @@ -15,21 +18,29 @@ pub async fn add_or_modify_item(add_or_modify_req: &KvItemAddOrModifyReq, _funs: Value::from(add_or_modify_req.key.to_string()), Value::from(add_or_modify_req.value.clone()), Value::from(add_or_modify_req.info.as_ref().unwrap_or(&"".to_string()).as_str()), + Value::from(ctx.owner.clone()), + Value::from(ctx.own_paths.clone()), + Value::from(add_or_modify_req.scope_level.unwrap_or(-1)), ]; let mut update_opt_fragments: Vec<&str> = Vec::new(); update_opt_fragments.push("v = $2"); if add_or_modify_req.info.is_some() { update_opt_fragments.push("info = $3"); } + update_opt_fragments.push("owner = $4"); + update_opt_fragments.push("own_paths = $5"); + if add_or_modify_req.scope_level.is_some() { + update_opt_fragments.push("scope_level = $6"); + } let bs_inst = inst.inst::(); let (mut conn, table_name) = kv_pg_initializer::init_table_and_conn(bs_inst, ctx, true).await?; conn.begin().await?; conn.execute_one( &format!( r#"INSERT INTO {} - (k, v, info) + (k, v, info, owner, own_paths, scope_level) VALUES - ($1, $2, $3) + ($1, $2, $3, $4, $5, $6) ON CONFLICT (k) DO UPDATE SET {} @@ -48,9 +59,9 @@ pub async fn get_item(key: String, extract: Option, _funs: &TardisFunsIn let bs_inst = inst.inst::(); let (conn, table_name) = kv_pg_initializer::init_table_and_conn(bs_inst, ctx, true).await?; let result = conn - .get_dto_by_sql( + .get_dto_by_sql::( &format!( - r#"SELECT k AS key, v{} AS value, info, create_time, update_time + r#"SELECT k AS key, v{} AS value, info, owner, own_paths, scope_level, create_time, update_time FROM {} WHERE k = $1"#, @@ -60,6 +71,19 @@ WHERE vec![Value::from(key)], ) .await?; + if let Some(detail) = result.as_ref() { + if !rbum_scope_helper::check_scope( + &detail.own_paths, + Some(detail.scope_level), + &RbumBasicFilterReq { + ignore_scope: false, + ..Default::default() + }, + ctx, + ) { + return Ok(None); + } + } Ok(result) } @@ -77,9 +101,9 @@ pub async fn find_items(keys: Vec, extract: Option, funs: &Tardi let bs_inst = inst_arc.inst::(); let (conn, table_name) = kv_pg_initializer::init_table_and_conn(bs_inst, ctx, true).await?; let result = conn - .find_dtos_by_sql( + .find_dtos_by_sql::( &format!( - r#"SELECT k AS key, v{} AS value, info, create_time, update_time + r#"SELECT k AS key, v{} AS value, info, owner, own_paths, scope_level, create_time, update_time FROM {} WHERE k IN ({})"#, @@ -89,7 +113,20 @@ WHERE ), sql_vals, ) - .await?; + .await? + .into_iter() + .filter(|item| { + rbum_scope_helper::check_scope( + &item.own_paths, + Some(item.scope_level), + &RbumBasicFilterReq { + ignore_scope: false, + ..Default::default() + }, + ctx, + ) + }) + .collect(); Ok(result) } @@ -141,7 +178,7 @@ pub async fn match_items(match_req: KvItemMatchReq, _funs: &TardisFunsInst, ctx: let result = conn .query_all( &format!( - r#"SELECT k, v{} AS v, info, create_time, update_time, count(*) OVER() AS total + r#"SELECT k, v{} AS v, info, owner, own_paths, scope_level, create_time, update_time, count(*) OVER() AS total FROM {} WHERE {} @@ -171,10 +208,25 @@ WHERE key: item.try_get("", "k")?, value: item.try_get("", "v")?, info: item.try_get("", "info")?, + owner: item.try_get("", "owner")?, + own_paths: item.try_get("", "own_paths")?, + scope_level: item.try_get("", "scope_level")?, create_time: item.try_get("", "create_time")?, update_time: item.try_get("", "update_time")?, }) }) + .filter(|item| { + item.is_ok() + && rbum_scope_helper::check_scope( + &item.as_ref().expect("invalid result").own_paths, + Some(item.as_ref().expect("invalid result").scope_level), + &RbumBasicFilterReq { + ignore_scope: false, + ..Default::default() + }, + ctx, + ) + }) .collect::>>()?; Ok(TardisPage { page_size: match_req.page_size as u64, diff --git a/spi/spi-kv/tests/test_kv_item.rs b/spi/spi-kv/tests/test_kv_item.rs index 4ab646319..330c84f68 100644 --- a/spi/spi-kv/tests/test_kv_item.rs +++ b/spi/spi-kv/tests/test_kv_item.rs @@ -9,14 +9,15 @@ use tardis::tokio::time::sleep; use tardis::web::web_resp::{TardisPage, TardisResp, Void}; pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { - client.set_auth(&TardisContext { + let mut ctx = TardisContext { own_paths: "t1/app001".to_string(), ak: "".to_string(), roles: vec![], groups: vec![], owner: "app001".to_string(), ..Default::default() - })?; + }; + client.set_auth(&ctx)?; let _: Void = client .put( @@ -29,7 +30,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { ) .await; - let result: KvItemDetailResp = client.get("/ci/item/?key=db:url").await; + let result: KvItemDetailResp = client.get("/ci/item?key=db:url").await; assert_eq!(result.key, "db:url"); assert_eq!(result.value, "postgres://xxxx"); assert_eq!(result.info, "xx系统的数据库地址"); @@ -83,24 +84,24 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { ) .await; - let result: KvItemDetailResp = client.get("/ci/item/?key=db_info:002").await; + let result: KvItemDetailResp = client.get("/ci/item?key=db_info:002").await; assert_eq!(result.key, "db_info:002"); assert_eq!(result.info, "002系统的数据库信息"); assert_eq!(result.value.get("url").unwrap().as_str().unwrap(), "postgres://xxxx002"); assert!(result.create_time < result.update_time); - let result: KvItemDetailResp = client.get("/ci/item/?key=db_info:002&extract=url").await; + let result: KvItemDetailResp = client.get("/ci/item?key=db_info:002&extract=url").await; assert_eq!(result.key, "db_info:002"); assert_eq!(result.info, "002系统的数据库信息"); assert_eq!(result.value.as_str().unwrap(), "postgres://xxxx002"); - let result: Vec = client.get("/ci/items/?keys=db_info:002&keys=db_info:001").await; + let result: Vec = client.get("/ci/items?keys=db_info:002&keys=db_info:001").await; assert_eq!(result.len(), 2); assert_eq!(result[1].key, "db_info:002"); assert_eq!(result[1].info, "002系统的数据库信息"); assert_eq!(result[1].value.get("url").unwrap().as_str().unwrap(), "postgres://xxxx002"); - let result: Vec = client.get("/ci/items/?keys=db_info:002&keys=db_info:001&&extract=url").await; + let result: Vec = client.get("/ci/items?keys=db_info:002&keys=db_info:001&&extract=url").await; assert_eq!(result.len(), 2); assert_eq!(result[1].key, "db_info:002"); assert_eq!(result[1].info, "002系统的数据库信息"); @@ -158,7 +159,7 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { client.delete("/ci/item?key=db_info:001").await; - let result: TardisResp = client.get_resp("/ci/item/?key=db_info:001").await; + let result: TardisResp = client.get_resp("/ci/item?key=db_info:001").await; assert!(result.data.is_none()); // key-Name @@ -257,5 +258,26 @@ pub async fn test(client: &mut TestHttpClient) -> TardisResult<()> { assert_eq!(result.total_size, 2); assert_eq!(result.records[1].key, "feed:kind"); assert_eq!(result.records[1].items[1].code, "task"); + + // filter own_paths + let _: Void = client + .put( + "/ci/item", + &json!({ + "key":"db:url", + "value": "postgres://xxxx", + "info":"xx系统的数据库地址", + "scope_level": 0, + }), + ) + .await; + ctx.own_paths = "t1".to_string(); + client.set_auth(&ctx)?; + + let result: KvItemDetailResp = client.get("/ci/item?key=db:url").await; + assert_eq!(result.key, "db:url"); + assert_eq!(result.value, "postgres://xxxx"); + assert_eq!(result.info, "xx系统的数据库地址"); + Ok(()) } diff --git a/support/iam/src/basic/dto/iam_cert_dto.rs b/support/iam/src/basic/dto/iam_cert_dto.rs index 96a4c2c19..b41441ab6 100644 --- a/support/iam/src/basic/dto/iam_cert_dto.rs +++ b/support/iam/src/basic/dto/iam_cert_dto.rs @@ -221,3 +221,8 @@ pub struct IamOauth2AkSkResp { pub struct IamCertDecodeRequest { pub codes: HashSet, } + +#[derive(poem_openapi::Object, Serialize, Deserialize, Debug)] +pub struct IamCertModifyVisibilityRequest { + pub sk_invisible: bool, +} diff --git a/support/iam/src/basic/serv/iam_cert_serv.rs b/support/iam/src/basic/serv/iam_cert_serv.rs index 45ce81a5a..07b592fd3 100644 --- a/support/iam/src/basic/serv/iam_cert_serv.rs +++ b/support/iam/src/basic/serv/iam_cert_serv.rs @@ -33,7 +33,8 @@ use crate::basic::dto::iam_cert_conf_dto::{ IamCertConfLdapAddOrModifyReq, IamCertConfMailVCodeAddOrModifyReq, IamCertConfPhoneVCodeAddOrModifyReq, IamCertConfTokenAddReq, IamCertConfUserPwdAddOrModifyReq, }; use crate::basic::dto::iam_cert_dto::{ - IamCertManageAddReq, IamCertManageModifyReq, IamThirdIntegrationConfigDto, IamThirdIntegrationSyncAddReq, IamThirdIntegrationSyncStatusDto, IamThirdPartyCertExtAddReq, + IamCertManageAddReq, IamCertManageModifyReq, IamCertModifyVisibilityRequest, IamThirdIntegrationConfigDto, IamThirdIntegrationSyncAddReq, IamThirdIntegrationSyncStatusDto, + IamThirdPartyCertExtAddReq, }; use crate::basic::dto::iam_filer_dto::{IamAccountFilterReq, IamResFilterReq, IamRoleFilterReq}; use crate::basic::serv::iam_account_serv::IamAccountServ; @@ -684,7 +685,7 @@ impl IamCertServ { .await?; if let Some(ext_cert) = ext_cert { let now_sk = RbumCertServ::show_sk(ext_cert.id.as_str(), &RbumCertFilterReq::default(), funs, ctx).await?; - let encoded_sk = encode_cert(&ext_cert.id, now_sk, ext_cert.sk_invisible, funs, ctx)?; + let encoded_sk = encode_cert(&ext_cert.id, now_sk, ext_cert.sk_invisible)?; Ok(RbumCertSummaryWithSkResp { id: ext_cert.id, ak: ext_cert.ak, @@ -757,7 +758,7 @@ impl IamCertServ { .await?; if let Some(ext_cert) = ext_cert { let now_sk = RbumCertServ::show_sk(ext_cert.id.as_str(), &RbumCertFilterReq::default(), funs, &mock_ctx).await?; - let encoded_sk = encode_cert(&ext_cert.id, now_sk, ext_cert.sk_invisible, funs, &mock_ctx)?; + let encoded_sk = encode_cert(&ext_cert.id, now_sk, ext_cert.sk_invisible)?; // let encoded_sk = now_sk; Ok(RbumCertSummaryWithSkResp { id: ext_cert.id, @@ -1492,7 +1493,7 @@ impl IamCertServ { let Ok(sk) = RbumCertServ::show_sk(&id, &RbumCertFilterReq::default(), funs, &mock_ctx).await else { return None; }; - Some((id, format!("{sk}/sk"))) + Some((format!("{id}/sk"), sk)) }) } else { None @@ -1508,11 +1509,79 @@ impl IamCertServ { }); Ok(batch_result) } + + pub async fn modify_sk_visibility(id: &str, req: IamCertModifyVisibilityRequest, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> { + let rels = IamRelServ::find_rels( + &RbumRelFilterReq { + basic: RbumBasicFilterReq { + own_paths: Some("".to_string()), + with_sub_own_paths: true, + ignore_scope: true, + ..Default::default() + }, + tag: Some(IamRelKind::IamCertRel.to_string()), + from_rbum_id: Some(id.to_string()), + to_own_paths: Some(ctx.own_paths.clone()), + ..Default::default() + }, + None, + None, + funs, + ctx, + ) + .await?; + let mut mock_ctx = TardisContext { ..ctx.clone() }; + if let Some(rel) = rels.first() { + mock_ctx.own_paths = rel.rel.own_paths.clone() + } + let ext_cert = RbumCertServ::do_find_one_detail_rbum( + &RbumCertFilterReq { + basic: RbumBasicFilterReq { + ids: Some(vec![id.into()]), + ..Default::default() + }, + kind: Some(IamCertExtKind::ThirdParty.to_string()), + ..Default::default() + }, + funs, + &mock_ctx, + ) + .await?; + if let Some(ext_cert) = ext_cert { + RbumCertServ::modify_rbum( + ext_cert.id.as_str(), + &mut RbumCertModifyReq { + sk_invisible: Some(req.sk_invisible), + ak: None, + sk: None, + is_ignore_check_sk: true, + ext: None, + start_time: None, + end_time: None, + conn_uri: None, + status: None, + }, + funs, + ctx, + ) + .await?; + Ok(()) + } else { + Err(funs.err().not_found( + "iam_cert", + "get_3th_kind_cert_by_id", + &format!("not found credential by id {id}"), + "404-rbum-cert-not-exist", + )) + } + } } -fn encode_cert(id: &str, sk: String, invisible: bool, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult { +fn encode_cert(id: &str, sk: String, invisible: bool) -> TardisResult { + let usage = "CERT"; + let field = "sk"; if invisible { - let key = format!("{id}/sk"); + let key = format!("${usage}{{{id}/{field}}}"); Ok(key) } else { Ok(sk) diff --git a/support/iam/src/console_app/api/iam_ca_cert_manage_api.rs b/support/iam/src/console_app/api/iam_ca_cert_manage_api.rs index 31aa31dac..ad9714472 100644 --- a/support/iam/src/console_app/api/iam_ca_cert_manage_api.rs +++ b/support/iam/src/console_app/api/iam_ca_cert_manage_api.rs @@ -1,11 +1,12 @@ use tardis::web::context_extractor::TardisContextExtractor; use tardis::web::poem_openapi; -use tardis::web::poem_openapi::param::Path; -use tardis::web::web_resp::{TardisApiResult, TardisResp}; +use tardis::web::poem_openapi::{param::Path, payload::Json}; +use tardis::web::web_resp::{TardisApiResult, TardisResp, Void}; use bios_basic::rbum::dto::rbum_cert_dto::RbumCertSummaryWithSkResp; use bios_basic::rbum::dto::rbum_rel_dto::RbumRelBoneResp; +use crate::basic::dto::iam_cert_dto::IamCertModifyVisibilityRequest; use crate::basic::serv::iam_cert_serv::IamCertServ; use crate::iam_constants; use bios_basic::helper::request_helper::add_remote_ip; @@ -27,6 +28,17 @@ impl IamCaCertManageApi { TardisResp::ok(cert) } + /// get manage cert + #[oai(path = "/:id", method = "put")] + async fn modify_sk_visibility(&self, id: Path, body: Json, ctx: TardisContextExtractor, request: &Request) -> TardisApiResult { + add_remote_ip(request, &ctx.0).await?; + let funs = iam_constants::get_tardis_inst(); + let ctx = IamCertServ::use_sys_or_tenant_ctx_unsafe(ctx.0)?; + IamCertServ::modify_sk_visibility(&id.0, body.0, &funs, &ctx).await?; + ctx.execute_task().await?; + TardisResp::ok(Void) + } + /// Find Manage Certs By item Id #[oai(path = "/rel/:item_id", method = "get")] async fn find_certs(&self, item_id: Path, ctx: TardisContextExtractor, request: &Request) -> TardisApiResult> { diff --git a/support/iam/src/console_interface/api/iam_ci_cert_api.rs b/support/iam/src/console_interface/api/iam_ci_cert_api.rs index 801e6150d..744a3d083 100644 --- a/support/iam/src/console_interface/api/iam_ci_cert_api.rs +++ b/support/iam/src/console_interface/api/iam_ci_cert_api.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use crate::basic::dto::iam_account_dto::IamAccountExtSysResp; -use crate::basic::dto::iam_cert_dto::{IamCertAkSkAddReq, IamCertAkSkResp, IamOauth2AkSkResp, IamThirdPartyCertExtAddReq, IamCertDecodeRequest}; +use crate::basic::dto::iam_cert_dto::{IamCertAkSkAddReq, IamCertAkSkResp, IamCertDecodeRequest, IamOauth2AkSkResp, IamThirdPartyCertExtAddReq}; use crate::basic::serv::iam_account_serv::IamAccountServ; use crate::basic::serv::iam_cert_ldap_serv::IamCertLdapServ; use crate::basic::serv::iam_cert_serv::IamCertServ; diff --git a/support/iam/src/console_tenant/api/iam_ct_cert_manage_api.rs b/support/iam/src/console_tenant/api/iam_ct_cert_manage_api.rs index 30e9629b8..a4ee9cf67 100644 --- a/support/iam/src/console_tenant/api/iam_ct_cert_manage_api.rs +++ b/support/iam/src/console_tenant/api/iam_ct_cert_manage_api.rs @@ -216,6 +216,4 @@ impl IamCtCertManageApi { ctx.execute_task().await?; TardisResp::ok(rbum_certs) } - - } diff --git a/support/iam/src/console_tenant/api/iam_ct_role_api.rs b/support/iam/src/console_tenant/api/iam_ct_role_api.rs index 8ee6cbfbf..c9688dc00 100644 --- a/support/iam/src/console_tenant/api/iam_ct_role_api.rs +++ b/support/iam/src/console_tenant/api/iam_ct_role_api.rs @@ -119,7 +119,6 @@ impl IamCtRoleApi { TardisResp::ok(result) } - /// 聚合查询租户及基础项目角色 Find Roles base app #[oai(path = "/base_app", method = "get")] async fn find_role_base_app( @@ -133,9 +132,7 @@ impl IamCtRoleApi { let funs = iam_constants::get_tardis_inst(); let app_result = IamRoleServ::find_items( &IamRoleFilterReq { - basic: RbumBasicFilterReq { - ..Default::default() - }, + basic: RbumBasicFilterReq { ..Default::default() }, kind: Some(IamRoleKind::App), in_base: Some(true), ..Default::default() @@ -145,12 +142,10 @@ impl IamCtRoleApi { &funs, &ctx.0, ) - .await?; + .await?; let tenant_result = IamRoleServ::find_items( &IamRoleFilterReq { - basic: RbumBasicFilterReq { - ..Default::default() - }, + basic: RbumBasicFilterReq { ..Default::default() }, // kind: Some(IamRoleKind::Tenant), in_base: Some(false), ..Default::default() @@ -160,7 +155,7 @@ impl IamCtRoleApi { &funs, &ctx.0, ) - .await?; + .await?; ctx.0.execute_task().await?; let mut result = vec![]; result.extend(tenant_result);