From 0dbea6ca5890e10a0389f9ea3758fd7a0c2910be Mon Sep 17 00:00:00 2001 From: cagedbird043 Date: Tue, 24 Feb 2026 20:01:48 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20Gemini=20?= =?UTF-8?q?=E6=8E=88=E6=9D=83=E9=93=BE=E6=8E=A5=E7=94=9F=E6=88=90=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E5=B9=B6=E6=94=B9=E8=BF=9B=E9=94=99=E8=AF=AF=E6=8F=90?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/handler/admin/gemini_oauth_handler.go | 6 +++++- backend/internal/pkg/geminicli/constants.go | 6 ++---- backend/internal/pkg/geminicli/oauth_test.go | 14 ++++++++------ 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/backend/internal/handler/admin/gemini_oauth_handler.go b/backend/internal/handler/admin/gemini_oauth_handler.go index 50caaa26..8c398a1e 100644 --- a/backend/internal/handler/admin/gemini_oauth_handler.go +++ b/backend/internal/handler/admin/gemini_oauth_handler.go @@ -61,7 +61,11 @@ func (h *GeminiOAuthHandler) GenerateAuthURL(c *gin.Context) { if err != nil { msg := err.Error() // Treat missing/invalid OAuth client configuration as a user/config error. - if strings.Contains(msg, "OAuth client not configured") || strings.Contains(msg, "requires your own OAuth Client") { + if strings.Contains(msg, "OAuth client not configured") || + strings.Contains(msg, "requires your own OAuth Client") || + strings.Contains(msg, "requires a custom OAuth Client") || + strings.Contains(msg, "GEMINI_CLI_OAUTH_CLIENT_SECRET_MISSING") || + strings.Contains(msg, "built-in Gemini CLI OAuth client_secret is not configured") { response.BadRequest(c, "Failed to generate auth URL: "+msg) return } diff --git a/backend/internal/pkg/geminicli/constants.go b/backend/internal/pkg/geminicli/constants.go index f85e3b97..97234ffd 100644 --- a/backend/internal/pkg/geminicli/constants.go +++ b/backend/internal/pkg/geminicli/constants.go @@ -38,10 +38,8 @@ const ( // GeminiCLIOAuthClientID/Secret are the public OAuth client credentials used by Google Gemini CLI. // They enable the "login without creating your own OAuth client" experience, but Google may // restrict which scopes are allowed for this client. - GeminiCLIOAuthClientID = "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com" - // GeminiCLIOAuthClientSecret is intentionally not embedded in this repository. - // If you rely on the built-in Gemini CLI OAuth client, you MUST provide its client_secret via config/env. - GeminiCLIOAuthClientSecret = "" + GeminiCLIOAuthClientID = "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com" + GeminiCLIOAuthClientSecret = "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" // GeminiCLIOAuthClientSecretEnv is the environment variable name for the built-in client secret. GeminiCLIOAuthClientSecretEnv = "GEMINI_CLI_OAUTH_CLIENT_SECRET" diff --git a/backend/internal/pkg/geminicli/oauth_test.go b/backend/internal/pkg/geminicli/oauth_test.go index 14bc3c6b..d6f1090b 100644 --- a/backend/internal/pkg/geminicli/oauth_test.go +++ b/backend/internal/pkg/geminicli/oauth_test.go @@ -685,15 +685,17 @@ func TestEffectiveOAuthConfig_WhitespaceTriming(t *testing.T) { } func TestEffectiveOAuthConfig_NoEnvSecret(t *testing.T) { - // 不设置环境变量且不提供凭据,应该报错 t.Setenv(GeminiCLIOAuthClientSecretEnv, "") - _, err := EffectiveOAuthConfig(OAuthConfig{}, "code_assist") - if err == nil { - t.Error("没有内置 secret 且未提供凭据时应该报错") + cfg, err := EffectiveOAuthConfig(OAuthConfig{}, "code_assist") + if err != nil { + t.Fatalf("不设置环境变量时应回退到内置 secret,实际报错: %v", err) } - if !strings.Contains(err.Error(), GeminiCLIOAuthClientSecretEnv) { - t.Errorf("错误消息应提及环境变量 %s,实际: %v", GeminiCLIOAuthClientSecretEnv, err) + if strings.TrimSpace(cfg.ClientSecret) == "" { + t.Error("ClientSecret 不应为空") + } + if cfg.ClientID != GeminiCLIOAuthClientID { + t.Errorf("ClientID 应回退为内置客户端 ID,实际: %q", cfg.ClientID) } } From 9bd6a62ab3f894e90703811f101e639a8b45cfea Mon Sep 17 00:00:00 2001 From: cagedbird043 Date: Tue, 24 Feb 2026 20:03:39 +0800 Subject: [PATCH 2/2] =?UTF-8?q?test:=20=E6=9B=B4=E6=96=B0=20Gemini=20OAuth?= =?UTF-8?q?=20=E5=86=85=E7=BD=AE=E5=9B=9E=E9=80=80=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/pkg/geminicli/oauth_test.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/backend/internal/pkg/geminicli/oauth_test.go b/backend/internal/pkg/geminicli/oauth_test.go index d6f1090b..2a430f9e 100644 --- a/backend/internal/pkg/geminicli/oauth_test.go +++ b/backend/internal/pkg/geminicli/oauth_test.go @@ -408,11 +408,10 @@ func TestBuildAuthorizationURL_WithProjectID(t *testing.T) { } } -func TestBuildAuthorizationURL_OAuthConfigError(t *testing.T) { - // 不设置环境变量,也不提供 client 凭据,EffectiveOAuthConfig 应该报错 +func TestBuildAuthorizationURL_UsesBuiltinSecretFallback(t *testing.T) { t.Setenv(GeminiCLIOAuthClientSecretEnv, "") - _, err := BuildAuthorizationURL( + authURL, err := BuildAuthorizationURL( OAuthConfig{}, "test-state", "test-challenge", @@ -420,8 +419,11 @@ func TestBuildAuthorizationURL_OAuthConfigError(t *testing.T) { "", "code_assist", ) - if err == nil { - t.Error("当 EffectiveOAuthConfig 失败时,BuildAuthorizationURL 应该返回错误") + if err != nil { + t.Fatalf("BuildAuthorizationURL() 不应报错: %v", err) + } + if !strings.Contains(authURL, "client_id="+GeminiCLIOAuthClientID) { + t.Errorf("应使用内置 Gemini CLI client_id,实际 URL: %s", authURL) } }