|
|
|
|
|
|
|
|
|
|
|
package cliproxy |
|
|
|
|
|
import ( |
|
|
"fmt" |
|
|
"strings" |
|
|
|
|
|
"github.com/router-for-me/CLIProxyAPI/v6/internal/api" |
|
|
sdkaccess "github.com/router-for-me/CLIProxyAPI/v6/sdk/access" |
|
|
sdkAuth "github.com/router-for-me/CLIProxyAPI/v6/sdk/auth" |
|
|
coreauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth" |
|
|
"github.com/router-for-me/CLIProxyAPI/v6/sdk/config" |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Builder struct { |
|
|
|
|
|
cfg *config.Config |
|
|
|
|
|
|
|
|
configPath string |
|
|
|
|
|
|
|
|
tokenProvider TokenClientProvider |
|
|
|
|
|
|
|
|
apiKeyProvider APIKeyClientProvider |
|
|
|
|
|
|
|
|
watcherFactory WatcherFactory |
|
|
|
|
|
|
|
|
hooks Hooks |
|
|
|
|
|
|
|
|
authManager *sdkAuth.Manager |
|
|
|
|
|
|
|
|
accessManager *sdkaccess.Manager |
|
|
|
|
|
|
|
|
coreManager *coreauth.Manager |
|
|
|
|
|
|
|
|
serverOptions []api.ServerOption |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Hooks struct { |
|
|
|
|
|
|
|
|
OnBeforeStart func(*config.Config) |
|
|
|
|
|
|
|
|
|
|
|
OnAfterStart func(*Service) |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func NewBuilder() *Builder { |
|
|
return &Builder{} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *Builder) WithConfig(cfg *config.Config) *Builder { |
|
|
b.cfg = cfg |
|
|
return b |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *Builder) WithConfigPath(path string) *Builder { |
|
|
b.configPath = path |
|
|
return b |
|
|
} |
|
|
|
|
|
|
|
|
func (b *Builder) WithTokenClientProvider(provider TokenClientProvider) *Builder { |
|
|
b.tokenProvider = provider |
|
|
return b |
|
|
} |
|
|
|
|
|
|
|
|
func (b *Builder) WithAPIKeyClientProvider(provider APIKeyClientProvider) *Builder { |
|
|
b.apiKeyProvider = provider |
|
|
return b |
|
|
} |
|
|
|
|
|
|
|
|
func (b *Builder) WithWatcherFactory(factory WatcherFactory) *Builder { |
|
|
b.watcherFactory = factory |
|
|
return b |
|
|
} |
|
|
|
|
|
|
|
|
func (b *Builder) WithHooks(h Hooks) *Builder { |
|
|
b.hooks = h |
|
|
return b |
|
|
} |
|
|
|
|
|
|
|
|
func (b *Builder) WithAuthManager(mgr *sdkAuth.Manager) *Builder { |
|
|
b.authManager = mgr |
|
|
return b |
|
|
} |
|
|
|
|
|
|
|
|
func (b *Builder) WithRequestAccessManager(mgr *sdkaccess.Manager) *Builder { |
|
|
b.accessManager = mgr |
|
|
return b |
|
|
} |
|
|
|
|
|
|
|
|
func (b *Builder) WithCoreAuthManager(mgr *coreauth.Manager) *Builder { |
|
|
b.coreManager = mgr |
|
|
return b |
|
|
} |
|
|
|
|
|
|
|
|
func (b *Builder) WithServerOptions(opts ...api.ServerOption) *Builder { |
|
|
b.serverOptions = append(b.serverOptions, opts...) |
|
|
return b |
|
|
} |
|
|
|
|
|
|
|
|
func (b *Builder) WithLocalManagementPassword(password string) *Builder { |
|
|
if password == "" { |
|
|
return b |
|
|
} |
|
|
b.serverOptions = append(b.serverOptions, api.WithLocalManagementPassword(password)) |
|
|
return b |
|
|
} |
|
|
|
|
|
|
|
|
func (b *Builder) Build() (*Service, error) { |
|
|
if b.cfg == nil { |
|
|
return nil, fmt.Errorf("cliproxy: configuration is required") |
|
|
} |
|
|
if b.configPath == "" { |
|
|
return nil, fmt.Errorf("cliproxy: configuration path is required") |
|
|
} |
|
|
|
|
|
tokenProvider := b.tokenProvider |
|
|
if tokenProvider == nil { |
|
|
tokenProvider = NewFileTokenClientProvider() |
|
|
} |
|
|
|
|
|
apiKeyProvider := b.apiKeyProvider |
|
|
if apiKeyProvider == nil { |
|
|
apiKeyProvider = NewAPIKeyClientProvider() |
|
|
} |
|
|
|
|
|
watcherFactory := b.watcherFactory |
|
|
if watcherFactory == nil { |
|
|
watcherFactory = defaultWatcherFactory |
|
|
} |
|
|
|
|
|
authManager := b.authManager |
|
|
if authManager == nil { |
|
|
authManager = newDefaultAuthManager() |
|
|
} |
|
|
|
|
|
accessManager := b.accessManager |
|
|
if accessManager == nil { |
|
|
accessManager = sdkaccess.NewManager() |
|
|
} |
|
|
|
|
|
providers, err := sdkaccess.BuildProviders(&b.cfg.SDKConfig) |
|
|
if err != nil { |
|
|
return nil, err |
|
|
} |
|
|
accessManager.SetProviders(providers) |
|
|
|
|
|
coreManager := b.coreManager |
|
|
if coreManager == nil { |
|
|
tokenStore := sdkAuth.GetTokenStore() |
|
|
if dirSetter, ok := tokenStore.(interface{ SetBaseDir(string) }); ok && b.cfg != nil { |
|
|
dirSetter.SetBaseDir(b.cfg.AuthDir) |
|
|
} |
|
|
|
|
|
strategy := "" |
|
|
if b.cfg != nil { |
|
|
strategy = strings.ToLower(strings.TrimSpace(b.cfg.Routing.Strategy)) |
|
|
} |
|
|
var selector coreauth.Selector |
|
|
switch strategy { |
|
|
case "fill-first", "fillfirst", "ff": |
|
|
selector = &coreauth.FillFirstSelector{} |
|
|
default: |
|
|
selector = &coreauth.RoundRobinSelector{} |
|
|
} |
|
|
|
|
|
coreManager = coreauth.NewManager(tokenStore, selector, nil) |
|
|
} |
|
|
|
|
|
coreManager.SetRoundTripperProvider(newDefaultRoundTripperProvider()) |
|
|
coreManager.SetOAuthModelMappings(b.cfg.OAuthModelMappings) |
|
|
|
|
|
service := &Service{ |
|
|
cfg: b.cfg, |
|
|
configPath: b.configPath, |
|
|
tokenProvider: tokenProvider, |
|
|
apiKeyProvider: apiKeyProvider, |
|
|
watcherFactory: watcherFactory, |
|
|
hooks: b.hooks, |
|
|
authManager: authManager, |
|
|
accessManager: accessManager, |
|
|
coreManager: coreManager, |
|
|
serverOptions: append([]api.ServerOption(nil), b.serverOptions...), |
|
|
} |
|
|
return service, nil |
|
|
} |
|
|
|