open-consul/acl/authorizer_test.go
Dhia Ayachi 219a3c5bd3
Leadership transfer cmd (#14132)
* add leadership transfer command

* add RPC call test (flaky)

* add missing import

* add changelog

* add command registration

* Apply suggestions from code review

Co-authored-by: Matt Keeler <mkeeler@users.noreply.github.com>

* add the possibility of providing an id to raft leadership transfer. Add few tests.

* delete old file from cherry pick

* rename changelog filename to PR #

* rename changelog and fix import

* fix failing test

* check for OperatorWrite

Co-authored-by: Matt Keeler <mkeeler@users.noreply.github.com>

* rename from leader-transfer to transfer-leader

* remove version check and add test for operator read

* move struct to operator.go

* first pass

* add code for leader transfer in the grpc backend and tests

* wire the http endpoint to the new grpc endpoint

* remove the RPC endpoint

* remove non needed struct

* fix naming

* add mog glue to API

* fix comment

* remove dead code

* fix linter error

* change package name for proto file

* remove error wrapping

* fix failing test

* add command registration

* add grpc service mock tests

* fix receiver to be pointer

* use defined values

Co-authored-by: Matt Keeler <mkeeler@users.noreply.github.com>

* reuse MockAclAuthorizer

* add documentation

* remove usage of external.TokenFromContext

* fix failing tests

* fix proto generation

* Apply suggestions from code review

Co-authored-by: Jared Kirschner <85913323+jkirschner-hashicorp@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Jared Kirschner <85913323+jkirschner-hashicorp@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Jared Kirschner <85913323+jkirschner-hashicorp@users.noreply.github.com>

* Apply suggestions from code review

* add more context in doc for the reason

* Apply suggestions from docs code review

Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com>

* regenerate proto

* fix linter errors

Co-authored-by: github-team-consul-core <github-team-consul-core@hashicorp.com>
Co-authored-by: Matt Keeler <mkeeler@users.noreply.github.com>
Co-authored-by: Jared Kirschner <85913323+jkirschner-hashicorp@users.noreply.github.com>
Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com>
2022-11-14 15:35:12 -05:00

469 lines
8.5 KiB
Go

package acl
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
)
func TestACL_Enforce(t *testing.T) {
type testCase struct {
method string
resource Resource
segment string
access string
ret EnforcementDecision
err string
}
testName := func(t testCase) string {
if t.segment != "" {
return fmt.Sprintf("%s/%s/%s/%s", t.resource, t.segment, t.access, t.ret.String())
}
return fmt.Sprintf("%s/%s/%s", t.resource, t.access, t.ret.String())
}
cases := []testCase{
{
method: "ACLRead",
resource: ResourceACL,
access: "read",
ret: Deny,
},
{
method: "ACLRead",
resource: ResourceACL,
access: "read",
ret: Allow,
},
{
method: "ACLWrite",
resource: ResourceACL,
access: "write",
ret: Deny,
},
{
method: "ACLWrite",
resource: ResourceACL,
access: "write",
ret: Allow,
},
{
resource: ResourceACL,
access: "list",
ret: Deny,
err: "Invalid access level",
},
{
method: "OperatorRead",
resource: ResourceOperator,
access: "read",
ret: Deny,
},
{
method: "OperatorRead",
resource: ResourceOperator,
access: "read",
ret: Allow,
},
{
method: "OperatorWrite",
resource: ResourceOperator,
access: "write",
ret: Deny,
},
{
method: "OperatorWrite",
resource: ResourceOperator,
access: "write",
ret: Allow,
},
{
resource: ResourceOperator,
access: "list",
ret: Deny,
err: "Invalid access level",
},
{
method: "KeyringRead",
resource: ResourceKeyring,
access: "read",
ret: Deny,
},
{
method: "KeyringRead",
resource: ResourceKeyring,
access: "read",
ret: Allow,
},
{
method: "KeyringWrite",
resource: ResourceKeyring,
access: "write",
ret: Deny,
},
{
method: "KeyringWrite",
resource: ResourceKeyring,
access: "write",
ret: Allow,
},
{
resource: ResourceKeyring,
access: "list",
ret: Deny,
err: "Invalid access level",
},
{
method: "AgentRead",
resource: ResourceAgent,
segment: "foo",
access: "read",
ret: Deny,
},
{
method: "AgentRead",
resource: ResourceAgent,
segment: "foo",
access: "read",
ret: Allow,
},
{
method: "AgentWrite",
resource: ResourceAgent,
segment: "foo",
access: "write",
ret: Deny,
},
{
method: "AgentWrite",
resource: ResourceAgent,
segment: "foo",
access: "write",
ret: Allow,
},
{
resource: ResourceAgent,
segment: "foo",
access: "list",
ret: Deny,
err: "Invalid access level",
},
{
method: "EventRead",
resource: ResourceEvent,
segment: "foo",
access: "read",
ret: Deny,
},
{
method: "EventRead",
resource: ResourceEvent,
segment: "foo",
access: "read",
ret: Allow,
},
{
method: "EventWrite",
resource: ResourceEvent,
segment: "foo",
access: "write",
ret: Deny,
},
{
method: "EventWrite",
resource: ResourceEvent,
segment: "foo",
access: "write",
ret: Allow,
},
{
resource: ResourceEvent,
segment: "foo",
access: "list",
ret: Deny,
err: "Invalid access level",
},
{
method: "IntentionRead",
resource: ResourceIntention,
segment: "foo",
access: "read",
ret: Deny,
},
{
method: "IntentionRead",
resource: ResourceIntention,
segment: "foo",
access: "read",
ret: Allow,
},
{
method: "IntentionWrite",
resource: ResourceIntention,
segment: "foo",
access: "write",
ret: Deny,
},
{
method: "IntentionWrite",
resource: ResourceIntention,
segment: "foo",
access: "write",
ret: Allow,
},
{
resource: ResourceIntention,
segment: "foo",
access: "list",
ret: Deny,
err: "Invalid access level",
},
{
method: "NodeRead",
resource: ResourceNode,
segment: "foo",
access: "read",
ret: Deny,
},
{
method: "NodeRead",
resource: ResourceNode,
segment: "foo",
access: "read",
ret: Allow,
},
{
method: "NodeWrite",
resource: ResourceNode,
segment: "foo",
access: "write",
ret: Deny,
},
{
method: "NodeWrite",
resource: ResourceNode,
segment: "foo",
access: "write",
ret: Allow,
},
{
resource: ResourceNode,
segment: "foo",
access: "list",
ret: Deny,
err: "Invalid access level",
},
{
method: "PeeringRead",
resource: ResourcePeering,
access: "read",
ret: Allow,
},
{
method: "PeeringRead",
resource: ResourcePeering,
access: "read",
ret: Deny,
},
{
method: "PeeringWrite",
resource: ResourcePeering,
access: "write",
ret: Allow,
},
{
method: "PeeringWrite",
resource: ResourcePeering,
access: "write",
ret: Deny,
},
{
method: "PreparedQueryRead",
resource: ResourceQuery,
segment: "foo",
access: "read",
ret: Deny,
},
{
method: "PreparedQueryRead",
resource: ResourceQuery,
segment: "foo",
access: "read",
ret: Allow,
},
{
method: "PreparedQueryWrite",
resource: ResourceQuery,
segment: "foo",
access: "write",
ret: Deny,
},
{
method: "PreparedQueryWrite",
resource: ResourceQuery,
segment: "foo",
access: "write",
ret: Allow,
},
{
resource: ResourceQuery,
segment: "foo",
access: "list",
ret: Deny,
err: "Invalid access level",
},
{
method: "ServiceRead",
resource: ResourceService,
segment: "foo",
access: "read",
ret: Deny,
},
{
method: "ServiceRead",
resource: ResourceService,
segment: "foo",
access: "read",
ret: Allow,
},
{
method: "ServiceWrite",
resource: ResourceService,
segment: "foo",
access: "write",
ret: Deny,
},
{
method: "ServiceWrite",
resource: ResourceService,
segment: "foo",
access: "write",
ret: Allow,
},
{
resource: ResourceSession,
segment: "foo",
access: "list",
ret: Deny,
err: "Invalid access level",
},
{
method: "SessionRead",
resource: ResourceSession,
segment: "foo",
access: "read",
ret: Deny,
},
{
method: "SessionRead",
resource: ResourceSession,
segment: "foo",
access: "read",
ret: Allow,
},
{
method: "SessionWrite",
resource: ResourceSession,
segment: "foo",
access: "write",
ret: Deny,
},
{
method: "SessionWrite",
resource: ResourceSession,
segment: "foo",
access: "write",
ret: Allow,
},
{
resource: ResourceSession,
segment: "foo",
access: "list",
ret: Deny,
err: "Invalid access level",
},
{
method: "KeyRead",
resource: ResourceKey,
segment: "foo",
access: "read",
ret: Deny,
},
{
method: "KeyRead",
resource: ResourceKey,
segment: "foo",
access: "read",
ret: Allow,
},
{
method: "KeyWrite",
resource: ResourceKey,
segment: "foo",
access: "write",
ret: Deny,
},
{
method: "KeyWrite",
resource: ResourceKey,
segment: "foo",
access: "write",
ret: Allow,
},
{
method: "KeyList",
resource: ResourceKey,
segment: "foo",
access: "list",
ret: Deny,
},
{
method: "KeyList",
resource: ResourceKey,
segment: "foo",
access: "list",
ret: Allow,
},
{
resource: ResourceKey,
segment: "foo",
access: "deny",
ret: Deny,
err: "Invalid access level",
},
{
resource: "not-a-real-resource",
access: "read",
ret: Deny,
err: "Invalid ACL resource requested:",
},
}
for _, tcase := range cases {
t.Run(testName(tcase), func(t *testing.T) {
m := &MockAuthorizer{}
if tcase.err == "" {
var nilCtx *AuthorizerContext
if tcase.segment != "" {
m.On(tcase.method, tcase.segment, nilCtx).Return(tcase.ret)
} else {
m.On(tcase.method, nilCtx).Return(tcase.ret)
}
}
ret, err := Enforce(m, tcase.resource, tcase.segment, tcase.access, nil)
if tcase.err == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tcase.err)
}
require.Equal(t, tcase.ret, ret)
m.AssertExpectations(t)
})
}
}