oidc: route auth requests through shared HTTP/tcp-proxy path while keeping TLS warmup

Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
21pages
2026-03-31 11:05:54 +08:00
parent 93cfd56954
commit 28cca601b5

View File

@@ -1,9 +1,10 @@
use super::HbbHttpResponse; use super::HbbHttpResponse;
use crate::hbbs_http::create_http_client_with_url; use crate::hbbs_http::create_http_client_with_url;
use hbb_common::{config::LocalConfig, log, ResultType}; use hbb_common::{config::LocalConfig, log, ResultType};
use reqwest::blocking::Client; use serde::de::DeserializeOwned;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr}; use serde_repr::{Deserialize_repr, Serialize_repr};
use serde_json::{Map, Value};
use std::{ use std::{
collections::HashMap, collections::HashMap,
sync::{Arc, RwLock}, sync::{Arc, RwLock},
@@ -109,7 +110,7 @@ pub struct AuthBody {
} }
pub struct OidcSession { pub struct OidcSession {
client: Option<Client>, warmed_api_server: Option<String>,
state_msg: &'static str, state_msg: &'static str,
failed_msg: String, failed_msg: String,
code_url: Option<OidcAuthUrl>, code_url: Option<OidcAuthUrl>,
@@ -136,7 +137,7 @@ impl Default for UserStatus {
impl OidcSession { impl OidcSession {
fn new() -> Self { fn new() -> Self {
Self { Self {
client: None, warmed_api_server: None,
state_msg: REQUESTING_ACCOUNT_AUTH, state_msg: REQUESTING_ACCOUNT_AUTH,
failed_msg: "".to_owned(), failed_msg: "".to_owned(),
code_url: None, code_url: None,
@@ -149,11 +150,28 @@ impl OidcSession {
fn ensure_client(api_server: &str) { fn ensure_client(api_server: &str) {
let mut write_guard = OIDC_SESSION.write().unwrap(); let mut write_guard = OIDC_SESSION.write().unwrap();
if write_guard.client.is_none() { if write_guard.warmed_api_server.as_deref() == Some(api_server) {
return;
}
// This URL is used to detect the appropriate TLS implementation for the server. // This URL is used to detect the appropriate TLS implementation for the server.
let login_option_url = format!("{}/api/login-options", &api_server); let login_option_url = format!("{}/api/login-options", api_server);
let client = create_http_client_with_url(&login_option_url); let _ = create_http_client_with_url(&login_option_url);
write_guard.client = Some(client); write_guard.warmed_api_server = Some(api_server.to_owned());
}
fn parse_hbb_http_response<T: DeserializeOwned>(body: &str) -> ResultType<HbbHttpResponse<T>> {
let map = serde_json::from_str::<Map<String, Value>>(body)?;
if let Some(error) = map.get("error") {
if let Some(err) = error.as_str() {
Ok(HbbHttpResponse::Error(err.to_owned()))
} else {
Ok(HbbHttpResponse::ErrorFormat)
}
} else {
match serde_json::from_value(Value::Object(map)) {
Ok(v) => Ok(HbbHttpResponse::Data(v)),
Err(_) => Ok(HbbHttpResponse::DataTypeFormat),
}
} }
} }
@@ -164,26 +182,15 @@ impl OidcSession {
uuid: &str, uuid: &str,
) -> ResultType<HbbHttpResponse<OidcAuthUrl>> { ) -> ResultType<HbbHttpResponse<OidcAuthUrl>> {
Self::ensure_client(api_server); Self::ensure_client(api_server);
let resp = if let Some(client) = &OIDC_SESSION.read().unwrap().client { let body = serde_json::json!({
client
.post(format!("{}/api/oidc/auth", api_server))
.json(&serde_json::json!({
"op": op, "op": op,
"id": id, "id": id,
"uuid": uuid, "uuid": uuid,
"deviceInfo": crate::ui_interface::get_login_device_info(), "deviceInfo": crate::ui_interface::get_login_device_info(),
})) })
.send()? .to_string();
} else { let resp = crate::post_request_sync(format!("{}/api/oidc/auth", api_server), body, "")?;
hbb_common::bail!("http client not initialized"); Self::parse_hbb_http_response(&resp)
};
let status = resp.status();
match resp.try_into() {
Ok(v) => Ok(v),
Err(err) => {
hbb_common::bail!("Http status: {}, err: {}", status, err);
}
}
} }
fn query( fn query(
@@ -197,11 +204,19 @@ impl OidcSession {
&[("code", code), ("id", id), ("uuid", uuid)], &[("code", code), ("id", id), ("uuid", uuid)],
)?; )?;
Self::ensure_client(api_server); Self::ensure_client(api_server);
if let Some(client) = &OIDC_SESSION.read().unwrap().client { #[derive(Deserialize)]
Ok(client.get(url).send()?.try_into()?) struct HttpResponseBody {
} else { body: String,
hbb_common::bail!("http client not initialized")
} }
let resp = crate::http_request_sync(
url.to_string(),
"GET".to_owned(),
None,
"{}".to_owned(),
)?;
let resp = serde_json::from_str::<HttpResponseBody>(&resp)?;
Self::parse_hbb_http_response(&resp.body)
} }
fn reset(&mut self) { fn reset(&mut self) {