2017-02-02 19:49:20 +00:00
|
|
|
package vault
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/hashicorp/vault/helper/salt"
|
|
|
|
)
|
|
|
|
|
|
|
|
func mockAuditedHeadersConfig(t *testing.T) *AuditedHeadersConfig {
|
|
|
|
_, barrier, _ := mockBarrier(t)
|
|
|
|
view := NewBarrierView(barrier, "foo/")
|
|
|
|
return &AuditedHeadersConfig{
|
|
|
|
Headers: make(map[string]*auditedHeaderSettings),
|
|
|
|
view: view,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAuditedHeadersConfig_CRUD(t *testing.T) {
|
|
|
|
conf := mockAuditedHeadersConfig(t)
|
|
|
|
|
|
|
|
testAuditedHeadersConfig_Add(t, conf)
|
|
|
|
testAuditedHeadersConfig_Remove(t, conf)
|
|
|
|
}
|
|
|
|
|
|
|
|
func testAuditedHeadersConfig_Add(t *testing.T, conf *AuditedHeadersConfig) {
|
|
|
|
err := conf.add("X-Test-Header", false)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error when adding header to config: %s", err)
|
|
|
|
}
|
|
|
|
|
2017-02-16 01:35:35 +00:00
|
|
|
settings, ok := conf.Headers["x-test-header"]
|
2017-02-02 19:49:20 +00:00
|
|
|
if !ok {
|
|
|
|
t.Fatal("Expected header to be found in config")
|
|
|
|
}
|
|
|
|
|
|
|
|
if settings.HMAC {
|
|
|
|
t.Fatal("Expected HMAC to be set to false, got true")
|
|
|
|
}
|
|
|
|
|
|
|
|
out, err := conf.view.Get(auditedHeadersEntry)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Could not retrieve headers entry from config: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
headers := make(map[string]*auditedHeaderSettings)
|
|
|
|
err = out.DecodeJSON(&headers)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error decoding header view: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expected := map[string]*auditedHeaderSettings{
|
2017-02-16 01:35:35 +00:00
|
|
|
"x-test-header": &auditedHeaderSettings{
|
2017-02-02 19:49:20 +00:00
|
|
|
HMAC: false,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(headers, expected) {
|
|
|
|
t.Fatalf("Expected config didn't match actual. Expected: %#v, Got: %#v", expected, headers)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = conf.add("X-Vault-Header", true)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error when adding header to config: %s", err)
|
|
|
|
}
|
|
|
|
|
2017-02-16 01:35:35 +00:00
|
|
|
settings, ok = conf.Headers["x-vault-header"]
|
2017-02-02 19:49:20 +00:00
|
|
|
if !ok {
|
|
|
|
t.Fatal("Expected header to be found in config")
|
|
|
|
}
|
|
|
|
|
|
|
|
if !settings.HMAC {
|
|
|
|
t.Fatal("Expected HMAC to be set to true, got false")
|
|
|
|
}
|
|
|
|
|
|
|
|
out, err = conf.view.Get(auditedHeadersEntry)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Could not retrieve headers entry from config: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
headers = make(map[string]*auditedHeaderSettings)
|
|
|
|
err = out.DecodeJSON(&headers)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error decoding header view: %s", err)
|
|
|
|
}
|
|
|
|
|
2017-02-16 01:35:35 +00:00
|
|
|
expected["x-vault-header"] = &auditedHeaderSettings{
|
2017-02-02 19:49:20 +00:00
|
|
|
HMAC: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(headers, expected) {
|
|
|
|
t.Fatalf("Expected config didn't match actual. Expected: %#v, Got: %#v", expected, headers)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func testAuditedHeadersConfig_Remove(t *testing.T, conf *AuditedHeadersConfig) {
|
|
|
|
err := conf.remove("X-Test-Header")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error when adding header to config: %s", err)
|
|
|
|
}
|
|
|
|
|
2017-02-16 01:35:35 +00:00
|
|
|
_, ok := conf.Headers["x-Test-HeAder"]
|
2017-02-02 19:49:20 +00:00
|
|
|
if ok {
|
|
|
|
t.Fatal("Expected header to not be found in config")
|
|
|
|
}
|
|
|
|
|
|
|
|
out, err := conf.view.Get(auditedHeadersEntry)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Could not retrieve headers entry from config: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
headers := make(map[string]*auditedHeaderSettings)
|
|
|
|
err = out.DecodeJSON(&headers)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error decoding header view: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expected := map[string]*auditedHeaderSettings{
|
2017-02-16 01:35:35 +00:00
|
|
|
"x-vault-header": &auditedHeaderSettings{
|
2017-02-02 19:49:20 +00:00
|
|
|
HMAC: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(headers, expected) {
|
|
|
|
t.Fatalf("Expected config didn't match actual. Expected: %#v, Got: %#v", expected, headers)
|
|
|
|
}
|
|
|
|
|
2017-02-16 01:35:35 +00:00
|
|
|
err = conf.remove("x-VaulT-Header")
|
2017-02-02 19:49:20 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error when adding header to config: %s", err)
|
|
|
|
}
|
|
|
|
|
2017-02-16 01:35:35 +00:00
|
|
|
_, ok = conf.Headers["x-vault-header"]
|
2017-02-02 19:49:20 +00:00
|
|
|
if ok {
|
|
|
|
t.Fatal("Expected header to not be found in config")
|
|
|
|
}
|
|
|
|
|
|
|
|
out, err = conf.view.Get(auditedHeadersEntry)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Could not retrieve headers entry from config: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
headers = make(map[string]*auditedHeaderSettings)
|
|
|
|
err = out.DecodeJSON(&headers)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error decoding header view: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expected = make(map[string]*auditedHeaderSettings)
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(headers, expected) {
|
|
|
|
t.Fatalf("Expected config didn't match actual. Expected: %#v, Got: %#v", expected, headers)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAuditedHeadersConfig_ApplyConfig(t *testing.T) {
|
|
|
|
conf := mockAuditedHeadersConfig(t)
|
|
|
|
|
2017-02-16 01:35:35 +00:00
|
|
|
conf.add("X-TesT-Header", false)
|
|
|
|
conf.add("X-Vault-HeAdEr", true)
|
2017-02-02 19:49:20 +00:00
|
|
|
|
|
|
|
reqHeaders := map[string][]string{
|
|
|
|
"X-Test-Header": []string{"foo"},
|
|
|
|
"X-Vault-Header": []string{"bar", "bar"},
|
|
|
|
"Content-Type": []string{"json"},
|
|
|
|
}
|
|
|
|
|
|
|
|
hashFunc := func(s string) string { return "hashed" }
|
|
|
|
|
|
|
|
result := conf.ApplyConfig(reqHeaders, hashFunc)
|
|
|
|
|
|
|
|
expected := map[string][]string{
|
2017-02-16 01:35:35 +00:00
|
|
|
"x-test-header": []string{"foo"},
|
|
|
|
"x-vault-header": []string{"hashed", "hashed"},
|
2017-02-02 19:49:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(result, expected) {
|
|
|
|
t.Fatalf("Expected headers did not match actual: Expected %#v\n Got %#v\n", expected, result)
|
|
|
|
}
|
|
|
|
|
|
|
|
//Make sure we didn't edit the reqHeaders map
|
|
|
|
reqHeadersCopy := map[string][]string{
|
|
|
|
"X-Test-Header": []string{"foo"},
|
|
|
|
"X-Vault-Header": []string{"bar", "bar"},
|
|
|
|
"Content-Type": []string{"json"},
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(reqHeaders, reqHeadersCopy) {
|
|
|
|
t.Fatalf("Req headers were changed, expected %#v\n got %#v", reqHeadersCopy, reqHeaders)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkAuditedHeaderConfig_ApplyConfig(b *testing.B) {
|
|
|
|
conf := &AuditedHeadersConfig{
|
|
|
|
Headers: make(map[string]*auditedHeaderSettings),
|
|
|
|
view: nil,
|
|
|
|
}
|
|
|
|
|
|
|
|
conf.Headers = map[string]*auditedHeaderSettings{
|
|
|
|
"X-Test-Header": &auditedHeaderSettings{false},
|
|
|
|
"X-Vault-Header": &auditedHeaderSettings{true},
|
|
|
|
}
|
|
|
|
|
|
|
|
reqHeaders := map[string][]string{
|
|
|
|
"X-Test-Header": []string{"foo"},
|
|
|
|
"X-Vault-Header": []string{"bar", "bar"},
|
|
|
|
"Content-Type": []string{"json"},
|
|
|
|
}
|
|
|
|
|
|
|
|
salter, err := salt.NewSalt(nil, nil)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
hashFunc := func(s string) string { return salter.GetIdentifiedHMAC(s) }
|
|
|
|
|
|
|
|
// Reset the timer since we did a lot above
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
conf.ApplyConfig(reqHeaders, hashFunc)
|
|
|
|
}
|
|
|
|
}
|