ResolveAuthProvider resolves credentials for the given provider and returns a TokenProvider that refreshes OAuth tokens transparently. Lookup order: 1. Auth-profiles store (first match by provider). 2. Environment variables. The returned provider is alive: callers that retain it across requests get
(ctx context.Context, provider ProviderID, logger *zap.Logger)
| 33 | // Caller is responsible for calling Close() when discarding the provider |
| 34 | // (typically the LLMManager owns and closes them). |
| 35 | func ResolveAuthProvider(ctx context.Context, provider ProviderID, logger *zap.Logger) (TokenProvider, error) { |
| 36 | store := LoadStore(logger) |
| 37 | for id, c := range store.Profiles { |
| 38 | if c == nil { |
| 39 | continue |
| 40 | } |
| 41 | if !isProviderMatch(c.Provider, provider) { |
| 42 | continue |
| 43 | } |
| 44 | switch c.CredType { |
| 45 | case CredentialOAuth: |
| 46 | tp := newOAuthTokenProvider(c, id, "auth-store", logger) |
| 47 | return tp, nil |
| 48 | case CredentialToken: |
| 49 | key := strings.TrimSpace(c.Token) |
| 50 | if key == "" { |
| 51 | continue |
| 52 | } |
| 53 | return &staticTokenProvider{ |
| 54 | token: key, |
| 55 | mode: AuthModeToken, |
| 56 | provider: provider, |
| 57 | profileID: id, |
| 58 | source: "auth-store", |
| 59 | email: c.Email, |
| 60 | }, nil |
| 61 | case CredentialAPIKey: |
| 62 | key := strings.TrimSpace(c.Key) |
| 63 | if key == "" { |
| 64 | continue |
| 65 | } |
| 66 | return &staticTokenProvider{ |
| 67 | token: key, |
| 68 | mode: AuthModeAPIKey, |
| 69 | provider: provider, |
| 70 | profileID: id, |
| 71 | source: "auth-store", |
| 72 | email: c.Email, |
| 73 | }, nil |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | if tp := envFallbackProvider(provider); tp != nil { |
| 78 | return tp, nil |
| 79 | } |
| 80 | |
| 81 | return nil, fmt.Errorf("%s", i18n.T("auth.resolver.no_credentials", provider)) |
| 82 | } |
| 83 | |
| 84 | func envFallbackProvider(provider ProviderID) TokenProvider { |
| 85 | switch provider { |