From 14b7cd28409d8fd8956e21c549130b3fe1141b9f Mon Sep 17 00:00:00 2001 From: AlanD20 Date: Thu, 30 May 2024 11:16:23 +0200 Subject: [PATCH 1/2] Prompt to unlock individual item when getting secret from keyring Signed-off-by: AlanD20 --- keyring_mock.go | 58 ++++++++++++++++++++++++++++++++++++++------ keyring_mock_test.go | 18 ++++++++++++++ keyring_unix.go | 6 +++++ 3 files changed, 75 insertions(+), 7 deletions(-) diff --git a/keyring_mock.go b/keyring_mock.go index 0e514ea..e0dcad6 100644 --- a/keyring_mock.go +++ b/keyring_mock.go @@ -1,7 +1,12 @@ package keyring +type mockProviderItem struct { + Value string + Locked bool +} + type mockProvider struct { - mockStore map[string]map[string]string + mockStore map[string]map[string]*mockProviderItem mockError error } @@ -12,12 +17,12 @@ func (m *mockProvider) Set(service, user, pass string) error { return m.mockError } if m.mockStore == nil { - m.mockStore = make(map[string]map[string]string) + m.mockStore = make(map[string]map[string]*mockProviderItem) } if m.mockStore[service] == nil { - m.mockStore[service] = make(map[string]string) + m.mockStore[service] = make(map[string]*mockProviderItem) } - m.mockStore[service][user] = pass + m.mockStore[service][user] = &mockProviderItem{Value: pass, Locked: true} return nil } @@ -27,8 +32,12 @@ func (m *mockProvider) Get(service, user string) (string, error) { return "", m.mockError } if b, ok := m.mockStore[service]; ok { - if v, ok := b[user]; ok { - return v, nil + if item, ok := b[user]; ok { + if item.Locked { + return "", ErrNotFound + } + _ = m.Lock(service, user) + return item.Value, nil } } return "", ErrNotFound @@ -41,7 +50,10 @@ func (m *mockProvider) Delete(service, user string) error { } if m.mockStore != nil { if _, ok := m.mockStore[service]; ok { - if _, ok := m.mockStore[service][user]; ok { + if item, ok := m.mockStore[service][user]; ok { + if item.Locked { + return ErrNotFound + } delete(m.mockStore[service], user) return nil } @@ -50,6 +62,38 @@ func (m *mockProvider) Delete(service, user string) error { return ErrNotFound } +// Unlock unlocks item from the keyring given a service name and a user +func (m *mockProvider) Unlock(service, user string) error { + if m.mockError != nil { + return m.mockError + } + if m.mockStore != nil { + if _, ok := m.mockStore[service]; ok { + if item, ok := m.mockStore[service][user]; ok { + item.Locked = false + return nil + } + } + } + return ErrNotFound +} + +// Lock locks item from the keyring given a service name and a user +func (m *mockProvider) Lock(service, user string) error { + if m.mockError != nil { + return m.mockError + } + if m.mockStore != nil { + if _, ok := m.mockStore[service]; ok { + if item, ok := m.mockStore[service][user]; ok { + item.Locked = true + return nil + } + } + } + return ErrNotFound +} + // MockInit sets the provider to a mocked memory store func MockInit() { provider = &mockProvider{} diff --git a/keyring_mock_test.go b/keyring_mock_test.go index 11931b2..485c3fe 100644 --- a/keyring_mock_test.go +++ b/keyring_mock_test.go @@ -22,6 +22,7 @@ func TestMockGet(t *testing.T) { t.Errorf("Should not fail, got: %s", err) } + _ = mp.Unlock(service, user) pw, err := mp.Get(service, user) if err != nil { t.Errorf("Should not fail, got: %s", err) @@ -32,6 +33,22 @@ func TestMockGet(t *testing.T) { } } +// TestGetLocked tests getting a locked password from the keyring. +func TestMockGetLocked(t *testing.T) { + mp := mockProvider{} + err := mp.Set(service, user, password) + if err != nil { + t.Errorf("Should not fail, got: %s", err) + } + + pwd, err := mp.Get(service, user) + assertError(t, err, ErrNotFound) + + if pwd != "" { + t.Errorf("Should not return item value, got: %s", pwd) + } +} + // TestGetNonExisting tests getting a secret not in the keyring. func TestMockGetNonExisting(t *testing.T) { mp := mockProvider{} @@ -49,6 +66,7 @@ func TestMockDelete(t *testing.T) { t.Errorf("Should not fail, got: %s", err) } + _ = mp.Unlock(service, user) err = mp.Delete(service, user) if err != nil { t.Errorf("Should not fail, got: %s", err) diff --git a/keyring_unix.go b/keyring_unix.go index 28537e7..523f6a3 100644 --- a/keyring_unix.go +++ b/keyring_unix.go @@ -95,6 +95,12 @@ func (s secretServiceProvider) Get(service, user string) (string, error) { } defer svc.Close(session) + // unlock if invdividual item is locked + err = svc.Unlock(item) + if err != nil { + return "", err + } + secret, err := svc.GetSecret(item, session.Path()) if err != nil { return "", err From 69620c4203b64fae02e190b02f8b72143d8eadc3 Mon Sep 17 00:00:00 2001 From: AlanD20 Date: Fri, 31 May 2024 23:49:30 +0200 Subject: [PATCH 2/2] remove mock provider changes Signed-off-by: AlanD20 --- keyring_mock.go | 58 ++++++-------------------------------------- keyring_mock_test.go | 18 -------------- 2 files changed, 7 insertions(+), 69 deletions(-) diff --git a/keyring_mock.go b/keyring_mock.go index e0dcad6..0e514ea 100644 --- a/keyring_mock.go +++ b/keyring_mock.go @@ -1,12 +1,7 @@ package keyring -type mockProviderItem struct { - Value string - Locked bool -} - type mockProvider struct { - mockStore map[string]map[string]*mockProviderItem + mockStore map[string]map[string]string mockError error } @@ -17,12 +12,12 @@ func (m *mockProvider) Set(service, user, pass string) error { return m.mockError } if m.mockStore == nil { - m.mockStore = make(map[string]map[string]*mockProviderItem) + m.mockStore = make(map[string]map[string]string) } if m.mockStore[service] == nil { - m.mockStore[service] = make(map[string]*mockProviderItem) + m.mockStore[service] = make(map[string]string) } - m.mockStore[service][user] = &mockProviderItem{Value: pass, Locked: true} + m.mockStore[service][user] = pass return nil } @@ -32,12 +27,8 @@ func (m *mockProvider) Get(service, user string) (string, error) { return "", m.mockError } if b, ok := m.mockStore[service]; ok { - if item, ok := b[user]; ok { - if item.Locked { - return "", ErrNotFound - } - _ = m.Lock(service, user) - return item.Value, nil + if v, ok := b[user]; ok { + return v, nil } } return "", ErrNotFound @@ -50,10 +41,7 @@ func (m *mockProvider) Delete(service, user string) error { } if m.mockStore != nil { if _, ok := m.mockStore[service]; ok { - if item, ok := m.mockStore[service][user]; ok { - if item.Locked { - return ErrNotFound - } + if _, ok := m.mockStore[service][user]; ok { delete(m.mockStore[service], user) return nil } @@ -62,38 +50,6 @@ func (m *mockProvider) Delete(service, user string) error { return ErrNotFound } -// Unlock unlocks item from the keyring given a service name and a user -func (m *mockProvider) Unlock(service, user string) error { - if m.mockError != nil { - return m.mockError - } - if m.mockStore != nil { - if _, ok := m.mockStore[service]; ok { - if item, ok := m.mockStore[service][user]; ok { - item.Locked = false - return nil - } - } - } - return ErrNotFound -} - -// Lock locks item from the keyring given a service name and a user -func (m *mockProvider) Lock(service, user string) error { - if m.mockError != nil { - return m.mockError - } - if m.mockStore != nil { - if _, ok := m.mockStore[service]; ok { - if item, ok := m.mockStore[service][user]; ok { - item.Locked = true - return nil - } - } - } - return ErrNotFound -} - // MockInit sets the provider to a mocked memory store func MockInit() { provider = &mockProvider{} diff --git a/keyring_mock_test.go b/keyring_mock_test.go index 485c3fe..11931b2 100644 --- a/keyring_mock_test.go +++ b/keyring_mock_test.go @@ -22,7 +22,6 @@ func TestMockGet(t *testing.T) { t.Errorf("Should not fail, got: %s", err) } - _ = mp.Unlock(service, user) pw, err := mp.Get(service, user) if err != nil { t.Errorf("Should not fail, got: %s", err) @@ -33,22 +32,6 @@ func TestMockGet(t *testing.T) { } } -// TestGetLocked tests getting a locked password from the keyring. -func TestMockGetLocked(t *testing.T) { - mp := mockProvider{} - err := mp.Set(service, user, password) - if err != nil { - t.Errorf("Should not fail, got: %s", err) - } - - pwd, err := mp.Get(service, user) - assertError(t, err, ErrNotFound) - - if pwd != "" { - t.Errorf("Should not return item value, got: %s", pwd) - } -} - // TestGetNonExisting tests getting a secret not in the keyring. func TestMockGetNonExisting(t *testing.T) { mp := mockProvider{} @@ -66,7 +49,6 @@ func TestMockDelete(t *testing.T) { t.Errorf("Should not fail, got: %s", err) } - _ = mp.Unlock(service, user) err = mp.Delete(service, user) if err != nil { t.Errorf("Should not fail, got: %s", err)