2023-03-15 16:00:52 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2015-03-15 21:26:48 +00:00
|
|
|
package vault
|
|
|
|
|
|
|
|
import (
|
2018-01-08 18:31:38 +00:00
|
|
|
"context"
|
2017-05-09 18:05:00 +00:00
|
|
|
"encoding/json"
|
2015-03-15 21:26:48 +00:00
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2021-07-16 00:17:31 +00:00
|
|
|
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
2019-04-12 21:54:35 +00:00
|
|
|
"github.com/hashicorp/vault/sdk/logical"
|
2015-03-15 21:26:48 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestPassthroughBackend_RootPaths(t *testing.T) {
|
2015-03-16 00:07:54 +00:00
|
|
|
b := testPassthroughBackend()
|
2015-09-21 20:57:41 +00:00
|
|
|
test := func(b logical.Backend) {
|
|
|
|
root := b.SpecialPaths()
|
2017-10-23 19:35:28 +00:00
|
|
|
if len(root.Root) != 0 {
|
2015-09-21 20:57:41 +00:00
|
|
|
t.Fatalf("unexpected: %v", root)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
test(b)
|
|
|
|
b = testPassthroughLeasedBackend()
|
|
|
|
test(b)
|
2015-03-15 21:26:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestPassthroughBackend_Write(t *testing.T) {
|
2015-09-21 20:57:41 +00:00
|
|
|
test := func(b logical.Backend) {
|
2016-01-07 15:30:47 +00:00
|
|
|
req := logical.TestRequest(t, logical.UpdateOperation, "foo")
|
2015-09-21 20:57:41 +00:00
|
|
|
req.Data["raw"] = "test"
|
|
|
|
|
2018-01-08 18:31:38 +00:00
|
|
|
resp, err := b.HandleRequest(context.Background(), req)
|
2015-09-21 20:57:41 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if resp != nil {
|
|
|
|
t.Fatalf("bad: %v", resp)
|
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
out, err := req.Storage.Get(context.Background(), "foo")
|
2015-09-21 20:57:41 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if out == nil {
|
|
|
|
t.Fatalf("failed to write to view")
|
|
|
|
}
|
2015-03-15 21:26:48 +00:00
|
|
|
}
|
2015-09-21 20:57:41 +00:00
|
|
|
b := testPassthroughBackend()
|
|
|
|
test(b)
|
|
|
|
b = testPassthroughLeasedBackend()
|
|
|
|
test(b)
|
2015-03-15 21:26:48 +00:00
|
|
|
}
|
|
|
|
|
2015-09-21 20:57:41 +00:00
|
|
|
func TestPassthroughBackend_Read(t *testing.T) {
|
2017-05-09 18:05:00 +00:00
|
|
|
test := func(b logical.Backend, ttlType string, ttl interface{}, leased bool) {
|
2016-01-07 15:30:47 +00:00
|
|
|
req := logical.TestRequest(t, logical.UpdateOperation, "foo")
|
2015-09-21 20:57:41 +00:00
|
|
|
req.Data["raw"] = "test"
|
2017-05-09 18:05:00 +00:00
|
|
|
var reqTTL interface{}
|
|
|
|
switch ttl.(type) {
|
|
|
|
case int64:
|
|
|
|
reqTTL = ttl.(int64)
|
|
|
|
case string:
|
|
|
|
reqTTL = ttl.(string)
|
|
|
|
default:
|
|
|
|
t.Fatal("unknown ttl type")
|
|
|
|
}
|
|
|
|
req.Data[ttlType] = reqTTL
|
2015-09-21 20:57:41 +00:00
|
|
|
storage := req.Storage
|
|
|
|
|
2018-01-08 18:31:38 +00:00
|
|
|
if _, err := b.HandleRequest(context.Background(), req); err != nil {
|
2015-09-21 20:57:41 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
req = logical.TestRequest(t, logical.ReadOperation, "foo")
|
|
|
|
req.Storage = storage
|
|
|
|
|
2018-01-08 18:31:38 +00:00
|
|
|
resp, err := b.HandleRequest(context.Background(), req)
|
2015-09-21 20:57:41 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2017-05-09 18:05:00 +00:00
|
|
|
expectedTTL, err := parseutil.ParseDurationSecond(ttl)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// What comes back if an int is passed in is a json.Number which is
|
|
|
|
// actually aliased as a string so to make the deep equal happy if it's
|
|
|
|
// actually a number we set it to an int64
|
|
|
|
var respTTL interface{} = resp.Data[ttlType]
|
|
|
|
_, ok := respTTL.(json.Number)
|
|
|
|
if ok {
|
|
|
|
respTTL, err = respTTL.(json.Number).Int64()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
resp.Data[ttlType] = respTTL
|
|
|
|
}
|
|
|
|
|
2015-09-21 20:57:41 +00:00
|
|
|
expected := &logical.Response{
|
|
|
|
Secret: &logical.Secret{
|
|
|
|
LeaseOptions: logical.LeaseOptions{
|
|
|
|
Renewable: true,
|
2017-05-09 18:05:00 +00:00
|
|
|
TTL: expectedTTL,
|
2015-09-21 20:57:41 +00:00
|
|
|
},
|
2015-04-09 19:14:04 +00:00
|
|
|
},
|
2015-09-21 20:57:41 +00:00
|
|
|
Data: map[string]interface{}{
|
|
|
|
"raw": "test",
|
2017-05-09 18:05:00 +00:00
|
|
|
ttlType: reqTTL,
|
2015-08-20 23:41:25 +00:00
|
|
|
},
|
2015-09-21 20:57:41 +00:00
|
|
|
}
|
2015-08-20 23:41:25 +00:00
|
|
|
|
2015-09-21 20:57:41 +00:00
|
|
|
if !leased {
|
|
|
|
expected.Secret.Renewable = false
|
|
|
|
}
|
|
|
|
resp.Secret.InternalData = nil
|
|
|
|
resp.Secret.LeaseID = ""
|
|
|
|
if !reflect.DeepEqual(resp, expected) {
|
2017-05-09 18:05:00 +00:00
|
|
|
t.Fatalf("bad response.\n\nexpected:\n%#v\n\nGot:\n%#v", expected, resp)
|
2015-09-21 20:57:41 +00:00
|
|
|
}
|
2015-08-20 23:41:25 +00:00
|
|
|
}
|
2015-09-21 20:57:41 +00:00
|
|
|
b := testPassthroughLeasedBackend()
|
2017-05-09 18:05:00 +00:00
|
|
|
test(b, "lease", "1h", true)
|
|
|
|
test(b, "ttl", "5", true)
|
2015-09-21 20:57:41 +00:00
|
|
|
b = testPassthroughBackend()
|
2017-05-09 18:05:00 +00:00
|
|
|
test(b, "lease", int64(10), false)
|
|
|
|
test(b, "ttl", "40s", false)
|
2015-08-20 23:41:25 +00:00
|
|
|
}
|
|
|
|
|
2015-03-15 21:26:48 +00:00
|
|
|
func TestPassthroughBackend_Delete(t *testing.T) {
|
2015-09-21 20:57:41 +00:00
|
|
|
test := func(b logical.Backend) {
|
2016-01-07 15:30:47 +00:00
|
|
|
req := logical.TestRequest(t, logical.UpdateOperation, "foo")
|
2015-09-21 20:57:41 +00:00
|
|
|
req.Data["raw"] = "test"
|
|
|
|
storage := req.Storage
|
|
|
|
|
2018-01-08 18:31:38 +00:00
|
|
|
if _, err := b.HandleRequest(context.Background(), req); err != nil {
|
2015-09-21 20:57:41 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
req = logical.TestRequest(t, logical.DeleteOperation, "foo")
|
|
|
|
req.Storage = storage
|
2018-01-08 18:31:38 +00:00
|
|
|
resp, err := b.HandleRequest(context.Background(), req)
|
2015-09-21 20:57:41 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if resp != nil {
|
|
|
|
t.Fatalf("bad: %v", resp)
|
|
|
|
}
|
|
|
|
|
|
|
|
req = logical.TestRequest(t, logical.ReadOperation, "foo")
|
|
|
|
req.Storage = storage
|
2018-01-08 18:31:38 +00:00
|
|
|
resp, err = b.HandleRequest(context.Background(), req)
|
2015-09-21 20:57:41 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if resp != nil {
|
|
|
|
t.Fatalf("bad: %v", resp)
|
|
|
|
}
|
2015-03-15 21:26:48 +00:00
|
|
|
}
|
2015-09-21 20:57:41 +00:00
|
|
|
b := testPassthroughBackend()
|
|
|
|
test(b)
|
|
|
|
b = testPassthroughLeasedBackend()
|
|
|
|
test(b)
|
2015-03-15 21:26:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestPassthroughBackend_List(t *testing.T) {
|
2015-09-21 20:57:41 +00:00
|
|
|
test := func(b logical.Backend) {
|
2016-01-07 15:30:47 +00:00
|
|
|
req := logical.TestRequest(t, logical.UpdateOperation, "foo")
|
2015-09-21 20:57:41 +00:00
|
|
|
req.Data["raw"] = "test"
|
|
|
|
storage := req.Storage
|
|
|
|
|
2018-01-08 18:31:38 +00:00
|
|
|
if _, err := b.HandleRequest(context.Background(), req); err != nil {
|
2015-09-21 20:57:41 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
req = logical.TestRequest(t, logical.ListOperation, "")
|
|
|
|
req.Storage = storage
|
2018-01-08 18:31:38 +00:00
|
|
|
resp, err := b.HandleRequest(context.Background(), req)
|
2015-09-21 20:57:41 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expected := &logical.Response{
|
|
|
|
Data: map[string]interface{}{
|
|
|
|
"keys": []string{"foo"},
|
|
|
|
},
|
|
|
|
}
|
2015-03-15 21:26:48 +00:00
|
|
|
|
2015-09-21 20:57:41 +00:00
|
|
|
if !reflect.DeepEqual(resp, expected) {
|
|
|
|
t.Fatalf("bad response.\n\nexpected: %#v\n\nGot: %#v", expected, resp)
|
|
|
|
}
|
2015-03-15 21:26:48 +00:00
|
|
|
}
|
2015-09-21 20:57:41 +00:00
|
|
|
b := testPassthroughBackend()
|
|
|
|
test(b)
|
|
|
|
b = testPassthroughLeasedBackend()
|
|
|
|
test(b)
|
2015-03-15 21:26:48 +00:00
|
|
|
}
|
2015-03-16 00:07:54 +00:00
|
|
|
|
2015-10-07 15:42:23 +00:00
|
|
|
func TestPassthroughBackend_Revoke(t *testing.T) {
|
2022-12-15 18:09:36 +00:00
|
|
|
test := func(t *testing.T, b logical.Backend) {
|
|
|
|
t.Helper()
|
2017-09-15 13:02:29 +00:00
|
|
|
req := logical.TestRequest(t, logical.RevokeOperation, "kv")
|
2015-10-07 15:42:23 +00:00
|
|
|
req.Secret = &logical.Secret{
|
|
|
|
InternalData: map[string]interface{}{
|
2017-09-15 13:02:29 +00:00
|
|
|
"secret_type": "kv",
|
2015-10-07 15:42:23 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2018-01-08 18:31:38 +00:00
|
|
|
if _, err := b.HandleRequest(context.Background(), req); err != nil {
|
2015-10-07 15:42:23 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
2022-12-15 18:09:36 +00:00
|
|
|
t.Run("passthrough", func(t *testing.T) {
|
|
|
|
test(t, testPassthroughBackend())
|
|
|
|
})
|
|
|
|
t.Run("passthrough-leased", func(t *testing.T) {
|
|
|
|
test(t, testPassthroughLeasedBackend())
|
|
|
|
})
|
2015-10-07 15:42:23 +00:00
|
|
|
}
|
|
|
|
|
2015-03-16 00:07:54 +00:00
|
|
|
func testPassthroughBackend() logical.Backend {
|
2018-01-19 06:44:44 +00:00
|
|
|
b, _ := PassthroughBackendFactory(context.Background(), &logical.BackendConfig{
|
2015-09-04 20:58:12 +00:00
|
|
|
Logger: nil,
|
|
|
|
System: logical.StaticSystemView{
|
|
|
|
DefaultLeaseTTLVal: time.Hour * 24,
|
2016-09-28 22:32:49 +00:00
|
|
|
MaxLeaseTTLVal: time.Hour * 24 * 32,
|
2015-09-04 20:58:12 +00:00
|
|
|
},
|
|
|
|
})
|
2015-03-16 00:07:54 +00:00
|
|
|
return b
|
|
|
|
}
|
2015-09-19 22:24:53 +00:00
|
|
|
|
|
|
|
func testPassthroughLeasedBackend() logical.Backend {
|
2018-01-19 06:44:44 +00:00
|
|
|
b, _ := LeasedPassthroughBackendFactory(context.Background(), &logical.BackendConfig{
|
2015-09-19 22:24:53 +00:00
|
|
|
Logger: nil,
|
|
|
|
System: logical.StaticSystemView{
|
|
|
|
DefaultLeaseTTLVal: time.Hour * 24,
|
2016-09-28 22:32:49 +00:00
|
|
|
MaxLeaseTTLVal: time.Hour * 24 * 32,
|
2015-09-19 22:24:53 +00:00
|
|
|
},
|
|
|
|
})
|
|
|
|
return b
|
|
|
|
}
|