From 5e4f027df8a3c8b120538524a00a63d8144311f4 Mon Sep 17 00:00:00 2001 From: Kumbirai Tanekha Date: Thu, 24 Aug 2023 12:46:14 +0000 Subject: [PATCH 1/4] Disable VCS stamping for dev build --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ec338831..eb009658 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ build: - go build -tags=dev -o ./dev/tmp/ ./cmd/conjur + go build -tags=dev -buildvcs=false -o ./dev/tmp/ ./cmd/conjur test: go test -tags=dev -count=1 -v ./... From 423508be88b1915ef848325f19b71ffd9a1ac6d9 Mon Sep 17 00:00:00 2001 From: Kumbirai Tanekha Date: Thu, 24 Aug 2023 12:47:07 +0000 Subject: [PATCH 2/4] Add test case for rotating logged-in host api key --- cmd/integration/host_integration_test.go | 21 ++++++++++++++++++++- cmd/integration/shared.go | 5 +++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/cmd/integration/host_integration_test.go b/cmd/integration/host_integration_test.go index 7b29345c..2b038b74 100644 --- a/cmd/integration/host_integration_test.go +++ b/cmd/integration/host_integration_test.go @@ -6,15 +6,34 @@ package main import ( "fmt" "testing" + + "github.com/stretchr/testify/assert" ) func TestHostIntegration(t *testing.T) { cli := newConjurTestCLI(t) cli.InitAndLoginAsAdmin(t) + + t.Run("rotate own api key", func(t *testing.T) { + cli.LoginAsHost(t, "bob") + + stdOut, stdErr, err := cli.Run("whoami") + assert.Contains(t, stdOut, `"username": "host/bob"`) + + priorApiKey := "" + stdOut, stdErr, err = cli.Run("host", "rotate-api-key") + assertAPIKeyRotationCmd(t, err, stdOut, stdErr, priorApiKey) + }) + t.Run("rotate host api key", func(t *testing.T) { + cli.LoginAsAdmin(t) + + stdOut, stdErr, err := cli.Run("whoami") + assert.Contains(t, stdOut, `"username": "admin"`) + priorAPIKey := "" - stdOut, stdErr, err := cli.Run("host", "rotate-api-key", "-i", fmt.Sprintf("%s:host:bob", cli.account)) + stdOut, stdErr, err = cli.Run("host", "rotate-api-key", "-i", fmt.Sprintf("%s:host:bob", cli.account)) assertAPIKeyRotationCmd(t, err, stdOut, stdErr, priorAPIKey) priorAPIKey = stdOut diff --git a/cmd/integration/shared.go b/cmd/integration/shared.go index bc12a1f1..521d3014 100644 --- a/cmd/integration/shared.go +++ b/cmd/integration/shared.go @@ -85,6 +85,11 @@ func (cli *testConjurCLI) LoginAsAdmin(t *testing.T) { assertLoginCmd(t, err, stdOut, stdErr) } +func (cli *testConjurCLI) LoginAsHost(t *testing.T, host string) { + stdOut, stdErr, err := cli.Run("login", "-i", "host/" + host, "-p", makeDevRequest("retrieve_api_key", map[string]string{"role_id": cli.account + ":host:" + host})) + assertLoginCmd(t, err, stdOut, stdErr) +} + func (cli *testConjurCLI) LoadPolicy(t *testing.T, policyText string) { stdOut, stdErr, err := cli.RunWithStdin( bytes.NewReader([]byte(policyText)), From 59e339bce461f2d034d3eeaf916a5048891b67ea Mon Sep 17 00:00:00 2001 From: Kumbirai Tanekha Date: Thu, 24 Aug 2023 12:47:37 +0000 Subject: [PATCH 3/4] Implement own api key rotation for host --- cmd/integration/host_integration_test.go | 1 - cmd/integration/shared.go | 2 +- pkg/cmd/host.go | 12 +++++-- pkg/cmd/host_test.go | 46 ++++++++++++++++-------- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/cmd/integration/host_integration_test.go b/cmd/integration/host_integration_test.go index 2b038b74..ced3cf53 100644 --- a/cmd/integration/host_integration_test.go +++ b/cmd/integration/host_integration_test.go @@ -14,7 +14,6 @@ func TestHostIntegration(t *testing.T) { cli := newConjurTestCLI(t) cli.InitAndLoginAsAdmin(t) - t.Run("rotate own api key", func(t *testing.T) { cli.LoginAsHost(t, "bob") diff --git a/cmd/integration/shared.go b/cmd/integration/shared.go index 521d3014..c99058c3 100644 --- a/cmd/integration/shared.go +++ b/cmd/integration/shared.go @@ -86,7 +86,7 @@ func (cli *testConjurCLI) LoginAsAdmin(t *testing.T) { } func (cli *testConjurCLI) LoginAsHost(t *testing.T, host string) { - stdOut, stdErr, err := cli.Run("login", "-i", "host/" + host, "-p", makeDevRequest("retrieve_api_key", map[string]string{"role_id": cli.account + ":host:" + host})) + stdOut, stdErr, err := cli.Run("login", "-i", "host/"+host, "-p", makeDevRequest("retrieve_api_key", map[string]string{"role_id": cli.account + ":host:" + host})) assertLoginCmd(t, err, stdOut, stdErr) } diff --git a/pkg/cmd/host.go b/pkg/cmd/host.go index cb812631..d62ca533 100644 --- a/pkg/cmd/host.go +++ b/pkg/cmd/host.go @@ -8,6 +8,7 @@ import ( type hostClient interface { RotateHostAPIKey(hostID string) ([]byte, error) + RotateCurrentUserAPIKey() ([]byte, error) } type hostClientFactoryFunc func(*cobra.Command) (hostClient, error) @@ -35,9 +36,10 @@ func newHostRotateAPIKeyCmd(clientFactory hostClientFactoryFunc) *cobra.Command cmd := &cobra.Command{ Use: "rotate-api-key", Short: "Rotate a host's API key", - Long: `Rotate the API key of the host specified by the [id] parameter. + Long: `Rotate the API key of the host specified by the [id] parameter or for the currently logged-in host if no [id] is provided. Examples: +- conjur host rotate-api-key - conjur host rotate-api-key --id ci-staging - conjur host rotate-api-key --id host:ci-staging - conjur host rotate-api-key --id dev:host:ci-staging`, @@ -54,7 +56,13 @@ Examples: return err } - newAPIKey, err := client.RotateHostAPIKey(hostID) + var newAPIKey []byte + if hostID == "" { + newAPIKey, err = client.RotateCurrentUserAPIKey() + } else { + newAPIKey, err = client.RotateHostAPIKey(hostID) + } + if err != nil { return err } diff --git a/pkg/cmd/host_test.go b/pkg/cmd/host_test.go index 290e2da2..4ae16100 100644 --- a/pkg/cmd/host_test.go +++ b/pkg/cmd/host_test.go @@ -9,20 +9,26 @@ import ( ) type mockHostClient struct { - t *testing.T - hostRotateAPIKey func(*testing.T, string) ([]byte, error) + t *testing.T + rotateCurrentUserAPIKey func() ([]byte, error) + rotateHostAPIKey func(*testing.T, string) ([]byte, error) +} + +func (m mockHostClient) RotateCurrentUserAPIKey() ([]byte, error) { + return m.rotateCurrentUserAPIKey() } func (m mockHostClient) RotateHostAPIKey(hostID string) ([]byte, error) { - return m.hostRotateAPIKey(m.t, hostID) + return m.rotateHostAPIKey(m.t, hostID) } -var hostRotateAPIKeyCmdTestCases = []struct { - name string - args []string - hostRotateAPIKey func(t *testing.T, hostID string) ([]byte, error) - clientFactoryError error - assert func(t *testing.T, stdout, stderr string, err error) +var rotateHostAPIKeyCmdTestCases = []struct { + name string + args []string + rotateCurrentUserAPIKey func() ([]byte, error) + rotateHostAPIKey func(t *testing.T, hostID string) ([]byte, error) + clientFactoryError error + assert func(t *testing.T, stdout, stderr string, err error) }{ { name: "without subcommand", @@ -39,9 +45,19 @@ var hostRotateAPIKeyCmdTestCases = []struct { }, }, { - name: "successful rotation", + name: "rotate API key for logged in host", + args: []string{"host", "rotate-api-key"}, + rotateCurrentUserAPIKey: func() ([]byte, error) { + return []byte("test-api-key"), nil + }, + assert: func(t *testing.T, stdout, stderr string, err error) { + assert.Contains(t, stdout, "test-api-key") + }, + }, + { + name: "rotate API key for specified host", args: []string{"host", "rotate-api-key", "--id=dev-host"}, - hostRotateAPIKey: func(t *testing.T, hostID string) ([]byte, error) { + rotateHostAPIKey: func(t *testing.T, hostID string) ([]byte, error) { // Assert on arguments assert.Equal(t, "dev-host", hostID) @@ -54,7 +70,7 @@ var hostRotateAPIKeyCmdTestCases = []struct { { name: "client error", args: []string{"host", "rotate-api-key", "--id=dev-host"}, - hostRotateAPIKey: func(t *testing.T, hostID string) ([]byte, error) { + rotateHostAPIKey: func(t *testing.T, hostID string) ([]byte, error) { return nil, fmt.Errorf("%s", "an error") }, assert: func(t *testing.T, stdout, stderr string, err error) { @@ -71,10 +87,10 @@ var hostRotateAPIKeyCmdTestCases = []struct { }, } -func TestHostRotateAPIKeyCmd(t *testing.T) { - for _, tc := range hostRotateAPIKeyCmdTestCases { +func TestRotateHostAPIKeyCmd(t *testing.T) { + for _, tc := range rotateHostAPIKeyCmdTestCases { t.Run(tc.name, func(t *testing.T) { - mockClient := mockHostClient{t: t, hostRotateAPIKey: tc.hostRotateAPIKey} + mockClient := mockHostClient{t: t, rotateHostAPIKey: tc.rotateHostAPIKey, rotateCurrentUserAPIKey: tc.rotateCurrentUserAPIKey} cmd := newHostCmd( func(cmd *cobra.Command) (hostClient, error) { From e9e6d01459725c616b9453b49896ed964251a7b5 Mon Sep 17 00:00:00 2001 From: Kumbirai Tanekha Date: Fri, 25 Aug 2023 16:19:24 +0000 Subject: [PATCH 4/4] Update CHANGELOG.md --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 029b5e6c..b124a429 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Nothing should go in this section, please add to the latest unreleased version (and update the corresponding date), or add a new version. -## [8.0.11] - 2023-07-27 +## [8.0.11] - 2023-08-25 + +### Fixed +- Handle trailing slash on appliance URL + [cyberark/conjur-cli-go#142](https://github.com/cyberark/conjur-cli-go/pull/142) +- Allow API key rotation for logged-in host + [cyberark/conjur-cli-go#143](https://github.com/cyberark/conjur-cli-go/pull/143) ## [8.0.10] - 2023-06-29