1
use axum::{
2
    body::Body,
3
    http::HeaderValue,
4
    response::{IntoResponse, Response},
5
};
6
use log::error;
7
use reqwest::{self, Client, Method, StatusCode};
8
use serde::Deserialize;
9

            
10
use sylvia_iot_corelib::{err::ErrResp, role::Role};
11

            
12
use super::{middleware::GetTokenInfoData, ErrReq, State};
13

            
14
pub mod application_dldata;
15
pub mod application_uldata;
16
pub mod coremgr_opdata;
17
pub mod network_dldata;
18
pub mod network_uldata;
19

            
20
16
#[derive(Deserialize)]
21
struct GetUser {
22
    data: User,
23
}
24

            
25
/// The user response that is from auth GET API.
26
72
#[derive(Deserialize)]
27
struct User {
28
    #[serde(rename = "userId")]
29
    _user_id: String,
30
    #[serde(rename = "account")]
31
    _account: String,
32
}
33

            
34
1248
#[derive(Deserialize)]
35
struct GetUnit {
36
    data: Unit,
37
}
38

            
39
/// The unit response that is from broker GET API.
40
5616
#[derive(Deserialize)]
41
struct Unit {
42
    #[serde(rename = "unitId")]
43
    _unit_id: String,
44
    #[serde(rename = "code")]
45
    _code: String,
46
}
47

            
48
12
async fn get_user_inner(
49
12
    fn_name: &str,
50
12
    client: &Client,
51
12
    auth_base: &str,
52
12
    user_id: &str,
53
12
    token: &HeaderValue,
54
12
) -> Result<Option<User>, Response> {
55
12
    let uri = format!("{}/api/v1/user/{}", auth_base, user_id);
56
12
    match get_stream_resp(fn_name, token, &client, uri.as_str()).await {
57
4
        Err(resp) => match resp.status() {
58
4
            StatusCode::NOT_FOUND => Ok(None),
59
            _ => Err(resp),
60
        },
61
8
        Ok(resp) => match resp.json::<GetUser>().await {
62
            Err(e) => {
63
                let e = format!("wrong response of user: {}", e);
64
                error!("[{}] {}", fn_name, e);
65
                Err(ErrResp::ErrIntMsg(Some(e)).into_response())
66
            }
67
8
            Ok(user) => Ok(Some(user.data)),
68
        },
69
    }
70
12
}
71

            
72
656
async fn get_unit_inner(
73
656
    fn_name: &str,
74
656
    client: &Client,
75
656
    broker_base: &str,
76
656
    unit_id: &str,
77
656
    token: &HeaderValue,
78
656
) -> Result<Option<Unit>, Response> {
79
656
    let uri = format!("{}/api/v1/unit/{}", broker_base, unit_id);
80
664
    match get_stream_resp(fn_name, token, &client, uri.as_str()).await {
81
32
        Err(resp) => match resp.status() {
82
32
            StatusCode::NOT_FOUND => Ok(None),
83
            _ => Err(resp),
84
        },
85
624
        Ok(resp) => match resp.json::<GetUnit>().await {
86
            Err(e) => {
87
                let e = format!("wrong response of unit: {}", e);
88
                error!("[{}] {}", fn_name, e);
89
                Err(ErrResp::ErrIntMsg(Some(e)).into_response())
90
            }
91
624
            Ok(unit) => Ok(Some(unit.data)),
92
        },
93
    }
94
656
}
95

            
96
1024
async fn get_unit_cond(
97
1024
    fn_name: &str,
98
1024
    token_info: &GetTokenInfoData,
99
1024
    query_unit: Option<&String>,
100
1024
    state: &State,
101
1024
) -> Result<Option<String>, Response> {
102
1024
    let broker_base = state.broker_base.as_str();
103
1024
    let client = state.client.clone();
104
1024

            
105
1024
    match query_unit {
106
        None => {
107
320
            if !Role::is_role(&token_info.roles, Role::ADMIN)
108
320
                && !Role::is_role(&token_info.roles, Role::MANAGER)
109
            {
110
32
                return Err(ErrResp::ErrParam(Some("missing `unit`".to_string())).into_response());
111
288
            }
112
288
            Ok(None)
113
        }
114
704
        Some(unit_id) => match unit_id.len() {
115
48
            0 => Ok(None),
116
            _ => {
117
656
                let token =
118
656
                    match HeaderValue::from_str(format!("Bearer {}", token_info.token).as_str()) {
119
                        Err(e) => {
120
                            error!("[{}] get token error: {}", fn_name, e);
121
                            return Err(ErrResp::ErrRsc(Some(format!("get token error: {}", e)))
122
                                .into_response());
123
                        }
124
656
                        Ok(value) => value,
125
656
                    };
126
664
                match get_unit_inner(fn_name, &client, broker_base, unit_id, &token).await {
127
                    Err(e) => {
128
                        error!("[{}] get unit error", fn_name);
129
                        return Err(e);
130
                    }
131
656
                    Ok(unit) => match unit {
132
                        None => {
133
32
                            return Err(ErrResp::Custom(
134
32
                                ErrReq::UNIT_NOT_EXIST.0,
135
32
                                ErrReq::UNIT_NOT_EXIST.1,
136
32
                                None,
137
32
                            )
138
32
                            .into_response())
139
                        }
140
624
                        Some(_) => Ok(Some(unit_id.clone())),
141
                    },
142
                }
143
            }
144
        },
145
    }
146
1024
}
147

            
148
668
async fn get_stream_resp(
149
668
    fn_name: &str,
150
668
    token: &HeaderValue,
151
668
    client: &Client,
152
668
    uri: &str,
153
668
) -> Result<reqwest::Response, Response> {
154
668
    match client
155
668
        .request(Method::GET, uri)
156
668
        .header(reqwest::header::AUTHORIZATION, token)
157
668
        .build()
158
    {
159
        Err(e) => {
160
            let e = format!("generate request error: {}", e);
161
            error!("[{}] {}", fn_name, e);
162
            Err(ErrResp::ErrRsc(Some(e)).into_response())
163
        }
164
676
        Ok(req) => match client.execute(req).await {
165
            Err(e) => {
166
                let e = format!("execute request error: {}", e);
167
                error!("[{}] {}", fn_name, e);
168
                Err(ErrResp::ErrIntMsg(Some(e)).into_response())
169
            }
170
668
            Ok(resp) => match resp.status() {
171
632
                StatusCode::OK => Ok(resp),
172
                _ => {
173
36
                    let mut resp_builder = Response::builder().status(resp.status());
174
108
                    for (k, v) in resp.headers() {
175
108
                        resp_builder = resp_builder.header(k, v);
176
108
                    }
177
36
                    match resp_builder.body(Body::from_stream(resp.bytes_stream())) {
178
                        Err(e) => {
179
                            let e = format!("wrap response body error: {}", e);
180
                            error!("[{}] {}", fn_name, e);
181
                            Err(ErrResp::ErrIntMsg(Some(e)).into_response())
182
                        }
183
36
                        Ok(resp) => Err(resp),
184
                    }
185
                }
186
            },
187
        },
188
    }
189
668
}