bios_iam/basic/middleware/
encrypt_mw.rs1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use tardis::web::poem_openapi;
5use tardis::{
6 basic::error::TardisError,
7 log,
8 web::{
9 poem::{self, endpoint::BoxEndpoint, http::HeaderValue, Body, Endpoint, IntoResponse, Middleware, Request, Response},
10 web_resp::TardisResp,
11 web_server::BoxMiddleware,
12 },
13};
14
15use crate::{iam_config::IamConfig, iam_constants};
16#[derive(Clone, Debug)]
17pub struct EncryptMW;
18
19impl EncryptMW {
20 pub fn boxed() -> BoxMiddleware<'static> {
21 Box::new(EncryptMW)
22 }
23}
24
25impl Middleware<BoxEndpoint<'static>> for EncryptMW {
26 type Output = BoxEndpoint<'static>;
27
28 fn transform(&self, ep: BoxEndpoint<'static>) -> Self::Output {
29 Box::new(poem::endpoint::ToDynEndpoint(EncryptMWImpl(ep)))
30 }
31}
32
33pub struct EncryptMWImpl<E>(E);
34
35impl<E: Endpoint> Endpoint for EncryptMWImpl<E> {
36 type Output = Response;
37
38 async fn call(&self, req: Request) -> poem::Result<Self::Output> {
39 let funs = iam_constants::get_tardis_inst();
40 let _method = req.method().to_string();
41 let _url = req.uri().to_string();
42 let req_head_crypto_value = req.header(&funs.conf::<IamConfig>().crypto_conf.head_key_crypto).map(|v| v.to_string());
43 let resp = self.0.call(req).await;
44 match resp {
45 Ok(resp) => {
46 let mut resp = resp.into_response();
47
48 if let Some(key_crypto) = req_head_crypto_value {
50 log::trace!("[Iam.Middleware] key_crypto:{key_crypto}");
51 let resp_body = resp.take_body().into_string().await?;
52
53 let mut headers = HashMap::new();
54 headers.insert(funs.conf::<IamConfig>().crypto_conf.head_key_crypto.to_string(), key_crypto);
55 let auth_encrypt_req = AuthEncryptReq { headers, body: resp_body.clone() };
56
57 let encrypt_resp: TardisResp<AuthEncryptResp> = funs
58 .web_client()
59 .put(&format!("{}/auth/crypto", funs.conf::<IamConfig>().crypto_conf.auth_url), &auth_encrypt_req, None)
60 .await
61 .map_err(|e| TardisError::internal_error(&format!("[Iam.Middleware] Encrypted api call error: {e}"), "500-auth-resp-crypto-error"))?
62 .body
63 .ok_or_else(|| TardisError::internal_error("[Iam.Middleware] Encrypted api call error: not found body", "500-auth-resp-crypto-error"))?;
64
65 if encrypt_resp.code != *"200" {
66 return Err(TardisError::internal_error(
67 &format!("[Iam.Middleware] Encrypted api call return error:{}", encrypt_resp.msg),
68 "500-auth-resp-crypto-error",
69 )
70 .into());
71 } else if let Some(resp_body) = encrypt_resp.data {
72 if let Some(encrypt_resp_header_value) = resp_body.headers.get(&funs.conf::<IamConfig>().crypto_conf.head_key_crypto) {
73 let resp_headers = resp.headers_mut();
74 if let Ok(header_value) = HeaderValue::from_str(encrypt_resp_header_value) {
75 resp_headers.insert(funs.conf::<IamConfig>().crypto_conf.get_crypto_header_name()?, header_value);
76 }
77 resp.set_body(Body::from_string(resp_body.body));
78 }
79 } else {
80 resp.set_body(Body::from_string(resp_body));
81 }
82 }
83 Ok(resp)
84 }
85 Err(error) => Err(error),
86 }
87 }
88}
89
90#[derive(Serialize, Deserialize, Debug)]
91pub struct AuthEncryptReq {
92 pub headers: HashMap<String, String>,
93 pub body: String,
94}
95
96#[derive(poem_openapi::Object, Serialize, Deserialize, Debug)]
97pub struct AuthEncryptResp {
98 pub headers: HashMap<String, String>,
99 pub body: String,
100}