Implemented proxying of GSD requests
This commit is contained in:
120
src/service_gsd.rs
Normal file
120
src/service_gsd.rs
Normal file
@ -0,0 +1,120 @@
|
||||
use axum::body::Body;
|
||||
use axum::extract::Request;
|
||||
use log::{error, info};
|
||||
use crate::config::Config;
|
||||
use reqwest::Response;
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GSDLoginRequestDTO {
|
||||
user: String,
|
||||
pass: String,
|
||||
app_names: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GSDLoginResponseDTO {
|
||||
status: GSDLoginResponseStatusDTO,
|
||||
data: Option<GSDLoginResponseDataDTO>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GSDLoginResponseDataDTO {
|
||||
session_id: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GSDLoginResponseStatusDTO {
|
||||
internal_status: String,
|
||||
status_message: String,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GSDService {
|
||||
host_url: String,
|
||||
app_names: Vec<String>,
|
||||
app_key: String,
|
||||
username: String,
|
||||
password: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum GSDServiceError {
|
||||
LoginFailed,
|
||||
LoginResponseParsingFailed,
|
||||
RequestError(String),
|
||||
}
|
||||
|
||||
impl GSDService {
|
||||
pub async fn get_session(&self) -> Result<String, GSDServiceError> {
|
||||
info!("Session: No session found. Generate session from GSD server {}", self.host_url);
|
||||
|
||||
let dto = GSDLoginRequestDTO {
|
||||
user: self.username.clone(),
|
||||
pass: self.password.clone(),
|
||||
app_names: self.app_names.clone(),
|
||||
};
|
||||
|
||||
let response = reqwest::Client::new()
|
||||
.post(format!("{}/v1/login", self.host_url.clone()))
|
||||
.header("appKey", self.app_key.as_str())
|
||||
.header("Content-Type", "application/json")
|
||||
.json(&dto)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("Session: error request to GSD: {}", e);
|
||||
GSDServiceError::LoginFailed
|
||||
})?;
|
||||
|
||||
let response_dto: GSDLoginResponseDTO = response
|
||||
.json()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("Session: error request to GSD: {}", e);
|
||||
GSDServiceError::LoginResponseParsingFailed
|
||||
})?;
|
||||
if response_dto.status.internal_status != "0" {
|
||||
error!("Session: error message from GSD: {}", response_dto.status.status_message);
|
||||
Err(GSDServiceError::LoginFailed)
|
||||
} else {
|
||||
match response_dto.data {
|
||||
Some(data) => {
|
||||
info!("Session: successfully obtained session with session id {}", &data.session_id);
|
||||
Ok(data.session_id.clone())
|
||||
},
|
||||
None => {
|
||||
error!("Session: failed to obtain session id. No session id in request found.");
|
||||
Err(GSDServiceError::LoginResponseParsingFailed)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn forward_post_request(&self, request: Request<Body>) -> Result<Response, GSDServiceError> {
|
||||
let (parts, body) = request.into_parts();
|
||||
|
||||
reqwest::Client::new()
|
||||
.post(format!("{}{}", self.host_url.clone(), parts.uri))
|
||||
.headers(parts.headers)
|
||||
.body(axum::body::to_bytes(body, usize::MAX).await.unwrap())
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| GSDServiceError::RequestError(e.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Config> for GSDService {
|
||||
fn from(config: &Config) -> Self {
|
||||
Self {
|
||||
host_url: config.gsd_rest_url.clone(),
|
||||
app_names: config.gsd_app_names.clone(),
|
||||
app_key: config.gsd_app_key.clone(),
|
||||
username: config.gsd_user.clone(),
|
||||
password: config.gsd_password.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user