Files
sub2api/backend/internal/repository/openai_oauth_service.go

90 lines
2.2 KiB
Go
Raw Normal View History

2025-12-22 22:58:31 +08:00
package repository
import (
"context"
"fmt"
"net/url"
"time"
2025-12-24 21:07:21 +08:00
"github.com/Wei-Shaw/sub2api/internal/pkg/openai"
2025-12-25 17:15:01 +08:00
"github.com/Wei-Shaw/sub2api/internal/service"
2025-12-22 22:58:31 +08:00
"github.com/imroc/req/v3"
)
// NewOpenAIOAuthClient creates a new OpenAI OAuth client
2025-12-25 17:15:01 +08:00
func NewOpenAIOAuthClient() service.OpenAIOAuthClient {
2025-12-25 10:52:56 +08:00
return &openaiOAuthService{tokenURL: openai.TokenURL}
}
type openaiOAuthService struct {
tokenURL string
2025-12-22 22:58:31 +08:00
}
func (s *openaiOAuthService) ExchangeCode(ctx context.Context, code, codeVerifier, redirectURI, proxyURL string) (*openai.TokenResponse, error) {
client := createOpenAIReqClient(proxyURL)
if redirectURI == "" {
redirectURI = openai.DefaultRedirectURI
}
formData := url.Values{}
formData.Set("grant_type", "authorization_code")
formData.Set("client_id", openai.ClientID)
formData.Set("code", code)
formData.Set("redirect_uri", redirectURI)
formData.Set("code_verifier", codeVerifier)
var tokenResp openai.TokenResponse
resp, err := client.R().
SetContext(ctx).
SetFormDataFromValues(formData).
SetSuccessResult(&tokenResp).
2025-12-25 10:52:56 +08:00
Post(s.tokenURL)
2025-12-22 22:58:31 +08:00
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
if !resp.IsSuccessState() {
return nil, fmt.Errorf("token exchange failed: status %d, body: %s", resp.StatusCode, resp.String())
}
return &tokenResp, nil
}
func (s *openaiOAuthService) RefreshToken(ctx context.Context, refreshToken, proxyURL string) (*openai.TokenResponse, error) {
client := createOpenAIReqClient(proxyURL)
formData := url.Values{}
formData.Set("grant_type", "refresh_token")
formData.Set("refresh_token", refreshToken)
formData.Set("client_id", openai.ClientID)
formData.Set("scope", openai.RefreshScopes)
var tokenResp openai.TokenResponse
resp, err := client.R().
SetContext(ctx).
SetFormDataFromValues(formData).
SetSuccessResult(&tokenResp).
2025-12-25 10:52:56 +08:00
Post(s.tokenURL)
2025-12-22 22:58:31 +08:00
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
if !resp.IsSuccessState() {
return nil, fmt.Errorf("token refresh failed: status %d, body: %s", resp.StatusCode, resp.String())
}
return &tokenResp, nil
}
func createOpenAIReqClient(proxyURL string) *req.Client {
return getSharedReqClient(reqClientOptions{
ProxyURL: proxyURL,
Timeout: 60 * time.Second,
})
2025-12-22 22:58:31 +08:00
}