refactor: 大规模模块拆分与重组,新增 aether-admin crate

- 新建独立 aether-admin crate 承载 admin 相关共享契约与纯辅助函数
- 拆分 ai_pipeline 下 kiro/private_envelope/conversion/planner 等大文件为子模块目录
- 重组 admin handlers 各业务域(billing/oauth/provider/system/users 等)为目录结构,移除 shared.rs/builders.rs 等反模式
- 移除 ai_pipeline runtime adapters 旧实现(claude/openai/gemini/kiro/vertex/antigravity 等),改由 provider transport 统一承载
- 移除 control_facade/execution_facade/auth_snapshot_facade 等冗余 facade 层
- 拆分 query/billing 与 query/monitoring 模块、state/runtime/payments 与 security 模块
- 扩展架构测试覆盖 admin_billing/admin_model/admin_users 等新模块
- 删除 docs/architecture/refactor-execution-plan.md 已完成的执行计划文档
This commit is contained in:
fawney19
2026-04-09 00:10:38 +08:00
parent 4fb9882b54
commit 4fc95adfb9
663 changed files with 48471 additions and 40232 deletions
@@ -0,0 +1,77 @@
pub(crate) use aether_admin::provider::state::{
decode_jwt_claims, enrich_admin_provider_oauth_auth_config, json_non_empty_string,
json_u64_value,
};
#[cfg(test)]
mod tests {
use super::enrich_admin_provider_oauth_auth_config;
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _};
use serde_json::json;
fn sample_unsigned_jwt(payload: serde_json::Value) -> String {
let header = URL_SAFE_NO_PAD.encode(r#"{"alg":"none","typ":"JWT"}"#);
let payload = URL_SAFE_NO_PAD.encode(payload.to_string());
format!("{header}.{payload}.sig")
}
#[test]
fn codex_enrichment_extracts_identity_from_nested_auth_claims() {
let access_token = sample_unsigned_jwt(json!({
"email": "[email protected]",
"https://api.openai.com/auth": {
"chatgpt_account_id": "acc-1",
"chatgpt_account_user_id": "user-1__acc-1",
"chatgpt_plan_type": "team",
"chatgpt_user_id": "user-1",
"organizations": [
{"id": "org-1", "title": "Personal", "is_default": true}
],
}
}));
let token_payload = json!({
"access_token": access_token,
});
let mut auth_config = serde_json::Map::new();
enrich_admin_provider_oauth_auth_config("codex", &mut auth_config, &token_payload);
assert_eq!(auth_config.get("email"), Some(&json!("[email protected]")));
assert_eq!(auth_config.get("account_id"), Some(&json!("acc-1")));
assert_eq!(
auth_config.get("account_user_id"),
Some(&json!("user-1__acc-1"))
);
assert_eq!(auth_config.get("plan_type"), Some(&json!("team")));
assert_eq!(auth_config.get("user_id"), Some(&json!("user-1")));
assert_eq!(
auth_config.get("organizations"),
Some(&json!([
{"id": "org-1", "title": "Personal", "is_default": true}
]))
);
}
#[test]
fn codex_enrichment_normalizes_direct_chatgpt_alias_fields() {
let token_payload = json!({
"email": "[email protected]",
"chatgpt_account_id": "acc-2",
"chatgpt_account_user_id": "user-2__acc-2",
"chatgpt_plan_type": "plus",
"chatgpt_user_id": "user-2",
});
let mut auth_config = serde_json::Map::new();
enrich_admin_provider_oauth_auth_config("codex", &mut auth_config, &token_payload);
assert_eq!(auth_config.get("email"), Some(&json!("[email protected]")));
assert_eq!(auth_config.get("account_id"), Some(&json!("acc-2")));
assert_eq!(
auth_config.get("account_user_id"),
Some(&json!("user-2__acc-2"))
);
assert_eq!(auth_config.get("plan_type"), Some(&json!("plus")));
assert_eq!(auth_config.get("user_id"), Some(&json!("user-2")));
}
}
@@ -0,0 +1,185 @@
use super::super::errors::{
build_internal_control_error_response, normalize_provider_oauth_refresh_error_message,
};
use super::json_non_empty_string;
use crate::handlers::admin::request::{AdminAppState, AdminProviderOAuthTemplate};
use axum::{body::Body, http, response::Response};
pub(crate) async fn exchange_admin_provider_oauth_code(
state: &AdminAppState<'_>,
template: AdminProviderOAuthTemplate,
code: &str,
state_nonce: &str,
pkce_verifier: Option<&str>,
) -> Result<serde_json::Value, Response<Body>> {
let token_url = state.provider_oauth_token_url(template.provider_type, template.token_url);
let request = state.http_client().post(token_url);
let response = if template.provider_type == "claude_code" {
let mut body = serde_json::Map::from_iter([
(
"grant_type".to_string(),
serde_json::Value::String("authorization_code".to_string()),
),
(
"client_id".to_string(),
serde_json::Value::String(template.client_id.to_string()),
),
(
"redirect_uri".to_string(),
serde_json::Value::String(template.redirect_uri.to_string()),
),
(
"code".to_string(),
serde_json::Value::String(code.to_string()),
),
(
"state".to_string(),
serde_json::Value::String(state_nonce.to_string()),
),
]);
if let Some(verifier) = pkce_verifier {
body.insert(
"code_verifier".to_string(),
serde_json::Value::String(verifier.to_string()),
);
}
request
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.json(&serde_json::Value::Object(body))
.send()
.await
} else {
let mut form = vec![
("grant_type", "authorization_code".to_string()),
("client_id", template.client_id.to_string()),
("redirect_uri", template.redirect_uri.to_string()),
("code", code.to_string()),
];
if !template.client_secret.trim().is_empty() {
form.push(("client_secret", template.client_secret.to_string()));
}
if let Some(verifier) = pkce_verifier {
form.push(("code_verifier", verifier.to_string()));
}
request
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Accept", "application/json")
.form(&form)
.send()
.await
}
.map_err(|_| {
build_internal_control_error_response(http::StatusCode::BAD_REQUEST, "token exchange 失败")
})?;
if !response.status().is_success() {
return Err(build_internal_control_error_response(
http::StatusCode::BAD_REQUEST,
"token exchange 失败",
));
}
let payload = response.json::<serde_json::Value>().await.map_err(|_| {
build_internal_control_error_response(
http::StatusCode::BAD_REQUEST,
"token exchange 返回缺少 access_token",
)
})?;
if json_non_empty_string(payload.get("access_token")).is_none() {
return Err(build_internal_control_error_response(
http::StatusCode::BAD_REQUEST,
"token exchange 返回缺少 access_token",
));
}
Ok(payload)
}
pub(crate) async fn exchange_admin_provider_oauth_refresh_token(
state: &AdminAppState<'_>,
template: AdminProviderOAuthTemplate,
refresh_token: &str,
) -> Result<serde_json::Value, Response<Body>> {
let token_url = state.provider_oauth_token_url(template.provider_type, template.token_url);
let request = state.http_client().post(token_url);
let scope = template.scopes.join(" ");
let response = if template.provider_type == "claude_code" {
let mut body = serde_json::Map::from_iter([
(
"grant_type".to_string(),
serde_json::Value::String("refresh_token".to_string()),
),
(
"client_id".to_string(),
serde_json::Value::String(template.client_id.to_string()),
),
(
"refresh_token".to_string(),
serde_json::Value::String(refresh_token.to_string()),
),
]);
if !scope.trim().is_empty() {
body.insert("scope".to_string(), serde_json::Value::String(scope));
}
request
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.json(&serde_json::Value::Object(body))
.send()
.await
} else {
let mut form = vec![
("grant_type", "refresh_token".to_string()),
("client_id", template.client_id.to_string()),
("refresh_token", refresh_token.to_string()),
];
if !scope.trim().is_empty() {
form.push(("scope", scope));
}
if !template.client_secret.trim().is_empty() {
form.push(("client_secret", template.client_secret.to_string()));
}
request
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Accept", "application/json")
.form(&form)
.send()
.await
}
.map_err(|_| {
build_internal_control_error_response(
http::StatusCode::BAD_REQUEST,
"Refresh Token 验证失败: token exchange 失败",
)
})?;
let status = response.status();
let body = response.text().await.map_err(|_| {
build_internal_control_error_response(
http::StatusCode::BAD_REQUEST,
"Refresh Token 验证失败: token exchange 失败",
)
})?;
if !status.is_success() {
let reason =
normalize_provider_oauth_refresh_error_message(Some(status.as_u16()), Some(&body));
return Err(build_internal_control_error_response(
http::StatusCode::BAD_REQUEST,
format!("Refresh Token 验证失败: {reason}"),
));
}
let payload = serde_json::from_str::<serde_json::Value>(&body).map_err(|_| {
build_internal_control_error_response(
http::StatusCode::BAD_REQUEST,
"token refresh 返回缺少 access_token",
)
})?;
if json_non_empty_string(payload.get("access_token")).is_none() {
return Err(build_internal_control_error_response(
http::StatusCode::BAD_REQUEST,
"token refresh 返回缺少 access_token",
));
}
Ok(payload)
}
@@ -0,0 +1,20 @@
mod auth_config;
mod exchange;
mod storage;
mod template;
pub(crate) use self::auth_config::enrich_admin_provider_oauth_auth_config;
pub(crate) use self::exchange::{
exchange_admin_provider_oauth_code, exchange_admin_provider_oauth_refresh_token,
};
pub(crate) use self::storage::build_provider_oauth_start_response;
pub(crate) use self::template::{
admin_provider_oauth_template, build_admin_provider_oauth_backend_unavailable_response,
build_admin_provider_oauth_supported_types_payload, is_fixed_provider_type_for_provider_oauth,
};
pub(crate) use aether_admin::provider::state::{
build_kiro_device_key_name, current_unix_secs, decode_jwt_claims, default_kiro_device_region,
default_kiro_device_start_url, generate_provider_oauth_nonce,
generate_provider_oauth_pkce_verifier, json_non_empty_string, json_u64_value,
normalize_kiro_device_region, parse_provider_oauth_callback_params, provider_oauth_pkce_s256,
};
@@ -0,0 +1,34 @@
use crate::handlers::admin::request::AdminProviderOAuthTemplate;
use serde_json::json;
use url::form_urlencoded;
pub(crate) fn build_provider_oauth_start_response(
template: AdminProviderOAuthTemplate,
nonce: &str,
code_challenge: Option<&str>,
) -> serde_json::Value {
let mut serializer = form_urlencoded::Serializer::new(String::new());
serializer.append_pair("client_id", template.client_id);
serializer.append_pair("response_type", "code");
serializer.append_pair("redirect_uri", template.redirect_uri);
serializer.append_pair("scope", &template.scopes.join(" "));
serializer.append_pair("state", nonce);
if template.provider_type == "codex" {
serializer.append_pair("prompt", "login");
serializer.append_pair("id_token_add_organizations", "true");
serializer.append_pair("codex_cli_simplified_flow", "true");
}
if template.use_pkce {
if let Some(code_challenge) = code_challenge {
serializer.append_pair("code_challenge", code_challenge);
serializer.append_pair("code_challenge_method", "S256");
}
}
json!({
"authorization_url": format!("{}?{}", template.authorize_url, serializer.finish()),
"redirect_uri": template.redirect_uri,
"provider_type": template.provider_type,
"instructions": "1) 打开 authorization_url 完成授权\n2) 授权后会跳转到 redirect_uri(localhost)\n3) 复制浏览器地址栏完整 URL,调用 complete 接口粘贴 callback_url",
})
}
@@ -0,0 +1,44 @@
use super::super::errors::build_internal_control_error_response;
use crate::handlers::admin::provider::shared::support::ADMIN_PROVIDER_OAUTH_DATA_UNAVAILABLE_DETAIL;
use crate::handlers::admin::request::{
admin_provider_oauth_template as request_admin_provider_oauth_template,
admin_provider_oauth_template_types,
is_fixed_provider_type_for_admin_oauth as request_is_fixed_provider_type_for_admin_oauth,
AdminProviderOAuthTemplate,
};
use axum::{body::Body, http, response::Response};
use serde_json::json;
pub(crate) fn is_fixed_provider_type_for_provider_oauth(provider_type: &str) -> bool {
request_is_fixed_provider_type_for_admin_oauth(provider_type)
}
pub(crate) fn admin_provider_oauth_template(
provider_type: &str,
) -> Option<AdminProviderOAuthTemplate> {
request_admin_provider_oauth_template(provider_type)
}
pub(crate) fn build_admin_provider_oauth_supported_types_payload() -> Vec<serde_json::Value> {
admin_provider_oauth_template_types()
.filter_map(|provider_type| admin_provider_oauth_template(provider_type))
.map(|template| {
json!({
"provider_type": template.provider_type,
"display_name": template.display_name,
"scopes": template.scopes,
"redirect_uri": template.redirect_uri,
"authorize_url": template.authorize_url,
"token_url": template.token_url,
"use_pkce": template.use_pkce,
})
})
.collect()
}
pub(crate) fn build_admin_provider_oauth_backend_unavailable_response() -> Response<Body> {
build_internal_control_error_response(
http::StatusCode::SERVICE_UNAVAILABLE,
ADMIN_PROVIDER_OAUTH_DATA_UNAVAILABLE_DETAIL,
)
}