mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 09:50:21 +08:00
feat(oauth): 允许替换已失效的活跃 OAuth 账号并同步 status_snapshot
- 活跃但 token 已过期或刷新失败的重复账号视为可替换 - 清除失效标记、刷新配额时同步更新 status_snapshot.oauth - oauth_invalid 清除接口同时识别 invalid_at 与 invalid_reason 两种标记 - 批量导入任务状态区分 created_count / replaced_count,前端据此展示新增/替换统计 - 补充重复替换场景的集成测试,用量测试等待超时从 10s 提升到 30s 以适应并行压力
This commit is contained in:
@@ -548,8 +548,40 @@ async fn gateway_clears_admin_provider_key_oauth_invalid_locally_with_trusted_ad
|
||||
"openai:chat",
|
||||
"sk-test-a",
|
||||
);
|
||||
key.auth_type = "oauth".to_string();
|
||||
key.oauth_invalid_at_unix_secs = Some(1_710_000_000);
|
||||
key.oauth_invalid_reason = Some("token expired".to_string());
|
||||
key.expires_at_unix_secs = Some(1_900_000_000);
|
||||
key.status_snapshot = Some(json!({
|
||||
"oauth": {
|
||||
"code": "invalid",
|
||||
"label": "已失效",
|
||||
"reason": "token expired",
|
||||
"expires_at": 1_900_000_000u64,
|
||||
"invalid_at": 1_710_000_000u64,
|
||||
"source": "oauth_invalid",
|
||||
"requires_reauth": true,
|
||||
"expiring_soon": false
|
||||
},
|
||||
"account": {
|
||||
"code": "ok",
|
||||
"label": serde_json::Value::Null,
|
||||
"reason": serde_json::Value::Null,
|
||||
"blocked": false,
|
||||
"source": serde_json::Value::Null,
|
||||
"recoverable": false
|
||||
},
|
||||
"quota": {
|
||||
"code": "unknown",
|
||||
"label": serde_json::Value::Null,
|
||||
"reason": serde_json::Value::Null,
|
||||
"exhausted": false,
|
||||
"usage_ratio": serde_json::Value::Null,
|
||||
"updated_at": serde_json::Value::Null,
|
||||
"reset_seconds": serde_json::Value::Null,
|
||||
"plan_type": serde_json::Value::Null
|
||||
}
|
||||
}));
|
||||
|
||||
let provider_catalog_repository = Arc::new(InMemoryProviderCatalogReadRepository::seed(
|
||||
vec![sample_provider("provider-openai", "openai", 10)],
|
||||
@@ -594,6 +626,22 @@ async fn gateway_clears_admin_provider_key_oauth_invalid_locally_with_trusted_ad
|
||||
assert_eq!(reloaded.len(), 1);
|
||||
assert_eq!(reloaded[0].oauth_invalid_at_unix_secs, None);
|
||||
assert_eq!(reloaded[0].oauth_invalid_reason, None);
|
||||
let oauth_snapshot = reloaded[0]
|
||||
.status_snapshot
|
||||
.as_ref()
|
||||
.and_then(serde_json::Value::as_object)
|
||||
.and_then(|snapshot| snapshot.get("oauth"))
|
||||
.and_then(serde_json::Value::as_object)
|
||||
.expect("oauth snapshot should exist");
|
||||
assert_eq!(oauth_snapshot.get("code"), Some(&json!("valid")));
|
||||
assert_eq!(oauth_snapshot.get("label"), Some(&json!("有效")));
|
||||
assert_eq!(oauth_snapshot.get("reason"), Some(&serde_json::Value::Null));
|
||||
assert_eq!(
|
||||
oauth_snapshot.get("invalid_at"),
|
||||
Some(&serde_json::Value::Null)
|
||||
);
|
||||
assert_eq!(oauth_snapshot.get("source"), Some(&json!("expires_at")));
|
||||
assert_eq!(oauth_snapshot.get("requires_reauth"), Some(&json!(false)));
|
||||
|
||||
gateway_handle.abort();
|
||||
upstream_handle.abort();
|
||||
|
||||
Reference in New Issue
Block a user