feat(backend): 添加 OAuth 能力查询接口,改进 OAuth 客户端选择逻辑

Handler 改进:
- 添加 GET /api/v1/admin/gemini/oauth/capabilities 接口
- 简化 GenerateAuthURL,redirect_uri 由服务层决定

Repository 改进:
- ExchangeCode/RefreshToken 根据 oauthType 选择正确的 OAuth 客户端
- Code Assist 始终使用内置客户端,AI Studio 使用用户配置的客户端
This commit is contained in:
ianshaw
2025-12-25 23:52:02 -08:00
parent 456e8984b0
commit 632318ad33
3 changed files with 30 additions and 14 deletions

View File

@@ -25,15 +25,23 @@ func NewGeminiOAuthClient(cfg *config.Config) service.GeminiOAuthClient {
}
}
func (c *geminiOAuthClient) ExchangeCode(ctx context.Context, code, codeVerifier, redirectURI, proxyURL string) (*geminicli.TokenResponse, error) {
func (c *geminiOAuthClient) ExchangeCode(ctx context.Context, oauthType, code, codeVerifier, redirectURI, proxyURL string) (*geminicli.TokenResponse, error) {
client := createGeminiReqClient(proxyURL)
// Both Code Assist and AI Studio OAuth use the same token endpoint and OAuth client.
oauthCfg, err := geminicli.EffectiveOAuthConfig(geminicli.OAuthConfig{
// Use different OAuth clients based on oauthType:
// - code_assist: always use built-in Gemini CLI OAuth client (public)
// - ai_studio: requires a user-provided OAuth client
oauthCfgInput := geminicli.OAuthConfig{
ClientID: c.cfg.Gemini.OAuth.ClientID,
ClientSecret: c.cfg.Gemini.OAuth.ClientSecret,
Scopes: c.cfg.Gemini.OAuth.Scopes,
}, "code_assist")
}
if oauthType == "code_assist" {
oauthCfgInput.ClientID = ""
oauthCfgInput.ClientSecret = ""
}
oauthCfg, err := geminicli.EffectiveOAuthConfig(oauthCfgInput, oauthType)
if err != nil {
return nil, err
}
@@ -61,15 +69,20 @@ func (c *geminiOAuthClient) ExchangeCode(ctx context.Context, code, codeVerifier
return &tokenResp, nil
}
func (c *geminiOAuthClient) RefreshToken(ctx context.Context, refreshToken, proxyURL string) (*geminicli.TokenResponse, error) {
func (c *geminiOAuthClient) RefreshToken(ctx context.Context, oauthType, refreshToken, proxyURL string) (*geminicli.TokenResponse, error) {
client := createGeminiReqClient(proxyURL)
// Both Code Assist and AI Studio OAuth use the same token endpoint and OAuth client.
oauthCfg, err := geminicli.EffectiveOAuthConfig(geminicli.OAuthConfig{
oauthCfgInput := geminicli.OAuthConfig{
ClientID: c.cfg.Gemini.OAuth.ClientID,
ClientSecret: c.cfg.Gemini.OAuth.ClientSecret,
Scopes: c.cfg.Gemini.OAuth.Scopes,
}, "code_assist")
}
if oauthType == "code_assist" {
oauthCfgInput.ClientID = ""
oauthCfgInput.ClientSecret = ""
}
oauthCfg, err := geminicli.EffectiveOAuthConfig(oauthCfgInput, oauthType)
if err != nil {
return nil, err
}