Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/zalando/go-keyring

go 1.18
go 1.24.11

require (
github.com/danieljoos/wincred v1.2.2
Expand Down
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0=
github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8=
github.com/danieljoos/wincred v1.2.3 h1:v7dZC2x32Ut3nEfRH+vhoZGvN72+dQ/snVXo/vMFLdQ=
github.com/danieljoos/wincred v1.2.3/go.mod h1:6qqX0WNrS4RzPZ1tnroDzq9kY3fu1KwE7MRLQK4X0bs=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.2.1 h1:I4wwMdWSkmI57ewd+elNGwLRf2/dtSaFz1DujfWYvOk=
github.com/godbus/dbus/v5 v5.2.1/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
7 changes: 7 additions & 0 deletions keyring.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ type Keyring interface {
Delete(service, user string) error
// DeleteAll deletes all secrets for a given service
DeleteAll(service string) error
// SetDescription sets the description of the secret
SetDescription(description string)
}

// Set password in keyring for user.
Expand All @@ -48,3 +50,8 @@ func Delete(service, user string) error {
func DeleteAll(service string) error {
return provider.DeleteAll(service)
}

// SetDescription sets the description of the secret
func SetDescription(description string) {
provider.SetDescription(description)
}
5 changes: 5 additions & 0 deletions keyring_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ const (

type macOSXKeychain struct{}

// SetDescription sets the description of the secret
func (k macOSXKeychain) SetDescription(description string) {
//no-op for darwin
}

// func (*MacOSXKeychain) IsAvailable() bool {
// return exec.Command(execPathKeychain).Run() != exec.ErrNotFound
// }
Expand Down
2 changes: 2 additions & 0 deletions keyring_fallback.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ func (fallbackServiceProvider) Delete(service, user string) error {
func (fallbackServiceProvider) DeleteAll(service string) error {
return ErrUnsupportedPlatform
}

func (fallbackServiceProvider) SetDescription(description string) {}
11 changes: 9 additions & 2 deletions keyring_mock.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package keyring

type mockProvider struct {
mockStore map[string]map[string]string
mockError error
mockStore map[string]map[string]string
mockError error
description string
}

// Set stores user and pass in the keyring under the defined service
Expand All @@ -18,6 +19,7 @@ func (m *mockProvider) Set(service, user, pass string) error {
m.mockStore[service] = make(map[string]string)
}
m.mockStore[service][user] = pass
m.mockStore[service]["description"] = m.description
return nil
}

Expand Down Expand Up @@ -59,6 +61,11 @@ func (m *mockProvider) DeleteAll(service string) error {
return nil
}

// SetDescription sets the description of the secret
func (m *mockProvider) SetDescription(description string) {
m.description = description
}

// MockInit sets the provider to a mocked memory store
func MockInit() {
provider = &mockProvider{}
Expand Down
8 changes: 8 additions & 0 deletions keyring_mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ func TestMockDeleteAll(t *testing.T) {
}
}

func TestMockSetDescription(t *testing.T) {
mp := mockProvider{}
mp.SetDescription("foo bar")
if mp.description != "foo bar" {
t.Errorf("Expected description foo bar, got %s", mp.description)
}
}

func assertError(t *testing.T, err error, expected error) {
if err != expected {
t.Errorf("Expected error %s, got %s", expected, err)
Expand Down
13 changes: 13 additions & 0 deletions keyring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,16 @@ func TestDeleteAllEmptyService(t *testing.T) {
t.Errorf("Should not have deleted secret from another service")
}
}

func TestSetDescription(t *testing.T) {
if runtime.GOOS != "windows" && runtime.GOOS != "darwin" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO switch case would be more readable

SetDescription("foo bar")
err := Set(service, user, password)
if err != nil {
t.Errorf("Should not fail, got: %s", err)
}
if secretDescription != "foo bar" {
t.Errorf("Expected description foo bar, got %s", secretDescription)
}
}
}
14 changes: 13 additions & 1 deletion keyring_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ import (

type secretServiceProvider struct{}

// secretDescription holds a user set secret description
var secretDescription string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be a member of the secretServiceProvider


// SetDescription sets the description of the secret
func (s secretServiceProvider) SetDescription(description string) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will likely need to be a pointer receiver, if we have it as member

secretDescription = description
}

// Set stores user and pass in the keyring under the defined service
// name.
func (s secretServiceProvider) Set(service, user, pass string) error {
Expand Down Expand Up @@ -40,8 +48,12 @@ func (s secretServiceProvider) Set(service, user, pass string) error {
return err
}

desc := fmt.Sprintf("Password for '%s' on '%s'", user, service)
if secretDescription != "" {
desc = secretDescription
}
err = svc.CreateItem(collection,
fmt.Sprintf("Password for '%s' on '%s'", user, service),
desc,
attributes, secret)
if err != nil {
return err
Expand Down
5 changes: 5 additions & 0 deletions keyring_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import (

type windowsKeychain struct{}

// SetDescription sets the description of the secret
func (k windowsKeychain) SetDescription(description string) {
//no-op for windows
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why should we have a comment here but not in the others?

}

// Get gets a secret from the keyring given a service name and a user.
func (k windowsKeychain) Get(service, username string) (string, error) {
cred, err := wincred.GetGenericCredential(k.credName(service, username))
Expand Down