All checks were successful
Build and Push Image / spfn-website (push) Successful in 2m49s
83 lines
2.3 KiB
Rust
83 lines
2.3 KiB
Rust
use std::env;
|
|
use axum::{Router, Json};
|
|
use axum::routing::post;
|
|
use reqwest::StatusCode;
|
|
use reqwest::Client;
|
|
use serde::{Serialize, Deserialize};
|
|
|
|
#[derive(Deserialize)]
|
|
struct GenerateTokenRequest {
|
|
username: String,
|
|
password: String,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
struct TokenRequest {
|
|
grant_type: String,
|
|
username: String,
|
|
password: String,
|
|
client_id: String,
|
|
client_secret: String,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
struct TokenResponse {
|
|
access_token: Option<String>,
|
|
token_type: Option<String>,
|
|
expires_in: Option<i64>,
|
|
error: Option<String>,
|
|
}
|
|
|
|
pub fn router() -> Router {
|
|
Router::new()
|
|
.route("/login/generate_token", post(gen_token))
|
|
}
|
|
|
|
async fn gen_token(Json(payload): Json<GenerateTokenRequest>) -> Result<Json<TokenResponse>, StatusCode> {
|
|
let client = Client::new();
|
|
|
|
let account_url = env::var("ACCOUNT_URL").unwrap_or("https://account.spfn.net".into());
|
|
let client_id = env::var("ACCOUNT_CLIENT_ID").unwrap_or("account".into());
|
|
let client_secret = match env::var("ACCOUNT_CLIENT_SECRET") {
|
|
Ok(secret) => secret,
|
|
Err(_) => {
|
|
println!("[/api/v1/login/generate_token] No account client secret specified - Token generation will always fail");
|
|
return Err(StatusCode::INTERNAL_SERVER_ERROR)
|
|
},
|
|
};
|
|
|
|
let body = TokenRequest {
|
|
grant_type: "password".into(),
|
|
username: payload.username,
|
|
password: payload.password,
|
|
client_id,
|
|
client_secret,
|
|
};
|
|
|
|
let response = client
|
|
.post(format!("{}/api/v2/oauth2/generate_token", account_url))
|
|
.form(&body)
|
|
.send()
|
|
.await;
|
|
|
|
match response {
|
|
Ok(res) => {
|
|
let body = res.json::<TokenResponse>().await;
|
|
|
|
match body {
|
|
Ok(b) => return Ok(Json(b)),
|
|
Err(e) => {
|
|
println!("[/api/v1/login/generate_token] Failed to parse token data from upstream: {}", e);
|
|
return Err(StatusCode::BAD_GATEWAY)
|
|
},
|
|
};
|
|
},
|
|
Err(e) => match e.status() {
|
|
Some(code) => return Err(code),
|
|
None => {
|
|
println!("[/api/v1/login/generate_token] No status error returned from upstream: {}", e);
|
|
return Err(StatusCode::BAD_GATEWAY);
|
|
}
|
|
}
|
|
}
|
|
}
|