From 78ca31eb66c38ed119576e1c7122a3c90eee54bf Mon Sep 17 00:00:00 2001 From: Tyler Creller Date: Fri, 5 Jan 2024 12:07:40 -0500 Subject: [PATCH 01/11] OCM-4946: Secure store darwin and linux --- authentication/securestore/main.go | 28 +++++++ .../securestore/secure_store_darwin.go | 73 +++++++++++++++++++ .../securestore/secure_store_linux.go | 73 +++++++++++++++++++ .../securestore/secure_store_windows.go | 30 ++++++++ go.mod | 9 +++ go.sum | 13 +++- 6 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 authentication/securestore/main.go create mode 100644 authentication/securestore/secure_store_darwin.go create mode 100644 authentication/securestore/secure_store_linux.go create mode 100644 authentication/securestore/secure_store_windows.go diff --git a/authentication/securestore/main.go b/authentication/securestore/main.go new file mode 100644 index 00000000..6ff103e2 --- /dev/null +++ b/authentication/securestore/main.go @@ -0,0 +1,28 @@ +package securestore + +const ( + LabelKey = "Red Hat SSO" + SecureStoreConfigKey = "securestore" +) + +// type Credentials struct { +// AccessToken string `json:"access_token,omitempty" doc:"Bearer access token."` +// ClientID string `json:"client_id,omitempty" doc:"OpenID client identifier."` +// ClientSecret string `json:"client_secret,omitempty" doc:"OpenID client secret."` +// Insecure bool `json:"insecure,omitempty" doc:"Enables insecure communication with the server. This disables verification of TLS certificates and host names."` +// Password string `json:"password,omitempty" doc:"User password."` +// RefreshToken string `json:"refresh_token,omitempty" doc:"Offline or refresh token."` +// Scopes []string `json:"scopes,omitempty" doc:"OpenID scope. If this option is used it will replace completely the default scopes. Can be repeated multiple times to specify multiple scopes."` +// TokenURL string `json:"token_url,omitempty" doc:"OpenID token URL."` +// URL string `json:"url,omitempty" doc:"URL of the API gateway. The value can be the complete URL or an alias. The valid aliases are 'production', 'staging' and 'integration'."` +// User string `json:"user,omitempty" doc:"User name."` +// Pager string `json:"pager,omitempty" doc:"Pager command, for example 'less'. If empty no pager will be used."` +// } + +func UpsertConfigToKeyring(credentials []byte) error { + return upsertCredentials(LabelKey, credentials) +} + +func GetConfigFromKeyring() ([]byte, error) { + return getCredentials(LabelKey) +} diff --git a/authentication/securestore/secure_store_darwin.go b/authentication/securestore/secure_store_darwin.go new file mode 100644 index 00000000..c59f422a --- /dev/null +++ b/authentication/securestore/secure_store_darwin.go @@ -0,0 +1,73 @@ +//go:build darwin +// +build darwin + +package securestore + +import ( + "fmt" + + keychain "github.com/keybase/go-keychain" +) + +// var nativeStore = osxkeychain.Osxkeychain{} + +func upsertCredentials(labelKey string, credentials []byte) error { + // b, err := json.Marshal(cred) + // if err != nil { + // fmt.Println(err) + // return + // } + + // Option 1 + // c := &credentials.Credentials{ + // ServerURL: "https://sso.redhat.com", + // Username: "token", + // Secret: cred, + // } + + // nativeStore.Add(c) + // secret, username, err := nativeStore.Get("https://sso.redhat.com") + // fmt.Println(secret, username, err) + // End: Option 1 + + item := keychain.NewItem() + item.SetSecClass(keychain.SecClassInternetPassword) + item.SetLabel(labelKey) + item.SetData(credentials) + item.SetSynchronizable(keychain.SynchronizableNo) + item.SetAccessible(keychain.AccessibleAfterFirstUnlockThisDeviceOnly) + + err := keychain.AddItem(item) + if err == keychain.ErrorDuplicateItem { + // Item already exists, update it + err = keychain.UpdateItem(item, item) + if err != nil { + return fmt.Errorf("error updating keychain item: %v", err) + } + } + + return nil +} + +func getCredentials(labelKey string) ([]byte, error) { + // secret, username, err := nativeStore.Get("https://sso.redhat.com") + // secretCreds := Credentials{} + // json.Unmarshal([]byte(secret), &secretCreds) + // return secretCreds, username, err + credentials := []byte("") + + query := keychain.NewItem() + query.SetSecClass(keychain.SecClassInternetPassword) + query.SetLabel(labelKey) + query.SetMatchLimit(keychain.MatchLimitOne) + query.SetReturnData(true) + results, err := keychain.QueryItem(query) + if err != nil { + return credentials, fmt.Errorf("error fetching keychain item: %v", err) + } else if len(results) != 1 { + // Not found + } else { + credentials = results[0].Data + } + return credentials, nil +} diff --git a/authentication/securestore/secure_store_linux.go b/authentication/securestore/secure_store_linux.go new file mode 100644 index 00000000..3e8b7baf --- /dev/null +++ b/authentication/securestore/secure_store_linux.go @@ -0,0 +1,73 @@ +//go:build linux +// +build linux + +package securestore + +import ( + "fmt" + + keychain "github.com/keybase/go-keychain" +) + +// var nativeStore = osxkeychain.Osxkeychain{} + +func upsertCredentials(labelKey string, credentials []byte) error { + // b, err := json.Marshal(cred) + // if err != nil { + // fmt.Println(err) + // return + // } + + // Option 1 + // c := &credentials.Credentials{ + // ServerURL: "https://sso.redhat.com", + // Username: "token", + // Secret: cred, + // } + + // nativeStore.Add(c) + // secret, username, err := nativeStore.Get("https://sso.redhat.com") + // fmt.Println(secret, username, err) + // End: Option 1 + + item := keychain.NewItem() + item.SetSecClass(keychain.SecClassInternetPassword) + item.SetLabel(labelKey) + item.SetData(credentials) + item.SetSynchronizable(keychain.SynchronizableNo) + item.SetAccessible(keychain.AccessibleAfterFirstUnlockThisDeviceOnly) + + err := keychain.AddItem(item) + if err == keychain.ErrorDuplicateItem { + // Item already exists, update it + err = keychain.UpdateItem(item, item) + if err != nil { + return fmt.Errorf("error updating keychain item: %v", err) + } + } + + return nil +} + +func getCredentials(labelKey string) ([]byte, error) { + // secret, username, err := nativeStore.Get("https://sso.redhat.com") + // secretCreds := Credentials{} + // json.Unmarshal([]byte(secret), &secretCreds) + // return secretCreds, username, err + credentials := []byte("") + + query := keychain.NewItem() + query.SetSecClass(keychain.SecClassInternetPassword) + query.SetLabel(labelKey) + query.SetMatchLimit(keychain.MatchLimitOne) + query.SetReturnData(true) + results, err := keychain.QueryItem(query) + if err != nil { + return credentials, fmt.Errorf("error fetching keychain item: %v", err) + } else if len(results) != 1 { + // Not found + } else { + credentials = results[0].Data + } + return credentials, nil +} diff --git a/authentication/securestore/secure_store_windows.go b/authentication/securestore/secure_store_windows.go new file mode 100644 index 00000000..5ff54c9b --- /dev/null +++ b/authentication/securestore/secure_store_windows.go @@ -0,0 +1,30 @@ +//go:build windows +// +build windows + +package securestore + +import ( + "fmt" + + "github.com/docker/docker-credential-helpers/credentials" + "github.com/docker/docker-credential-helpers/wincred" +) + +var nativeStore = wincred.WinCred{} + +func upsertCredentials() { + c := &credentials.Credentials{ + ServerURL: "https://sso.redhat.com", + Username: "token", + Secret: "", + } + + nativeStore.Add(c) + secret, username, err := nativeStore.Get("https://sso.redhat.com") + fmt.Println(secret, username, err) +} + +func getCreds() (string, string, error) { + secret, username, err := nativeStore.Get("https://sso.redhat.com") + return secret, username, err +} diff --git a/go.mod b/go.mod index 72f87087..600b4625 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.21 require ( github.com/cenkalti/backoff/v4 v4.1.3 + github.com/docker/docker-credential-helpers v0.8.0 github.com/evanphx/json-patch/v5 v5.6.0 github.com/golang-jwt/jwt/v4 v4.4.1 github.com/golang/glog v1.0.0 @@ -12,6 +13,7 @@ require ( github.com/jackc/pgconn v1.12.0 github.com/jackc/pgx/v4 v4.16.0 github.com/json-iterator/go v1.1.12 + github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 github.com/lib/pq v1.10.5 github.com/microcosm-cc/bluemonday v1.0.18 github.com/onsi/ginkgo/v2 v2.1.4 @@ -20,6 +22,8 @@ require ( github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 golang.org/x/net v0.19.0 golang.org/x/oauth2 v0.15.0 + golang.org/x/crypto v0.17.0 // indirect + golang.org/x/net v0.10.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -28,6 +32,8 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/danieljoos/wincred v1.2.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect github.com/gorilla/css v1.0.0 // indirect github.com/itchyny/timefmt-go v0.1.3 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect @@ -48,5 +54,8 @@ require ( golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + google.golang.org/protobuf v1.26.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index a1948984..bec00027 100644 --- a/go.sum +++ b/go.sum @@ -62,9 +62,13 @@ github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMe github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= +github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0SkRa/eYHgec= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8= +github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -212,6 +216,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -298,12 +304,15 @@ github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:s github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -337,6 +346,8 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= From eb90283b78e06ddc16259fd9db2ec35314cc972c Mon Sep 17 00:00:00 2001 From: Tyler Creller Date: Fri, 5 Jan 2024 12:58:59 -0500 Subject: [PATCH 02/11] Clean HEAD From 74a69506f47f62a090aeaeb581c63510a8cf6faa Mon Sep 17 00:00:00 2001 From: Tyler Creller Date: Fri, 5 Jan 2024 16:41:44 -0500 Subject: [PATCH 03/11] OCM-4946: use docker creds for linux --- .../securestore/secure_store_linux.go | 65 +++---------------- 1 file changed, 9 insertions(+), 56 deletions(-) diff --git a/authentication/securestore/secure_store_linux.go b/authentication/securestore/secure_store_linux.go index 3e8b7baf..bdb5aac2 100644 --- a/authentication/securestore/secure_store_linux.go +++ b/authentication/securestore/secure_store_linux.go @@ -4,70 +4,23 @@ package securestore import ( - "fmt" - - keychain "github.com/keybase/go-keychain" + "github.com/docker/docker-credential-helpers/secretservice" ) -// var nativeStore = osxkeychain.Osxkeychain{} +var nativeStore = secretservice.SecretService{} func upsertCredentials(labelKey string, credentials []byte) error { - // b, err := json.Marshal(cred) - // if err != nil { - // fmt.Println(err) - // return - // } - - // Option 1 - // c := &credentials.Credentials{ - // ServerURL: "https://sso.redhat.com", - // Username: "token", - // Secret: cred, - // } - - // nativeStore.Add(c) - // secret, username, err := nativeStore.Get("https://sso.redhat.com") - // fmt.Println(secret, username, err) - // End: Option 1 - - item := keychain.NewItem() - item.SetSecClass(keychain.SecClassInternetPassword) - item.SetLabel(labelKey) - item.SetData(credentials) - item.SetSynchronizable(keychain.SynchronizableNo) - item.SetAccessible(keychain.AccessibleAfterFirstUnlockThisDeviceOnly) - - err := keychain.AddItem(item) - if err == keychain.ErrorDuplicateItem { - // Item already exists, update it - err = keychain.UpdateItem(item, item) - if err != nil { - return fmt.Errorf("error updating keychain item: %v", err) - } + c := &credentials.Credentials{ + ServerURL: labelKey, + Username: labelKey, + Secret: credentials, } + err := nativeStore.Add(c) return nil } func getCredentials(labelKey string) ([]byte, error) { - // secret, username, err := nativeStore.Get("https://sso.redhat.com") - // secretCreds := Credentials{} - // json.Unmarshal([]byte(secret), &secretCreds) - // return secretCreds, username, err - credentials := []byte("") - - query := keychain.NewItem() - query.SetSecClass(keychain.SecClassInternetPassword) - query.SetLabel(labelKey) - query.SetMatchLimit(keychain.MatchLimitOne) - query.SetReturnData(true) - results, err := keychain.QueryItem(query) - if err != nil { - return credentials, fmt.Errorf("error fetching keychain item: %v", err) - } else if len(results) != 1 { - // Not found - } else { - credentials = results[0].Data - } - return credentials, nil + secret, err := nativeStore.Get(labelKey) + return secret, err } From 82f520ceb2058c40e6b75419204f67e9b7f265f7 Mon Sep 17 00:00:00 2001 From: Tyler Creller Date: Thu, 11 Jan 2024 15:05:05 -0600 Subject: [PATCH 04/11] OCM-4964: Generic Secure Store Service --- authentication/securestore/secure_store.go | 71 +++++++++++ .../securestore/secure_store_darwin.go | 120 +++++++++--------- .../securestore/secure_store_linux.go | 73 ++++++++--- .../securestore/secure_store_windows.go | 44 +++---- go.mod | 8 ++ go.sum | 20 ++- 6 files changed, 233 insertions(+), 103 deletions(-) create mode 100644 authentication/securestore/secure_store.go diff --git a/authentication/securestore/secure_store.go b/authentication/securestore/secure_store.go new file mode 100644 index 00000000..5be11422 --- /dev/null +++ b/authentication/securestore/secure_store.go @@ -0,0 +1,71 @@ +package securestore + +import ( + "github.com/99designs/keyring" +) + +const ( + CollectionLabel = "RedHat" // Secret Service prefers no spaces +) + +func getKeyringConfig() keyring.Config { + return keyring.Config{ + // Generic + ServiceName: CollectionLabel, + // MacOS + KeychainName: CollectionLabel, + KeychainTrustApplication: true, + KeychainSynchronizable: false, + KeychainAccessibleWhenUnlocked: true, + KeychainPasswordFunc: keyring.TerminalPrompt, + // Windows + WinCredPrefix: CollectionLabel, + // Secret Service + LibSecretCollectionName: CollectionLabel, + // KWallet + KWalletFolder: CollectionLabel, + KWalletAppID: CollectionLabel, + // KeyCtl + KeyCtlScope: "user", + // Pass + PassDir: "~/", // TODO: use default ocm config + PassPrefix: CollectionLabel, + // Encrypted File + FilePasswordFunc: keyring.TerminalPrompt, + FileDir: "~/", // TODO: use default ocm config + } +} +func upsertCredentials(labelKey string, creds []byte) error { + ring, err := keyring.Open(getKeyringConfig()) + if err != nil { + // TODO + } + + err = ring.Set(keyring.Item{ + Key: labelKey, + Data: creds, + }) + + return err +} + +func getCredentials(labelKey string) ([]byte, error) { + credentials := []byte("") + + ring, err := keyring.Open(getKeyringConfig()) + if err != nil { + // TODO + } + + i, err := ring.Get(labelKey) + if err != nil && err != keyring.ErrKeyNotFound { + return credentials, err + } else if err == keyring.ErrKeyNotFound { + // Not Found + } else { + credentials = i.Data + } + + return credentials, nil + +} diff --git a/authentication/securestore/secure_store_darwin.go b/authentication/securestore/secure_store_darwin.go index c59f422a..5b9051f8 100644 --- a/authentication/securestore/secure_store_darwin.go +++ b/authentication/securestore/secure_store_darwin.go @@ -1,73 +1,73 @@ -//go:build darwin -// +build darwin +// //go:build darwin +// // +build darwin package securestore -import ( - "fmt" +// import ( +// "fmt" - keychain "github.com/keybase/go-keychain" -) +// keychain "github.com/keybase/go-keychain" +// ) -// var nativeStore = osxkeychain.Osxkeychain{} +// // var nativeStore = osxkeychain.Osxkeychain{} -func upsertCredentials(labelKey string, credentials []byte) error { - // b, err := json.Marshal(cred) - // if err != nil { - // fmt.Println(err) - // return - // } +// func upsertCredentials(labelKey string, credentials []byte) error { +// // b, err := json.Marshal(cred) +// // if err != nil { +// // fmt.Println(err) +// // return +// // } - // Option 1 - // c := &credentials.Credentials{ - // ServerURL: "https://sso.redhat.com", - // Username: "token", - // Secret: cred, - // } +// // Option 1 +// // c := &credentials.Credentials{ +// // ServerURL: "https://sso.redhat.com", +// // Username: "token", +// // Secret: cred, +// // } - // nativeStore.Add(c) - // secret, username, err := nativeStore.Get("https://sso.redhat.com") - // fmt.Println(secret, username, err) - // End: Option 1 +// // nativeStore.Add(c) +// // secret, username, err := nativeStore.Get("https://sso.redhat.com") +// // fmt.Println(secret, username, err) +// // End: Option 1 - item := keychain.NewItem() - item.SetSecClass(keychain.SecClassInternetPassword) - item.SetLabel(labelKey) - item.SetData(credentials) - item.SetSynchronizable(keychain.SynchronizableNo) - item.SetAccessible(keychain.AccessibleAfterFirstUnlockThisDeviceOnly) +// item := keychain.NewItem() +// item.SetSecClass(keychain.SecClassInternetPassword) +// item.SetLabel(labelKey) +// item.SetData(credentials) +// item.SetSynchronizable(keychain.SynchronizableNo) +// item.SetAccessible(keychain.AccessibleAfterFirstUnlockThisDeviceOnly) - err := keychain.AddItem(item) - if err == keychain.ErrorDuplicateItem { - // Item already exists, update it - err = keychain.UpdateItem(item, item) - if err != nil { - return fmt.Errorf("error updating keychain item: %v", err) - } - } +// err := keychain.AddItem(item) +// if err == keychain.ErrorDuplicateItem { +// // Item already exists, update it +// err = keychain.UpdateItem(item, item) +// if err != nil { +// return fmt.Errorf("error updating keychain item: %v", err) +// } +// } - return nil -} +// return nil +// } -func getCredentials(labelKey string) ([]byte, error) { - // secret, username, err := nativeStore.Get("https://sso.redhat.com") - // secretCreds := Credentials{} - // json.Unmarshal([]byte(secret), &secretCreds) - // return secretCreds, username, err - credentials := []byte("") +// func getCredentials(labelKey string) ([]byte, error) { +// // secret, username, err := nativeStore.Get("https://sso.redhat.com") +// // secretCreds := Credentials{} +// // json.Unmarshal([]byte(secret), &secretCreds) +// // return secretCreds, username, err +// credentials := []byte("") - query := keychain.NewItem() - query.SetSecClass(keychain.SecClassInternetPassword) - query.SetLabel(labelKey) - query.SetMatchLimit(keychain.MatchLimitOne) - query.SetReturnData(true) - results, err := keychain.QueryItem(query) - if err != nil { - return credentials, fmt.Errorf("error fetching keychain item: %v", err) - } else if len(results) != 1 { - // Not found - } else { - credentials = results[0].Data - } - return credentials, nil -} +// query := keychain.NewItem() +// query.SetSecClass(keychain.SecClassInternetPassword) +// query.SetLabel(labelKey) +// query.SetMatchLimit(keychain.MatchLimitOne) +// query.SetReturnData(true) +// results, err := keychain.QueryItem(query) +// if err != nil { +// return credentials, fmt.Errorf("error fetching keychain item: %v", err) +// } else if len(results) != 1 { +// // Not found +// } else { +// credentials = results[0].Data +// } +// return credentials, nil +// } diff --git a/authentication/securestore/secure_store_linux.go b/authentication/securestore/secure_store_linux.go index bdb5aac2..045b1cce 100644 --- a/authentication/securestore/secure_store_linux.go +++ b/authentication/securestore/secure_store_linux.go @@ -1,26 +1,61 @@ -//go:build linux -// +build linux +// //go:build linux +// // +build linux package securestore -import ( - "github.com/docker/docker-credential-helpers/secretservice" -) +// import ( +// "github.com/99designs/keyring" +// ) -var nativeStore = secretservice.SecretService{} +// const ( +// CollectionLabel = "RedHat" // Secret Service prefers no spaces +// ) -func upsertCredentials(labelKey string, credentials []byte) error { - c := &credentials.Credentials{ - ServerURL: labelKey, - Username: labelKey, - Secret: credentials, - } +// func getKeyringConfig() keyring.Config { +// return keyring.Config{ - err := nativeStore.Add(c) - return nil -} +// ServiceName: CollectionLabel, +// // Secret Service +// LibSecretCollectionName: CollectionLabel, +// // KWallet +// KWalletFolder: CollectionLabel, +// // KeyCtl +// KeyCtlScope: "user", +// // Pass +// PassDir: CollectionLabel, +// } +// } +// func upsertCredentials(labelKey string, creds []byte) error { +// ring, err := keyring.Open(getKeyringConfig()) +// if err != nil { +// // TODO +// } -func getCredentials(labelKey string) ([]byte, error) { - secret, err := nativeStore.Get(labelKey) - return secret, err -} +// err = ring.Set(keyring.Item{ +// Key: labelKey, +// Data: creds, +// }) + +// return err +// } + +// func getCredentials(labelKey string) ([]byte, error) { +// credentials := []byte("") + +// ring, err := keyring.Open(getKeyringConfig()) +// if err != nil { +// // TODO +// } + +// i, err := ring.Get(labelKey) +// if err != nil && err != keyring.ErrKeyNotFound { +// return credentials, err +// } else if err == keyring.ErrKeyNotFound { +// // Not Found +// } else { +// credentials = i.Data +// } + +// return credentials, nil + +// } diff --git a/authentication/securestore/secure_store_windows.go b/authentication/securestore/secure_store_windows.go index 5ff54c9b..9e6c4190 100644 --- a/authentication/securestore/secure_store_windows.go +++ b/authentication/securestore/secure_store_windows.go @@ -1,30 +1,30 @@ -//go:build windows -// +build windows +// //go:build windows +// // +build windows package securestore -import ( - "fmt" +// import ( +// "fmt" - "github.com/docker/docker-credential-helpers/credentials" - "github.com/docker/docker-credential-helpers/wincred" -) +// "github.com/docker/docker-credential-helpers/credentials" +// "github.com/docker/docker-credential-helpers/wincred" +// ) -var nativeStore = wincred.WinCred{} +// var nativeStore = wincred.WinCred{} -func upsertCredentials() { - c := &credentials.Credentials{ - ServerURL: "https://sso.redhat.com", - Username: "token", - Secret: "", - } +// func upsertCredentials() { +// c := &credentials.Credentials{ +// ServerURL: "https://sso.redhat.com", +// Username: "token", +// Secret: "", +// } - nativeStore.Add(c) - secret, username, err := nativeStore.Get("https://sso.redhat.com") - fmt.Println(secret, username, err) -} +// nativeStore.Add(c) +// secret, username, err := nativeStore.Get("https://sso.redhat.com") +// fmt.Println(secret, username, err) +// } -func getCreds() (string, string, error) { - secret, username, err := nativeStore.Get("https://sso.redhat.com") - return secret, username, err -} +// func getCreds() (string, string, error) { +// secret, username, err := nativeStore.Get("https://sso.redhat.com") +// return secret, username, err +// } diff --git a/go.mod b/go.mod index 600b4625..b694ae46 100644 --- a/go.mod +++ b/go.mod @@ -27,14 +27,20 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) +require github.com/99designs/keyring v1.2.2 + require ( + github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/danieljoos/wincred v1.2.0 // indirect + github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/gorilla/css v1.0.0 // indirect + github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/itchyny/timefmt-go v0.1.3 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgio v1.0.0 // indirect @@ -45,6 +51,7 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mtibben/percent v0.2.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect @@ -55,6 +62,7 @@ require ( google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect golang.org/x/sys v0.15.0 // indirect + golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/protobuf v1.26.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index bec00027..c75c6032 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,10 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= +github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= +github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= @@ -69,6 +73,8 @@ 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/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8= github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40= +github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -85,6 +91,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -151,6 +159,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -223,7 +233,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= @@ -253,8 +262,12 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= +github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= @@ -477,6 +490,8 @@ golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -623,8 +638,9 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 48bf2ed700156bdd1db883d037d5fddd3a93ba2c Mon Sep 17 00:00:00 2001 From: Tyler Creller Date: Fri, 12 Jan 2024 10:33:55 -0500 Subject: [PATCH 05/11] OCM-4946: Use single keyring impl for all OS --- authentication/securestore/main.go | 114 +++++++++++++++++---- authentication/securestore/secure_store.go | 71 ------------- go.mod | 3 +- go.sum | 4 - 4 files changed, 95 insertions(+), 97 deletions(-) delete mode 100644 authentication/securestore/secure_store.go diff --git a/authentication/securestore/main.go b/authentication/securestore/main.go index 6ff103e2..59c40c82 100644 --- a/authentication/securestore/main.go +++ b/authentication/securestore/main.go @@ -1,28 +1,102 @@ package securestore +import ( + "github.com/99designs/keyring" +) + const ( - LabelKey = "Red Hat SSO" - SecureStoreConfigKey = "securestore" + SecureStoreConfigKey = "securestore" // OCM_CONFIG key to enable secure OS store + KindInternetPassword = "Internet password" // MacOS Keychain item kind + LabelKey = "RedHatSSO" + CollectionLabel = "OCM" + KeychainName = "login" // MacOS Keychain name + DefaultFilePath = "~/.config/ocm/ocm.json" ) -// type Credentials struct { -// AccessToken string `json:"access_token,omitempty" doc:"Bearer access token."` -// ClientID string `json:"client_id,omitempty" doc:"OpenID client identifier."` -// ClientSecret string `json:"client_secret,omitempty" doc:"OpenID client secret."` -// Insecure bool `json:"insecure,omitempty" doc:"Enables insecure communication with the server. This disables verification of TLS certificates and host names."` -// Password string `json:"password,omitempty" doc:"User password."` -// RefreshToken string `json:"refresh_token,omitempty" doc:"Offline or refresh token."` -// Scopes []string `json:"scopes,omitempty" doc:"OpenID scope. If this option is used it will replace completely the default scopes. Can be repeated multiple times to specify multiple scopes."` -// TokenURL string `json:"token_url,omitempty" doc:"OpenID token URL."` -// URL string `json:"url,omitempty" doc:"URL of the API gateway. The value can be the complete URL or an alias. The valid aliases are 'production', 'staging' and 'integration'."` -// User string `json:"user,omitempty" doc:"User name."` -// Pager string `json:"pager,omitempty" doc:"Pager command, for example 'less'. If empty no pager will be used."` -// } - -func UpsertConfigToKeyring(credentials []byte) error { - return upsertCredentials(LabelKey, credentials) +func getKeyringConfig() keyring.Config { + return keyring.Config{ + // The order of the backends is important. The first backend in the list is the first one + // that will attempt to be used. + AllowedBackends: []keyring.BackendType{ + keyring.WinCredBackend, + keyring.KeychainBackend, // Tested + keyring.SecretServiceBackend, // Tested + keyring.KWalletBackend, + keyring.KeyCtlBackend, + keyring.PassBackend, // Tested + // The FileBackend is a last resort and will store credentials in an encrypted file. This has + // the worst user experience as the user will have to enter a password every time they attempt + // to access the file. + keyring.FileBackend, // Tested + }, + // Generic + ServiceName: CollectionLabel, + // MacOS + KeychainName: KeychainName, + KeychainTrustApplication: true, + KeychainSynchronizable: false, + KeychainAccessibleWhenUnlocked: false, + // Windows + WinCredPrefix: CollectionLabel, + // Secret Service + LibSecretCollectionName: CollectionLabel, + // KWallet + KWalletFolder: CollectionLabel, + KWalletAppID: CollectionLabel, + // KeyCtl + KeyCtlScope: "user", + // Encrypted File + FilePasswordFunc: keyring.TerminalPrompt, + FileDir: DefaultFilePath, + } +} + +// AvailableBackends provides a slice of all available backend keys on the current OS. +// +// The first backend in the slice is the first one that will be used. +func AvailableBackends() []string { + b := []string{} + for _, k := range keyring.AvailableBackends() { + b = append(b, string(k)) + } + return b +} + +// UpsertConfigToKeyring will upsert the provided credentials to first priority OS secure store. +func UpsertConfigToKeyring(creds []byte, debug bool) error { + ring, err := keyring.Open(getKeyringConfig()) + if err != nil { + return err + } + + err = ring.Set(keyring.Item{ + Label: LabelKey, + Key: LabelKey, + Description: KindInternetPassword, + Data: creds, + }) + + return err } -func GetConfigFromKeyring() ([]byte, error) { - return getCredentials(LabelKey) +// GetConfigFromKeyring will retrieve the credentials from the first priority OS secure store. +func GetConfigFromKeyring(debug bool) ([]byte, error) { + credentials := []byte("") + + ring, err := keyring.Open(getKeyringConfig()) + if err != nil { + return nil, err + } + + i, err := ring.Get(LabelKey) + if err != nil && err != keyring.ErrKeyNotFound { + return credentials, err + } else if err == keyring.ErrKeyNotFound { + // Not found, continue + } else { + credentials = i.Data + } + + return credentials, nil + } diff --git a/authentication/securestore/secure_store.go b/authentication/securestore/secure_store.go deleted file mode 100644 index 5be11422..00000000 --- a/authentication/securestore/secure_store.go +++ /dev/null @@ -1,71 +0,0 @@ -package securestore - -import ( - "github.com/99designs/keyring" -) - -const ( - CollectionLabel = "RedHat" // Secret Service prefers no spaces -) - -func getKeyringConfig() keyring.Config { - return keyring.Config{ - // Generic - ServiceName: CollectionLabel, - // MacOS - KeychainName: CollectionLabel, - KeychainTrustApplication: true, - KeychainSynchronizable: false, - KeychainAccessibleWhenUnlocked: true, - KeychainPasswordFunc: keyring.TerminalPrompt, - // Windows - WinCredPrefix: CollectionLabel, - // Secret Service - LibSecretCollectionName: CollectionLabel, - // KWallet - KWalletFolder: CollectionLabel, - KWalletAppID: CollectionLabel, - // KeyCtl - KeyCtlScope: "user", - // Pass - PassDir: "~/", // TODO: use default ocm config - PassPrefix: CollectionLabel, - // Encrypted File - FilePasswordFunc: keyring.TerminalPrompt, - FileDir: "~/", // TODO: use default ocm config - } -} -func upsertCredentials(labelKey string, creds []byte) error { - ring, err := keyring.Open(getKeyringConfig()) - if err != nil { - // TODO - } - - err = ring.Set(keyring.Item{ - Key: labelKey, - Data: creds, - }) - - return err -} - -func getCredentials(labelKey string) ([]byte, error) { - credentials := []byte("") - - ring, err := keyring.Open(getKeyringConfig()) - if err != nil { - // TODO - } - - i, err := ring.Get(labelKey) - if err != nil && err != keyring.ErrKeyNotFound { - return credentials, err - } else if err == keyring.ErrKeyNotFound { - // Not Found - } else { - credentials = i.Data - } - - return credentials, nil - -} diff --git a/go.mod b/go.mod index b694ae46..25cf2cf2 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.21 require ( github.com/cenkalti/backoff/v4 v4.1.3 - github.com/docker/docker-credential-helpers v0.8.0 github.com/evanphx/json-patch/v5 v5.6.0 github.com/golang-jwt/jwt/v4 v4.4.1 github.com/golang/glog v1.0.0 @@ -13,7 +12,6 @@ require ( github.com/jackc/pgconn v1.12.0 github.com/jackc/pgx/v4 v4.16.0 github.com/json-iterator/go v1.1.12 - github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 github.com/lib/pq v1.10.5 github.com/microcosm-cc/bluemonday v1.0.18 github.com/onsi/ginkgo/v2 v2.1.4 @@ -61,6 +59,7 @@ require ( golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect + github.com/stretchr/testify v1.8.4 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect diff --git a/go.sum b/go.sum index c75c6032..c71c1570 100644 --- a/go.sum +++ b/go.sum @@ -71,8 +71,6 @@ github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0S github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8= -github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40= github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -226,8 +224,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= -github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= From eb51268b4e285a989c7c28684b9d093a91b95b6c Mon Sep 17 00:00:00 2001 From: Tyler Creller Date: Fri, 12 Jan 2024 13:05:37 -0600 Subject: [PATCH 06/11] OCM4964: Revised secure store labels --- authentication/securestore/main.go | 37 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/authentication/securestore/main.go b/authentication/securestore/main.go index 59c40c82..9d8e60f9 100644 --- a/authentication/securestore/main.go +++ b/authentication/securestore/main.go @@ -7,10 +7,9 @@ import ( const ( SecureStoreConfigKey = "securestore" // OCM_CONFIG key to enable secure OS store KindInternetPassword = "Internet password" // MacOS Keychain item kind - LabelKey = "RedHatSSO" - CollectionLabel = "OCM" - KeychainName = "login" // MacOS Keychain name - DefaultFilePath = "~/.config/ocm/ocm.json" + ItemKey = "RedHatSSO" + CollectionName = "login" // Common OS default collection name + DefaultFilePath = "~/.config/ocm" // File path when using File backend ) func getKeyringConfig() keyring.Config { @@ -19,30 +18,30 @@ func getKeyringConfig() keyring.Config { // that will attempt to be used. AllowedBackends: []keyring.BackendType{ keyring.WinCredBackend, - keyring.KeychainBackend, // Tested - keyring.SecretServiceBackend, // Tested + keyring.KeychainBackend, + keyring.SecretServiceBackend, keyring.KWalletBackend, keyring.KeyCtlBackend, - keyring.PassBackend, // Tested + keyring.PassBackend, // The FileBackend is a last resort and will store credentials in an encrypted file. This has // the worst user experience as the user will have to enter a password every time they attempt // to access the file. - keyring.FileBackend, // Tested + keyring.FileBackend, }, // Generic - ServiceName: CollectionLabel, + ServiceName: ItemKey, // MacOS - KeychainName: KeychainName, + KeychainName: CollectionName, KeychainTrustApplication: true, KeychainSynchronizable: false, KeychainAccessibleWhenUnlocked: false, // Windows - WinCredPrefix: CollectionLabel, + WinCredPrefix: ItemKey, // Secret Service - LibSecretCollectionName: CollectionLabel, + LibSecretCollectionName: CollectionName, // KWallet - KWalletFolder: CollectionLabel, - KWalletAppID: CollectionLabel, + KWalletFolder: CollectionName, + KWalletAppID: ItemKey, // KeyCtl KeyCtlScope: "user", // Encrypted File @@ -63,15 +62,15 @@ func AvailableBackends() []string { } // UpsertConfigToKeyring will upsert the provided credentials to first priority OS secure store. -func UpsertConfigToKeyring(creds []byte, debug bool) error { +func UpsertConfigToKeyring(creds []byte) error { ring, err := keyring.Open(getKeyringConfig()) if err != nil { return err } err = ring.Set(keyring.Item{ - Label: LabelKey, - Key: LabelKey, + Label: ItemKey, + Key: ItemKey, Description: KindInternetPassword, Data: creds, }) @@ -80,7 +79,7 @@ func UpsertConfigToKeyring(creds []byte, debug bool) error { } // GetConfigFromKeyring will retrieve the credentials from the first priority OS secure store. -func GetConfigFromKeyring(debug bool) ([]byte, error) { +func GetConfigFromKeyring() ([]byte, error) { credentials := []byte("") ring, err := keyring.Open(getKeyringConfig()) @@ -88,7 +87,7 @@ func GetConfigFromKeyring(debug bool) ([]byte, error) { return nil, err } - i, err := ring.Get(LabelKey) + i, err := ring.Get(ItemKey) if err != nil && err != keyring.ErrKeyNotFound { return credentials, err } else if err == keyring.ErrKeyNotFound { From 1736d080e99c66c3b126c09c5eab482552050fb9 Mon Sep 17 00:00:00 2001 From: Tyler Creller Date: Fri, 12 Jan 2024 14:12:15 -0500 Subject: [PATCH 07/11] OCM-4964: Remove OS specific files --- .../securestore/secure_store_darwin.go | 73 ------------------- .../securestore/secure_store_linux.go | 61 ---------------- .../securestore/secure_store_windows.go | 30 -------- 3 files changed, 164 deletions(-) delete mode 100644 authentication/securestore/secure_store_darwin.go delete mode 100644 authentication/securestore/secure_store_linux.go delete mode 100644 authentication/securestore/secure_store_windows.go diff --git a/authentication/securestore/secure_store_darwin.go b/authentication/securestore/secure_store_darwin.go deleted file mode 100644 index 5b9051f8..00000000 --- a/authentication/securestore/secure_store_darwin.go +++ /dev/null @@ -1,73 +0,0 @@ -// //go:build darwin -// // +build darwin - -package securestore - -// import ( -// "fmt" - -// keychain "github.com/keybase/go-keychain" -// ) - -// // var nativeStore = osxkeychain.Osxkeychain{} - -// func upsertCredentials(labelKey string, credentials []byte) error { -// // b, err := json.Marshal(cred) -// // if err != nil { -// // fmt.Println(err) -// // return -// // } - -// // Option 1 -// // c := &credentials.Credentials{ -// // ServerURL: "https://sso.redhat.com", -// // Username: "token", -// // Secret: cred, -// // } - -// // nativeStore.Add(c) -// // secret, username, err := nativeStore.Get("https://sso.redhat.com") -// // fmt.Println(secret, username, err) -// // End: Option 1 - -// item := keychain.NewItem() -// item.SetSecClass(keychain.SecClassInternetPassword) -// item.SetLabel(labelKey) -// item.SetData(credentials) -// item.SetSynchronizable(keychain.SynchronizableNo) -// item.SetAccessible(keychain.AccessibleAfterFirstUnlockThisDeviceOnly) - -// err := keychain.AddItem(item) -// if err == keychain.ErrorDuplicateItem { -// // Item already exists, update it -// err = keychain.UpdateItem(item, item) -// if err != nil { -// return fmt.Errorf("error updating keychain item: %v", err) -// } -// } - -// return nil -// } - -// func getCredentials(labelKey string) ([]byte, error) { -// // secret, username, err := nativeStore.Get("https://sso.redhat.com") -// // secretCreds := Credentials{} -// // json.Unmarshal([]byte(secret), &secretCreds) -// // return secretCreds, username, err -// credentials := []byte("") - -// query := keychain.NewItem() -// query.SetSecClass(keychain.SecClassInternetPassword) -// query.SetLabel(labelKey) -// query.SetMatchLimit(keychain.MatchLimitOne) -// query.SetReturnData(true) -// results, err := keychain.QueryItem(query) -// if err != nil { -// return credentials, fmt.Errorf("error fetching keychain item: %v", err) -// } else if len(results) != 1 { -// // Not found -// } else { -// credentials = results[0].Data -// } -// return credentials, nil -// } diff --git a/authentication/securestore/secure_store_linux.go b/authentication/securestore/secure_store_linux.go deleted file mode 100644 index 045b1cce..00000000 --- a/authentication/securestore/secure_store_linux.go +++ /dev/null @@ -1,61 +0,0 @@ -// //go:build linux -// // +build linux - -package securestore - -// import ( -// "github.com/99designs/keyring" -// ) - -// const ( -// CollectionLabel = "RedHat" // Secret Service prefers no spaces -// ) - -// func getKeyringConfig() keyring.Config { -// return keyring.Config{ - -// ServiceName: CollectionLabel, -// // Secret Service -// LibSecretCollectionName: CollectionLabel, -// // KWallet -// KWalletFolder: CollectionLabel, -// // KeyCtl -// KeyCtlScope: "user", -// // Pass -// PassDir: CollectionLabel, -// } -// } -// func upsertCredentials(labelKey string, creds []byte) error { -// ring, err := keyring.Open(getKeyringConfig()) -// if err != nil { -// // TODO -// } - -// err = ring.Set(keyring.Item{ -// Key: labelKey, -// Data: creds, -// }) - -// return err -// } - -// func getCredentials(labelKey string) ([]byte, error) { -// credentials := []byte("") - -// ring, err := keyring.Open(getKeyringConfig()) -// if err != nil { -// // TODO -// } - -// i, err := ring.Get(labelKey) -// if err != nil && err != keyring.ErrKeyNotFound { -// return credentials, err -// } else if err == keyring.ErrKeyNotFound { -// // Not Found -// } else { -// credentials = i.Data -// } - -// return credentials, nil - -// } diff --git a/authentication/securestore/secure_store_windows.go b/authentication/securestore/secure_store_windows.go deleted file mode 100644 index 9e6c4190..00000000 --- a/authentication/securestore/secure_store_windows.go +++ /dev/null @@ -1,30 +0,0 @@ -// //go:build windows -// // +build windows - -package securestore - -// import ( -// "fmt" - -// "github.com/docker/docker-credential-helpers/credentials" -// "github.com/docker/docker-credential-helpers/wincred" -// ) - -// var nativeStore = wincred.WinCred{} - -// func upsertCredentials() { -// c := &credentials.Credentials{ -// ServerURL: "https://sso.redhat.com", -// Username: "token", -// Secret: "", -// } - -// nativeStore.Add(c) -// secret, username, err := nativeStore.Get("https://sso.redhat.com") -// fmt.Println(secret, username, err) -// } - -// func getCreds() (string, string, error) { -// secret, username, err := nativeStore.Get("https://sso.redhat.com") -// return secret, username, err -// } From afa64a9985795de5aabef05270e11faae386491d Mon Sep 17 00:00:00 2001 From: Tyler Creller Date: Tue, 16 Jan 2024 16:32:43 -0500 Subject: [PATCH 08/11] OCM-4964: Add compression --- authentication/securestore/main.go | 61 +++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/authentication/securestore/main.go b/authentication/securestore/main.go index 9d8e60f9..8b274a9e 100644 --- a/authentication/securestore/main.go +++ b/authentication/securestore/main.go @@ -1,6 +1,11 @@ package securestore import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "github.com/99designs/keyring" ) @@ -10,6 +15,7 @@ const ( ItemKey = "RedHatSSO" CollectionName = "login" // Common OS default collection name DefaultFilePath = "~/.config/ocm" // File path when using File backend + MaxWindowsByteSize = 2500 // Windows Credential Manager has a 2500 byte limit ) func getKeyringConfig() keyring.Config { @@ -68,11 +74,22 @@ func UpsertConfigToKeyring(creds []byte) error { return err } + compressed, err := compressConfig(creds) + if err != nil { + return err + } + + // check if available backend contains windows credential manager and exceeds the byte limit + if len(compressed) > MaxWindowsByteSize && + keyring.AvailableBackends()[0] == keyring.WinCredBackend { + return fmt.Errorf("credentials are too large for Windows Credential Manager: %d bytes (max %d)", len(compressed), MaxWindowsByteSize) + } + err = ring.Set(keyring.Item{ Label: ItemKey, Key: ItemKey, Description: KindInternetPassword, - Data: creds, + Data: compressed, }) return err @@ -96,6 +113,46 @@ func GetConfigFromKeyring() ([]byte, error) { credentials = i.Data } - return credentials, nil + creds, err := decompressConfig(credentials) + if err != nil { + return nil, err + } + + return creds, nil + +} + +// Compresses credential bytes to help ensure all OS secure stores can store the data. +// Windows Credential Manager has a 2500 byte limit. +func compressConfig(creds []byte) ([]byte, error) { + var b bytes.Buffer + gz := gzip.NewWriter(&b) + + _, err := gz.Write(creds) + if err != nil { + return nil, err + } + + err = gz.Close() + if err != nil { + return nil, err + } + + return b.Bytes(), nil +} + +// Decompresses credential bytes +func decompressConfig(creds []byte) ([]byte, error) { + reader := bytes.NewReader(creds) + gzreader, err := gzip.NewReader(reader) + if err != nil { + return nil, err + } + + output, err := io.ReadAll(gzreader) + if err != nil { + return nil, err + } + return output, err } From 812c20133518035ce72ac351870ee0df80b92ab1 Mon Sep 17 00:00:00 2001 From: Tyler Creller Date: Wed, 17 Jan 2024 10:53:10 -0500 Subject: [PATCH 09/11] OCM-4964: Error handling with no creds --- authentication/securestore/main.go | 5 +++++ go.mod | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/authentication/securestore/main.go b/authentication/securestore/main.go index 8b274a9e..33e9d71f 100644 --- a/authentication/securestore/main.go +++ b/authentication/securestore/main.go @@ -113,6 +113,11 @@ func GetConfigFromKeyring() ([]byte, error) { credentials = i.Data } + if len(credentials) == 0 { + // No creds to decompress, return early + return credentials, nil + } + creds, err := decompressConfig(credentials) if err != nil { return nil, err diff --git a/go.mod b/go.mod index 25cf2cf2..1ea705e8 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/openshift-online/ocm-sdk-go go 1.21 require ( + github.com/99designs/keyring v1.2.2 github.com/cenkalti/backoff/v4 v4.1.3 github.com/evanphx/json-patch/v5 v5.6.0 github.com/golang-jwt/jwt/v4 v4.4.1 @@ -25,8 +26,6 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) -require github.com/99designs/keyring v1.2.2 - require ( github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/aymerick/douceur v0.2.0 // indirect From dddbe09b4bac6a4590cfc5ef7b9f2cf4939faeff Mon Sep 17 00:00:00 2001 From: Tyler Creller Date: Wed, 17 Jan 2024 10:55:28 -0500 Subject: [PATCH 10/11] tidy --- go.mod | 14 ++++---------- go.sum | 2 -- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 1ea705e8..941ec47f 100644 --- a/go.mod +++ b/go.mod @@ -19,10 +19,9 @@ require ( github.com/onsi/gomega v1.19.0 github.com/prometheus/client_golang v1.12.1 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 + golang.org/x/crypto v0.17.0 // indirect golang.org/x/net v0.19.0 golang.org/x/oauth2 v0.15.0 - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/net v0.10.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -31,11 +30,10 @@ require ( github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/golang/protobuf v1.5.3 // indirect github.com/danieljoos/wincred v1.2.0 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/gorilla/css v1.0.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/itchyny/timefmt-go v0.1.3 // indirect @@ -53,15 +51,11 @@ require ( github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect - golang.org/x/crypto v0.16.0 // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/text v0.14.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.31.0 // indirect github.com/stretchr/testify v1.8.4 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect - google.golang.org/protobuf v1.26.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index c71c1570..ef215f85 100644 --- a/go.sum +++ b/go.sum @@ -353,8 +353,6 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= From e05e0b885844ad6af7ebad85a1ee48dd40901fc7 Mon Sep 17 00:00:00 2001 From: Tyler Creller Date: Wed, 17 Jan 2024 11:10:27 -0500 Subject: [PATCH 11/11] OCM-4964: Add example --- examples/go.mod | 8 ++++++++ examples/go.sum | 28 ++++++++++++++++++++++++---- examples/secure_store.go | 27 +++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 examples/secure_store.go diff --git a/examples/go.mod b/examples/go.mod index 46884b3a..cb09e42f 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -14,11 +14,16 @@ require ( ) require ( + github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect + github.com/99designs/keyring v1.2.2 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/danieljoos/wincred v1.2.0 // indirect + github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/go-logr/logr v1.2.0 // indirect + github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.4.1 // indirect github.com/golang/glog v1.0.0 // indirect @@ -27,11 +32,13 @@ require ( github.com/google/gofuzz v1.1.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/css v1.0.0 // indirect + github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/microcosm-cc/bluemonday v1.0.18 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mtibben/percent v0.2.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect @@ -39,6 +46,7 @@ require ( golang.org/x/net v0.19.0 // indirect golang.org/x/oauth2 v0.15.0 // indirect golang.org/x/sys v0.15.0 // indirect + golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect diff --git a/examples/go.sum b/examples/go.sum index bb2aa6c4..29a5375d 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -31,6 +31,10 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= +github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= +github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -60,10 +64,14 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= +github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0SkRa/eYHgec= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -96,6 +104,8 @@ github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34 github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -169,6 +179,8 @@ github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -229,6 +241,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= +github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -288,12 +302,15 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -310,8 +327,8 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -448,6 +465,8 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -594,8 +613,9 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= diff --git a/examples/secure_store.go b/examples/secure_store.go new file mode 100644 index 00000000..11b86b96 --- /dev/null +++ b/examples/secure_store.go @@ -0,0 +1,27 @@ +package main + +import ( + "fmt" + + "github.com/openshift-online/ocm-sdk-go/authentication/securestore" +) + +func main() { + // Get a list of available backends on the current OS + available := securestore.AvailableBackends() + fmt.Printf("Available backends: %v\n", available) + + // Create bytes + config := []byte("mybytestring") + + // Upsert to keyring + securestore.UpsertConfigToKeyring(config) + + // Upsert again to keyring + config = []byte("mybytestringagain") + securestore.UpsertConfigToKeyring(config) + + // Read bytes back from Keyring + readVal, _ := securestore.GetConfigFromKeyring() + fmt.Printf("Read from keyring: %s\n", string(readVal)) +}