consul/acl/authorizer_test.go

500 lines
9.1 KiB
Go
Raw Normal View History

// Copyright (c) HashiCorp, Inc.
[COMPLIANCE] License changes (#18443) * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Updating the license from MPL to Business Source License Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at <Blog URL>, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl. * add missing license headers * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
2023-08-11 13:12:13 +00:00
// SPDX-License-Identifier: BUSL-1.1
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: "IdentityRead",
resource: ResourceIdentity,
segment: "foo",
access: "read",
ret: Deny,
},
{
method: "IdentityRead",
resource: ResourceIdentity,
segment: "foo",
access: "read",
ret: Allow,
},
{
method: "IdentityWrite",
resource: ResourceIdentity,
segment: "foo",
access: "write",
ret: Deny,
},
{
method: "IdentityWrite",
resource: ResourceIdentity,
segment: "foo",
access: "write",
ret: Allow,
},
{
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) {
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 20:35:12 +00:00
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)
})
}
}