spfn-website/src/api/v1/login.rs
BloxerHD018 2c73e04222
All checks were successful
Build and Push Image / spfn-website (push) Successful in 2m46s
Make Account URL Customisable
2026-06-23 20:22:57 +01:00

79 lines
2.1 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: String,
token_type: String,
expires_in: i64,
}
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!("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(_) => 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);
}
}
}
}