feat: add --debug tracing for bitwarden calls
This commit is contained in:
parent
98f07f557d
commit
98bac84ab8
10 changed files with 259 additions and 3 deletions
|
|
@ -18,6 +18,8 @@ const (
|
||||||
CommandVersion = "version"
|
CommandVersion = "version"
|
||||||
CommandDoctor = "doctor"
|
CommandDoctor = "doctor"
|
||||||
|
|
||||||
|
bitwardenDebugEnvName = "MCP_FRAMEWORK_BITWARDEN_DEBUG"
|
||||||
|
|
||||||
ConfigSubcommandShow = "show"
|
ConfigSubcommandShow = "show"
|
||||||
ConfigSubcommandTest = "test"
|
ConfigSubcommandTest = "test"
|
||||||
ConfigSubcommandDelete = "delete"
|
ConfigSubcommandDelete = "delete"
|
||||||
|
|
@ -118,7 +120,13 @@ func Run(ctx context.Context, opts Options) error {
|
||||||
return ErrBinaryNameRequired
|
return ErrBinaryNameRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
command, commandArgs, showHelp := parseArgs(expandAliases(normalized.Args, normalized.Aliases))
|
resolvedArgs := expandAliases(normalized.Args, normalized.Aliases)
|
||||||
|
resolvedArgs, debugEnabled := extractGlobalDebugFlag(resolvedArgs)
|
||||||
|
if debugEnabled {
|
||||||
|
_ = os.Setenv(bitwardenDebugEnvName, "1")
|
||||||
|
}
|
||||||
|
|
||||||
|
command, commandArgs, showHelp := parseArgs(resolvedArgs)
|
||||||
if showHelp {
|
if showHelp {
|
||||||
return printHelp(normalized, command, commandArgs)
|
return printHelp(normalized, command, commandArgs)
|
||||||
}
|
}
|
||||||
|
|
@ -252,6 +260,25 @@ func parseArgs(args []string) (command string, commandArgs []string, showHelp bo
|
||||||
return command, commandArgs, false
|
return command, commandArgs, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractGlobalDebugFlag(args []string) ([]string, bool) {
|
||||||
|
args = trimArgs(args)
|
||||||
|
if len(args) == 0 {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
filtered := make([]string, 0, len(args))
|
||||||
|
debugEnabled := false
|
||||||
|
for _, arg := range args {
|
||||||
|
if strings.TrimSpace(arg) == "--debug" {
|
||||||
|
debugEnabled = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
filtered = append(filtered, arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered, debugEnabled
|
||||||
|
}
|
||||||
|
|
||||||
func expandAliases(args []string, aliases map[string][]string) []string {
|
func expandAliases(args []string, aliases map[string][]string) []string {
|
||||||
args = trimArgs(args)
|
args = trimArgs(args)
|
||||||
if len(args) == 0 || len(aliases) == 0 {
|
if len(args) == 0 || len(aliases) == 0 {
|
||||||
|
|
@ -512,6 +539,13 @@ func printGlobalHelp(opts Options) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, err := fmt.Fprintln(opts.Stdout, "\nOptions globales:"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := fmt.Fprintln(opts.Stdout, " --debug Active le debug des appels Bitwarden."); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
_, err := fmt.Fprintf(opts.Stdout, "\nAide detaillee: %s help <command>\n", opts.BinaryName)
|
_, err := fmt.Fprintf(opts.Stdout, "\nAide detaillee: %s help <command>\n", opts.BinaryName)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"os"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -482,3 +483,73 @@ func TestRunPrintsDoctorAliasInGlobalHelpWhenEnabled(t *testing.T) {
|
||||||
t.Fatalf("global help output missing default doctor alias details: %q", text)
|
t.Fatalf("global help output missing default doctor alias details: %q", text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRunAcceptsGlobalDebugFlagAndRoutesCommand(t *testing.T) {
|
||||||
|
var stdout bytes.Buffer
|
||||||
|
var stderr bytes.Buffer
|
||||||
|
var got Invocation
|
||||||
|
|
||||||
|
t.Setenv("MCP_FRAMEWORK_BITWARDEN_DEBUG", "")
|
||||||
|
|
||||||
|
err := Run(context.Background(), Options{
|
||||||
|
BinaryName: "my-mcp",
|
||||||
|
Args: []string{"--debug", "setup", "--profile", "prod"},
|
||||||
|
Stdout: &stdout,
|
||||||
|
Stderr: &stderr,
|
||||||
|
Hooks: Hooks{
|
||||||
|
Setup: func(_ context.Context, inv Invocation) error {
|
||||||
|
got = inv
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Run error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got.Command != CommandSetup {
|
||||||
|
t.Fatalf("invocation command = %q, want %q", got.Command, CommandSetup)
|
||||||
|
}
|
||||||
|
wantArgs := []string{"--profile", "prod"}
|
||||||
|
if !slices.Equal(got.Args, wantArgs) {
|
||||||
|
t.Fatalf("invocation args = %v, want %v", got.Args, wantArgs)
|
||||||
|
}
|
||||||
|
if os.Getenv("MCP_FRAMEWORK_BITWARDEN_DEBUG") != "1" {
|
||||||
|
t.Fatalf("MCP_FRAMEWORK_BITWARDEN_DEBUG = %q, want %q", os.Getenv("MCP_FRAMEWORK_BITWARDEN_DEBUG"), "1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunAcceptsGlobalDebugFlagAfterCommand(t *testing.T) {
|
||||||
|
var stdout bytes.Buffer
|
||||||
|
var stderr bytes.Buffer
|
||||||
|
var got Invocation
|
||||||
|
|
||||||
|
t.Setenv("MCP_FRAMEWORK_BITWARDEN_DEBUG", "")
|
||||||
|
|
||||||
|
err := Run(context.Background(), Options{
|
||||||
|
BinaryName: "my-mcp",
|
||||||
|
Args: []string{"setup", "--debug", "--profile", "prod"},
|
||||||
|
Stdout: &stdout,
|
||||||
|
Stderr: &stderr,
|
||||||
|
Hooks: Hooks{
|
||||||
|
Setup: func(_ context.Context, inv Invocation) error {
|
||||||
|
got = inv
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Run error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got.Command != CommandSetup {
|
||||||
|
t.Fatalf("invocation command = %q, want %q", got.Command, CommandSetup)
|
||||||
|
}
|
||||||
|
wantArgs := []string{"--profile", "prod"}
|
||||||
|
if !slices.Equal(got.Args, wantArgs) {
|
||||||
|
t.Fatalf("invocation args = %v, want %v", got.Args, wantArgs)
|
||||||
|
}
|
||||||
|
if os.Getenv("MCP_FRAMEWORK_BITWARDEN_DEBUG") != "1" {
|
||||||
|
t.Fatalf("MCP_FRAMEWORK_BITWARDEN_DEBUG = %q, want %q", os.Getenv("MCP_FRAMEWORK_BITWARDEN_DEBUG"), "1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ type DoctorOptions struct {
|
||||||
|
|
||||||
type BitwardenDoctorOptions struct {
|
type BitwardenDoctorOptions struct {
|
||||||
Command string
|
Command string
|
||||||
|
Debug bool
|
||||||
Shell string
|
Shell string
|
||||||
LookupEnv func(string) (string, bool)
|
LookupEnv func(string) (string, bool)
|
||||||
}
|
}
|
||||||
|
|
@ -238,6 +239,7 @@ func BitwardenReadyCheck(options BitwardenDoctorOptions) DoctorCheck {
|
||||||
return func(context.Context) DoctorResult {
|
return func(context.Context) DoctorResult {
|
||||||
err := checkBitwardenReady(secretstore.Options{
|
err := checkBitwardenReady(secretstore.Options{
|
||||||
BitwardenCommand: strings.TrimSpace(options.Command),
|
BitwardenCommand: strings.TrimSpace(options.Command),
|
||||||
|
BitwardenDebug: options.Debug,
|
||||||
Shell: strings.TrimSpace(options.Shell),
|
Shell: strings.TrimSpace(options.Shell),
|
||||||
LookupEnv: options.LookupEnv,
|
LookupEnv: options.LookupEnv,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -43,3 +43,5 @@ Si `Hooks.Version` n'est pas fourni, la sous-commande `version` affiche automati
|
||||||
Sans arguments, `bootstrap.Run` affiche l'aide globale (pas de lancement implicite de `mcp`).
|
Sans arguments, `bootstrap.Run` affiche l'aide globale (pas de lancement implicite de `mcp`).
|
||||||
La commande `config` impose une sous-commande (`show`, `test`, et optionnellement `delete`).
|
La commande `config` impose une sous-commande (`show`, `test`, et optionnellement `delete`).
|
||||||
Les alias déclarés (ou `EnableDoctorAlias`) sont affichés dans l'aide globale.
|
Les alias déclarés (ou `EnableDoctorAlias`) sont affichés dans l'aide globale.
|
||||||
|
Le flag global `--debug` est supporté et active le debug des appels Bitwarden
|
||||||
|
(`MCP_FRAMEWORK_BITWARDEN_DEBUG=1`).
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,10 @@ fmt.Println(report.Remediation) // action recommandée
|
||||||
|
|
||||||
## Debug Bitwarden en 60 secondes
|
## Debug Bitwarden en 60 secondes
|
||||||
|
|
||||||
|
Tu peux activer les traces d'appels Bitwarden avec le flag CLI global `--debug`
|
||||||
|
(via `bootstrap`) ou en exportant `MCP_FRAMEWORK_BITWARDEN_DEBUG=1`.
|
||||||
|
Les commandes `bw` exécutées seront affichées (avec redaction des payloads sensibles).
|
||||||
|
|
||||||
1. Vérifier l'état de session :
|
1. Vérifier l'état de session :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -17,6 +18,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultBitwardenCommand = "bw"
|
defaultBitwardenCommand = "bw"
|
||||||
|
bitwardenDebugEnvName = "MCP_FRAMEWORK_BITWARDEN_DEBUG"
|
||||||
bitwardenSessionEnvName = "BW_SESSION"
|
bitwardenSessionEnvName = "BW_SESSION"
|
||||||
bitwardenSecretFieldName = "mcp-secret"
|
bitwardenSecretFieldName = "mcp-secret"
|
||||||
bitwardenServiceFieldName = "mcp-service"
|
bitwardenServiceFieldName = "mcp-service"
|
||||||
|
|
@ -34,10 +36,12 @@ type bitwardenRunner func(command string, stdin []byte, args ...string) ([]byte,
|
||||||
|
|
||||||
var runBitwardenCLI bitwardenRunner = executeBitwardenCLI
|
var runBitwardenCLI bitwardenRunner = executeBitwardenCLI
|
||||||
var bitwardenLoaderActive atomic.Bool
|
var bitwardenLoaderActive atomic.Bool
|
||||||
|
var bitwardenDebugOutput io.Writer = os.Stderr
|
||||||
|
|
||||||
type bitwardenStore struct {
|
type bitwardenStore struct {
|
||||||
command string
|
command string
|
||||||
serviceName string
|
serviceName string
|
||||||
|
debug bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type bitwardenListItem struct {
|
type bitwardenListItem struct {
|
||||||
|
|
@ -54,10 +58,12 @@ func newBitwardenStore(options Options, policy BackendPolicy, serviceName string
|
||||||
if command == "" {
|
if command == "" {
|
||||||
command = defaultBitwardenCommand
|
command = defaultBitwardenCommand
|
||||||
}
|
}
|
||||||
|
debugEnabled := isBitwardenDebugEnabled(options.BitwardenDebug)
|
||||||
|
|
||||||
store := &bitwardenStore{
|
store := &bitwardenStore{
|
||||||
command: command,
|
command: command,
|
||||||
serviceName: serviceName,
|
serviceName: serviceName,
|
||||||
|
debug: debugEnabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := store.execute("verify bitwarden CLI availability", nil, "--version"); err != nil {
|
if _, err := store.execute("verify bitwarden CLI availability", nil, "--version"); err != nil {
|
||||||
|
|
@ -80,6 +86,7 @@ func newBitwardenStore(options Options, policy BackendPolicy, serviceName string
|
||||||
|
|
||||||
if err := EnsureBitwardenReady(Options{
|
if err := EnsureBitwardenReady(Options{
|
||||||
BitwardenCommand: command,
|
BitwardenCommand: command,
|
||||||
|
BitwardenDebug: debugEnabled,
|
||||||
LookupEnv: options.LookupEnv,
|
LookupEnv: options.LookupEnv,
|
||||||
Shell: options.Shell,
|
Shell: options.Shell,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
|
@ -99,6 +106,7 @@ func EnsureBitwardenReady(options Options) error {
|
||||||
if command == "" {
|
if command == "" {
|
||||||
command = defaultBitwardenCommand
|
command = defaultBitwardenCommand
|
||||||
}
|
}
|
||||||
|
debugEnabled := isBitwardenDebugEnabled(options.BitwardenDebug)
|
||||||
unlockCommand := bitwardenUnlockRemediation(command, options.Shell)
|
unlockCommand := bitwardenUnlockRemediation(command, options.Shell)
|
||||||
|
|
||||||
lookupEnv := options.LookupEnv
|
lookupEnv := options.LookupEnv
|
||||||
|
|
@ -106,7 +114,7 @@ func EnsureBitwardenReady(options Options) error {
|
||||||
lookupEnv = os.LookupEnv
|
lookupEnv = os.LookupEnv
|
||||||
}
|
}
|
||||||
|
|
||||||
output, err := runBitwardenCLI(command, nil, "status")
|
output, err := runBitwardenCommand(command, debugEnabled, nil, "status")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("check bitwarden CLI status: %w", err)
|
return fmt.Errorf("check bitwarden CLI status: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -438,7 +446,7 @@ func (s *bitwardenStore) encodePayload(payload map[string]any) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *bitwardenStore) execute(operation string, stdin []byte, args ...string) ([]byte, error) {
|
func (s *bitwardenStore) execute(operation string, stdin []byte, args ...string) ([]byte, error) {
|
||||||
output, err := runBitwardenCLI(s.command, stdin, args...)
|
output, err := runBitwardenCommand(s.command, s.debug, stdin, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%s: %w", operation, err)
|
return nil, fmt.Errorf("%s: %w", operation, err)
|
||||||
}
|
}
|
||||||
|
|
@ -521,6 +529,71 @@ func bitwardenItemMatchesMarkers(payload map[string]any, serviceName, secretName
|
||||||
strings.TrimSpace(markedSecretName) == strings.TrimSpace(secretName)
|
strings.TrimSpace(markedSecretName) == strings.TrimSpace(secretName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runBitwardenCommand(command string, debug bool, stdin []byte, args ...string) ([]byte, error) {
|
||||||
|
if debug {
|
||||||
|
logBitwardenCommand(command, args...)
|
||||||
|
}
|
||||||
|
return runBitwardenCLI(command, stdin, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isBitwardenDebugEnabled(explicit bool) bool {
|
||||||
|
if explicit {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
raw, ok := os.LookupEnv(bitwardenDebugEnvName)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch strings.ToLower(strings.TrimSpace(raw)) {
|
||||||
|
case "1", "true", "yes", "y", "on":
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func logBitwardenCommand(command string, args ...string) {
|
||||||
|
writer := bitwardenDebugOutput
|
||||||
|
if writer == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
renderedArgs := sanitizeBitwardenDebugArgs(args)
|
||||||
|
if len(renderedArgs) == 0 {
|
||||||
|
_, _ = fmt.Fprintf(writer, "[bitwarden debug] %s\n", strings.TrimSpace(command))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintf(
|
||||||
|
writer,
|
||||||
|
"[bitwarden debug] %s %s\n",
|
||||||
|
strings.TrimSpace(command),
|
||||||
|
strings.Join(renderedArgs, " "),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sanitizeBitwardenDebugArgs(args []string) []string {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rendered := make([]string, len(args))
|
||||||
|
for idx, arg := range args {
|
||||||
|
rendered[idx] = strings.TrimSpace(arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(rendered) >= 3 && rendered[0] == "create" && rendered[1] == "item" {
|
||||||
|
rendered[2] = "<redacted>"
|
||||||
|
}
|
||||||
|
if len(rendered) >= 4 && rendered[0] == "edit" && rendered[1] == "item" {
|
||||||
|
rendered[3] = "<redacted>"
|
||||||
|
}
|
||||||
|
|
||||||
|
return rendered
|
||||||
|
}
|
||||||
|
|
||||||
func executeBitwardenCLI(command string, stdin []byte, args ...string) ([]byte, error) {
|
func executeBitwardenCLI(command string, stdin []byte, args ...string) ([]byte, error) {
|
||||||
stopLoader := startBitwardenLoader()
|
stopLoader := startBitwardenLoader()
|
||||||
defer stopLoader()
|
defer stopLoader()
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package secretstore
|
package secretstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
@ -367,6 +369,59 @@ func TestExecuteBitwardenCLIClassifiesLoginError(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOpenBitwardenCLIDebugFromEnvPrintsBitwardenCalls(t *testing.T) {
|
||||||
|
withBitwardenSession(t)
|
||||||
|
fakeCLI := newFakeBitwardenCLI("bw")
|
||||||
|
withBitwardenRunner(t, fakeCLI.run)
|
||||||
|
t.Setenv("MCP_FRAMEWORK_BITWARDEN_DEBUG", "1")
|
||||||
|
|
||||||
|
var logs bytes.Buffer
|
||||||
|
withBitwardenDebugOutput(t, &logs)
|
||||||
|
|
||||||
|
_, err := Open(Options{
|
||||||
|
ServiceName: "email-mcp",
|
||||||
|
BackendPolicy: BackendBitwardenCLI,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Open returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
text := logs.String()
|
||||||
|
if !strings.Contains(text, "bw --version") {
|
||||||
|
t.Fatalf("debug logs = %q, want command bw --version", text)
|
||||||
|
}
|
||||||
|
if !strings.Contains(text, "bw status") {
|
||||||
|
t.Fatalf("debug logs = %q, want command bw status", text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBitwardenDebugRedactsSensitivePayloadArguments(t *testing.T) {
|
||||||
|
withBitwardenSession(t)
|
||||||
|
fakeCLI := newFakeBitwardenCLI("bw")
|
||||||
|
withBitwardenRunner(t, fakeCLI.run)
|
||||||
|
|
||||||
|
var logs bytes.Buffer
|
||||||
|
withBitwardenDebugOutput(t, &logs)
|
||||||
|
|
||||||
|
store, err := Open(Options{
|
||||||
|
ServiceName: "graylog-mcp",
|
||||||
|
BackendPolicy: BackendBitwardenCLI,
|
||||||
|
BitwardenDebug: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Open returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := store.SetSecret("api-token", "API token", "secret-v1"); err != nil {
|
||||||
|
t.Fatalf("SetSecret returned error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
text := logs.String()
|
||||||
|
if !strings.Contains(text, "bw create item <redacted>") {
|
||||||
|
t.Fatalf("debug logs = %q, want redacted create payload", text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBitwardenLoaderFrameUsesSingleLineRewriteAndMessage(t *testing.T) {
|
func TestBitwardenLoaderFrameUsesSingleLineRewriteAndMessage(t *testing.T) {
|
||||||
frame := bitwardenLoaderFrame(0)
|
frame := bitwardenLoaderFrame(0)
|
||||||
if !strings.HasPrefix(frame, "\r\033[2K") {
|
if !strings.HasPrefix(frame, "\r\033[2K") {
|
||||||
|
|
@ -455,6 +510,16 @@ func withBitwardenRunner(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func withBitwardenDebugOutput(t *testing.T, writer io.Writer) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
previous := bitwardenDebugOutput
|
||||||
|
bitwardenDebugOutput = writer
|
||||||
|
t.Cleanup(func() {
|
||||||
|
bitwardenDebugOutput = previous
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type fakeBitwardenCLI struct {
|
type fakeBitwardenCLI struct {
|
||||||
command string
|
command string
|
||||||
itemsByID map[string]fakeBitwardenItem
|
itemsByID map[string]fakeBitwardenItem
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ type OpenFromManifestOptions struct {
|
||||||
KWalletAppID string
|
KWalletAppID string
|
||||||
KWalletFolder string
|
KWalletFolder string
|
||||||
BitwardenCommand string
|
BitwardenCommand string
|
||||||
|
BitwardenDebug bool
|
||||||
Shell string
|
Shell string
|
||||||
ManifestLoader ManifestLoader
|
ManifestLoader ManifestLoader
|
||||||
ExecutableResolver ExecutableResolver
|
ExecutableResolver ExecutableResolver
|
||||||
|
|
@ -38,6 +39,7 @@ func OpenFromManifest(options OpenFromManifestOptions) (Store, error) {
|
||||||
KWalletAppID: options.KWalletAppID,
|
KWalletAppID: options.KWalletAppID,
|
||||||
KWalletFolder: options.KWalletFolder,
|
KWalletFolder: options.KWalletFolder,
|
||||||
BitwardenCommand: strings.TrimSpace(options.BitwardenCommand),
|
BitwardenCommand: strings.TrimSpace(options.BitwardenCommand),
|
||||||
|
BitwardenDebug: options.BitwardenDebug,
|
||||||
Shell: strings.TrimSpace(options.Shell),
|
Shell: strings.TrimSpace(options.Shell),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ type DescribeRuntimeOptions struct {
|
||||||
KWalletAppID string
|
KWalletAppID string
|
||||||
KWalletFolder string
|
KWalletFolder string
|
||||||
BitwardenCommand string
|
BitwardenCommand string
|
||||||
|
BitwardenDebug bool
|
||||||
Shell string
|
Shell string
|
||||||
ManifestLoader ManifestLoader
|
ManifestLoader ManifestLoader
|
||||||
ExecutableResolver ExecutableResolver
|
ExecutableResolver ExecutableResolver
|
||||||
|
|
@ -73,6 +74,7 @@ func DescribeRuntime(options DescribeRuntimeOptions) (RuntimeDescription, error)
|
||||||
KWalletAppID: options.KWalletAppID,
|
KWalletAppID: options.KWalletAppID,
|
||||||
KWalletFolder: options.KWalletFolder,
|
KWalletFolder: options.KWalletFolder,
|
||||||
BitwardenCommand: options.BitwardenCommand,
|
BitwardenCommand: options.BitwardenCommand,
|
||||||
|
BitwardenDebug: options.BitwardenDebug,
|
||||||
Shell: options.Shell,
|
Shell: options.Shell,
|
||||||
})
|
})
|
||||||
if openErr != nil {
|
if openErr != nil {
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ type Options struct {
|
||||||
KWalletAppID string
|
KWalletAppID string
|
||||||
KWalletFolder string
|
KWalletFolder string
|
||||||
BitwardenCommand string
|
BitwardenCommand string
|
||||||
|
BitwardenDebug bool
|
||||||
Shell string
|
Shell string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue