diff --git a/go.mod b/go.mod index 05302c71..77ebbc60 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ go 1.19 // replace github.com/cyberark/conjur-api-go => ./conjur-api-go require ( - github.com/cyberark/conjur-api-go v0.10.3-0.20230110163356-49b3ca82eaed // Run "go get github.com/cyberark/conjur-api-go@main" to update + github.com/cyberark/conjur-api-go v0.10.3-0.20230125184231-3582065a6c70 // Run "go get github.com/cyberark/conjur-api-go@main" to update github.com/manifoldco/promptui v0.9.0 github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 github.com/spf13/cobra v1.5.0 diff --git a/go.sum b/go.sum index d9b59522..8613352d 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWs github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyberark/conjur-api-go v0.10.3-0.20230110163356-49b3ca82eaed h1:A8A/58MnhECT6Yq0AuE6vTwp1xZBYxI/sbljl+Av3gw= -github.com/cyberark/conjur-api-go v0.10.3-0.20230110163356-49b3ca82eaed/go.mod h1:8+qYC7L6wPY1e56hoZmHSdGa2fHALck8PtS+cUky75Y= +github.com/cyberark/conjur-api-go v0.10.3-0.20230125184231-3582065a6c70 h1:MtcIHz9Ayu/yEbYfHGj/uuhq/ozYNPOMg5WEPDxrHA0= +github.com/cyberark/conjur-api-go v0.10.3-0.20230125184231-3582065a6c70/go.mod h1:TYds39qj4L37XE/kXoeb4O5t95MdTsXAFD/6ilGppwg= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/pkg/clients/clients.go b/pkg/clients/clients.go index c22ff353..6a248fd8 100644 --- a/pkg/clients/clients.go +++ b/pkg/clients/clients.go @@ -23,7 +23,8 @@ type ConjurClient interface { LoadPolicy(mode conjurapi.PolicyMode, policyID string, policy io.Reader) (*conjurapi.PolicyResponse, error) AddSecret(variableID string, secretValue string) error RetrieveSecret(variableID string) ([]byte, error) - CheckPermission(resourceID string, roleID string, privilege string) (bool, error) + CheckPermission(resourceID string, privilege string) (bool, error) + CheckPermissionForRole(resourceID string, roleID string, privilege string) (bool, error) ResourceExists(resourceID string) (bool, error) Resource(resourceID string) (resource map[string]interface{}, err error) ResourceIDs(filter *conjurapi.ResourceFilter) ([]string, error) diff --git a/pkg/cmd/check.go b/pkg/cmd/check.go index 25543781..829380c9 100644 --- a/pkg/cmd/check.go +++ b/pkg/cmd/check.go @@ -6,7 +6,8 @@ import ( ) type checkClient interface { - CheckPermission(resourceID string, roleID string, privilege string) (bool, error) + CheckPermission(resourceID string, privilege string) (bool, error) + CheckPermissionForRole(resourceID string, roleID string, privilege string) (bool, error) } type checkClientFactoryFunc func(*cobra.Command) (checkClient, error) @@ -21,12 +22,17 @@ func newCheckCmd(clientFactory checkClientFactoryFunc) *cobra.Command { Short: "Check a role's privilege on a resource", Long: `Check a role's privilege on a resource - This command requires a [resource-id] and a [privilege], and includes an - optional [-r|--role] flag to specify a particular role. +This command requires a [resource-id] and a [privilege]. + +By default, this command checks if the currently authenticated +user has privilege over the resource. When the optional [-r|--role] +flag is provided, the command checks if the specified role has +privilege over the resource. Examples: - conjur check dev:host:somehost write +- conjur check -r user:someuser dev:variable:somevariable read - conjur check -r dev:user:someuser dev:variable:somevariable read`, RunE: func(cmd *cobra.Command, args []string) error { var resourceID string @@ -49,7 +55,13 @@ Examples: return err } - result, err := client.CheckPermission(resourceID, roleID, privilege) + var result bool + + if len(roleID) == 0 { + result, err = client.CheckPermission(resourceID, privilege) + } else { + result, err = client.CheckPermissionForRole(resourceID, roleID, privilege) + } if err != nil { return err } @@ -60,7 +72,7 @@ Examples: }, } - cmd.Flags().StringP("role", "r", "", "Check a role's privilege on a resource") + cmd.Flags().StringP("role", "r", "", "Partially- or fully-qualified role ID to check privilege for") return cmd } diff --git a/pkg/cmd/check_test.go b/pkg/cmd/check_test.go index c85816f4..ad8b6436 100644 --- a/pkg/cmd/check_test.go +++ b/pkg/cmd/check_test.go @@ -9,20 +9,26 @@ import ( ) type mockCheckClient struct { - t *testing.T - checkPermission func(t *testing.T, resourceID string, roleID, stringprivilege string) (bool, error) + t *testing.T + checkPermission func(t *testing.T, resourceID string, privilege string) (bool, error) + checkPermissionForRole func(t *testing.T, resourceID string, roleID string, privilege string) (bool, error) } -func (m mockCheckClient) CheckPermission(resourceID string, roleID string, privilege string) (bool, error) { - return m.checkPermission(m.t, resourceID, roleID, privilege) +func (m mockCheckClient) CheckPermission(resourceID string, privilege string) (bool, error) { + return m.checkPermission(m.t, resourceID, privilege) +} + +func (m mockCheckClient) CheckPermissionForRole(resourceID string, roleID string, privilege string) (bool, error) { + return m.checkPermissionForRole(m.t, resourceID, roleID, privilege) } var checkCmdTestCases = []struct { - name string - args []string - checkPermission func(t *testing.T, resourceID string, roleID string, privilege string) (bool, error) - clientFactoryError error - assert func(t *testing.T, stdout string, stderr string, err error) + name string + args []string + checkPermission func(t *testing.T, resourceID string, privilege string) (bool, error) + checkPermissionForRole func(t *testing.T, resourceID string, roleID string, privilege string) (bool, error) + clientFactoryError error + assert func(t *testing.T, stdout string, stderr string, err error) }{ { name: "check help", @@ -62,7 +68,7 @@ var checkCmdTestCases = []struct { { name: "check returns true for default admin role", args: []string{"check", "dev:variable:secret", "read"}, - checkPermission: func(t *testing.T, resourceID string, roleID string, privilege string) (bool, error) { + checkPermission: func(t *testing.T, resourceID string, privilege string) (bool, error) { assert.Equal(t, "dev:variable:secret", resourceID) assert.Equal(t, "read", privilege) @@ -75,7 +81,7 @@ var checkCmdTestCases = []struct { { name: "check returns false for default admin role", args: []string{"check", "dev:variable:secret", "write"}, - checkPermission: func(t *testing.T, resourceID string, roleID string, privilege string) (bool, error) { + checkPermission: func(t *testing.T, resourceID string, privilege string) (bool, error) { assert.Equal(t, "dev:variable:secret", resourceID) assert.Equal(t, "write", privilege) @@ -88,7 +94,7 @@ var checkCmdTestCases = []struct { { name: "check returns true for specific role", args: []string{"check", "-r", "dev:user:alice", "dev:variable:secret", "read"}, - checkPermission: func(t *testing.T, resourceID string, roleID string, privilege string) (bool, error) { + checkPermissionForRole: func(t *testing.T, resourceID string, roleID string, privilege string) (bool, error) { assert.Equal(t, "dev:variable:secret", resourceID) assert.Equal(t, "dev:user:alice", roleID) assert.Equal(t, "read", privilege) @@ -102,7 +108,7 @@ var checkCmdTestCases = []struct { { name: "check returns false for specific role", args: []string{"check", "-r", "dev:user:alice", "dev:variable:secret", "write"}, - checkPermission: func(t *testing.T, resourceID string, roleID string, privilege string) (bool, error) { + checkPermissionForRole: func(t *testing.T, resourceID string, roleID string, privilege string) (bool, error) { assert.Equal(t, "dev:variable:secret", resourceID) assert.Equal(t, "dev:user:alice", roleID) assert.Equal(t, "write", privilege) @@ -116,7 +122,7 @@ var checkCmdTestCases = []struct { { name: "check client error", args: []string{"check", "abcdefg", "hijklmn"}, - checkPermission: func(t *testing.T, resourceID string, roleID string, privilege string) (bool, error) { + checkPermission: func(t *testing.T, resourceID string, privilege string) (bool, error) { return false, fmt.Errorf("%s", "an error") }, assert: func(t *testing.T, stdout, stderr string, err error) { @@ -136,7 +142,11 @@ var checkCmdTestCases = []struct { func TestCheckCmd(t *testing.T) { for _, tc := range checkCmdTestCases { t.Run(tc.name, func(t *testing.T) { - mockClient := mockCheckClient{t: t, checkPermission: tc.checkPermission} + mockClient := mockCheckClient{ + t: t, + checkPermission: tc.checkPermission, + checkPermissionForRole: tc.checkPermissionForRole, + } cmd := newCheckCmd( func(cmd *cobra.Command) (checkClient, error) {