From 2af8a871da4fe7e7f9f553aa2acb7c911a4133cc Mon Sep 17 00:00:00 2001 From: George Tsiolis Date: Wed, 27 May 2026 18:59:30 +0300 Subject: [PATCH] Read fallback auth token when keyring is reachable but empty Co-Authored-By: Claude Opus 4.7 --- internal/auth/token_storage.go | 11 ++++------- internal/auth/token_storage_test.go | 23 ++++++++++++++++++++--- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/internal/auth/token_storage.go b/internal/auth/token_storage.go index c7685640..53d363a8 100644 --- a/internal/auth/token_storage.go +++ b/internal/auth/token_storage.go @@ -46,10 +46,9 @@ func (s *systemTokenStorage) GetAuthToken() (string, error) { if err == nil { return token, nil } - if errors.Is(err, keyring.ErrNotFound) { - return "", ErrTokenNotFound + if !errors.Is(err, keyring.ErrNotFound) { + s.logger.Info("system keyring unavailable (%v), falling back to file-based storage", err) } - s.logger.Info("system keyring unavailable (%v), falling back to file-based storage", err) return s.file.GetAuthToken() } @@ -62,11 +61,9 @@ func (s *systemTokenStorage) SetAuthToken(token string) error { } func (s *systemTokenStorage) DeleteAuthToken() error { - err := s.keyring.Delete(keyringService, keyringAuthTokenKey) - if err == nil || errors.Is(err, keyring.ErrNotFound) { - return nil + if err := s.keyring.Delete(keyringService, keyringAuthTokenKey); err != nil && !errors.Is(err, keyring.ErrNotFound) { + s.logger.Info("system keyring unavailable (%v), falling back to file-based storage", err) } - s.logger.Info("system keyring unavailable (%v), falling back to file-based storage", err) return s.file.DeleteAuthToken() } diff --git a/internal/auth/token_storage_test.go b/internal/auth/token_storage_test.go index b9e6523f..65963f9c 100644 --- a/internal/auth/token_storage_test.go +++ b/internal/auth/token_storage_test.go @@ -32,12 +32,13 @@ func TestSystemTokenStorage_GetReturnsTokenFromKeyring(t *testing.T) { assert.Equal(t, "system-token", token) } -func TestSystemTokenStorage_GetReturnsErrTokenNotFoundWhenKeyringEmpty(t *testing.T) { +func TestSystemTokenStorage_GetReturnsErrTokenNotFoundWhenKeyringAndFileEmpty(t *testing.T) { ctrl := gomock.NewController(t) kr := NewMockkeyringer(ctrl) file := NewMockAuthTokenStorage(ctrl) kr.EXPECT().Get(keyringService, keyringAuthTokenKey).Return("", keyring.ErrNotFound) + file.EXPECT().GetAuthToken().Return("", ErrTokenNotFound) token, err := newTestStorage(t, kr, file).GetAuthToken() @@ -45,6 +46,20 @@ func TestSystemTokenStorage_GetReturnsErrTokenNotFoundWhenKeyringEmpty(t *testin assert.ErrorIs(t, err, ErrTokenNotFound) } +func TestSystemTokenStorage_GetReturnsFileTokenWhenKeyringEmpty(t *testing.T) { + ctrl := gomock.NewController(t) + kr := NewMockkeyringer(ctrl) + file := NewMockAuthTokenStorage(ctrl) + + kr.EXPECT().Get(keyringService, keyringAuthTokenKey).Return("", keyring.ErrNotFound) + file.EXPECT().GetAuthToken().Return("file-token", nil) + + token, err := newTestStorage(t, kr, file).GetAuthToken() + + assert.NoError(t, err) + assert.Equal(t, "file-token", token) +} + func TestSystemTokenStorage_GetFallsBackToFileWhenKeyringUnavailable(t *testing.T) { ctrl := gomock.NewController(t) kr := NewMockkeyringer(ctrl) @@ -84,24 +99,26 @@ func TestSystemTokenStorage_SetFallsBackToFileWhenKeyringUnavailable(t *testing. assert.NoError(t, err) } -func TestSystemTokenStorage_DeleteRemovesFromKeyring(t *testing.T) { +func TestSystemTokenStorage_DeleteRemovesFromKeyringAndFile(t *testing.T) { ctrl := gomock.NewController(t) kr := NewMockkeyringer(ctrl) file := NewMockAuthTokenStorage(ctrl) kr.EXPECT().Delete(keyringService, keyringAuthTokenKey).Return(nil) + file.EXPECT().DeleteAuthToken().Return(nil) err := newTestStorage(t, kr, file).DeleteAuthToken() assert.NoError(t, err) } -func TestSystemTokenStorage_DeleteSucceedsWhenKeyringTokenMissing(t *testing.T) { +func TestSystemTokenStorage_DeleteClearsFileWhenKeyringTokenMissing(t *testing.T) { ctrl := gomock.NewController(t) kr := NewMockkeyringer(ctrl) file := NewMockAuthTokenStorage(ctrl) kr.EXPECT().Delete(keyringService, keyringAuthTokenKey).Return(keyring.ErrNotFound) + file.EXPECT().DeleteAuthToken().Return(nil) err := newTestStorage(t, kr, file).DeleteAuthToken()