bios_iam/basic/middleware/
encrypt_mw.rs

1use 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                //如果有这个头,那么需要返回加密
49                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}