Skip to content

Commit

Permalink
Iam featrue/add ak sk cert (ideal-world#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
RWDai authored Dec 21, 2022
1 parent b13456a commit bd74360
Show file tree
Hide file tree
Showing 16 changed files with 315 additions and 18 deletions.
12 changes: 7 additions & 5 deletions basic/src/rbum/serv/rbum_cert_serv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ impl RbumCertServ {
input_sk: &str,
rel_rbum_kind: &RbumCertRelKind,
ignore_end_time: bool,
own_paths: &str,
own_paths: Option<String>,
allowed_kinds: Vec<&str>,
funs: &TardisFunsInst,
) -> TardisResult<(String, RbumCertRelKind, String)> {
Expand Down Expand Up @@ -841,11 +841,13 @@ impl RbumCertServ {
.from(rbum_cert::Entity)
.and_where(Expr::col(rbum_cert::Column::Ak).eq(ak))
.and_where(Expr::col(rbum_cert::Column::RelRbumKind).eq(rel_rbum_kind.to_int()))
.and_where(Expr::col(rbum_cert::Column::OwnPaths).eq(own_paths))
.and_where(Expr::col(rbum_cert::Column::Status).eq(RbumCertStatusKind::Enabled.to_int()))
.and_where(Expr::col(rbum_cert::Column::StartTime).lte(Utc::now().naive_utc()))
//basic sk must have cert conf
.and_where(Expr::col(rbum_cert::Column::RelRbumCertConfId).ne(""));
if let Some(own_paths) = own_paths.clone() {
query.and_where(Expr::col(rbum_cert::Column::OwnPaths).eq(own_paths));
}
let rbum_cert = funs.db().get_dto::<IdAndSkResp>(&query).await?;
if let Some(rbum_cert) = rbum_cert {
if funs.cache().exists(&format!("{}{}", funs.rbum_conf_cache_key_cert_locked_(), rbum_cert.rel_rbum_id)).await? {
Expand Down Expand Up @@ -890,7 +892,7 @@ impl RbumCertServ {
.await?)
} else {
log::warn!(
"validation error [sk is not match] by ak {},rel_rbum_cert_conf_id {}, own_paths {}",
"validation error [sk is not match] by ak {},rel_rbum_cert_conf_id {}, own_paths {:?}",
ak,
rbum_cert_conf_id,
own_paths
Expand All @@ -906,11 +908,11 @@ impl RbumCertServ {
Err(funs.err().unauthorized(&Self::get_obj_name(), "valid", "validation error", "401-rbum-cert-valid-error"))
}
} else {
log::warn!("validation error by ak {},rbum_cert_conf_id is None, own_paths {}", ak, own_paths);
log::warn!("validation error by ak {},rbum_cert_conf_id is None, own_paths {:?}", ak, own_paths);
Err(funs.err().unauthorized(&Self::get_obj_name(), "valid", "validation error", "401-rbum-cert-valid-error"))
}
} else {
log::warn!("validation error by ak {},rel_rbum_kind {}, own_paths {}", ak, rel_rbum_kind, own_paths);
log::warn!("validation error by ak {},rel_rbum_kind {}, own_paths {:?}", ak, rel_rbum_kind, own_paths);
Err(funs.err().unauthorized(&Self::get_obj_name(), "valid", "validation error", "401-rbum-cert-valid-error"))
}
}
Expand Down
22 changes: 22 additions & 0 deletions core/iam/src/basic/dto/iam_cert_dto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,25 @@ pub struct IamCertLdapAddOrModifyReq {
#[oai(validator(min_length = "2", max_length = "2000"))]
pub dn: TrimString,
}

#[derive(poem_openapi::Object, Serialize, Deserialize, Debug)]
pub struct IamCertAkSkAddReq {
pub tenant_id: String,
pub app_id: Option<String>,
}

#[derive(poem_openapi::Object, Serialize, Deserialize, Debug)]
pub struct IamCertAkSkResp {
pub id: String,
pub ak: String,
pub sk: String,
}

#[derive(poem_openapi::Object, Serialize, Deserialize, Debug)]
pub struct IamOauth2AkSkResp {
pub access_token: String,
pub token_type: String,
pub expires_in: String,
pub refresh_token: String,
pub scope: String,
}
124 changes: 123 additions & 1 deletion core/iam/src/basic/serv/iam_cert_aksk_serv.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,136 @@
use bios_basic::rbum::dto::rbum_cert_conf_dto::{RbumCertConfAddReq, RbumCertConfModifyReq};
use bios_basic::rbum::dto::rbum_cert_dto::RbumCertAddReq;
use bios_basic::rbum::dto::rbum_filer_dto::RbumCertFilterReq;
use bios_basic::rbum::rbum_enumeration::{RbumCertConfStatusKind, RbumCertRelKind, RbumCertStatusKind};
use bios_basic::rbum::serv::rbum_cert_serv::{RbumCertConfServ, RbumCertServ};
use bios_basic::rbum::serv::rbum_crud_serv::RbumCrudOperation;
use tardis::basic::field::TrimString;
use tardis::{
basic::{dto::TardisContext, result::TardisResult},
TardisFunsInst,
};

use crate::basic::dto::iam_cert_conf_dto::IamCertConfAkSkAddOrModifyReq;
use crate::basic::dto::iam_cert_dto::IamCertAkSkAddReq;
use crate::basic::serv::iam_key_cache_serv::IamIdentCacheServ;
use crate::iam_config::IamBasicConfigApi;
use crate::iam_constants::RBUM_SYSTEM_OWNER;
use crate::iam_enumeration::IamCertKernelKind;

pub struct IamCertAkSkServ;

impl IamCertAkSkServ {
///rel_iam_item_id app_id
pub async fn add_cert_conf(add_req: &IamCertConfAkSkAddOrModifyReq, rel_iam_item_id: Option<String>, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<String> {
Ok("//todo".into())
let id = RbumCertConfServ::add_rbum(
&mut RbumCertConfAddReq {
kind: TrimString(IamCertKernelKind::AkSk.to_string()),
supplier: None,
name: TrimString(IamCertKernelKind::AkSk.to_string()),
note: None,
ak_note: None,
ak_rule: None,
sk_note: None,
sk_rule: None,
ext: None,
sk_need: Some(false),
sk_dynamic: None,
sk_encrypted: Some(false),
repeatable: None,
is_basic: Some(false),
is_ak_repeatable: None,
rest_by_kinds: None,
expire_sec: None,
sk_lock_cycle_sec: None,
sk_lock_err_times: None,
sk_lock_duration_sec: None,
coexist_num: Some(1),
conn_uri: None,
status: RbumCertConfStatusKind::Enabled,
rel_rbum_domain_id: funs.iam_basic_domain_iam_id(),
rel_rbum_item_id: rel_iam_item_id,
},
funs,
ctx,
)
.await?;
Ok(id)
}

///never use
pub async fn modify_cert_conf(id: &str, modify_req: &IamCertConfAkSkAddOrModifyReq, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> {
RbumCertConfServ::modify_rbum(
id,
&mut RbumCertConfModifyReq {
name: None,
note: None,
ak_note: None,
ak_rule: None,
sk_note: None,
sk_rule: None,
ext: None,
sk_need: None,
sk_encrypted: None,
repeatable: None,
is_basic: None,
rest_by_kinds: None,
expire_sec: None,
sk_lock_cycle_sec: None,
sk_lock_err_times: None,
sk_lock_duration_sec: None,
coexist_num: None,
conn_uri: None,
status: None,
},
funs,
ctx,
)
.await
}

pub async fn add_cert(add_req: &IamCertAkSkAddReq, ak: &str, sk: &str, rel_rbum_cert_conf_id: &str, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<String> {
let new_ctx = TardisContext {
owner: RBUM_SYSTEM_OWNER.to_string(),
own_paths: if add_req.app_id.is_some() {
format!("{}/{}", add_req.tenant_id, add_req.app_id.clone().unwrap())
} else {
add_req.tenant_id.clone()
},
..ctx.clone()
};
let rel_rbum_id = if add_req.app_id.is_some() {
add_req.app_id.as_ref().unwrap()
} else {
&add_req.tenant_id
};
let id = RbumCertServ::add_rbum(
&mut RbumCertAddReq {
ak: ak.into(),
sk: Some(sk.into()),
kind: None,
supplier: None,
vcode: None,
ext: None,
start_time: None,
end_time: None,
conn_uri: None,
status: RbumCertStatusKind::Enabled,
rel_rbum_cert_conf_id: Some(rel_rbum_cert_conf_id.to_string()),
rel_rbum_kind: RbumCertRelKind::Item,
rel_rbum_id: rel_rbum_id.clone(),
is_outside: false,
},
funs,
&new_ctx,
)
.await?;
IamIdentCacheServ::add_aksk(ak, sk, rel_rbum_id, funs).await?;
Ok(id)
}
pub async fn delete_cert(id: &str, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> {
let resp = RbumCertServ::peek_rbum(id, &RbumCertFilterReq { ..Default::default() }, funs, ctx).await?;
RbumCertServ::delete_rbum(id, funs, ctx).await?;
IamIdentCacheServ::delete_aksk(&resp.ak, funs).await?;
Ok(())
}
}
6 changes: 3 additions & 3 deletions core/iam/src/basic/serv/iam_cert_ldap_serv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -483,14 +483,14 @@ impl IamCertLdapServ {
//验证用户名密码登录
let (_, _, rbum_item_id) = if let Some(tenant_id) = tenant_id.clone() {
let global_check =
RbumCertServ::validate_by_ak_and_basic_sk(user_name, password, &RbumCertRelKind::Item, false, "", vec![&IamCertKernelKind::UserPwd.to_string()], funs).await;
RbumCertServ::validate_by_ak_and_basic_sk(user_name, password, &RbumCertRelKind::Item, false, Some("".to_string()), vec![&IamCertKernelKind::UserPwd.to_string()], funs).await;
if global_check.is_err() {
let tenant_check = RbumCertServ::validate_by_ak_and_basic_sk(
user_name,
password,
&RbumCertRelKind::Item,
false,
&tenant_id,
Some(tenant_id.clone()),
vec![&IamCertKernelKind::UserPwd.to_string()],
funs,
)
Expand All @@ -504,7 +504,7 @@ impl IamCertLdapServ {
global_check?
}
} else {
RbumCertServ::validate_by_ak_and_basic_sk(user_name, password, &RbumCertRelKind::Item, false, "", vec![&IamCertKernelKind::UserPwd.to_string()], funs).await?
RbumCertServ::validate_by_ak_and_basic_sk(user_name, password, &RbumCertRelKind::Item, false, Some("".to_string()), vec![&IamCertKernelKind::UserPwd.to_string()], funs).await?
};
if let true = Self::check_user_pwd_is_bind(user_name, code, tenant_id.clone(), funs).await? {
return Err(funs.err().not_found("rbum_cert", "bind_user_pwd_by_ldap", "user is bound by ldap", "409-iam-user-is-bound"));
Expand Down
21 changes: 21 additions & 0 deletions core/iam/src/basic/serv/iam_key_cache_serv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,27 @@ impl IamIdentCacheServ {
}
Err(funs.err().not_found("iam_cache_context", "get", "not found context", "404-iam-cache-context-not-exist"))
}

pub async fn add_aksk(ak: &str, sk: &str, rel_iam_item_id: &str, funs: &TardisFunsInst) -> TardisResult<()> {
log::trace!("add aksk: ak={},sk={}", ak, sk);

funs.cache()
.set(
format!("{}{}", funs.conf::<IamConfig>().cache_key_aksk_info_, ak).as_str(),
format!("{},{}", sk, rel_iam_item_id,).as_str(),
)
.await?;

Ok(())
}

pub async fn delete_aksk(ak: &str, funs: &TardisFunsInst) -> TardisResult<()> {
log::trace!("delete aksk: ak={}", ak);

funs.cache().del(format!("{}{}", funs.conf::<IamConfig>().cache_key_aksk_info_, ak).as_str()).await?;

Ok(())
}
}

pub struct IamResCacheServ;
Expand Down
1 change: 1 addition & 0 deletions core/iam/src/console_interface.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod api;
pub mod serv;
1 change: 1 addition & 0 deletions core/iam/src/console_interface/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod iam_ci_cert_api;
45 changes: 45 additions & 0 deletions core/iam/src/console_interface/api/iam_ci_cert_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::basic::dto::iam_cert_dto::{IamCertAkSkAddReq, IamCertAkSkResp, IamOauth2AkSkResp};
use crate::console_interface::serv::iam_ci_cert_aksk_serv::IamCiCertAkSkServ;
use crate::console_interface::serv::iam_ci_oauth2_token_serv::IamCiOauth2AkSkServ;
use crate::iam_constants;
use crate::iam_enumeration::Oauth2GrantType;
use tardis::web::context_extractor::TardisContextExtractor;
use tardis::web::poem_openapi;
use tardis::web::poem_openapi::param::Query;
use tardis::web::poem_openapi::payload::Json;
use tardis::web::web_resp::{TardisApiResult, TardisResp, Void};

pub struct IamCiCertApi;

/// Interface Console Cert API
#[poem_openapi::OpenApi(prefix_path = "/ci", tag = "bios_basic::ApiTag::Interface")]
impl IamCiCertApi {
/// add aksk cert
#[oai(path = "/aksk", method = "put")]
async fn add_aksk(&self, add_req: Json<IamCertAkSkAddReq>, ctx: TardisContextExtractor) -> TardisApiResult<IamCertAkSkResp> {
let funs = iam_constants::get_tardis_inst();
let result = IamCiCertAkSkServ::general_cert(add_req.0, &funs, &ctx.0).await?;
TardisResp::ok(result)
}

#[oai(path = "/conf/aksk", method = "delete")]
async fn delete_aksk(&self, id: Query<String>, ctx: TardisContextExtractor) -> TardisApiResult<Void> {
let funs = iam_constants::get_tardis_inst();
IamCiCertAkSkServ::delete_cert(&id.0, &funs, &ctx.0).await?;
TardisResp::ok(Void {})
}

#[oai(path = "/token", method = "get")]
async fn get_token(
&self,
grant_type: Query<String>,
client_id: Query<String>,
client_secret: Query<String>,
scope: Query<Option<String>>,
) -> TardisApiResult<IamOauth2AkSkResp> {
let grant_type = Oauth2GrantType::parse(&grant_type.0)?;
let funs = iam_constants::get_tardis_inst();
let resp = IamCiOauth2AkSkServ::generate_token(grant_type, &client_id.0, &client_secret.0, scope.0, funs).await?;
TardisResp::ok(resp)
}
}
3 changes: 2 additions & 1 deletion core/iam/src/console_interface/serv.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod iam_cp_cert_aksk_serv;
pub mod iam_ci_cert_aksk_serv;
pub mod iam_ci_oauth2_token_serv;
25 changes: 25 additions & 0 deletions core/iam/src/console_interface/serv/iam_ci_cert_aksk_serv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::basic::dto::iam_cert_dto::{IamCertAkSkAddReq, IamCertAkSkResp};
use crate::basic::serv::iam_cert_aksk_serv::IamCertAkSkServ;
use crate::basic::serv::iam_cert_serv::IamCertServ;
use crate::basic::serv::iam_tenant_serv::IamTenantServ;
use crate::iam_enumeration::IamCertKernelKind;
use tardis::basic::dto::TardisContext;
use tardis::basic::result::TardisResult;
use tardis::{TardisFuns, TardisFunsInst};

pub struct IamCiCertAkSkServ;

impl IamCiCertAkSkServ {
pub async fn general_cert(add_req: IamCertAkSkAddReq, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<IamCertAkSkResp> {
let cert_conf_id = IamCertServ::get_cert_conf_id_by_kind(IamCertKernelKind::AkSk.to_string().as_str(), Some(IamTenantServ::get_id_by_ctx(ctx, funs)?), funs).await?;
let ak = TardisFuns::crypto.key.generate_ak()?;
let sk = TardisFuns::crypto.key.generate_sk(&ak)?;

let cert_id = IamCertAkSkServ::add_cert(&add_req, &ak, &sk, &cert_conf_id, funs, ctx).await?;
Ok(IamCertAkSkResp { id: cert_id, ak, sk })
}

pub async fn delete_cert(id: &str, funs: &TardisFunsInst, ctx: &TardisContext) -> TardisResult<()> {
IamCertAkSkServ::delete_cert(id, funs, ctx).await
}
}
41 changes: 41 additions & 0 deletions core/iam/src/console_interface/serv/iam_ci_oauth2_token_serv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use crate::basic::dto::iam_cert_dto::IamOauth2AkSkResp;
use crate::basic::serv::iam_key_cache_serv::IamIdentCacheServ;
use crate::iam_enumeration::{IamCertKernelKind, IamCertTokenKind, Oauth2GrantType};
use bios_basic::rbum::rbum_enumeration::RbumCertRelKind;
use bios_basic::rbum::serv::rbum_cert_serv::RbumCertServ;
use tardis::basic::result::TardisResult;
use tardis::{TardisFuns, TardisFunsInst};

pub struct IamCiOauth2AkSkServ;

impl IamCiOauth2AkSkServ {
pub async fn generate_token(grant_type: Oauth2GrantType, client_id: &str, client_secret: &str, scope: Option<String>, funs: TardisFunsInst) -> TardisResult<IamOauth2AkSkResp> {
let (_, _, rel_iam_item_id) = RbumCertServ::validate_by_ak_and_basic_sk(
client_id,
client_secret,
&RbumCertRelKind::Item,
false,
None,
vec![&IamCertKernelKind::AkSk.to_string()],
&funs,
)
.await?;
match grant_type {
Oauth2GrantType::AuthorizationCode => {}
Oauth2GrantType::Password => {}
Oauth2GrantType::ClientCredentials => {}
}

let access_token = TardisFuns::crypto.key.generate_token()?;
let refresh_token = TardisFuns::crypto.key.generate_token()?;
let expire_sec = 30 * 24 * 60 * 60;
IamIdentCacheServ::add_token(&access_token.clone(), &IamCertTokenKind::TokenOauth2, &rel_iam_item_id, expire_sec, 1, &funs).await?;
Ok(IamOauth2AkSkResp {
access_token,
token_type: "Bearer".to_string(),
expires_in: expire_sec.to_string(),
refresh_token,
scope: "".to_string(),
})
}
}
4 changes: 0 additions & 4 deletions core/iam/src/console_interface/serv/iam_cp_cert_aksk_serv.rs

This file was deleted.

Loading

0 comments on commit bd74360

Please sign in to comment.