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::{ErrReq, State, middleware::GetTokenInfoData};
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
#[derive(Deserialize)]
21
struct GetUser {
22
    data: User,
23
}
24

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

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

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

            
48
24
async fn get_user_inner(
49
24
    fn_name: &str,
50
24
    client: &Client,
51
24
    auth_base: &str,
52
24
    user_id: &str,
53
24
    token: &HeaderValue,
54
24
) -> Result<Option<User>, Response> {
55
24
    let uri = format!("{}/api/v1/user/{}", auth_base, user_id);
56
24
    match get_stream_resp(fn_name, token, &client, uri.as_str()).await {
57
8
        Err(resp) => match resp.status() {
58
8
            StatusCode::NOT_FOUND => Ok(None),
59
            _ => Err(resp),
60
        },
61
16
        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
16
            Ok(user) => Ok(Some(user.data)),
68
        },
69
    }
70
24
}
71

            
72
1312
async fn get_unit_inner(
73
1312
    fn_name: &str,
74
1312
    client: &Client,
75
1312
    broker_base: &str,
76
1312
    unit_id: &str,
77
1312
    token: &HeaderValue,
78
1312
) -> Result<Option<Unit>, Response> {
79
1312
    let uri = format!("{}/api/v1/unit/{}", broker_base, unit_id);
80
1312
    match get_stream_resp(fn_name, token, &client, uri.as_str()).await {
81
64
        Err(resp) => match resp.status() {
82
64
            StatusCode::NOT_FOUND => Ok(None),
83
            _ => Err(resp),
84
        },
85
1248
        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
1248
            Ok(unit) => Ok(Some(unit.data)),
92
        },
93
    }
94
1312
}
95

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

            
105
2048
    match query_unit {
106
        None => {
107
640
            if !Role::is_role(&token_info.roles, Role::ADMIN)
108
640
                && !Role::is_role(&token_info.roles, Role::MANAGER)
109
            {
110
64
                return Err(ErrResp::ErrParam(Some("missing `unit`".to_string())).into_response());
111
576
            }
112
576
            Ok(None)
113
        }
114
1408
        Some(unit_id) => match unit_id.len() {
115
96
            0 => Ok(None),
116
            _ => {
117
1312
                let token =
118
1312
                    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
1312
                        Ok(value) => value,
125
1312
                    };
126
1312
                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
1312
                    Ok(unit) => match unit {
132
                        None => {
133
64
                            return Err(ErrResp::Custom(
134
64
                                ErrReq::UNIT_NOT_EXIST.0,
135
64
                                ErrReq::UNIT_NOT_EXIST.1,
136
64
                                None,
137
64
                            )
138
64
                            .into_response());
139
                        }
140
1248
                        Some(_) => Ok(Some(unit_id.clone())),
141
                    },
142
                }
143
            }
144
        },
145
    }
146
2048
}
147

            
148
1336
async fn get_stream_resp(
149
1336
    fn_name: &str,
150
1336
    token: &HeaderValue,
151
1336
    client: &Client,
152
1336
    uri: &str,
153
1336
) -> Result<reqwest::Response, Response> {
154
1336
    match client
155
1336
        .request(Method::GET, uri)
156
1336
        .header(reqwest::header::AUTHORIZATION, token)
157
1336
        .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
1336
        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
1336
            Ok(resp) => match resp.status() {
171
1264
                StatusCode::OK => Ok(resp),
172
                _ => {
173
72
                    let mut resp_builder = Response::builder().status(resp.status());
174
216
                    for (k, v) in resp.headers() {
175
216
                        resp_builder = resp_builder.header(k, v);
176
216
                    }
177
72
                    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
72
                        Ok(resp) => Err(resp),
184
                    }
185
                }
186
            },
187
        },
188
    }
189
1336
}