mcp-framework/cli/setup_secret.go

76 lines
1.8 KiB
Go

package cli
import (
"errors"
"fmt"
"strings"
"forge.lclr.dev/AI/mcp-framework/secretstore"
)
type SetupSecretWriteOptions struct {
Store secretstore.Store
SecretName string
SecretLabel string
TokenEnv string
Value SetupValue
}
func WriteSetupSecretVerified(options SetupSecretWriteOptions) error {
if options.Store == nil {
return errors.New("secret store must not be nil")
}
secretName := strings.TrimSpace(options.SecretName)
if secretName == "" {
return errors.New("secret name must not be empty")
}
secretLabel := strings.TrimSpace(options.SecretLabel)
if secretLabel == "" {
secretLabel = secretName
}
if options.Value.KeptStoredSecret {
return verifyStoredSetupSecret(options.Store, secretName, options.TokenEnv)
}
if !options.Value.Set {
return nil
}
if err := secretstore.SetSecretVerified(options.Store, secretName, secretLabel, options.Value.String); err != nil {
if errors.Is(err, secretstore.ErrReadOnly) {
tokenEnv := strings.TrimSpace(options.TokenEnv)
if tokenEnv != "" {
return fmt.Errorf("secret store is read-only, export %s and retry setup: %w", tokenEnv, err)
}
}
return fmt.Errorf("save secret %q during setup: %w", secretName, err)
}
return nil
}
func verifyStoredSetupSecret(store secretstore.Store, secretName, tokenEnv string) error {
secret, err := store.GetSecret(secretName)
if err != nil {
if errors.Is(err, secretstore.ErrNotFound) {
tokenEnv = strings.TrimSpace(tokenEnv)
if tokenEnv != "" {
return fmt.Errorf(
"secret %q is not readable after setup, export %s and retry: %w",
secretName,
tokenEnv,
err,
)
}
}
return fmt.Errorf("verify secret %q after setup: %w", secretName, err)
}
if strings.TrimSpace(secret) == "" {
return fmt.Errorf("secret %q is empty after setup", secretName)
}
return nil
}