From 7c016e8c5e5bfb1f8feb32cfeb3c859f37c9b559 Mon Sep 17 00:00:00 2001 From: thibaud-lclr Date: Wed, 13 May 2026 13:56:10 +0200 Subject: [PATCH] =?UTF-8?q?refactor(secretstore):=20supprimer=20le=20fichi?= =?UTF-8?q?er=20de=20session=20service-sp=C3=A9cifique?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le fichier ~/.config//bw-session est redondant depuis l'introduction du fichier partagé mcp-framework. On n'écrit plus que dans le partagé et on lit uniquement depuis lui dans refreshSessionEnv et loadAnyBitwardenSession. EnsureBitwardenSessionEnv tente le fichier service-spécifique en premier (rétrocompat) puis bascule sur le partagé. Co-Authored-By: Claude Sonnet 4.6 --- secretstore/bitwarden.go | 13 +++---------- secretstore/bitwarden_session.go | 25 ++++++++++--------------- secretstore/bitwarden_session_test.go | 6 +++--- secretstore/bitwarden_test.go | 4 ++-- 4 files changed, 18 insertions(+), 30 deletions(-) diff --git a/secretstore/bitwarden.go b/secretstore/bitwarden.go index 792f223..2d4d22c 100644 --- a/secretstore/bitwarden.go +++ b/secretstore/bitwarden.go @@ -394,18 +394,11 @@ func (s *bitwardenStore) ensureReady() error { } func (s *bitwardenStore) refreshSessionEnv() { - // Prefer the shared file: it holds the latest session from any MCP login. - if session, err := LoadBitwardenSession(BitwardenSessionOptions{ - ServiceName: bitwardenSharedSessionName, - }); err == nil && strings.TrimSpace(session) != "" { - _ = os.Setenv(bitwardenSessionEnvName, strings.TrimSpace(session)) + session, err := LoadBitwardenSession(BitwardenSessionOptions{ServiceName: bitwardenSharedSessionName}) + if err != nil || strings.TrimSpace(session) == "" { return } - if session, err := LoadBitwardenSession(BitwardenSessionOptions{ - ServiceName: s.serviceName, - }); err == nil && strings.TrimSpace(session) != "" { - _ = os.Setenv(bitwardenSessionEnvName, strings.TrimSpace(session)) - } + _ = os.Setenv(bitwardenSessionEnvName, strings.TrimSpace(session)) } type bitwardenResolvedItem struct { diff --git a/secretstore/bitwarden_session.go b/secretstore/bitwarden_session.go index 3b20af4..e72f01e 100644 --- a/secretstore/bitwarden_session.go +++ b/secretstore/bitwarden_session.go @@ -111,10 +111,14 @@ func EnsureBitwardenSessionEnv(options BitwardenSessionOptions) (bool, error) { session, err := LoadBitwardenSession(options) if err != nil { - if errors.Is(err, ErrNotFound) { + if !errors.Is(err, ErrNotFound) { + return false, err + } + // Service-specific file not found; try the shared file written by any MCP login. + session, err = LoadBitwardenSession(BitwardenSessionOptions{ServiceName: bitwardenSharedSessionName}) + if err != nil { return false, nil } - return false, err } if err := os.Setenv(bitwardenSessionEnvName, session); err != nil { @@ -163,7 +167,7 @@ func LoginBitwarden(options BitwardenLoginOptions) (string, error) { // Vault is already unlocked. Reuse an existing session to avoid calling // bw unlock again, which would generate a new token and invalidate the // tokens held by other running MCP processes. - if existing := loadAnyBitwardenSession(serviceName); existing != "" { + if existing := loadAnyBitwardenSession(); existing != "" { if err := os.Setenv(bitwardenSessionEnvName, existing); err != nil { return "", fmt.Errorf("set %s from existing session: %w", bitwardenSessionEnvName, err) } @@ -191,28 +195,19 @@ func LoginBitwarden(options BitwardenLoginOptions) (string, error) { return "", fmt.Errorf("set %s after bitwarden unlock: %w", bitwardenSessionEnvName, err) } - if _, err := SaveBitwardenSession(BitwardenSessionOptions{ServiceName: serviceName}, session); err != nil { - return "", fmt.Errorf("persist bitwarden session: %w", err) - } - // Save to shared file so other MCP processes can reuse this session - // without needing to call bw unlock themselves. if _, err := SaveBitwardenSession(BitwardenSessionOptions{ServiceName: bitwardenSharedSessionName}, session); err != nil { - return "", fmt.Errorf("persist shared bitwarden session: %w", err) + return "", fmt.Errorf("persist bitwarden session: %w", err) } return session, nil } // loadAnyBitwardenSession looks for an existing valid session in: the process -// environment, the service-specific file, and the shared file written by any -// MCP login. Returns the first non-empty session found. -func loadAnyBitwardenSession(serviceName string) string { +// environment, then the shared file written by any MCP login. +func loadAnyBitwardenSession() string { if session, ok := os.LookupEnv(bitwardenSessionEnvName); ok && strings.TrimSpace(session) != "" { return strings.TrimSpace(session) } - if session, err := LoadBitwardenSession(BitwardenSessionOptions{ServiceName: serviceName}); err == nil { - return session - } if session, err := LoadBitwardenSession(BitwardenSessionOptions{ServiceName: bitwardenSharedSessionName}); err == nil { return session } diff --git a/secretstore/bitwarden_session_test.go b/secretstore/bitwarden_session_test.go index 8a8e54d..4c0d377 100644 --- a/secretstore/bitwarden_session_test.go +++ b/secretstore/bitwarden_session_test.go @@ -60,12 +60,12 @@ func TestLoginBitwardenRunsInteractiveFlowAndPersistsSession(t *testing.T) { t.Fatalf("interactive call #2 args = %v, want [unlock --raw]", calls[1]) } - persisted, err := LoadBitwardenSession(BitwardenSessionOptions{ServiceName: "email-mcp"}) + persisted, err := LoadBitwardenSession(BitwardenSessionOptions{ServiceName: bitwardenSharedSessionName}) if err != nil { - t.Fatalf("LoadBitwardenSession returned error: %v", err) + t.Fatalf("LoadBitwardenSession (shared) returned error: %v", err) } if persisted != "persisted-session" { - t.Fatalf("persisted session = %q, want persisted-session", persisted) + t.Fatalf("shared persisted session = %q, want persisted-session", persisted) } } diff --git a/secretstore/bitwarden_test.go b/secretstore/bitwarden_test.go index 705a467..bf4d451 100644 --- a/secretstore/bitwarden_test.go +++ b/secretstore/bitwarden_test.go @@ -761,7 +761,7 @@ func TestBitwardenStorePicksUpSessionRotatedByAnotherProcess(t *testing.T) { t.Fatalf("Open returned error: %v", err) } - if _, err := SaveBitwardenSession(BitwardenSessionOptions{ServiceName: "email-mcp"}, "new-session"); err != nil { + if _, err := SaveBitwardenSession(BitwardenSessionOptions{ServiceName: bitwardenSharedSessionName}, "new-session"); err != nil { t.Fatalf("SaveBitwardenSession returned error: %v", err) } @@ -800,7 +800,7 @@ func TestBitwardenStorePicksUpSessionFromFileWhenEnvIsEmpty(t *testing.T) { t.Fatalf("Open returned error: %v", err) } - if _, err := SaveBitwardenSession(BitwardenSessionOptions{ServiceName: "email-mcp"}, "file-session"); err != nil { + if _, err := SaveBitwardenSession(BitwardenSessionOptions{ServiceName: bitwardenSharedSessionName}, "file-session"); err != nil { t.Fatalf("SaveBitwardenSession returned error: %v", err) }