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