mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-12 04:09:48 +08:00
feat(provider): 原生接入 Windsurf provider
This commit is contained in:
@@ -36,6 +36,13 @@ fn is_openai_provider_oauth_provider_type(value: Option<&serde_json::Value>) ->
|
||||
})
|
||||
}
|
||||
|
||||
fn is_windsurf_provider_oauth_provider_type(value: Option<&serde_json::Value>) -> bool {
|
||||
value
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.map(str::trim)
|
||||
.is_some_and(|provider_type| provider_type.eq_ignore_ascii_case("windsurf"))
|
||||
}
|
||||
|
||||
fn match_codex_provider_oauth_identity(
|
||||
new_auth_config: &serde_json::Map<String, serde_json::Value>,
|
||||
existing_auth_config: &serde_json::Map<String, serde_json::Value>,
|
||||
@@ -106,6 +113,41 @@ fn match_codex_provider_oauth_identity(
|
||||
None
|
||||
}
|
||||
|
||||
fn match_windsurf_provider_oauth_identity(
|
||||
new_auth_config: &serde_json::Map<String, serde_json::Value>,
|
||||
existing_auth_config: &serde_json::Map<String, serde_json::Value>,
|
||||
) -> Option<bool> {
|
||||
let new_provider_type = new_auth_config.get("provider_type");
|
||||
let existing_provider_type = existing_auth_config.get("provider_type");
|
||||
if !is_windsurf_provider_oauth_provider_type(new_provider_type)
|
||||
&& !is_windsurf_provider_oauth_provider_type(existing_provider_type)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let new_account_id = normalize_provider_oauth_identity_value(new_auth_config.get("account_id"));
|
||||
let existing_account_id =
|
||||
normalize_provider_oauth_identity_value(existing_auth_config.get("account_id"));
|
||||
if let (Some(new_account_id), Some(existing_account_id)) =
|
||||
(new_account_id.as_deref(), existing_account_id.as_deref())
|
||||
{
|
||||
return Some(new_account_id == existing_account_id);
|
||||
}
|
||||
|
||||
let new_credential_fingerprint =
|
||||
normalize_provider_oauth_identity_value(new_auth_config.get("credential_fingerprint"));
|
||||
let existing_credential_fingerprint =
|
||||
normalize_provider_oauth_identity_value(existing_auth_config.get("credential_fingerprint"));
|
||||
if let (Some(new_fingerprint), Some(existing_fingerprint)) = (
|
||||
new_credential_fingerprint.as_deref(),
|
||||
existing_credential_fingerprint.as_deref(),
|
||||
) {
|
||||
return Some(new_fingerprint == existing_fingerprint);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn is_codex_cross_plan_group_non_duplicate(
|
||||
new_auth_config: &serde_json::Map<String, serde_json::Value>,
|
||||
existing_auth_config: &serde_json::Map<String, serde_json::Value>,
|
||||
@@ -169,10 +211,17 @@ pub(crate) async fn find_duplicate_provider_oauth_key(
|
||||
) -> Result<Option<StoredProviderCatalogKey>, String> {
|
||||
let new_email = normalize_provider_oauth_identity_value(auth_config.get("email"));
|
||||
let new_user_id = normalize_provider_oauth_identity_value(auth_config.get("user_id"));
|
||||
let new_account_id = normalize_provider_oauth_identity_value(auth_config.get("account_id"));
|
||||
let new_credential_fingerprint =
|
||||
normalize_provider_oauth_identity_value(auth_config.get("credential_fingerprint"));
|
||||
let new_auth_method = normalize_provider_oauth_identity_value(auth_config.get("auth_method"));
|
||||
let new_kiro_provider = normalize_provider_oauth_identity_value(auth_config.get("provider"));
|
||||
|
||||
if new_email.is_none() && new_user_id.is_none() {
|
||||
if new_email.is_none()
|
||||
&& new_user_id.is_none()
|
||||
&& new_account_id.is_none()
|
||||
&& new_credential_fingerprint.is_none()
|
||||
{
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
@@ -201,15 +250,28 @@ pub(crate) async fn find_duplicate_provider_oauth_key(
|
||||
normalize_provider_oauth_identity_value(existing_auth_config.get("auth_method"));
|
||||
let existing_kiro_provider =
|
||||
normalize_provider_oauth_identity_value(existing_auth_config.get("provider"));
|
||||
let is_windsurf = auth_config
|
||||
.get("provider_type")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.is_some_and(|value| value.eq_ignore_ascii_case("windsurf"))
|
||||
|| existing_auth_config
|
||||
.get("provider_type")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.is_some_and(|value| value.eq_ignore_ascii_case("windsurf"));
|
||||
|
||||
let mut is_duplicate = false;
|
||||
let codex_identity_match =
|
||||
match_codex_provider_oauth_identity(auth_config, &existing_auth_config);
|
||||
let windsurf_identity_match =
|
||||
match_windsurf_provider_oauth_identity(auth_config, &existing_auth_config);
|
||||
if let Some(codex_identity_match) = codex_identity_match {
|
||||
is_duplicate = codex_identity_match;
|
||||
} else if let Some(windsurf_identity_match) = windsurf_identity_match {
|
||||
is_duplicate = windsurf_identity_match;
|
||||
}
|
||||
|
||||
if codex_identity_match.is_none()
|
||||
&& windsurf_identity_match.is_none()
|
||||
&& !is_duplicate
|
||||
&& new_user_id.is_some()
|
||||
&& existing_user_id.is_some()
|
||||
@@ -220,7 +282,9 @@ pub(crate) async fn find_duplicate_provider_oauth_key(
|
||||
}
|
||||
|
||||
if codex_identity_match.is_none()
|
||||
&& windsurf_identity_match.is_none()
|
||||
&& !is_duplicate
|
||||
&& !is_windsurf
|
||||
&& new_email.is_some()
|
||||
&& existing_email.is_some()
|
||||
&& new_email == existing_email
|
||||
@@ -261,6 +325,12 @@ pub(crate) async fn find_duplicate_provider_oauth_key(
|
||||
let identifier =
|
||||
normalize_provider_oauth_identity_value(auth_config.get("account_user_id"))
|
||||
.or_else(|| normalize_provider_oauth_identity_value(auth_config.get("account_id")))
|
||||
.or_else(|| {
|
||||
normalize_provider_oauth_identity_value(
|
||||
auth_config.get("credential_fingerprint"),
|
||||
)
|
||||
.map(|value| format!("fingerprint:{value}"))
|
||||
})
|
||||
.or_else(|| new_email.clone())
|
||||
.or_else(|| new_user_id.clone())
|
||||
.unwrap_or_default();
|
||||
@@ -272,3 +342,91 @@ pub(crate) async fn find_duplicate_provider_oauth_key(
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::match_windsurf_provider_oauth_identity;
|
||||
use serde_json::{json, Map, Value};
|
||||
|
||||
fn auth_config(value: Value) -> Map<String, Value> {
|
||||
value.as_object().cloned().expect("auth config object")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn windsurf_identity_matches_account_id_without_email() {
|
||||
let new_auth_config = auth_config(json!({
|
||||
"provider_type": "windsurf",
|
||||
"auth_method": "api_key",
|
||||
"account_id": "acct-ws-1"
|
||||
}));
|
||||
let existing_auth_config = auth_config(json!({
|
||||
"provider_type": "windsurf",
|
||||
"auth_method": "browser",
|
||||
"account_id": "acct-ws-1"
|
||||
}));
|
||||
|
||||
assert_eq!(
|
||||
match_windsurf_provider_oauth_identity(&new_auth_config, &existing_auth_config),
|
||||
Some(true)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn windsurf_identity_rejects_different_account_id() {
|
||||
let new_auth_config = auth_config(json!({
|
||||
"provider_type": "windsurf",
|
||||
"account_id": "acct-ws-1",
|
||||
"email": "[email protected]"
|
||||
}));
|
||||
let existing_auth_config = auth_config(json!({
|
||||
"provider_type": "windsurf",
|
||||
"account_id": "acct-ws-2",
|
||||
"email": "[email protected]"
|
||||
}));
|
||||
|
||||
assert_eq!(
|
||||
match_windsurf_provider_oauth_identity(&new_auth_config, &existing_auth_config),
|
||||
Some(false)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn windsurf_identity_matches_credential_fingerprint_without_profile() {
|
||||
let new_auth_config = auth_config(json!({
|
||||
"provider_type": "windsurf",
|
||||
"auth_method": "api_key",
|
||||
"credential_fingerprint": "abcdef0123456789"
|
||||
}));
|
||||
let existing_auth_config = auth_config(json!({
|
||||
"provider_type": "windsurf",
|
||||
"auth_method": "browser",
|
||||
"credential_fingerprint": "abcdef0123456789"
|
||||
}));
|
||||
|
||||
assert_eq!(
|
||||
match_windsurf_provider_oauth_identity(&new_auth_config, &existing_auth_config),
|
||||
Some(true)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn windsurf_identity_does_not_match_user_supplied_email_only() {
|
||||
let new_auth_config = auth_config(json!({
|
||||
"provider_type": "windsurf",
|
||||
"auth_method": "api_key",
|
||||
"email": "[email protected]",
|
||||
"email_verified": false
|
||||
}));
|
||||
let existing_auth_config = auth_config(json!({
|
||||
"provider_type": "windsurf",
|
||||
"auth_method": "api_key",
|
||||
"email": "[email protected]",
|
||||
"email_verified": false
|
||||
}));
|
||||
|
||||
assert_eq!(
|
||||
match_windsurf_provider_oauth_identity(&new_auth_config, &existing_auth_config),
|
||||
None
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user