Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
12 changes: 12 additions & 0 deletions store/keychain/keychain.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ import (

var _ store.Store = &keychainStore[store.Secret]{}

// ErrNoDefaultCollection is returned when the secret service has no usable
// default collection (no 'login' collection and no collection assigned to the
// 'default' alias). This typically happens on headless hosts where the keyring
// has not been initialized.
//
// It is exported so callers can use [errors.Is] to detect the absence of usable
// keychain infrastructure and fall back gracefully, rather than relying on
// fragile error message comparisons. This condition is only produced on Linux,
// but the sentinel is declared here (rather than in the Linux-specific file) so
// that cross-platform callers can reference it on every platform.
var ErrNoDefaultCollection = errors.New("no default keychain collection available")

type (
Option interface{ apply(any) error }
optionFunc[K any] func(K) error
Expand Down
8 changes: 1 addition & 7 deletions store/keychain/keychain_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,6 @@ const (
secretServiceIsCollectionLockedProperty = "org.freedesktop.Secret.Collection.Locked"
)

// errNoDefaultCollection is returned when the secret service has no usable
// default collection (no 'login' collection and no collection assigned to the
// 'default' alias). This typically happens on headless hosts where the keyring
// has not been initialized.
var errNoDefaultCollection = errors.New("no default keychain collection available")

// getDefaultCollection gets the secret service collection dbus object path.
//
// It prefers the loginKeychainObjectPath, since most users on X11 would have
Expand Down Expand Up @@ -122,7 +116,7 @@ func resolveDefaultCollection(collections []dbus.ObjectPath, aliasPath dbus.Obje
// The null path is syntactically valid (so IsValid above returns true) but
// does not point at a real collection, so it must be rejected explicitly.
if aliasPath == nullObjectPath {
return "", errNoDefaultCollection
return "", ErrNoDefaultCollection
}

return aliasPath, nil
Expand Down
2 changes: 1 addition & 1 deletion store/keychain/keychain_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func TestResolveDefaultCollection(t *testing.T) {
// ReadAlias returns the null object path "/"
collections: []dbus.ObjectPath{},
aliasPath: nullObjectPath,
wantErr: errNoDefaultCollection,
wantErr: ErrNoDefaultCollection,
},
{
name: "rejects syntactically invalid alias path",
Expand Down
Loading