From 9b5b9f6fdcab49530155d92048b42bb426882119 Mon Sep 17 00:00:00 2001 From: Jeremy Jacobson Date: Tue, 1 Aug 2023 19:05:46 +0000 Subject: [PATCH 1/4] backport of commit 1a9cded960965d615a3a2146a4fef656839b1e34 --- agent/acl_endpoint.go | 7 +++ command/acl/acl_helpers.go | 8 +++- command/acl/acl_test.go | 88 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 command/acl/acl_test.go diff --git a/agent/acl_endpoint.go b/agent/acl_endpoint.go index d6f230a8f64..60aa13a1490 100644 --- a/agent/acl_endpoint.go +++ b/agent/acl_endpoint.go @@ -6,6 +6,7 @@ package agent import ( "fmt" "net/http" + "net/url" "strings" "github.com/hashicorp/consul/acl" @@ -145,6 +146,12 @@ func (s *HTTPHandlers) ACLPolicyCRUD(resp http.ResponseWriter, req *http.Request } func (s *HTTPHandlers) ACLPolicyRead(resp http.ResponseWriter, req *http.Request, policyID, policyName string) (interface{}, error) { + // policy name needs to be unescaped in case there were `/` characters + policyName, err := url.QueryUnescape(policyName) + if err != nil { + return nil, err + } + args := structs.ACLPolicyGetRequest{ Datacenter: s.agent.config.Datacenter, PolicyID: policyID, diff --git a/command/acl/acl_helpers.go b/command/acl/acl_helpers.go index 0a6545be1af..644fb0a4027 100644 --- a/command/acl/acl_helpers.go +++ b/command/acl/acl_helpers.go @@ -45,9 +45,13 @@ func GetTokenAccessorIDFromPartial(client *api.Client, partialAccessorID string) } func GetPolicyIDFromPartial(client *api.Client, partialID string) (string, error) { - if partialID == "global-management" { - return structs.ACLPolicyGlobalManagementID, nil + // try the builtin policies (by name) first + for _, policy := range structs.ACLBuiltinPolicies { + if partialID == policy.Name { + return policy.ID, nil + } } + // The full UUID string was given if len(partialID) == 36 { return partialID, nil diff --git a/command/acl/acl_test.go b/command/acl/acl_test.go new file mode 100644 index 00000000000..e04dbd0b5c8 --- /dev/null +++ b/command/acl/acl_test.go @@ -0,0 +1,88 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package acl + +import ( + "io" + "testing" + + "github.com/hashicorp/consul/agent" + "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/testrpc" + "github.com/stretchr/testify/require" +) + +func Test_GetPolicyIDByName_Builtins(t *testing.T) { + t.Parallel() + + a := agent.StartTestAgent(t, + agent.TestAgent{ + LogOutput: io.Discard, + HCL: ` + primary_datacenter = "dc1" + acl { + enabled = true + tokens { + initial_management = "root" + } + } + `, + }, + ) + + defer a.Shutdown() + testrpc.WaitForTestAgent(t, a.RPC, "dc1", testrpc.WithToken("root")) + + client := a.Client() + client.AddHeader("X-Consul-Token", "root") + + t.Run("global management policy", func(t *testing.T) { + id, err := GetPolicyIDByName(client, structs.ACLPolicyGlobalManagementName) + require.NoError(t, err) + require.Equal(t, structs.ACLPolicyGlobalManagementID, id) + }) + + t.Run("global read-only policy", func(t *testing.T) { + id, err := GetPolicyIDByName(client, structs.ACLPolicyGlobalReadOnlyName) + require.NoError(t, err) + require.Equal(t, structs.ACLPolicyGlobalReadOnlyID, id) + }) +} + +func Test_GetPolicyIDFromPartial_Builtins(t *testing.T) { + t.Parallel() + + a := agent.StartTestAgent(t, + agent.TestAgent{ + LogOutput: io.Discard, + HCL: ` + primary_datacenter = "dc1" + acl { + enabled = true + tokens { + initial_management = "root" + } + } + `, + }, + ) + + defer a.Shutdown() + testrpc.WaitForTestAgent(t, a.RPC, "dc1", testrpc.WithToken("root")) + + client := a.Client() + client.AddHeader("X-Consul-Token", "root") + + t.Run("global management policy", func(t *testing.T) { + id, err := GetPolicyIDFromPartial(client, structs.ACLPolicyGlobalManagementName) + require.NoError(t, err) + require.Equal(t, structs.ACLPolicyGlobalManagementID, id) + }) + + t.Run("global read-only policy", func(t *testing.T) { + id, err := GetPolicyIDFromPartial(client, structs.ACLPolicyGlobalReadOnlyName) + require.NoError(t, err) + require.Equal(t, structs.ACLPolicyGlobalReadOnlyID, id) + }) +} From ba49e08adaf127014c020531e42d19ac452c3145 Mon Sep 17 00:00:00 2001 From: Jeremy Jacobson Date: Thu, 3 Aug 2023 19:51:54 +0000 Subject: [PATCH 2/4] backport of commit cfec746d8b2d0b47b4aa66c951defa135f8791de --- command/acl/acl_helpers.go | 6 ++---- command/acl/acl_test.go | 20 +++++++++----------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/command/acl/acl_helpers.go b/command/acl/acl_helpers.go index 644fb0a4027..2e6bc86dd23 100644 --- a/command/acl/acl_helpers.go +++ b/command/acl/acl_helpers.go @@ -46,10 +46,8 @@ func GetTokenAccessorIDFromPartial(client *api.Client, partialAccessorID string) func GetPolicyIDFromPartial(client *api.Client, partialID string) (string, error) { // try the builtin policies (by name) first - for _, policy := range structs.ACLBuiltinPolicies { - if partialID == policy.Name { - return policy.ID, nil - } + if policy, ok := structs.ACLBuiltinPolicies[partialID]; ok { + return policy.ID, nil } // The full UUID string was given diff --git a/command/acl/acl_test.go b/command/acl/acl_test.go index e04dbd0b5c8..764fc35e7d5 100644 --- a/command/acl/acl_test.go +++ b/command/acl/acl_test.go @@ -4,6 +4,7 @@ package acl import ( + "fmt" "io" "testing" @@ -37,17 +38,14 @@ func Test_GetPolicyIDByName_Builtins(t *testing.T) { client := a.Client() client.AddHeader("X-Consul-Token", "root") - t.Run("global management policy", func(t *testing.T) { - id, err := GetPolicyIDByName(client, structs.ACLPolicyGlobalManagementName) - require.NoError(t, err) - require.Equal(t, structs.ACLPolicyGlobalManagementID, id) - }) - - t.Run("global read-only policy", func(t *testing.T) { - id, err := GetPolicyIDByName(client, structs.ACLPolicyGlobalReadOnlyName) - require.NoError(t, err) - require.Equal(t, structs.ACLPolicyGlobalReadOnlyID, id) - }) + for _, policy := range structs.ACLBuiltinPolicies { + name := fmt.Sprintf("%s policy", policy.Name) + t.Run(name, func(t *testing.T) { + id, err := GetPolicyIDByName(client, policy.Name) + require.NoError(t, err) + require.Equal(t, policy.ID, id) + }) + } } func Test_GetPolicyIDFromPartial_Builtins(t *testing.T) { From 58bf6da14c6a0ff6b80b76d35cbf499a996e3bfe Mon Sep 17 00:00:00 2001 From: Jeremy Jacobson Date: Thu, 3 Aug 2023 19:52:42 +0000 Subject: [PATCH 3/4] backport of commit 8a9db4cffc557641f9209770c6134086f25322af --- command/acl/acl_test.go | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/command/acl/acl_test.go b/command/acl/acl_test.go index 764fc35e7d5..2095795ff00 100644 --- a/command/acl/acl_test.go +++ b/command/acl/acl_test.go @@ -72,15 +72,12 @@ func Test_GetPolicyIDFromPartial_Builtins(t *testing.T) { client := a.Client() client.AddHeader("X-Consul-Token", "root") - t.Run("global management policy", func(t *testing.T) { - id, err := GetPolicyIDFromPartial(client, structs.ACLPolicyGlobalManagementName) - require.NoError(t, err) - require.Equal(t, structs.ACLPolicyGlobalManagementID, id) - }) - - t.Run("global read-only policy", func(t *testing.T) { - id, err := GetPolicyIDFromPartial(client, structs.ACLPolicyGlobalReadOnlyName) - require.NoError(t, err) - require.Equal(t, structs.ACLPolicyGlobalReadOnlyID, id) - }) + for _, policy := range structs.ACLBuiltinPolicies { + name := fmt.Sprintf("%s policy", policy.Name) + t.Run(name, func(t *testing.T) { + id, err := GetPolicyIDFromPartial(client, policy.Name) + require.NoError(t, err) + require.Equal(t, policy.ID, id) + }) + } } From aa61b5dac031f2429e6760e4c127a5f1fad3d1fa Mon Sep 17 00:00:00 2001 From: Jeremy Jacobson Date: Thu, 3 Aug 2023 19:56:42 +0000 Subject: [PATCH 4/4] backport of commit ac13bf16d6b5f853c26003cf088ff03988d8e235 --- command/acl/acl_helpers.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/command/acl/acl_helpers.go b/command/acl/acl_helpers.go index 2e6bc86dd23..b0e65d224c7 100644 --- a/command/acl/acl_helpers.go +++ b/command/acl/acl_helpers.go @@ -46,6 +46,12 @@ func GetTokenAccessorIDFromPartial(client *api.Client, partialAccessorID string) func GetPolicyIDFromPartial(client *api.Client, partialID string) (string, error) { // try the builtin policies (by name) first + for _, policy := range structs.ACLBuiltinPolicies { + if partialID == policy.Name { + return policy.ID, nil + } + } + if policy, ok := structs.ACLBuiltinPolicies[partialID]; ok { return policy.ID, nil }