Fix UI custom header values (#10511)

* Fix UI custom header values

* Fix changelog entry

* Introduce param for multi values

* Fix multivalue

* multivalue should be bool

* Sort imports

* Fix conflict

* Remove changelog entry

* Revert entry delete
This commit is contained in:
Michel Vocks 2020-12-15 15:58:03 +01:00 committed by GitHub
parent fc9fa540af
commit 191aa65bc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 25 deletions

3
changelog/10490.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
api/sys/config/ui: Fixes issue where multiple UI custom header values are ignored and only the first given value is used
```

View File

@ -2432,18 +2432,28 @@ func (b *SystemBackend) handleDisableAudit(ctx context.Context, req *logical.Req
func (b *SystemBackend) handleConfigUIHeadersRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
header := data.Get("header").(string)
multivalue := data.Get("multivalue").(bool)
value, err := b.Core.uiConfig.GetHeader(ctx, header)
values, err := b.Core.uiConfig.GetHeader(ctx, header)
if err != nil {
return nil, err
}
if value == "" {
if len(values) == 0 {
return nil, nil
}
// Return multiple values if specified
if multivalue {
return &logical.Response{
Data: map[string]interface{}{
"values": values,
},
}, nil
}
return &logical.Response{
Data: map[string]interface{}{
"value": value,
"value": values[0],
},
}, nil
}
@ -2477,7 +2487,7 @@ func (b *SystemBackend) handleConfigUIHeadersUpdate(ctx context.Context, req *lo
for _, v := range values {
value.Add(header, v)
}
err := b.Core.uiConfig.SetHeader(ctx, header, value.Get(header))
err := b.Core.uiConfig.SetHeader(ctx, header, value.Values(header))
if err != nil {
return nil, err
}

View File

@ -71,6 +71,10 @@ func (b *SystemBackend) configPaths() []*framework.Path {
Type: framework.TypeStringSlice,
Description: "The values to set the header.",
},
"multivalue": &framework.FieldSchema{
Type: framework.TypeBool,
Description: "Returns multiple values if true",
},
},
Operations: map[logical.Operation]framework.OperationHandler{

View File

@ -92,25 +92,25 @@ func (c *UIConfig) HeaderKeys(ctx context.Context) ([]string, error) {
return keys, nil
}
// GetHeader retrieves the configured value for the given header
func (c *UIConfig) GetHeader(ctx context.Context, header string) (string, error) {
// GetHeader retrieves the configured values for the given header
func (c *UIConfig) GetHeader(ctx context.Context, header string) ([]string, error) {
c.l.RLock()
defer c.l.RUnlock()
config, err := c.get(ctx)
if err != nil {
return "", err
return nil, err
}
if config == nil {
return "", nil
return nil, nil
}
value := config.Headers.Get(header)
value := config.Headers.Values(header)
return value, nil
}
// SetHeader sets the value for the given header
func (c *UIConfig) SetHeader(ctx context.Context, header, value string) error {
// SetHeader sets the values for the given header
func (c *UIConfig) SetHeader(ctx context.Context, header string, values []string) error {
c.l.Lock()
defer c.l.Unlock()
@ -123,7 +123,14 @@ func (c *UIConfig) SetHeader(ctx context.Context, header, value string) error {
Headers: http.Header{},
}
}
config.Headers.Set(header, value)
// Clear custom header values before setting new
config.Headers.Del(header)
// Set new values
for _, value := range values {
config.Headers.Add(header, value)
}
return c.save(ctx, config)
}

View File

@ -51,10 +51,10 @@ func TestConfig_Headers(t *testing.T) {
if err != nil {
t.Fatalf("err: %v", err)
}
if head != "" {
if len(head) != 0 {
t.Fatal("header returned found, should not be found")
}
err = config.SetHeader(context.Background(), "Test-Header", "123")
err = config.SetHeader(context.Background(), "Test-Header", []string{"123", "456"})
if err != nil {
t.Fatalf("err: %v", err)
}
@ -62,22 +62,28 @@ func TestConfig_Headers(t *testing.T) {
if err != nil {
t.Fatalf("err: %v", err)
}
if head == "" {
t.Fatal("header not found when it should be")
if len(head) != 2 {
t.Fatalf("header not found or incorrect number of values: %#v", head)
}
if head != "123" {
t.Fatalf("expected: %s, got: %s", "123", head)
if head[0] != "123" {
t.Fatalf("expected: %s, got: %s", "123", head[0])
}
if head[1] != "456" {
t.Fatalf("expected: %s, got: %s", "456", head[1])
}
head, err = config.GetHeader(context.Background(), "tEST-hEADER")
if err != nil {
t.Fatalf("err: %v", err)
}
if head == "" {
t.Fatal("header not found when it should be")
if len(head) != 2 {
t.Fatalf("header not found or incorrect number of values: %#v", head)
}
if head != "123" {
t.Fatalf("expected: %s, got: %s", "123", head)
if head[0] != "123" {
t.Fatalf("expected: %s, got: %s", "123", head[0])
}
if head[1] != "456" {
t.Fatalf("expected: %s, got: %s", "456", head[1])
}
keys, err := config.HeaderKeys(context.Background())
@ -88,7 +94,7 @@ func TestConfig_Headers(t *testing.T) {
t.Fatalf("expected 1 key, got %d", len(keys))
}
err = config.SetHeader(context.Background(), "Test-Header-2", "321")
err = config.SetHeader(context.Background(), "Test-Header-2", []string{"321"})
if err != nil {
t.Fatalf("err: %v", err)
}
@ -112,7 +118,7 @@ func TestConfig_Headers(t *testing.T) {
if err != nil {
t.Fatalf("err: %v", err)
}
if head != "" {
if len(head) != 0 {
t.Fatal("header returned found, should not be found")
}
keys, err = config.HeaderKeys(context.Background())
@ -151,7 +157,7 @@ func TestConfig_DefaultHeaders(t *testing.T) {
t.Fatalf("header does not match: expected %s, got %s", defaultCSP, head)
}
err = config.SetHeader(context.Background(), "Content-security-Policy", "test")
err = config.SetHeader(context.Background(), "Content-security-Policy", []string{"test"})
if err != nil {
t.Fatalf("err: %v", err)
}

View File

@ -24,6 +24,8 @@ This endpoint returns the given UI header configuration.
- `name` `(string: <required>)`  The name of the custom header.
- `multivalue` `(bool: <optional>)` - Returns multiple values if true.
### Sample Request
```shell-session
@ -40,6 +42,22 @@ $ curl \
}
```
### Sample Request (Multi value)
```shell-session
$ curl \
--header "X-Vault-Token: ..." \
http://127.0.0.1:8200/v1/sys/config/ui/headers/X-Custom-Header?multivalue=true
```
### Sample Response
```json
{
"values": ["custom-value-1", "custom-value-2"]
}
```
## Configure UI Headers
This endpoint allows configuring the values to be returned for the UI header.