github.com/hashicorp/vault/sdk@v0.13.0/physical/file/file_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package file
     5  
     6  import (
     7  	"context"
     8  	"encoding/json"
     9  	"io/ioutil"
    10  	"os"
    11  	"path/filepath"
    12  	"reflect"
    13  	"testing"
    14  
    15  	log "github.com/hashicorp/go-hclog"
    16  	"github.com/hashicorp/vault/sdk/helper/logging"
    17  	"github.com/hashicorp/vault/sdk/physical"
    18  )
    19  
    20  func TestFileBackend_Base64URLEncoding(t *testing.T) {
    21  	backendPath, err := ioutil.TempDir("", "vault")
    22  	if err != nil {
    23  		t.Fatalf("err: %s", err)
    24  	}
    25  	defer os.RemoveAll(backendPath)
    26  
    27  	logger := logging.NewVaultLogger(log.Debug)
    28  
    29  	b, err := NewFileBackend(map[string]string{
    30  		"path": backendPath,
    31  	}, logger)
    32  	if err != nil {
    33  		t.Fatalf("err: %s", err)
    34  	}
    35  
    36  	// List the entries. Length should be zero.
    37  	keys, err := b.List(context.Background(), "")
    38  	if err != nil {
    39  		t.Fatalf("err: %v", err)
    40  	}
    41  	if len(keys) != 0 {
    42  		t.Fatalf("bad: len(keys): expected: 0, actual: %d", len(keys))
    43  	}
    44  
    45  	// Create a storage entry without base64 encoding the file name
    46  	rawFullPath := filepath.Join(backendPath, "_foo")
    47  	e := &physical.Entry{Key: "foo", Value: []byte("test")}
    48  	f, err := os.OpenFile(
    49  		rawFullPath,
    50  		os.O_CREATE|os.O_TRUNC|os.O_WRONLY,
    51  		0o600)
    52  	if err != nil {
    53  		t.Fatal(err)
    54  	}
    55  	json.NewEncoder(f).Encode(e)
    56  	f.Close()
    57  
    58  	// Get should work
    59  	out, err := b.Get(context.Background(), "foo")
    60  	if err != nil {
    61  		t.Fatalf("err: %v", err)
    62  	}
    63  	if !reflect.DeepEqual(out, e) {
    64  		t.Fatalf("bad: %v expected: %v", out, e)
    65  	}
    66  
    67  	// List the entries. There should be one entry.
    68  	keys, err = b.List(context.Background(), "")
    69  	if err != nil {
    70  		t.Fatalf("err: %v", err)
    71  	}
    72  	if len(keys) != 1 {
    73  		t.Fatalf("bad: len(keys): expected: 1, actual: %d", len(keys))
    74  	}
    75  
    76  	err = b.Put(context.Background(), e)
    77  	if err != nil {
    78  		t.Fatalf("err: %v", err)
    79  	}
    80  
    81  	// List the entries again. There should still be one entry.
    82  	keys, err = b.List(context.Background(), "")
    83  	if err != nil {
    84  		t.Fatalf("err: %v", err)
    85  	}
    86  	if len(keys) != 1 {
    87  		t.Fatalf("bad: len(keys): expected: 1, actual: %d", len(keys))
    88  	}
    89  
    90  	// Get should work
    91  	out, err = b.Get(context.Background(), "foo")
    92  	if err != nil {
    93  		t.Fatalf("err: %v", err)
    94  	}
    95  	if !reflect.DeepEqual(out, e) {
    96  		t.Fatalf("bad: %v expected: %v", out, e)
    97  	}
    98  
    99  	err = b.Delete(context.Background(), "foo")
   100  	if err != nil {
   101  		t.Fatalf("err: %v", err)
   102  	}
   103  
   104  	out, err = b.Get(context.Background(), "foo")
   105  	if err != nil {
   106  		t.Fatalf("err: %v", err)
   107  	}
   108  	if out != nil {
   109  		t.Fatalf("bad: entry: expected: nil, actual: %#v", e)
   110  	}
   111  
   112  	keys, err = b.List(context.Background(), "")
   113  	if err != nil {
   114  		t.Fatalf("err: %v", err)
   115  	}
   116  	if len(keys) != 0 {
   117  		t.Fatalf("bad: len(keys): expected: 0, actual: %d", len(keys))
   118  	}
   119  
   120  	f, err = os.OpenFile(
   121  		rawFullPath,
   122  		os.O_CREATE|os.O_TRUNC|os.O_WRONLY,
   123  		0o600)
   124  	if err != nil {
   125  		t.Fatal(err)
   126  	}
   127  	json.NewEncoder(f).Encode(e)
   128  	f.Close()
   129  
   130  	keys, err = b.List(context.Background(), "")
   131  	if err != nil {
   132  		t.Fatalf("err: %v", err)
   133  	}
   134  	if len(keys) != 1 {
   135  		t.Fatalf("bad: len(keys): expected: 1, actual: %d", len(keys))
   136  	}
   137  }
   138  
   139  func TestFileBackend_ValidatePath(t *testing.T) {
   140  	dir, err := ioutil.TempDir("", "vault")
   141  	if err != nil {
   142  		t.Fatalf("err: %s", err)
   143  	}
   144  	defer os.RemoveAll(dir)
   145  
   146  	logger := logging.NewVaultLogger(log.Debug)
   147  
   148  	b, err := NewFileBackend(map[string]string{
   149  		"path": dir,
   150  	}, logger)
   151  	if err != nil {
   152  		t.Fatalf("err: %s", err)
   153  	}
   154  
   155  	if err := b.Delete(context.Background(), "foo/bar/../zip"); err == nil {
   156  		t.Fatal("expected error")
   157  	}
   158  	if err := b.Delete(context.Background(), "foo/bar/zip"); err != nil {
   159  		t.Fatal("did not expect error")
   160  	}
   161  }
   162  
   163  func TestFileBackend(t *testing.T) {
   164  	dir, err := ioutil.TempDir("", "vault")
   165  	if err != nil {
   166  		t.Fatalf("err: %s", err)
   167  	}
   168  	defer os.RemoveAll(dir)
   169  
   170  	logger := logging.NewVaultLogger(log.Debug)
   171  
   172  	b, err := NewFileBackend(map[string]string{
   173  		"path": dir,
   174  	}, logger)
   175  	if err != nil {
   176  		t.Fatalf("err: %s", err)
   177  	}
   178  
   179  	physical.ExerciseBackend(t, b)
   180  
   181  	// Underscores should not trip things up; ref GH-3476
   182  	e := &physical.Entry{Key: "_zip", Value: []byte("foobar")}
   183  	err = b.Put(context.Background(), e)
   184  	if err != nil {
   185  		t.Fatalf("err: %v", err)
   186  	}
   187  	e = &physical.Entry{Key: "_zip/_zap", Value: []byte("boofar")}
   188  	err = b.Put(context.Background(), e)
   189  	if err != nil {
   190  		t.Fatalf("err: %v", err)
   191  	}
   192  	e, err = b.Get(context.Background(), "_zip/_zap")
   193  	if err != nil {
   194  		t.Fatalf("err: %v", err)
   195  	}
   196  	if e == nil {
   197  		t.Fatal("got nil entry")
   198  	}
   199  	vals, err := b.List(context.Background(), "")
   200  	if err != nil {
   201  		t.Fatal(err)
   202  	}
   203  	if len(vals) != 2 || vals[0] == vals[1] {
   204  		t.Fatalf("bad: %v", vals)
   205  	}
   206  	for _, val := range vals {
   207  		if val != "_zip/" && val != "_zip" {
   208  			t.Fatalf("bad val: %v", val)
   209  		}
   210  	}
   211  	vals, err = b.List(context.Background(), "_zip/")
   212  	if err != nil {
   213  		t.Fatal(err)
   214  	}
   215  	if len(vals) != 1 || vals[0] != "_zap" {
   216  		t.Fatalf("bad: %v", vals)
   217  	}
   218  	err = b.Delete(context.Background(), "_zip/_zap")
   219  	if err != nil {
   220  		t.Fatal(err)
   221  	}
   222  	vals, err = b.List(context.Background(), "")
   223  	if err != nil {
   224  		t.Fatal(err)
   225  	}
   226  	if len(vals) != 1 || vals[0] != "_zip" {
   227  		t.Fatalf("bad: %v", vals)
   228  	}
   229  	err = b.Delete(context.Background(), "_zip")
   230  	if err != nil {
   231  		t.Fatal(err)
   232  	}
   233  	vals, err = b.List(context.Background(), "")
   234  	if err != nil {
   235  		t.Fatal(err)
   236  	}
   237  	if len(vals) != 0 {
   238  		t.Fatalf("bad: %v", vals)
   239  	}
   240  
   241  	physical.ExerciseBackend_ListPrefix(t, b)
   242  }
   243  
   244  func TestFileBackendCreateTempKey(t *testing.T) {
   245  	dir := t.TempDir()
   246  
   247  	logger := logging.NewVaultLogger(log.Debug)
   248  
   249  	b, err := NewFileBackend(map[string]string{
   250  		"path": dir,
   251  	}, logger)
   252  	if err != nil {
   253  		t.Fatalf("err: %s", err)
   254  	}
   255  	temp := &physical.Entry{Key: "example.temp", Value: []byte("tempfoo")}
   256  	err = b.Put(context.Background(), temp)
   257  	if err != nil {
   258  		t.Fatalf("err: %v", err)
   259  	}
   260  
   261  	nonTemp := &physical.Entry{Key: "example", Value: []byte("foobar")}
   262  	err = b.Put(context.Background(), nonTemp)
   263  	if err != nil {
   264  		t.Fatalf("err: %v", err)
   265  	}
   266  
   267  	vals, err := b.List(context.Background(), "")
   268  	if err != nil {
   269  		t.Fatal(err)
   270  	}
   271  	if len(vals) != 2 || vals[0] == vals[1] {
   272  		t.Fatalf("bad: %v", vals)
   273  	}
   274  	for _, val := range vals {
   275  		if val != "example.temp" && val != "example" {
   276  			t.Fatalf("bad val: %v", val)
   277  		}
   278  	}
   279  	out, err := b.Get(context.Background(), "example")
   280  	if err != nil {
   281  		t.Fatalf("err: %v", err)
   282  	}
   283  	if !reflect.DeepEqual(out, nonTemp) {
   284  		t.Fatalf("bad: %v expected: %v", out, nonTemp)
   285  	}
   286  	out, err = b.Get(context.Background(), "example.temp")
   287  	if err != nil {
   288  		t.Fatalf("err: %v", err)
   289  	}
   290  	if !reflect.DeepEqual(out, temp) {
   291  		t.Fatalf("bad: %v expected: %v", out, temp)
   292  	}
   293  }