fix(gemini): 修复已注册用户 OAuth 授权时错误调用 onboardUser 的问题

问题:Google One Ultra 等已注册用户在 OAuth 授权时,如果 LoadCodeAssist
返回了 currentTier/paidTier 但没有返回 cloudaicompanionProject,之前的
逻辑会继续调用 onboardUser,导致 INVALID_ARGUMENT 错误。

修复:对齐 Gemini CLI 的处理逻辑:
- 当检测到用户已注册(有 currentTier/paidTier)时,不再调用 onboardUser
- 先尝试从 Cloud Resource Manager 获取可用项目
- 如果仍无法获取,返回友好的错误提示,引导用户手动填写 Project ID

这个修复解决了 Google One 订阅用户无法正常授权的问题。
This commit is contained in:
IanShaw027
2026-02-05 13:57:02 +08:00
parent 05af95dade
commit 979114db45

View File

@@ -944,6 +944,32 @@ func (s *GeminiOAuthService) fetchProjectID(ctx context.Context, accessToken, pr
return strings.TrimSpace(loadResp.CloudAICompanionProject), tierID, nil return strings.TrimSpace(loadResp.CloudAICompanionProject), tierID, nil
} }
// 关键逻辑:对齐 Gemini CLI 对“已注册用户”的处理方式。
// 当 LoadCodeAssist 返回了 currentTier / paidTier表示账号已注册但没有返回 cloudaicompanionProject 时:
// - 不要再调用 onboardUser通常不会再分配 project_id且可能触发 INVALID_ARGUMENT
// - 先尝试从 Cloud Resource Manager 获取可用项目;仍失败则提示用户手动填写 project_id
if loadResp != nil {
registeredTierID := strings.TrimSpace(loadResp.GetTier())
if registeredTierID != "" {
// 已注册但未返回 cloudaicompanionProject这在 Google One 用户中较常见:需要用户自行提供 project_id。
log.Printf("[GeminiOAuth] User has tier (%s) but no cloudaicompanionProject, trying Cloud Resource Manager...", registeredTierID)
// Try to get project from Cloud Resource Manager
fallback, fbErr := fetchProjectIDFromResourceManager(ctx, accessToken, proxyURL)
if fbErr == nil && strings.TrimSpace(fallback) != "" {
log.Printf("[GeminiOAuth] Found project from Cloud Resource Manager: %s", fallback)
return strings.TrimSpace(fallback), tierID, nil
}
// No project found - user must provide project_id manually
log.Printf("[GeminiOAuth] No project found from Cloud Resource Manager, user must provide project_id manually")
return "", tierID, fmt.Errorf("user is registered (tier: %s) but no project_id available. Please provide Project ID manually in the authorization form, or create a project at https://console.cloud.google.com", registeredTierID)
}
}
// 未检测到 currentTier/paidTier视为新用户继续调用 onboardUser
log.Printf("[GeminiOAuth] No currentTier/paidTier found, proceeding with onboardUser (tierID: %s)", tierID)
req := &geminicli.OnboardUserRequest{ req := &geminicli.OnboardUserRequest{
TierID: tierID, TierID: tierID,
Metadata: geminicli.LoadCodeAssistMetadata{ Metadata: geminicli.LoadCodeAssistMetadata{