mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 19:47:54 +00:00
Support trimming trailing slashes via a mount tuneable to support CMPv2 (#28752)
* Support trimming trailing slashes via a mount tuneable to support CMPv2 * changelog/ * Perform trimming in handleLoginRequest too * Eagerly fetch the mount entry so we only test this once * Add a mount match function that gets path and entry * Update vault/request_handling.go Co-authored-by: Steven Clark <steven.clark@hashicorp.com> * more docs * Some patches (from ENT) didnt apply * patch fail * Update vault/router.go Co-authored-by: Steven Clark <steven.clark@hashicorp.com> * PR feedback * dupe * another dupe * Add support for enabling trim_request_trailing_slashes on mount creation * Fix read mount api returning configuration for trim_request_trailing_slashes * Fix test assertion * Switch enable and tune arguments to BoolPtrVal to allow end-users to specify false flag * Add trim-request-trailing-slashes to the auth enable API and CLI --------- Co-authored-by: Steven Clark <steven.clark@hashicorp.com>
This commit is contained in:
@@ -23,24 +23,25 @@ var (
|
||||
type AuthEnableCommand struct {
|
||||
*BaseCommand
|
||||
|
||||
flagDescription string
|
||||
flagPath string
|
||||
flagDefaultLeaseTTL time.Duration
|
||||
flagMaxLeaseTTL time.Duration
|
||||
flagAuditNonHMACRequestKeys []string
|
||||
flagAuditNonHMACResponseKeys []string
|
||||
flagListingVisibility string
|
||||
flagPluginName string
|
||||
flagPassthroughRequestHeaders []string
|
||||
flagAllowedResponseHeaders []string
|
||||
flagOptions map[string]string
|
||||
flagLocal bool
|
||||
flagSealWrap bool
|
||||
flagExternalEntropyAccess bool
|
||||
flagTokenType string
|
||||
flagVersion int
|
||||
flagPluginVersion string
|
||||
flagIdentityTokenKey string
|
||||
flagDescription string
|
||||
flagPath string
|
||||
flagDefaultLeaseTTL time.Duration
|
||||
flagMaxLeaseTTL time.Duration
|
||||
flagAuditNonHMACRequestKeys []string
|
||||
flagAuditNonHMACResponseKeys []string
|
||||
flagListingVisibility string
|
||||
flagPluginName string
|
||||
flagPassthroughRequestHeaders []string
|
||||
flagAllowedResponseHeaders []string
|
||||
flagOptions map[string]string
|
||||
flagLocal bool
|
||||
flagSealWrap bool
|
||||
flagExternalEntropyAccess bool
|
||||
flagTokenType string
|
||||
flagVersion int
|
||||
flagPluginVersion string
|
||||
flagIdentityTokenKey string
|
||||
flagTrimRequestTrailingSlashes BoolPtr
|
||||
}
|
||||
|
||||
func (c *AuthEnableCommand) Synopsis() string {
|
||||
@@ -217,6 +218,12 @@ func (c *AuthEnableCommand) Flags() *FlagSets {
|
||||
Usage: "Select the key used to sign plugin identity tokens.",
|
||||
})
|
||||
|
||||
f.BoolPtrVar(&BoolPtrVar{
|
||||
Name: flagNameTrimRequestTrailingSlashes,
|
||||
Target: &c.flagTrimRequestTrailingSlashes,
|
||||
Usage: "Whether to trim trailing slashes for incoming requests to this mount",
|
||||
})
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
@@ -324,6 +331,11 @@ func (c *AuthEnableCommand) Run(args []string) int {
|
||||
if fl.Name == flagNameIdentityTokenKey {
|
||||
authOpts.Config.IdentityTokenKey = c.flagIdentityTokenKey
|
||||
}
|
||||
|
||||
if fl.Name == flagNameTrimRequestTrailingSlashes && c.flagTrimRequestTrailingSlashes.IsSet() {
|
||||
val := c.flagTrimRequestTrailingSlashes.Get()
|
||||
authOpts.Config.TrimRequestTrailingSlashes = &val
|
||||
}
|
||||
})
|
||||
|
||||
if err := client.Sys().EnableAuthWithOptions(authPath, authOpts); err != nil {
|
||||
|
||||
@@ -100,6 +100,7 @@ func TestAuthEnableCommand_Run(t *testing.T) {
|
||||
"-allowed-response-headers", "authorization",
|
||||
"-listing-visibility", "unauth",
|
||||
"-identity-token-key", "default",
|
||||
"-trim-request-trailing-slashes=true",
|
||||
"userpass",
|
||||
})
|
||||
if exp := 0; code != exp {
|
||||
@@ -127,6 +128,9 @@ func TestAuthEnableCommand_Run(t *testing.T) {
|
||||
if exp := "The best kind of test"; authInfo.Description != exp {
|
||||
t.Errorf("expected %q to be %q", authInfo.Description, exp)
|
||||
}
|
||||
if !authInfo.Config.TrimRequestTrailingSlashes {
|
||||
t.Errorf("expected trim_request_trailing_slashes to be enabled")
|
||||
}
|
||||
if diff := deep.Equal([]string{"authorization,authentication", "www-authentication"}, authInfo.Config.PassthroughRequestHeaders); len(diff) > 0 {
|
||||
t.Errorf("Failed to find expected values in PassthroughRequestHeaders. Difference is: %v", diff)
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ type AuthTuneCommand struct {
|
||||
flagUserLockoutCounterResetDuration time.Duration
|
||||
flagUserLockoutDisable bool
|
||||
flagIdentityTokenKey string
|
||||
flagTrimRequestTrailingSlashes BoolPtr
|
||||
}
|
||||
|
||||
func (c *AuthTuneCommand) Synopsis() string {
|
||||
@@ -195,6 +196,11 @@ func (c *AuthTuneCommand) Flags() *FlagSets {
|
||||
Usage: "Select the semantic version of the plugin to run. The new version must be registered in " +
|
||||
"the plugin catalog, and will not start running until the plugin is reloaded.",
|
||||
})
|
||||
f.BoolPtrVar(&BoolPtrVar{
|
||||
Name: flagNameTrimRequestTrailingSlashes,
|
||||
Target: &c.flagTrimRequestTrailingSlashes,
|
||||
Usage: "Whether to trim trailing slashes for incoming requests to this mount",
|
||||
})
|
||||
|
||||
f.StringVar(&StringVar{
|
||||
Name: flagNameIdentityTokenKey,
|
||||
@@ -306,6 +312,11 @@ func (c *AuthTuneCommand) Run(args []string) int {
|
||||
if fl.Name == flagNameIdentityTokenKey {
|
||||
mountConfigInput.IdentityTokenKey = c.flagIdentityTokenKey
|
||||
}
|
||||
|
||||
if fl.Name == flagNameTrimRequestTrailingSlashes && c.flagTrimRequestTrailingSlashes.IsSet() {
|
||||
val := c.flagTrimRequestTrailingSlashes.Get()
|
||||
mountConfigInput.TrimRequestTrailingSlashes = &val
|
||||
}
|
||||
})
|
||||
|
||||
// Append /auth (since that's where auths live) and a trailing slash to
|
||||
|
||||
@@ -120,6 +120,7 @@ func TestAuthTuneCommand_Run(t *testing.T) {
|
||||
"-listing-visibility", "unauth",
|
||||
"-plugin-version", version,
|
||||
"-identity-token-key", "default",
|
||||
"-trim-request-trailing-slashes=true",
|
||||
"my-auth/",
|
||||
})
|
||||
if exp := 0; code != exp {
|
||||
@@ -156,6 +157,9 @@ func TestAuthTuneCommand_Run(t *testing.T) {
|
||||
if exp := 3600; mountInfo.Config.MaxLeaseTTL != exp {
|
||||
t.Errorf("expected %d to be %d", mountInfo.Config.MaxLeaseTTL, exp)
|
||||
}
|
||||
if !mountInfo.Config.TrimRequestTrailingSlashes {
|
||||
t.Errorf("expected trim_request_trailing_slashes to be enabled")
|
||||
}
|
||||
if diff := deep.Equal([]string{"authorization", "www-authentication"}, mountInfo.Config.PassthroughRequestHeaders); len(diff) > 0 {
|
||||
t.Errorf("Failed to find expected values in PassthroughRequestHeaders. Difference is: %v", diff)
|
||||
}
|
||||
|
||||
@@ -97,6 +97,8 @@ const (
|
||||
flagNamePluginVersion = "plugin-version"
|
||||
// flagNameIdentityTokenKey selects the key used to sign plugin identity tokens
|
||||
flagNameIdentityTokenKey = "identity-token-key"
|
||||
// flagNameTrimRequestTrailingSlashes selects the key used to determine whether to trim trailing slashes
|
||||
flagNameTrimRequestTrailingSlashes = "trim-request-trailing-slashes"
|
||||
// flagNameUserLockoutThreshold is the flag name used for tuning the auth mount lockout threshold parameter
|
||||
flagNameUserLockoutThreshold = "user-lockout-threshold"
|
||||
// flagNameUserLockoutDuration is the flag name used for tuning the auth mount lockout duration parameter
|
||||
|
||||
@@ -23,26 +23,27 @@ var (
|
||||
type SecretsEnableCommand struct {
|
||||
*BaseCommand
|
||||
|
||||
flagDescription string
|
||||
flagPath string
|
||||
flagDefaultLeaseTTL time.Duration
|
||||
flagMaxLeaseTTL time.Duration
|
||||
flagAuditNonHMACRequestKeys []string
|
||||
flagAuditNonHMACResponseKeys []string
|
||||
flagListingVisibility string
|
||||
flagPassthroughRequestHeaders []string
|
||||
flagAllowedResponseHeaders []string
|
||||
flagForceNoCache bool
|
||||
flagPluginName string
|
||||
flagPluginVersion string
|
||||
flagOptions map[string]string
|
||||
flagLocal bool
|
||||
flagSealWrap bool
|
||||
flagExternalEntropyAccess bool
|
||||
flagVersion int
|
||||
flagAllowedManagedKeys []string
|
||||
flagDelegatedAuthAccessors []string
|
||||
flagIdentityTokenKey string
|
||||
flagDescription string
|
||||
flagPath string
|
||||
flagDefaultLeaseTTL time.Duration
|
||||
flagMaxLeaseTTL time.Duration
|
||||
flagAuditNonHMACRequestKeys []string
|
||||
flagAuditNonHMACResponseKeys []string
|
||||
flagListingVisibility string
|
||||
flagPassthroughRequestHeaders []string
|
||||
flagAllowedResponseHeaders []string
|
||||
flagForceNoCache bool
|
||||
flagPluginName string
|
||||
flagPluginVersion string
|
||||
flagOptions map[string]string
|
||||
flagLocal bool
|
||||
flagSealWrap bool
|
||||
flagExternalEntropyAccess bool
|
||||
flagVersion int
|
||||
flagAllowedManagedKeys []string
|
||||
flagDelegatedAuthAccessors []string
|
||||
flagIdentityTokenKey string
|
||||
flagTrimRequestTrailingSlashes BoolPtr
|
||||
}
|
||||
|
||||
func (c *SecretsEnableCommand) Synopsis() string {
|
||||
@@ -245,6 +246,12 @@ func (c *SecretsEnableCommand) Flags() *FlagSets {
|
||||
Usage: "Select the key used to sign plugin identity tokens.",
|
||||
})
|
||||
|
||||
f.BoolPtrVar(&BoolPtrVar{
|
||||
Name: flagNameTrimRequestTrailingSlashes,
|
||||
Target: &c.flagTrimRequestTrailingSlashes,
|
||||
Usage: "Whether to trim trailing slashes for incoming requests to this mount",
|
||||
})
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
@@ -359,6 +366,11 @@ func (c *SecretsEnableCommand) Run(args []string) int {
|
||||
if fl.Name == flagNameIdentityTokenKey {
|
||||
mountInput.Config.IdentityTokenKey = c.flagIdentityTokenKey
|
||||
}
|
||||
|
||||
if fl.Name == flagNameTrimRequestTrailingSlashes && c.flagTrimRequestTrailingSlashes.IsSet() {
|
||||
val := c.flagTrimRequestTrailingSlashes.Get()
|
||||
mountInput.Config.TrimRequestTrailingSlashes = &val
|
||||
}
|
||||
})
|
||||
|
||||
if err := client.Sys().Mount(mountPath, mountInput); err != nil {
|
||||
|
||||
@@ -120,6 +120,7 @@ func TestSecretsEnableCommand_Run(t *testing.T) {
|
||||
"-allowed-managed-keys", "key1,key2",
|
||||
"-identity-token-key", "default",
|
||||
"-delegated-auth-accessors", "authAcc1,authAcc2",
|
||||
"-trim-request-trailing-slashes=true",
|
||||
"-force-no-cache",
|
||||
"pki",
|
||||
})
|
||||
@@ -157,6 +158,9 @@ func TestSecretsEnableCommand_Run(t *testing.T) {
|
||||
if exp := true; mountInfo.Config.ForceNoCache != exp {
|
||||
t.Errorf("expected %t to be %t", mountInfo.Config.ForceNoCache, exp)
|
||||
}
|
||||
if !mountInfo.Config.TrimRequestTrailingSlashes {
|
||||
t.Errorf("expected trim_request_trailing_slashes to be enabled")
|
||||
}
|
||||
if diff := deep.Equal([]string{"authorization,authentication", "www-authentication"}, mountInfo.Config.PassthroughRequestHeaders); len(diff) > 0 {
|
||||
t.Errorf("Failed to find expected values in PassthroughRequestHeaders. Difference is: %v", diff)
|
||||
}
|
||||
|
||||
@@ -23,20 +23,21 @@ var (
|
||||
type SecretsTuneCommand struct {
|
||||
*BaseCommand
|
||||
|
||||
flagAuditNonHMACRequestKeys []string
|
||||
flagAuditNonHMACResponseKeys []string
|
||||
flagDefaultLeaseTTL time.Duration
|
||||
flagDescription string
|
||||
flagListingVisibility string
|
||||
flagMaxLeaseTTL time.Duration
|
||||
flagPassthroughRequestHeaders []string
|
||||
flagAllowedResponseHeaders []string
|
||||
flagOptions map[string]string
|
||||
flagVersion int
|
||||
flagPluginVersion string
|
||||
flagAllowedManagedKeys []string
|
||||
flagDelegatedAuthAccessors []string
|
||||
flagIdentityTokenKey string
|
||||
flagAuditNonHMACRequestKeys []string
|
||||
flagAuditNonHMACResponseKeys []string
|
||||
flagDefaultLeaseTTL time.Duration
|
||||
flagDescription string
|
||||
flagListingVisibility string
|
||||
flagMaxLeaseTTL time.Duration
|
||||
flagPassthroughRequestHeaders []string
|
||||
flagAllowedResponseHeaders []string
|
||||
flagOptions map[string]string
|
||||
flagVersion int
|
||||
flagPluginVersion string
|
||||
flagAllowedManagedKeys []string
|
||||
flagDelegatedAuthAccessors []string
|
||||
flagIdentityTokenKey string
|
||||
flagTrimRequestTrailingSlashes BoolPtr
|
||||
}
|
||||
|
||||
func (c *SecretsTuneCommand) Synopsis() string {
|
||||
@@ -175,6 +176,12 @@ func (c *SecretsTuneCommand) Flags() *FlagSets {
|
||||
Usage: "Select the key used to sign plugin identity tokens.",
|
||||
})
|
||||
|
||||
f.BoolPtrVar(&BoolPtrVar{
|
||||
Name: flagNameTrimRequestTrailingSlashes,
|
||||
Target: &c.flagTrimRequestTrailingSlashes,
|
||||
Usage: "Whether to trim trailing slashes for incoming requests to this mount",
|
||||
})
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
@@ -267,6 +274,10 @@ func (c *SecretsTuneCommand) Run(args []string) int {
|
||||
if fl.Name == flagNameIdentityTokenKey {
|
||||
mountConfigInput.IdentityTokenKey = c.flagIdentityTokenKey
|
||||
}
|
||||
if fl.Name == flagNameTrimRequestTrailingSlashes && c.flagTrimRequestTrailingSlashes.IsSet() {
|
||||
val := c.flagTrimRequestTrailingSlashes.Get()
|
||||
mountConfigInput.TrimRequestTrailingSlashes = &val
|
||||
}
|
||||
})
|
||||
|
||||
if err := client.Sys().TuneMount(mountPath, mountConfigInput); err != nil {
|
||||
|
||||
@@ -196,6 +196,7 @@ func TestSecretsTuneCommand_Run(t *testing.T) {
|
||||
"-listing-visibility", "unauth",
|
||||
"-plugin-version", version,
|
||||
"-delegated-auth-accessors", "authAcc1,authAcc2",
|
||||
"-trim-request-trailing-slashes=true",
|
||||
"mount_tune_integration/",
|
||||
})
|
||||
if exp := 0; code != exp {
|
||||
@@ -232,6 +233,9 @@ func TestSecretsTuneCommand_Run(t *testing.T) {
|
||||
if exp := 3600; mountInfo.Config.MaxLeaseTTL != exp {
|
||||
t.Errorf("expected %d to be %d", mountInfo.Config.MaxLeaseTTL, exp)
|
||||
}
|
||||
if !mountInfo.Config.TrimRequestTrailingSlashes {
|
||||
t.Errorf("expected trim_request_trailing_slashes to be enabled")
|
||||
}
|
||||
if diff := deep.Equal([]string{"authorization", "www-authentication"}, mountInfo.Config.PassthroughRequestHeaders); len(diff) > 0 {
|
||||
t.Errorf("Failed to find expected values for PassthroughRequestHeaders. Difference is: %v", diff)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user