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 }