mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-06 06:37:02 +02:00
VAULT-24437 Address OpenAPI endpoint ignoring redact_version listener parameter (#26607)
* VAULT-24437 Address OpenAPI endpoint ignoring redact_version listener parameter * VAULT-24437 changelog * VAULT-24437 changelog mistake
This commit is contained in:
parent
5369aa88b0
commit
b896dc1610
3
changelog/26607.txt
Normal file
3
changelog/26607.txt
Normal file
@ -0,0 +1,3 @@
|
||||
```release-note:bug
|
||||
core: Fix `redact_version` listener parameter being ignored for some OpenAPI related endpoints.
|
||||
```
|
@ -4,8 +4,16 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-cleanhttp"
|
||||
"github.com/hashicorp/vault/helper/testhelpers/corehelpers"
|
||||
"github.com/hashicorp/vault/internalshared/configutil"
|
||||
"github.com/hashicorp/vault/sdk/helper/consts"
|
||||
"github.com/hashicorp/vault/vault"
|
||||
"github.com/hashicorp/vault/version"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@ -157,3 +165,109 @@ func TestOptions_WithRedactVersion(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestRedactVersionListener tests that the version will be redacted
|
||||
// from e.g. sys/health and the OpenAPI response if `redact_version`
|
||||
// is set on the listener.
|
||||
func TestRedactVersionListener(t *testing.T) {
|
||||
conf := &vault.CoreConfig{
|
||||
EnableUI: false,
|
||||
EnableRaw: true,
|
||||
BuiltinRegistry: corehelpers.NewMockBuiltinRegistry(),
|
||||
}
|
||||
core, _, token := vault.TestCoreUnsealedWithConfig(t, conf)
|
||||
|
||||
// Setup listener without redaction
|
||||
ln, addr := TestListener(t)
|
||||
props := &vault.HandlerProperties{
|
||||
Core: core,
|
||||
ListenerConfig: &configutil.Listener{
|
||||
RedactVersion: false,
|
||||
},
|
||||
}
|
||||
TestServerWithListenerAndProperties(t, ln, addr, core, props)
|
||||
defer ln.Close()
|
||||
TestServerAuth(t, addr, token)
|
||||
|
||||
testRedactVersionEndpoints(t, addr, token, version.Version)
|
||||
|
||||
// Setup listener with redaction
|
||||
ln, addr = TestListener(t)
|
||||
props.ListenerConfig.RedactVersion = true
|
||||
TestServerWithListenerAndProperties(t, ln, addr, core, props)
|
||||
defer ln.Close()
|
||||
TestServerAuth(t, addr, token)
|
||||
|
||||
testRedactVersionEndpoints(t, addr, token, "")
|
||||
}
|
||||
|
||||
// testRedactVersionEndpoints tests the endpoints containing versions
|
||||
// contain the expected version
|
||||
func testRedactVersionEndpoints(t *testing.T, addr, token, expectedVersion string) {
|
||||
client := cleanhttp.DefaultClient()
|
||||
req, err := http.NewRequest("GET", addr+"/v1/auth/token?help=1", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
req.Header.Set(consts.AuthHeaderName, token)
|
||||
resp, err := client.Do(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
testResponseStatus(t, resp, 200)
|
||||
|
||||
var actual map[string]interface{}
|
||||
testResponseBody(t, resp, &actual)
|
||||
|
||||
require.NotNil(t, actual["openapi"])
|
||||
openAPI, ok := actual["openapi"].(map[string]interface{})
|
||||
require.True(t, ok)
|
||||
|
||||
require.NotNil(t, openAPI["info"])
|
||||
info, ok := openAPI["info"].(map[string]interface{})
|
||||
require.True(t, ok)
|
||||
|
||||
require.NotNil(t, info["version"])
|
||||
version, ok := info["version"].(string)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, expectedVersion, version)
|
||||
|
||||
req, err = http.NewRequest("GET", addr+"/v1/sys/internal/specs/openapi", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
req.Header.Set(consts.AuthHeaderName, "")
|
||||
resp, err = client.Do(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
testResponseStatus(t, resp, 200)
|
||||
testResponseBody(t, resp, &actual)
|
||||
|
||||
require.NotNil(t, actual["info"])
|
||||
info, ok = openAPI["info"].(map[string]interface{})
|
||||
require.True(t, ok)
|
||||
|
||||
require.NotNil(t, info["version"])
|
||||
version, ok = info["version"].(string)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, expectedVersion, version)
|
||||
|
||||
req, err = http.NewRequest("GET", addr+"/v1/sys/health", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
req.Header.Set(consts.AuthHeaderName, "")
|
||||
resp, err = client.Do(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
testResponseStatus(t, resp, 200)
|
||||
testResponseBody(t, resp, &actual)
|
||||
|
||||
require.NotNil(t, actual["version"])
|
||||
version, ok = actual["version"].(string)
|
||||
require.True(t, ok)
|
||||
|
||||
// sys/health is special and uses a different format to the OpenAPI
|
||||
// version.GetVersion().VersionNumber() instead of version.Version
|
||||
// We use substring to make sure the check works anyway.
|
||||
// In practice, version.GetVersion().VersionNumber() will give something like 1.17.0-beta1
|
||||
// and version.Version gives something like 1.17.0
|
||||
require.Truef(t, strings.HasPrefix(version, expectedVersion), "version was not as expected, version=%s, expectedVersion=%s",
|
||||
version, expectedVersion)
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ func (b *Backend) HandleRequest(ctx context.Context, req *logical.Request) (*log
|
||||
|
||||
// If the path is empty and it is a help operation, handle that.
|
||||
if req.Path == "" && req.Operation == logical.HelpOperation {
|
||||
return b.handleRootHelp(req)
|
||||
return b.handleRootHelp(ctx, req)
|
||||
}
|
||||
|
||||
// Find the matching route
|
||||
@ -548,7 +548,7 @@ func (b *Backend) route(path string) (*Path, map[string]string) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (b *Backend) handleRootHelp(req *logical.Request) (*logical.Response, error) {
|
||||
func (b *Backend) handleRootHelp(ctx context.Context, req *logical.Request) (*logical.Response, error) {
|
||||
// Build a mapping of the paths and get the paths alphabetized to
|
||||
// make the output prettier.
|
||||
pathsMap := make(map[string]*Path)
|
||||
@ -596,6 +596,10 @@ func (b *Backend) handleRootHelp(req *logical.Request) (*logical.Response, error
|
||||
vaultVersion = env.VaultVersion
|
||||
}
|
||||
|
||||
redactVersion, _, _, _ := logical.CtxRedactionSettingsValue(ctx)
|
||||
if redactVersion {
|
||||
vaultVersion = ""
|
||||
}
|
||||
doc := NewOASDocument(vaultVersion)
|
||||
if err := documentPaths(b, requestResponsePrefix, doc); err != nil {
|
||||
b.Logger().Warn("error generating OpenAPI", "error", err)
|
||||
|
@ -384,6 +384,10 @@ func (p *Path) helpCallback(b *Backend) OperationFunc {
|
||||
vaultVersion = env.VaultVersion
|
||||
}
|
||||
}
|
||||
redactVersion, _, _, _ := logical.CtxRedactionSettingsValue(ctx)
|
||||
if redactVersion {
|
||||
vaultVersion = ""
|
||||
}
|
||||
doc := NewOASDocument(vaultVersion)
|
||||
if err := documentPath(p, b, requestResponsePrefix, doc); err != nil {
|
||||
b.Logger().Warn("error generating OpenAPI", "error", err)
|
||||
|
@ -5259,8 +5259,14 @@ func (b *SystemBackend) pathInternalOpenAPI(ctx context.Context, req *logical.Re
|
||||
|
||||
context := d.Get("context").(string)
|
||||
|
||||
vaultVersion := version.Version
|
||||
redactVersion, _, _, _ := logical.CtxRedactionSettingsValue(ctx)
|
||||
if redactVersion {
|
||||
vaultVersion = ""
|
||||
}
|
||||
|
||||
// Set up target document
|
||||
doc := framework.NewOASDocument(version.Version)
|
||||
doc := framework.NewOASDocument(vaultVersion)
|
||||
|
||||
// Generic mount paths will primarily be used for code generation purposes.
|
||||
// This will result in parameterized mount paths being returned instead of
|
||||
|
Loading…
Reference in New Issue
Block a user