From d12f60aa71e64ac9251cb784969aa8c3b7a731aa Mon Sep 17 00:00:00 2001 From: Ezequiel Raynaudo Date: Tue, 2 Aug 2022 08:45:55 -0300 Subject: [PATCH] Feat/access denied error (#1) * Update gitignore * Add ErrAccessDenied error * Add error description on errSecUserCanceled * Run CI on pull requests --- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- .gitignore | 1 + keychain.go | 34 ++++++++++++++++++++++++++++------ keyring.go | 3 +++ 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f8ee58a..4953cf5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,5 +1,5 @@ name: golangci-lint -on: push +on: pull_request jobs: golangci: strategy: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1e81147..3339bf0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,5 +1,5 @@ name: Continuous Integration -on: push +on: pull_request jobs: linux: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 8000dd9..1174595 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .vagrant +.idea diff --git a/keychain.go b/keychain.go index 8850922..d31f8f4 100644 --- a/keychain.go +++ b/keychain.go @@ -3,6 +3,13 @@ package keyring +/* +#cgo LDFLAGS: -framework CoreFoundation -framework Security + +#include +#include +*/ +import "C" import ( "errors" "fmt" @@ -10,6 +17,12 @@ import ( gokeychain "github.com/99designs/go-keychain" ) +// Extended error list that gokeychain doesn't catch +var ( + // ErrorUserCanceled corresponds to errSecUserCanceled result code + ErrorUserCanceled = gokeychain.Error(C.errSecUserCanceled) +) + type keychain struct { path string service string @@ -58,14 +71,23 @@ func (k *keychain) Get(key string) (Item, error) { debugf("Querying keychain for service=%q, account=%q, keychain=%q", k.service, key, k.path) results, err := gokeychain.QueryItem(query) - if err == gokeychain.ErrorItemNotFound || len(results) == 0 { - debugf("No results found") - return Item{}, ErrKeyNotFound + if err != nil { + switch err { + case ErrorUserCanceled: + debugf("Keychain access denied") + return Item{}, ErrAccessDenied + case gokeychain.ErrorItemNotFound: + debugf("Item not found in the keyring") + return Item{}, ErrKeyNotFound + default: + debugf("Error: %#v", err) + return Item{}, err + } } - if err != nil { - debugf("Error: %#v", err) - return Item{}, err + if len(results) == 0 { + debugf("No results found") + return Item{}, ErrKeyNotFound } item := Item{ diff --git a/keyring.go b/keyring.go index 12161b7..d98ae1d 100644 --- a/keyring.go +++ b/keyring.go @@ -122,6 +122,9 @@ var ErrMetadataNeedsCredentials = errors.New("The keyring backend requires crede // ErrMetadataNotSupported is returned when Metadata is not available for the backend. var ErrMetadataNotSupported = errors.New("The keyring backend does not support metadata access") +// ErrAccessDenied is returned by Keyring Get when access to Keychain is denied by the user +var ErrAccessDenied = errors.New("Keyring backend access denied by user") + var ( // Debug specifies whether to print debugging output. Debug bool