-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
VAULT-19863: Per-listener redaction settings (#23534)
* add redaction config settings to listener * sys seal redaction + test modification for default handler properties * build date should be redacted by 'redact_version' too * sys-health redaction + test fiddling * sys-leader redaction * added changelog * Lots of places need ListenerConfig * Renamed options to something more specific for now * tests for listener config options * changelog updated * updates based on PR comments * updates based on PR comments - removed unrequired test case field * fixes for docker tests and potentially server dev mode related flags
- Loading branch information
Peter Wilson
authored
Oct 6, 2023
1 parent
ebef296
commit e5432b0
Showing
13 changed files
with
448 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:feature | ||
config/listener: allow per-listener configuration settings to redact sensitive parts of response to unauthenticated endpoints. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
|
||
package http | ||
|
||
// ListenerConfigOption is how listenerConfigOptions are passed as arguments. | ||
type ListenerConfigOption func(*listenerConfigOptions) error | ||
|
||
// listenerConfigOptions are used to represent configuration of listeners for http handlers. | ||
type listenerConfigOptions struct { | ||
withRedactionValue string | ||
withRedactAddresses bool | ||
withRedactClusterName bool | ||
withRedactVersion bool | ||
} | ||
|
||
// getDefaultOptions returns listenerConfigOptions with their default values. | ||
func getDefaultOptions() listenerConfigOptions { | ||
return listenerConfigOptions{ | ||
withRedactionValue: "", // Redacted values will be set to an empty string by default. | ||
} | ||
} | ||
|
||
// getOpts applies each supplied ListenerConfigOption and returns the fully configured listenerConfigOptions. | ||
// Each ListenerConfigOption is applied in the order it appears in the argument list, so it is | ||
// possible to supply the same ListenerConfigOption numerous times and the 'last write wins'. | ||
func getOpts(opt ...ListenerConfigOption) (listenerConfigOptions, error) { | ||
opts := getDefaultOptions() | ||
for _, o := range opt { | ||
if o == nil { | ||
continue | ||
} | ||
if err := o(&opts); err != nil { | ||
return listenerConfigOptions{}, err | ||
} | ||
} | ||
return opts, nil | ||
} | ||
|
||
// WithRedactionValue provides an ListenerConfigOption to represent the value used to redact | ||
// values which require redaction. | ||
func WithRedactionValue(r string) ListenerConfigOption { | ||
return func(o *listenerConfigOptions) error { | ||
o.withRedactionValue = r | ||
return nil | ||
} | ||
} | ||
|
||
// WithRedactAddresses provides an ListenerConfigOption to represent whether redaction of addresses is required. | ||
func WithRedactAddresses(r bool) ListenerConfigOption { | ||
return func(o *listenerConfigOptions) error { | ||
o.withRedactAddresses = r | ||
return nil | ||
} | ||
} | ||
|
||
// WithRedactClusterName provides an ListenerConfigOption to represent whether redaction of cluster names is required. | ||
func WithRedactClusterName(r bool) ListenerConfigOption { | ||
return func(o *listenerConfigOptions) error { | ||
o.withRedactClusterName = r | ||
return nil | ||
} | ||
} | ||
|
||
// WithRedactVersion provides an ListenerConfigOption to represent whether redaction of version is required. | ||
func WithRedactVersion(r bool) ListenerConfigOption { | ||
return func(o *listenerConfigOptions) error { | ||
o.withRedactVersion = r | ||
return nil | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
|
||
package http | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
// TestOptions_Default ensures that the default values are as expected. | ||
func TestOptions_Default(t *testing.T) { | ||
opts := getDefaultOptions() | ||
require.NotNil(t, opts) | ||
require.Equal(t, "", opts.withRedactionValue) | ||
} | ||
|
||
// TestOptions_WithRedactionValue ensures that we set the correct value to use for | ||
// redaction when required. | ||
func TestOptions_WithRedactionValue(t *testing.T) { | ||
t.Parallel() | ||
|
||
tests := map[string]struct { | ||
Value string | ||
ExpectedValue string | ||
IsErrorExpected bool | ||
}{ | ||
"empty": { | ||
Value: "", | ||
ExpectedValue: "", | ||
IsErrorExpected: false, | ||
}, | ||
"whitespace": { | ||
Value: " ", | ||
ExpectedValue: " ", | ||
IsErrorExpected: false, | ||
}, | ||
"value": { | ||
Value: "*****", | ||
ExpectedValue: "*****", | ||
IsErrorExpected: false, | ||
}, | ||
} | ||
|
||
for name, tc := range tests { | ||
name := name | ||
tc := tc | ||
t.Run(name, func(t *testing.T) { | ||
t.Parallel() | ||
opts := &listenerConfigOptions{} | ||
applyOption := WithRedactionValue(tc.Value) | ||
err := applyOption(opts) | ||
switch { | ||
case tc.IsErrorExpected: | ||
require.Error(t, err) | ||
default: | ||
require.NoError(t, err) | ||
require.Equal(t, tc.ExpectedValue, opts.withRedactionValue) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
// TestOptions_WithRedactAddresses ensures that the option works as intended. | ||
func TestOptions_WithRedactAddresses(t *testing.T) { | ||
t.Parallel() | ||
|
||
tests := map[string]struct { | ||
Value bool | ||
ExpectedValue bool | ||
}{ | ||
"true": { | ||
Value: true, | ||
ExpectedValue: true, | ||
}, | ||
"false": { | ||
Value: false, | ||
ExpectedValue: false, | ||
}, | ||
} | ||
|
||
for name, tc := range tests { | ||
name := name | ||
tc := tc | ||
t.Run(name, func(t *testing.T) { | ||
t.Parallel() | ||
opts := &listenerConfigOptions{} | ||
applyOption := WithRedactAddresses(tc.Value) | ||
err := applyOption(opts) | ||
require.NoError(t, err) | ||
require.Equal(t, tc.ExpectedValue, opts.withRedactAddresses) | ||
}) | ||
} | ||
} | ||
|
||
// TestOptions_WithRedactClusterName ensures that the option works as intended. | ||
func TestOptions_WithRedactClusterName(t *testing.T) { | ||
t.Parallel() | ||
|
||
tests := map[string]struct { | ||
Value bool | ||
ExpectedValue bool | ||
}{ | ||
"true": { | ||
Value: true, | ||
ExpectedValue: true, | ||
}, | ||
"false": { | ||
Value: false, | ||
ExpectedValue: false, | ||
}, | ||
} | ||
|
||
for name, tc := range tests { | ||
name := name | ||
tc := tc | ||
t.Run(name, func(t *testing.T) { | ||
t.Parallel() | ||
opts := &listenerConfigOptions{} | ||
applyOption := WithRedactClusterName(tc.Value) | ||
err := applyOption(opts) | ||
require.NoError(t, err) | ||
require.Equal(t, tc.ExpectedValue, opts.withRedactClusterName) | ||
}) | ||
} | ||
} | ||
|
||
// TestOptions_WithRedactVersion ensures that the option works as intended. | ||
func TestOptions_WithRedactVersion(t *testing.T) { | ||
t.Parallel() | ||
|
||
tests := map[string]struct { | ||
Value bool | ||
ExpectedValue bool | ||
}{ | ||
"true": { | ||
Value: true, | ||
ExpectedValue: true, | ||
}, | ||
"false": { | ||
Value: false, | ||
ExpectedValue: false, | ||
}, | ||
} | ||
|
||
for name, tc := range tests { | ||
name := name | ||
tc := tc | ||
t.Run(name, func(t *testing.T) { | ||
t.Parallel() | ||
opts := &listenerConfigOptions{} | ||
applyOption := WithRedactVersion(tc.Value) | ||
err := applyOption(opts) | ||
require.NoError(t, err) | ||
require.Equal(t, tc.ExpectedValue, opts.withRedactVersion) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.