1package vault
2
3import (
4	"context"
5	"crypto/sha256"
6	"encoding/base64"
7	"encoding/hex"
8	"fmt"
9	"io/ioutil"
10	"os"
11	"path/filepath"
12	"reflect"
13	"strings"
14	"testing"
15	"time"
16
17	"github.com/fatih/structs"
18	"github.com/go-test/deep"
19	hclog "github.com/hashicorp/go-hclog"
20	"github.com/hashicorp/vault/audit"
21	"github.com/hashicorp/vault/helper/builtinplugins"
22	"github.com/hashicorp/vault/helper/identity"
23	"github.com/hashicorp/vault/helper/namespace"
24	"github.com/hashicorp/vault/sdk/framework"
25	"github.com/hashicorp/vault/sdk/helper/consts"
26	"github.com/hashicorp/vault/sdk/helper/jsonutil"
27	"github.com/hashicorp/vault/sdk/helper/salt"
28	"github.com/hashicorp/vault/sdk/logical"
29	"github.com/hashicorp/vault/sdk/version"
30	"github.com/mitchellh/mapstructure"
31)
32
33func TestSystemBackend_RootPaths(t *testing.T) {
34	expected := []string{
35		"auth/*",
36		"remount",
37		"audit",
38		"audit/*",
39		"raw",
40		"raw/*",
41		"replication/primary/secondary-token",
42		"replication/performance/primary/secondary-token",
43		"replication/dr/primary/secondary-token",
44		"replication/reindex",
45		"replication/dr/reindex",
46		"replication/performance/reindex",
47		"rotate",
48		"config/cors",
49		"config/auditing/*",
50		"config/ui/headers/*",
51		"plugins/catalog/*",
52		"revoke-prefix/*",
53		"revoke-force/*",
54		"leases/revoke-prefix/*",
55		"leases/revoke-force/*",
56		"leases/lookup/*",
57	}
58
59	b := testSystemBackend(t)
60	actual := b.SpecialPaths().Root
61	if !reflect.DeepEqual(actual, expected) {
62		t.Fatalf("bad: mismatch\nexpected:\n%#v\ngot:\n%#v", expected, actual)
63	}
64}
65
66func TestSystemConfigCORS(t *testing.T) {
67	b := testSystemBackend(t)
68	_, barrier, _ := mockBarrier(t)
69	view := NewBarrierView(barrier, "")
70	b.(*SystemBackend).Core.systemBarrierView = view
71
72	req := logical.TestRequest(t, logical.UpdateOperation, "config/cors")
73	req.Data["allowed_origins"] = "http://www.example.com"
74	req.Data["allowed_headers"] = "X-Custom-Header"
75	_, err := b.HandleRequest(namespace.RootContext(nil), req)
76	if err != nil {
77		t.Fatal(err)
78	}
79
80	expected := &logical.Response{
81		Data: map[string]interface{}{
82			"enabled":         true,
83			"allowed_origins": []string{"http://www.example.com"},
84			"allowed_headers": append(StdAllowedHeaders, "X-Custom-Header"),
85		},
86	}
87
88	req = logical.TestRequest(t, logical.ReadOperation, "config/cors")
89	actual, err := b.HandleRequest(namespace.RootContext(nil), req)
90	if err != nil {
91		t.Fatalf("err: %v", err)
92	}
93
94	if !reflect.DeepEqual(actual, expected) {
95		t.Fatalf("bad: %#v", actual)
96	}
97
98	// Do it again. Bug #6182
99	req = logical.TestRequest(t, logical.UpdateOperation, "config/cors")
100	req.Data["allowed_origins"] = "http://www.example.com"
101	req.Data["allowed_headers"] = "X-Custom-Header"
102	_, err = b.HandleRequest(namespace.RootContext(nil), req)
103	if err != nil {
104		t.Fatal(err)
105	}
106
107	req = logical.TestRequest(t, logical.ReadOperation, "config/cors")
108	actual, err = b.HandleRequest(namespace.RootContext(nil), req)
109	if err != nil {
110		t.Fatalf("err: %v", err)
111	}
112
113	if !reflect.DeepEqual(actual, expected) {
114		t.Fatalf("bad: %#v", actual)
115	}
116
117	req = logical.TestRequest(t, logical.DeleteOperation, "config/cors")
118	_, err = b.HandleRequest(namespace.RootContext(nil), req)
119	if err != nil {
120		t.Fatalf("err: %v", err)
121	}
122
123	req = logical.TestRequest(t, logical.ReadOperation, "config/cors")
124	actual, err = b.HandleRequest(namespace.RootContext(nil), req)
125	if err != nil {
126		t.Fatalf("err: %v", err)
127	}
128
129	expected = &logical.Response{
130		Data: map[string]interface{}{
131			"enabled": false,
132		},
133	}
134
135	if !reflect.DeepEqual(actual, expected) {
136		t.Fatalf("DELETE FAILED -- bad: %#v", actual)
137	}
138
139}
140
141func TestSystemBackend_mounts(t *testing.T) {
142	b := testSystemBackend(t)
143	req := logical.TestRequest(t, logical.ReadOperation, "mounts")
144	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
145	if err != nil {
146		t.Fatalf("err: %v", err)
147	}
148
149	// We can't know the pointer address ahead of time so simply
150	// copy what's given
151	exp := map[string]interface{}{
152		"secret/": map[string]interface{}{
153			"type":                    "kv",
154			"external_entropy_access": false,
155			"description":             "key/value secret storage",
156			"accessor":                resp.Data["secret/"].(map[string]interface{})["accessor"],
157			"uuid":                    resp.Data["secret/"].(map[string]interface{})["uuid"],
158			"config": map[string]interface{}{
159				"default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
160				"max_lease_ttl":     resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
161				"force_no_cache":    false,
162			},
163			"local":     false,
164			"seal_wrap": false,
165			"options": map[string]string{
166				"version": "1",
167			},
168		},
169		"sys/": map[string]interface{}{
170			"type":                    "system",
171			"external_entropy_access": false,
172			"description":             "system endpoints used for control, policy and debugging",
173			"accessor":                resp.Data["sys/"].(map[string]interface{})["accessor"],
174			"uuid":                    resp.Data["sys/"].(map[string]interface{})["uuid"],
175			"config": map[string]interface{}{
176				"default_lease_ttl":           resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
177				"max_lease_ttl":               resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
178				"force_no_cache":              false,
179				"passthrough_request_headers": []string{"Accept"},
180			},
181			"local":     false,
182			"seal_wrap": false,
183			"options":   map[string]string(nil),
184		},
185		"cubbyhole/": map[string]interface{}{
186			"description":             "per-token private secret storage",
187			"type":                    "cubbyhole",
188			"external_entropy_access": false,
189			"accessor":                resp.Data["cubbyhole/"].(map[string]interface{})["accessor"],
190			"uuid":                    resp.Data["cubbyhole/"].(map[string]interface{})["uuid"],
191			"config": map[string]interface{}{
192				"default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
193				"max_lease_ttl":     resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
194				"force_no_cache":    false,
195			},
196			"local":     true,
197			"seal_wrap": false,
198			"options":   map[string]string(nil),
199		},
200		"identity/": map[string]interface{}{
201			"description":             "identity store",
202			"type":                    "identity",
203			"external_entropy_access": false,
204			"accessor":                resp.Data["identity/"].(map[string]interface{})["accessor"],
205			"uuid":                    resp.Data["identity/"].(map[string]interface{})["uuid"],
206			"config": map[string]interface{}{
207				"default_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
208				"max_lease_ttl":     resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
209				"force_no_cache":    false,
210			},
211			"local":     false,
212			"seal_wrap": false,
213			"options":   map[string]string(nil),
214		},
215	}
216	if diff := deep.Equal(resp.Data, exp); len(diff) > 0 {
217		t.Fatalf("bad, diff: %#v", diff)
218	}
219}
220
221func TestSystemBackend_mount(t *testing.T) {
222	b := testSystemBackend(t)
223
224	req := logical.TestRequest(t, logical.UpdateOperation, "mounts/prod/secret/")
225	req.Data["type"] = "kv"
226	req.Data["config"] = map[string]interface{}{
227		"default_lease_ttl": "35m",
228		"max_lease_ttl":     "45m",
229	}
230	req.Data["local"] = true
231	req.Data["seal_wrap"] = true
232	req.Data["options"] = map[string]string{
233		"version": "1",
234	}
235
236	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
237	if err != nil {
238		t.Fatalf("err: %v", err)
239	}
240	if resp != nil {
241		t.Fatalf("bad: %v", resp)
242	}
243
244	req = logical.TestRequest(t, logical.ReadOperation, "mounts")
245	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
246	if err != nil {
247		t.Fatalf("err: %v", err)
248	}
249
250	// We can't know the pointer address ahead of time so simply
251	// copy what's given
252	exp := map[string]interface{}{
253		"secret/": map[string]interface{}{
254			"type":                    "kv",
255			"external_entropy_access": false,
256			"description":             "key/value secret storage",
257			"accessor":                resp.Data["secret/"].(map[string]interface{})["accessor"],
258			"uuid":                    resp.Data["secret/"].(map[string]interface{})["uuid"],
259			"config": map[string]interface{}{
260				"default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
261				"max_lease_ttl":     resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
262				"force_no_cache":    false,
263			},
264			"local":     false,
265			"seal_wrap": false,
266			"options": map[string]string{
267				"version": "1",
268			},
269		},
270		"sys/": map[string]interface{}{
271			"type":                    "system",
272			"external_entropy_access": false,
273			"description":             "system endpoints used for control, policy and debugging",
274			"accessor":                resp.Data["sys/"].(map[string]interface{})["accessor"],
275			"uuid":                    resp.Data["sys/"].(map[string]interface{})["uuid"],
276			"config": map[string]interface{}{
277				"default_lease_ttl":           resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
278				"max_lease_ttl":               resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
279				"force_no_cache":              false,
280				"passthrough_request_headers": []string{"Accept"},
281			},
282			"local":     false,
283			"seal_wrap": false,
284			"options":   map[string]string(nil),
285		},
286		"cubbyhole/": map[string]interface{}{
287			"description":             "per-token private secret storage",
288			"type":                    "cubbyhole",
289			"external_entropy_access": false,
290			"accessor":                resp.Data["cubbyhole/"].(map[string]interface{})["accessor"],
291			"uuid":                    resp.Data["cubbyhole/"].(map[string]interface{})["uuid"],
292			"config": map[string]interface{}{
293				"default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
294				"max_lease_ttl":     resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
295				"force_no_cache":    false,
296			},
297			"local":     true,
298			"seal_wrap": false,
299			"options":   map[string]string(nil),
300		},
301		"identity/": map[string]interface{}{
302			"description":             "identity store",
303			"type":                    "identity",
304			"external_entropy_access": false,
305			"accessor":                resp.Data["identity/"].(map[string]interface{})["accessor"],
306			"uuid":                    resp.Data["identity/"].(map[string]interface{})["uuid"],
307			"config": map[string]interface{}{
308				"default_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
309				"max_lease_ttl":     resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
310				"force_no_cache":    false,
311			},
312			"local":     false,
313			"seal_wrap": false,
314			"options":   map[string]string(nil),
315		},
316		"prod/secret/": map[string]interface{}{
317			"description":             "",
318			"type":                    "kv",
319			"external_entropy_access": false,
320			"accessor":                resp.Data["prod/secret/"].(map[string]interface{})["accessor"],
321			"uuid":                    resp.Data["prod/secret/"].(map[string]interface{})["uuid"],
322			"config": map[string]interface{}{
323				"default_lease_ttl": int64(2100),
324				"max_lease_ttl":     int64(2700),
325				"force_no_cache":    false,
326			},
327			"local":     true,
328			"seal_wrap": true,
329			"options": map[string]string{
330				"version": "1",
331			},
332		},
333	}
334	if diff := deep.Equal(resp.Data, exp); len(diff) > 0 {
335		t.Fatalf("bad: diff: %#v", diff)
336	}
337
338}
339
340func TestSystemBackend_mount_force_no_cache(t *testing.T) {
341	core, b, _ := testCoreSystemBackend(t)
342
343	req := logical.TestRequest(t, logical.UpdateOperation, "mounts/prod/secret/")
344	req.Data["type"] = "kv"
345	req.Data["config"] = map[string]interface{}{
346		"force_no_cache": true,
347	}
348
349	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
350	if err != nil {
351		t.Fatalf("err: %v", err)
352	}
353	if resp != nil {
354		t.Fatalf("bad: %v", resp)
355	}
356
357	mountEntry := core.router.MatchingMountEntry(namespace.RootContext(nil), "prod/secret/")
358	if mountEntry == nil {
359		t.Fatalf("missing mount entry")
360	}
361	if !mountEntry.Config.ForceNoCache {
362		t.Fatalf("bad config %#v", mountEntry)
363	}
364}
365
366func TestSystemBackend_mount_invalid(t *testing.T) {
367	b := testSystemBackend(t)
368
369	req := logical.TestRequest(t, logical.UpdateOperation, "mounts/prod/secret/")
370	req.Data["type"] = "nope"
371	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
372	if err != logical.ErrInvalidRequest {
373		t.Fatalf("err: %v", err)
374	}
375	if resp.Data["error"] != `plugin not found in the catalog: nope` {
376		t.Fatalf("bad: %v", resp)
377	}
378}
379
380func TestSystemBackend_unmount(t *testing.T) {
381	b := testSystemBackend(t)
382
383	req := logical.TestRequest(t, logical.DeleteOperation, "mounts/secret/")
384	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
385	if err != nil {
386		t.Fatalf("err: %v", err)
387	}
388	if resp != nil {
389		t.Fatalf("bad: %v", resp)
390	}
391}
392
393var capabilitiesPolicy = `
394name = "test"
395path "foo/bar*" {
396	capabilities = ["create", "sudo", "update"]
397}
398path "sys/capabilities*" {
399	capabilities = ["update"]
400}
401path "bar/baz" {
402	capabilities = ["read", "update"]
403}
404path "bar/baz" {
405	capabilities = ["delete"]
406}
407`
408
409func TestSystemBackend_PathCapabilities(t *testing.T) {
410	var resp *logical.Response
411	var err error
412
413	core, b, rootToken := testCoreSystemBackend(t)
414
415	policy, _ := ParseACLPolicy(namespace.RootNamespace, capabilitiesPolicy)
416	err = core.policyStore.SetPolicy(namespace.RootContext(nil), policy)
417	if err != nil {
418		t.Fatalf("err: %v", err)
419	}
420
421	path1 := "foo/bar"
422	path2 := "foo/bar/sample"
423	path3 := "sys/capabilities"
424	path4 := "bar/baz"
425
426	rootCheckFunc := func(t *testing.T, resp *logical.Response) {
427		// All the paths should have "root" as the capability
428		expectedRoot := []string{"root"}
429		if !reflect.DeepEqual(resp.Data[path1], expectedRoot) ||
430			!reflect.DeepEqual(resp.Data[path2], expectedRoot) ||
431			!reflect.DeepEqual(resp.Data[path3], expectedRoot) ||
432			!reflect.DeepEqual(resp.Data[path4], expectedRoot) {
433			t.Fatalf("bad: capabilities; expected: %#v, actual: %#v", expectedRoot, resp.Data)
434		}
435	}
436
437	// Check the capabilities using the root token
438	resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
439		Path:      "capabilities",
440		Operation: logical.UpdateOperation,
441		Data: map[string]interface{}{
442			"paths": []string{path1, path2, path3, path4},
443			"token": rootToken,
444		},
445	})
446	if err != nil || (resp != nil && resp.IsError()) {
447		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
448	}
449	rootCheckFunc(t, resp)
450
451	// Check the capabilities using capabilities-self
452	resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
453		ClientToken: rootToken,
454		Path:        "capabilities-self",
455		Operation:   logical.UpdateOperation,
456		Data: map[string]interface{}{
457			"paths": []string{path1, path2, path3, path4},
458		},
459	})
460	if err != nil || (resp != nil && resp.IsError()) {
461		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
462	}
463	rootCheckFunc(t, resp)
464
465	// Lookup the accessor of the root token
466	te, err := core.tokenStore.Lookup(namespace.RootContext(nil), rootToken)
467	if err != nil {
468		t.Fatal(err)
469	}
470
471	// Check the capabilities using capabilities-accessor endpoint
472	resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
473		Path:      "capabilities-accessor",
474		Operation: logical.UpdateOperation,
475		Data: map[string]interface{}{
476			"paths":    []string{path1, path2, path3, path4},
477			"accessor": te.Accessor,
478		},
479	})
480	if err != nil || (resp != nil && resp.IsError()) {
481		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
482	}
483	rootCheckFunc(t, resp)
484
485	// Create a non-root token
486	testMakeServiceTokenViaBackend(t, core.tokenStore, rootToken, "tokenid", "", []string{"test"})
487
488	nonRootCheckFunc := func(t *testing.T, resp *logical.Response) {
489		expected1 := []string{"create", "sudo", "update"}
490		expected2 := expected1
491		expected3 := []string{"update"}
492		expected4 := []string{"delete", "read", "update"}
493
494		if !reflect.DeepEqual(resp.Data[path1], expected1) ||
495			!reflect.DeepEqual(resp.Data[path2], expected2) ||
496			!reflect.DeepEqual(resp.Data[path3], expected3) ||
497			!reflect.DeepEqual(resp.Data[path4], expected4) {
498			t.Fatalf("bad: capabilities; actual: %#v", resp.Data)
499		}
500	}
501
502	// Check the capabilities using a non-root token
503	resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
504		Path:      "capabilities",
505		Operation: logical.UpdateOperation,
506		Data: map[string]interface{}{
507			"paths": []string{path1, path2, path3, path4},
508			"token": "tokenid",
509		},
510	})
511	if err != nil || (resp != nil && resp.IsError()) {
512		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
513	}
514	nonRootCheckFunc(t, resp)
515
516	// Check the capabilities of a non-root token using capabilities-self
517	// endpoint
518	resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
519		ClientToken: "tokenid",
520		Path:        "capabilities-self",
521		Operation:   logical.UpdateOperation,
522		Data: map[string]interface{}{
523			"paths": []string{path1, path2, path3, path4},
524		},
525	})
526	if err != nil || (resp != nil && resp.IsError()) {
527		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
528	}
529	nonRootCheckFunc(t, resp)
530
531	// Lookup the accessor of the non-root token
532	te, err = core.tokenStore.Lookup(namespace.RootContext(nil), "tokenid")
533	if err != nil {
534		t.Fatal(err)
535	}
536
537	// Check the capabilities using a non-root token using
538	// capabilities-accessor endpoint
539	resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
540		Path:      "capabilities-accessor",
541		Operation: logical.UpdateOperation,
542		Data: map[string]interface{}{
543			"paths":    []string{path1, path2, path3, path4},
544			"accessor": te.Accessor,
545		},
546	})
547	if err != nil || (resp != nil && resp.IsError()) {
548		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
549	}
550	nonRootCheckFunc(t, resp)
551}
552
553func TestSystemBackend_Capabilities_BC(t *testing.T) {
554	testCapabilities(t, "capabilities")
555	testCapabilities(t, "capabilities-self")
556}
557
558func testCapabilities(t *testing.T, endpoint string) {
559	core, b, rootToken := testCoreSystemBackend(t)
560	req := logical.TestRequest(t, logical.UpdateOperation, endpoint)
561	if endpoint == "capabilities-self" {
562		req.ClientToken = rootToken
563	} else {
564		req.Data["token"] = rootToken
565	}
566	req.Data["path"] = "any_path"
567
568	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
569	if err != nil {
570		t.Fatal(err)
571	}
572	if resp == nil {
573		t.Fatalf("bad: %v", resp)
574	}
575
576	actual := resp.Data["capabilities"]
577	expected := []string{"root"}
578	if !reflect.DeepEqual(actual, expected) {
579		t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected)
580	}
581
582	policy, _ := ParseACLPolicy(namespace.RootNamespace, capabilitiesPolicy)
583	err = core.policyStore.SetPolicy(namespace.RootContext(nil), policy)
584	if err != nil {
585		t.Fatalf("err: %v", err)
586	}
587
588	testMakeServiceTokenViaBackend(t, core.tokenStore, rootToken, "tokenid", "", []string{"test"})
589	req = logical.TestRequest(t, logical.UpdateOperation, endpoint)
590	if endpoint == "capabilities-self" {
591		req.ClientToken = "tokenid"
592	} else {
593		req.Data["token"] = "tokenid"
594	}
595	req.Data["path"] = "foo/bar"
596
597	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
598	if err != nil {
599		t.Fatalf("err: %v", err)
600	}
601	if resp == nil {
602		t.Fatalf("bad: %v", resp)
603	}
604
605	actual = resp.Data["capabilities"]
606	expected = []string{"create", "sudo", "update"}
607	if !reflect.DeepEqual(actual, expected) {
608		t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected)
609	}
610}
611
612func TestSystemBackend_CapabilitiesAccessor_BC(t *testing.T) {
613	core, b, rootToken := testCoreSystemBackend(t)
614	te, err := core.tokenStore.Lookup(namespace.RootContext(nil), rootToken)
615	if err != nil {
616		t.Fatal(err)
617	}
618
619	req := logical.TestRequest(t, logical.UpdateOperation, "capabilities-accessor")
620	// Accessor of root token
621	req.Data["accessor"] = te.Accessor
622	req.Data["path"] = "any_path"
623
624	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
625	if err != nil {
626		t.Fatalf("err: %v", err)
627	}
628	if resp == nil {
629		t.Fatalf("bad: %v", resp)
630	}
631
632	actual := resp.Data["capabilities"]
633	expected := []string{"root"}
634	if !reflect.DeepEqual(actual, expected) {
635		t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected)
636	}
637
638	policy, _ := ParseACLPolicy(namespace.RootNamespace, capabilitiesPolicy)
639	err = core.policyStore.SetPolicy(namespace.RootContext(nil), policy)
640	if err != nil {
641		t.Fatalf("err: %v", err)
642	}
643
644	testMakeServiceTokenViaBackend(t, core.tokenStore, rootToken, "tokenid", "", []string{"test"})
645
646	te, err = core.tokenStore.Lookup(namespace.RootContext(nil), "tokenid")
647	if err != nil {
648		t.Fatal(err)
649	}
650
651	req = logical.TestRequest(t, logical.UpdateOperation, "capabilities-accessor")
652	req.Data["accessor"] = te.Accessor
653	req.Data["path"] = "foo/bar"
654
655	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
656	if err != nil {
657		t.Fatalf("err: %v", err)
658	}
659	if resp == nil {
660		t.Fatalf("bad: %v", resp)
661	}
662
663	actual = resp.Data["capabilities"]
664	expected = []string{"create", "sudo", "update"}
665	if !reflect.DeepEqual(actual, expected) {
666		t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected)
667	}
668}
669
670func TestSystemBackend_remount(t *testing.T) {
671	b := testSystemBackend(t)
672
673	req := logical.TestRequest(t, logical.UpdateOperation, "remount")
674	req.Data["from"] = "secret"
675	req.Data["to"] = "foo"
676	req.Data["config"] = structs.Map(MountConfig{})
677	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
678	if err != nil {
679		t.Fatalf("err: %v", err)
680	}
681	if resp != nil {
682		t.Fatalf("bad: %v", resp)
683	}
684}
685
686func TestSystemBackend_remount_invalid(t *testing.T) {
687	b := testSystemBackend(t)
688
689	req := logical.TestRequest(t, logical.UpdateOperation, "remount")
690	req.Data["from"] = "unknown"
691	req.Data["to"] = "foo"
692	req.Data["config"] = structs.Map(MountConfig{})
693	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
694	if err != logical.ErrInvalidRequest {
695		t.Fatalf("err: %v", err)
696	}
697	if resp.Data["error"] != `no matching mount at "unknown/"` {
698		t.Fatalf("bad: %v", resp)
699	}
700}
701
702func TestSystemBackend_remount_system(t *testing.T) {
703	b := testSystemBackend(t)
704
705	req := logical.TestRequest(t, logical.UpdateOperation, "remount")
706	req.Data["from"] = "sys"
707	req.Data["to"] = "foo"
708	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
709	if err != logical.ErrInvalidRequest {
710		t.Fatalf("err: %v", err)
711	}
712	if resp.Data["error"] != `cannot remount "sys/"` {
713		t.Fatalf("bad: %v", resp)
714	}
715}
716
717func TestSystemBackend_leases(t *testing.T) {
718	core, b, root := testCoreSystemBackend(t)
719
720	// Create a key with a lease
721	req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
722	req.Data["foo"] = "bar"
723	req.ClientToken = root
724	resp, err := core.HandleRequest(namespace.RootContext(nil), req)
725	if err != nil {
726		t.Fatalf("err: %v", err)
727	}
728	if resp != nil {
729		t.Fatalf("bad: %#v", resp)
730	}
731
732	// Read a key with a LeaseID
733	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
734	req.ClientToken = root
735	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
736	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
737	if err != nil {
738		t.Fatalf("err: %v", err)
739	}
740	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
741		t.Fatalf("bad: %#v", resp)
742	}
743
744	// Read lease
745	req = logical.TestRequest(t, logical.UpdateOperation, "leases/lookup")
746	req.Data["lease_id"] = resp.Secret.LeaseID
747	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
748	if err != nil {
749		t.Fatalf("err: %v", err)
750	}
751	if resp.Data["renewable"] == nil || resp.Data["renewable"].(bool) {
752		t.Fatal("kv leases are not renewable")
753	}
754
755	// Invalid lease
756	req = logical.TestRequest(t, logical.UpdateOperation, "leases/lookup")
757	req.Data["lease_id"] = "invalid"
758	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
759	if err != logical.ErrInvalidRequest {
760		t.Fatalf("expected invalid request, got err: %v", err)
761	}
762}
763
764func TestSystemBackend_leases_list(t *testing.T) {
765	core, b, root := testCoreSystemBackend(t)
766
767	// Create a key with a lease
768	req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
769	req.Data["foo"] = "bar"
770	req.ClientToken = root
771	resp, err := core.HandleRequest(namespace.RootContext(nil), req)
772	if err != nil {
773		t.Fatalf("err: %v", err)
774	}
775	if resp != nil {
776		t.Fatalf("bad: %#v", resp)
777	}
778
779	// Read a key with a LeaseID
780	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
781	req.ClientToken = root
782	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
783	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
784	if err != nil {
785		t.Fatalf("err: %v", err)
786	}
787	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
788		t.Fatalf("bad: %#v", resp)
789	}
790
791	// List top level
792	req = logical.TestRequest(t, logical.ListOperation, "leases/lookup/")
793	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
794	if err != nil {
795		t.Fatalf("err: %v", err)
796	}
797	if resp == nil || resp.Data == nil {
798		t.Fatalf("bad: %#v", resp)
799	}
800	var keys []string
801	if err := mapstructure.WeakDecode(resp.Data["keys"], &keys); err != nil {
802		t.Fatalf("err: %v", err)
803	}
804	if len(keys) != 1 {
805		t.Fatalf("Expected 1 subkey lease, got %d: %#v", len(keys), keys)
806	}
807	if keys[0] != "secret/" {
808		t.Fatal("Expected only secret subkey")
809	}
810
811	// List lease
812	req = logical.TestRequest(t, logical.ListOperation, "leases/lookup/secret/foo")
813	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
814	if err != nil {
815		t.Fatalf("err: %v", err)
816	}
817	if resp == nil || resp.Data == nil {
818		t.Fatalf("bad: %#v", resp)
819	}
820	keys = []string{}
821	if err := mapstructure.WeakDecode(resp.Data["keys"], &keys); err != nil {
822		t.Fatalf("err: %v", err)
823	}
824	if len(keys) != 1 {
825		t.Fatalf("Expected 1 secret lease, got %d: %#v", len(keys), keys)
826	}
827
828	// Generate multiple leases
829	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
830	req.ClientToken = root
831	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
832	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
833	if err != nil {
834		t.Fatalf("err: %v", err)
835	}
836	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
837		t.Fatalf("bad: %#v", resp)
838	}
839
840	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
841	req.ClientToken = root
842	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
843	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
844	if err != nil {
845		t.Fatalf("err: %v", err)
846	}
847	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
848		t.Fatalf("bad: %#v", resp)
849	}
850
851	req = logical.TestRequest(t, logical.ListOperation, "leases/lookup/secret/foo")
852	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
853	if err != nil {
854		t.Fatalf("err: %v", err)
855	}
856	if resp == nil || resp.Data == nil {
857		t.Fatalf("bad: %#v", resp)
858	}
859	keys = []string{}
860	if err := mapstructure.WeakDecode(resp.Data["keys"], &keys); err != nil {
861		t.Fatalf("err: %v", err)
862	}
863	if len(keys) != 3 {
864		t.Fatalf("Expected 3 secret lease, got %d: %#v", len(keys), keys)
865	}
866
867	// Listing subkeys
868	req = logical.TestRequest(t, logical.UpdateOperation, "secret/bar")
869	req.Data["foo"] = "bar"
870	req.ClientToken = root
871	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
872	if err != nil {
873		t.Fatalf("err: %v", err)
874	}
875	if resp != nil {
876		t.Fatalf("bad: %#v", resp)
877	}
878
879	// Read a key with a LeaseID
880	req = logical.TestRequest(t, logical.ReadOperation, "secret/bar")
881	req.ClientToken = root
882	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
883	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
884	if err != nil {
885		t.Fatalf("err: %v", err)
886	}
887	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
888		t.Fatalf("bad: %#v", resp)
889	}
890
891	req = logical.TestRequest(t, logical.ListOperation, "leases/lookup/secret")
892	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
893	if err != nil {
894		t.Fatalf("err: %v", err)
895	}
896	if resp == nil || resp.Data == nil {
897		t.Fatalf("bad: %#v", resp)
898	}
899	keys = []string{}
900	if err := mapstructure.WeakDecode(resp.Data["keys"], &keys); err != nil {
901		t.Fatalf("err: %v", err)
902	}
903	if len(keys) != 2 {
904		t.Fatalf("Expected 2 secret lease, got %d: %#v", len(keys), keys)
905	}
906	expected := []string{"bar/", "foo/"}
907	if !reflect.DeepEqual(expected, keys) {
908		t.Fatalf("exp: %#v, act: %#v", expected, keys)
909	}
910}
911
912func TestSystemBackend_renew(t *testing.T) {
913	core, b, root := testCoreSystemBackend(t)
914
915	// Create a key with a lease
916	req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
917	req.Data["foo"] = "bar"
918	req.ClientToken = root
919	resp, err := core.HandleRequest(namespace.RootContext(nil), req)
920	if err != nil {
921		t.Fatalf("err: %v", err)
922	}
923	if resp != nil {
924		t.Fatalf("bad: %#v", resp)
925	}
926
927	// Read a key with a LeaseID
928	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
929	req.ClientToken = root
930	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
931	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
932	if err != nil {
933		t.Fatalf("err: %v", err)
934	}
935	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
936		t.Fatalf("bad: %#v", resp)
937	}
938
939	// Attempt renew
940	req2 := logical.TestRequest(t, logical.UpdateOperation, "leases/renew/"+resp.Secret.LeaseID)
941	resp2, err := b.HandleRequest(namespace.RootContext(nil), req2)
942	if err != logical.ErrInvalidRequest {
943		t.Fatalf("err: %v", err)
944	}
945
946	// Should get error about non-renewability
947	if resp2.Data["error"] != "lease is not renewable" {
948		t.Fatalf("bad: %#v", resp)
949	}
950
951	// Add a TTL to the lease
952	req = logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
953	req.Data["foo"] = "bar"
954	req.Data["ttl"] = "180s"
955	req.ClientToken = root
956	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
957	if err != nil {
958		t.Fatalf("err: %v", err)
959	}
960	if resp != nil {
961		t.Fatalf("bad: %#v", resp)
962	}
963
964	// Read a key with a LeaseID
965	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
966	req.ClientToken = root
967	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
968	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
969	if err != nil {
970		t.Fatalf("err: %v", err)
971	}
972	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
973		t.Fatalf("bad: %#v", resp)
974	}
975
976	// Attempt renew
977	req2 = logical.TestRequest(t, logical.UpdateOperation, "leases/renew/"+resp.Secret.LeaseID)
978	resp2, err = b.HandleRequest(namespace.RootContext(nil), req2)
979	if err != nil {
980		t.Fatalf("err: %v", err)
981	}
982	if resp2.IsError() {
983		t.Fatalf("got an error")
984	}
985	if resp2.Data == nil {
986		t.Fatal("nil data")
987	}
988	if resp.Secret.TTL != 180*time.Second {
989		t.Fatalf("bad lease duration: %v", resp.Secret.TTL)
990	}
991
992	// Test the other route path
993	req2 = logical.TestRequest(t, logical.UpdateOperation, "leases/renew")
994	req2.Data["lease_id"] = resp.Secret.LeaseID
995	resp2, err = b.HandleRequest(namespace.RootContext(nil), req2)
996	if err != nil {
997		t.Fatalf("err: %v", err)
998	}
999	if resp2.IsError() {
1000		t.Fatalf("got an error")
1001	}
1002	if resp2.Data == nil {
1003		t.Fatal("nil data")
1004	}
1005	if resp.Secret.TTL != 180*time.Second {
1006		t.Fatalf("bad lease duration: %v", resp.Secret.TTL)
1007	}
1008
1009	// Test orig path
1010	req2 = logical.TestRequest(t, logical.UpdateOperation, "renew")
1011	req2.Data["lease_id"] = resp.Secret.LeaseID
1012	resp2, err = b.HandleRequest(namespace.RootContext(nil), req2)
1013	if err != nil {
1014		t.Fatalf("err: %v", err)
1015	}
1016	if resp2.IsError() {
1017		t.Fatalf("got an error")
1018	}
1019	if resp2.Data == nil {
1020		t.Fatal("nil data")
1021	}
1022	if resp.Secret.TTL != time.Second*180 {
1023		t.Fatalf("bad lease duration: %v", resp.Secret.TTL)
1024	}
1025}
1026
1027func TestSystemBackend_renew_invalidID(t *testing.T) {
1028	b := testSystemBackend(t)
1029
1030	// Attempt renew
1031	req := logical.TestRequest(t, logical.UpdateOperation, "leases/renew/foobarbaz")
1032	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1033	if err != logical.ErrInvalidRequest {
1034		t.Fatalf("err: %v", err)
1035	}
1036	if resp.Data["error"] != "lease not found" {
1037		t.Fatalf("bad: %v", resp)
1038	}
1039
1040	// Attempt renew with other method
1041	req = logical.TestRequest(t, logical.UpdateOperation, "leases/renew")
1042	req.Data["lease_id"] = "foobarbaz"
1043	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1044	if err != logical.ErrInvalidRequest {
1045		t.Fatalf("err: %v", err)
1046	}
1047	if resp.Data["error"] != "lease not found" {
1048		t.Fatalf("bad: %v", resp)
1049	}
1050}
1051
1052func TestSystemBackend_renew_invalidID_origUrl(t *testing.T) {
1053	b := testSystemBackend(t)
1054
1055	// Attempt renew
1056	req := logical.TestRequest(t, logical.UpdateOperation, "renew/foobarbaz")
1057	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1058	if err != logical.ErrInvalidRequest {
1059		t.Fatalf("err: %v", err)
1060	}
1061	if resp.Data["error"] != "lease not found" {
1062		t.Fatalf("bad: %v", resp)
1063	}
1064
1065	// Attempt renew with other method
1066	req = logical.TestRequest(t, logical.UpdateOperation, "renew")
1067	req.Data["lease_id"] = "foobarbaz"
1068	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1069	if err != logical.ErrInvalidRequest {
1070		t.Fatalf("err: %v", err)
1071	}
1072	if resp.Data["error"] != "lease not found" {
1073		t.Fatalf("bad: %v", resp)
1074	}
1075}
1076
1077func TestSystemBackend_revoke(t *testing.T) {
1078	core, b, root := testCoreSystemBackend(t)
1079
1080	// Create a key with a lease
1081	req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
1082	req.Data["foo"] = "bar"
1083	req.Data["lease"] = "1h"
1084	req.ClientToken = root
1085	resp, err := core.HandleRequest(namespace.RootContext(nil), req)
1086	if err != nil {
1087		t.Fatalf("err: %v", err)
1088	}
1089	if resp != nil {
1090		t.Fatalf("bad: %#v", resp)
1091	}
1092
1093	// Read a key with a LeaseID
1094	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
1095	req.ClientToken = root
1096	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
1097	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
1098	if err != nil {
1099		t.Fatalf("err: %v", err)
1100	}
1101	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
1102		t.Fatalf("bad: %#v", resp)
1103	}
1104
1105	// Attempt revoke
1106	req2 := logical.TestRequest(t, logical.UpdateOperation, "revoke/"+resp.Secret.LeaseID)
1107	resp2, err := b.HandleRequest(namespace.RootContext(nil), req2)
1108	if err != nil {
1109		t.Fatalf("err: %v %#v", err, resp2)
1110	}
1111	if resp2 != nil {
1112		t.Fatalf("bad: %#v", resp)
1113	}
1114
1115	// Attempt renew
1116	req3 := logical.TestRequest(t, logical.UpdateOperation, "renew/"+resp.Secret.LeaseID)
1117	resp3, err := b.HandleRequest(namespace.RootContext(nil), req3)
1118	if err != logical.ErrInvalidRequest {
1119		t.Fatalf("err: %v", err)
1120	}
1121	if resp3.Data["error"] != "lease not found" {
1122		t.Fatalf("bad: %v", *resp3)
1123	}
1124
1125	// Read a key with a LeaseID
1126	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
1127	req.ClientToken = root
1128	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
1129	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
1130	if err != nil {
1131		t.Fatalf("err: %v", err)
1132	}
1133	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
1134		t.Fatalf("bad: %#v", resp)
1135	}
1136
1137	// Test the other route path
1138	req2 = logical.TestRequest(t, logical.UpdateOperation, "revoke")
1139	req2.Data["lease_id"] = resp.Secret.LeaseID
1140	resp2, err = b.HandleRequest(namespace.RootContext(nil), req2)
1141	if err != nil {
1142		t.Fatalf("err: %v %#v", err, resp2)
1143	}
1144	if resp2 != nil {
1145		t.Fatalf("bad: %#v", resp)
1146	}
1147
1148	// Read a key with a LeaseID
1149	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
1150	req.ClientToken = root
1151	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
1152	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
1153	if err != nil {
1154		t.Fatalf("err: %v", err)
1155	}
1156	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
1157		t.Fatalf("bad: %#v", resp)
1158	}
1159
1160	// Test the other route path
1161	req2 = logical.TestRequest(t, logical.UpdateOperation, "leases/revoke")
1162	req2.Data["lease_id"] = resp.Secret.LeaseID
1163	resp2, err = b.HandleRequest(namespace.RootContext(nil), req2)
1164	if err != nil {
1165		t.Fatalf("err: %v %#v", err, resp2)
1166	}
1167	if resp2 != nil {
1168		t.Fatalf("bad: %#v", resp)
1169	}
1170}
1171
1172func TestSystemBackend_revoke_invalidID(t *testing.T) {
1173	b := testSystemBackend(t)
1174
1175	// Attempt revoke
1176	req := logical.TestRequest(t, logical.UpdateOperation, "leases/revoke/foobarbaz")
1177	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1178	if err != nil {
1179		t.Fatalf("err: %v", err)
1180	}
1181	if resp != nil {
1182		t.Fatalf("bad: %v", resp)
1183	}
1184
1185	// Attempt revoke with other method
1186	req = logical.TestRequest(t, logical.UpdateOperation, "leases/revoke")
1187	req.Data["lease_id"] = "foobarbaz"
1188	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1189	if err != nil {
1190		t.Fatalf("err: %v", err)
1191	}
1192	if resp != nil {
1193		t.Fatalf("bad: %v", resp)
1194	}
1195}
1196
1197func TestSystemBackend_revoke_invalidID_origUrl(t *testing.T) {
1198	b := testSystemBackend(t)
1199
1200	// Attempt revoke
1201	req := logical.TestRequest(t, logical.UpdateOperation, "revoke/foobarbaz")
1202	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1203	if err != nil {
1204		t.Fatalf("err: %v", err)
1205	}
1206	if resp != nil {
1207		t.Fatalf("bad: %v", resp)
1208	}
1209
1210	// Attempt revoke with other method
1211	req = logical.TestRequest(t, logical.UpdateOperation, "revoke")
1212	req.Data["lease_id"] = "foobarbaz"
1213	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1214	if err != nil {
1215		t.Fatalf("err: %v", err)
1216	}
1217	if resp != nil {
1218		t.Fatalf("bad: %v", resp)
1219	}
1220}
1221
1222func TestSystemBackend_revokePrefix(t *testing.T) {
1223	core, b, root := testCoreSystemBackend(t)
1224
1225	// Create a key with a lease
1226	req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
1227	req.Data["foo"] = "bar"
1228	req.Data["lease"] = "1h"
1229	req.ClientToken = root
1230	resp, err := core.HandleRequest(namespace.RootContext(nil), req)
1231	if err != nil {
1232		t.Fatalf("err: %v", err)
1233	}
1234	if resp != nil {
1235		t.Fatalf("bad: %#v", resp)
1236	}
1237
1238	// Read a key with a LeaseID
1239	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
1240	req.ClientToken = root
1241	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
1242	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
1243	if err != nil {
1244		t.Fatalf("err: %v", err)
1245	}
1246	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
1247		t.Fatalf("bad: %#v", resp)
1248	}
1249
1250	// Attempt revoke
1251	req2 := logical.TestRequest(t, logical.UpdateOperation, "leases/revoke-prefix/secret/")
1252	resp2, err := b.HandleRequest(namespace.RootContext(nil), req2)
1253	if err != nil {
1254		t.Fatalf("err: %v %#v", err, resp2)
1255	}
1256	if resp2 != nil {
1257		t.Fatalf("bad: %#v", resp)
1258	}
1259
1260	// Attempt renew
1261	req3 := logical.TestRequest(t, logical.UpdateOperation, "leases/renew/"+resp.Secret.LeaseID)
1262	resp3, err := b.HandleRequest(namespace.RootContext(nil), req3)
1263	if err != logical.ErrInvalidRequest {
1264		t.Fatalf("err: %v", err)
1265	}
1266	if resp3.Data["error"] != "lease not found" {
1267		t.Fatalf("bad: %v", *resp3)
1268	}
1269}
1270
1271func TestSystemBackend_revokePrefix_origUrl(t *testing.T) {
1272	core, b, root := testCoreSystemBackend(t)
1273
1274	// Create a key with a lease
1275	req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
1276	req.Data["foo"] = "bar"
1277	req.Data["lease"] = "1h"
1278	req.ClientToken = root
1279	resp, err := core.HandleRequest(namespace.RootContext(nil), req)
1280	if err != nil {
1281		t.Fatalf("err: %v", err)
1282	}
1283	if resp != nil {
1284		t.Fatalf("bad: %#v", resp)
1285	}
1286
1287	// Read a key with a LeaseID
1288	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
1289	req.ClientToken = root
1290	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
1291	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
1292	if err != nil {
1293		t.Fatalf("err: %v", err)
1294	}
1295	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
1296		t.Fatalf("bad: %#v", resp)
1297	}
1298
1299	// Attempt revoke
1300	req2 := logical.TestRequest(t, logical.UpdateOperation, "revoke-prefix/secret/")
1301	resp2, err := b.HandleRequest(namespace.RootContext(nil), req2)
1302	if err != nil {
1303		t.Fatalf("err: %v %#v", err, resp2)
1304	}
1305	if resp2 != nil {
1306		t.Fatalf("bad: %#v", resp)
1307	}
1308
1309	// Attempt renew
1310	req3 := logical.TestRequest(t, logical.UpdateOperation, "renew/"+resp.Secret.LeaseID)
1311	resp3, err := b.HandleRequest(namespace.RootContext(nil), req3)
1312	if err != logical.ErrInvalidRequest {
1313		t.Fatalf("err: %v", err)
1314	}
1315	if resp3.Data["error"] != "lease not found" {
1316		t.Fatalf("bad: %#v", *resp3)
1317	}
1318}
1319
1320func TestSystemBackend_revokePrefixAuth_newUrl(t *testing.T) {
1321	core, _, _ := TestCoreUnsealed(t)
1322
1323	ts := core.tokenStore
1324	bc := &logical.BackendConfig{
1325		Logger: core.logger,
1326		System: logical.StaticSystemView{
1327			DefaultLeaseTTLVal: time.Hour * 24,
1328			MaxLeaseTTLVal:     time.Hour * 24 * 32,
1329		},
1330	}
1331	b := NewSystemBackend(core, hclog.New(&hclog.LoggerOptions{}))
1332	err := b.Backend.Setup(namespace.RootContext(nil), bc)
1333	if err != nil {
1334		t.Fatal(err)
1335	}
1336
1337	exp := ts.expiration
1338
1339	te := &logical.TokenEntry{
1340		ID:          "foo",
1341		Path:        "auth/github/login/bar",
1342		TTL:         time.Hour,
1343		NamespaceID: namespace.RootNamespaceID,
1344	}
1345	testMakeTokenDirectly(t, ts, te)
1346
1347	te, err = ts.Lookup(namespace.RootContext(nil), "foo")
1348	if err != nil {
1349		t.Fatal(err)
1350	}
1351	if te == nil {
1352		t.Fatal("token entry was nil")
1353	}
1354
1355	// Create a new token
1356	auth := &logical.Auth{
1357		ClientToken: te.ID,
1358		LeaseOptions: logical.LeaseOptions{
1359			TTL: time.Hour,
1360		},
1361	}
1362	err = exp.RegisterAuth(namespace.RootContext(nil), te, auth)
1363	if err != nil {
1364		t.Fatalf("err: %v", err)
1365	}
1366
1367	req := logical.TestRequest(t, logical.UpdateOperation, "leases/revoke-prefix/auth/github/")
1368	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1369	if err != nil {
1370		t.Fatalf("err: %v %v", err, resp)
1371	}
1372	if resp != nil {
1373		t.Fatalf("bad: %#v", resp)
1374	}
1375
1376	te, err = ts.Lookup(namespace.RootContext(nil), te.ID)
1377	if err != nil {
1378		t.Fatalf("err: %v", err)
1379	}
1380	if te != nil {
1381		t.Fatalf("bad: %v", te)
1382	}
1383}
1384
1385func TestSystemBackend_revokePrefixAuth_origUrl(t *testing.T) {
1386	core, _, _ := TestCoreUnsealed(t)
1387	ts := core.tokenStore
1388	bc := &logical.BackendConfig{
1389		Logger: core.logger,
1390		System: logical.StaticSystemView{
1391			DefaultLeaseTTLVal: time.Hour * 24,
1392			MaxLeaseTTLVal:     time.Hour * 24 * 32,
1393		},
1394	}
1395	b := NewSystemBackend(core, hclog.New(&hclog.LoggerOptions{}))
1396	err := b.Backend.Setup(namespace.RootContext(nil), bc)
1397	if err != nil {
1398		t.Fatal(err)
1399	}
1400
1401	exp := ts.expiration
1402
1403	te := &logical.TokenEntry{
1404		ID:          "foo",
1405		Path:        "auth/github/login/bar",
1406		TTL:         time.Hour,
1407		NamespaceID: namespace.RootNamespaceID,
1408	}
1409	testMakeTokenDirectly(t, ts, te)
1410
1411	te, err = ts.Lookup(namespace.RootContext(nil), "foo")
1412	if err != nil {
1413		t.Fatal(err)
1414	}
1415	if te == nil {
1416		t.Fatal("token entry was nil")
1417	}
1418
1419	// Create a new token
1420	auth := &logical.Auth{
1421		ClientToken: te.ID,
1422		LeaseOptions: logical.LeaseOptions{
1423			TTL: time.Hour,
1424		},
1425	}
1426	err = exp.RegisterAuth(namespace.RootContext(nil), te, auth)
1427	if err != nil {
1428		t.Fatalf("err: %v", err)
1429	}
1430
1431	req := logical.TestRequest(t, logical.UpdateOperation, "revoke-prefix/auth/github/")
1432	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1433	if err != nil {
1434		t.Fatalf("err: %v %v", err, resp)
1435	}
1436	if resp != nil {
1437		t.Fatalf("bad: %#v", resp)
1438	}
1439
1440	te, err = ts.Lookup(namespace.RootContext(nil), te.ID)
1441	if err != nil {
1442		t.Fatalf("err: %v", err)
1443	}
1444	if te != nil {
1445		t.Fatalf("bad: %v", te)
1446	}
1447}
1448
1449func TestSystemBackend_authTable(t *testing.T) {
1450	b := testSystemBackend(t)
1451	req := logical.TestRequest(t, logical.ReadOperation, "auth")
1452	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1453	if err != nil {
1454		t.Fatalf("err: %v", err)
1455	}
1456
1457	exp := map[string]interface{}{
1458		"token/": map[string]interface{}{
1459			"type":                    "token",
1460			"external_entropy_access": false,
1461			"description":             "token based credentials",
1462			"accessor":                resp.Data["token/"].(map[string]interface{})["accessor"],
1463			"uuid":                    resp.Data["token/"].(map[string]interface{})["uuid"],
1464			"config": map[string]interface{}{
1465				"default_lease_ttl": int64(0),
1466				"max_lease_ttl":     int64(0),
1467				"force_no_cache":    false,
1468				"token_type":        "default-service",
1469			},
1470			"local":     false,
1471			"seal_wrap": false,
1472			"options":   map[string]string(nil),
1473		},
1474	}
1475	if diff := deep.Equal(resp.Data, exp); diff != nil {
1476		t.Fatal(diff)
1477	}
1478}
1479
1480func TestSystemBackend_enableAuth(t *testing.T) {
1481	c, b, _ := testCoreSystemBackend(t)
1482	c.credentialBackends["noop"] = func(context.Context, *logical.BackendConfig) (logical.Backend, error) {
1483		return &NoopBackend{BackendType: logical.TypeCredential}, nil
1484	}
1485
1486	req := logical.TestRequest(t, logical.UpdateOperation, "auth/foo")
1487	req.Data["type"] = "noop"
1488	req.Data["config"] = map[string]interface{}{
1489		"default_lease_ttl": "35m",
1490		"max_lease_ttl":     "45m",
1491	}
1492	req.Data["local"] = true
1493	req.Data["seal_wrap"] = true
1494
1495	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1496	if err != nil {
1497		t.Fatalf("err: %v", err)
1498	}
1499	if resp != nil {
1500		t.Fatalf("bad: %v", resp)
1501	}
1502
1503	req = logical.TestRequest(t, logical.ReadOperation, "auth")
1504	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1505	if err != nil {
1506		t.Fatalf("err: %v", err)
1507	}
1508	if resp == nil {
1509		t.Fatal("resp is nil")
1510	}
1511
1512	exp := map[string]interface{}{
1513		"foo/": map[string]interface{}{
1514			"type":                    "noop",
1515			"external_entropy_access": false,
1516			"description":             "",
1517			"accessor":                resp.Data["foo/"].(map[string]interface{})["accessor"],
1518			"uuid":                    resp.Data["foo/"].(map[string]interface{})["uuid"],
1519			"config": map[string]interface{}{
1520				"default_lease_ttl": int64(2100),
1521				"max_lease_ttl":     int64(2700),
1522				"force_no_cache":    false,
1523				"token_type":        "default-service",
1524			},
1525			"local":     true,
1526			"seal_wrap": true,
1527			"options":   map[string]string{},
1528		},
1529		"token/": map[string]interface{}{
1530			"type":                    "token",
1531			"external_entropy_access": false,
1532			"description":             "token based credentials",
1533			"accessor":                resp.Data["token/"].(map[string]interface{})["accessor"],
1534			"uuid":                    resp.Data["token/"].(map[string]interface{})["uuid"],
1535			"config": map[string]interface{}{
1536				"default_lease_ttl": int64(0),
1537				"max_lease_ttl":     int64(0),
1538				"force_no_cache":    false,
1539				"token_type":        "default-service",
1540			},
1541			"local":     false,
1542			"seal_wrap": false,
1543			"options":   map[string]string(nil),
1544		},
1545	}
1546	if diff := deep.Equal(resp.Data, exp); diff != nil {
1547		t.Fatal(diff)
1548	}
1549}
1550
1551func TestSystemBackend_enableAuth_invalid(t *testing.T) {
1552	b := testSystemBackend(t)
1553	req := logical.TestRequest(t, logical.UpdateOperation, "auth/foo")
1554	req.Data["type"] = "nope"
1555	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1556	if err != logical.ErrInvalidRequest {
1557		t.Fatalf("err: %v", err)
1558	}
1559	if resp.Data["error"] != `plugin not found in the catalog: nope` {
1560		t.Fatalf("bad: %v", resp)
1561	}
1562}
1563
1564func TestSystemBackend_disableAuth(t *testing.T) {
1565	c, b, _ := testCoreSystemBackend(t)
1566	c.credentialBackends["noop"] = func(context.Context, *logical.BackendConfig) (logical.Backend, error) {
1567		return &NoopBackend{}, nil
1568	}
1569
1570	// Register the backend
1571	req := logical.TestRequest(t, logical.UpdateOperation, "auth/foo")
1572	req.Data["type"] = "noop"
1573	b.HandleRequest(namespace.RootContext(nil), req)
1574
1575	// Deregister it
1576	req = logical.TestRequest(t, logical.DeleteOperation, "auth/foo")
1577	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1578	if err != nil {
1579		t.Fatalf("err: %v", err)
1580	}
1581	if resp != nil {
1582		t.Fatalf("bad: %v", resp)
1583	}
1584}
1585
1586func TestSystemBackend_tuneAuth(t *testing.T) {
1587	c, b, _ := testCoreSystemBackend(t)
1588	c.credentialBackends["noop"] = func(context.Context, *logical.BackendConfig) (logical.Backend, error) {
1589		return &NoopBackend{BackendType: logical.TypeCredential}, nil
1590	}
1591
1592	req := logical.TestRequest(t, logical.ReadOperation, "auth/token/tune")
1593	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1594	if err != nil {
1595		t.Fatalf("err: %v", err)
1596	}
1597	if resp == nil {
1598		t.Fatal("resp is nil")
1599	}
1600
1601	exp := map[string]interface{}{
1602		"description":       "token based credentials",
1603		"default_lease_ttl": int(2764800),
1604		"max_lease_ttl":     int(2764800),
1605		"force_no_cache":    false,
1606		"token_type":        "default-service",
1607	}
1608
1609	if diff := deep.Equal(resp.Data, exp); diff != nil {
1610		t.Fatal(diff)
1611	}
1612
1613	req = logical.TestRequest(t, logical.UpdateOperation, "auth/token/tune")
1614	req.Data["description"] = ""
1615	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1616	if err != nil {
1617		t.Fatalf("err: %v", err)
1618	}
1619
1620	req = logical.TestRequest(t, logical.ReadOperation, "auth/token/tune")
1621	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1622	if err != nil {
1623		t.Fatalf("err: %v", err)
1624	}
1625	if resp == nil {
1626		t.Fatal("resp is nil")
1627	}
1628
1629	if resp.Data["description"] != "" {
1630		t.Fatalf("got: %#v expect: %#v", resp.Data["description"], "")
1631	}
1632}
1633
1634func TestSystemBackend_policyList(t *testing.T) {
1635	b := testSystemBackend(t)
1636	req := logical.TestRequest(t, logical.ReadOperation, "policy")
1637	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1638	if err != nil {
1639		t.Fatalf("err: %v", err)
1640	}
1641
1642	exp := map[string]interface{}{
1643		"keys":     []string{"default", "root"},
1644		"policies": []string{"default", "root"},
1645	}
1646	if !reflect.DeepEqual(resp.Data, exp) {
1647		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1648	}
1649}
1650
1651func TestSystemBackend_policyCRUD(t *testing.T) {
1652	b := testSystemBackend(t)
1653
1654	// Create the policy
1655	rules := `path "foo/" { policy = "read" }`
1656	req := logical.TestRequest(t, logical.UpdateOperation, "policy/Foo")
1657	req.Data["rules"] = rules
1658	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1659	if err != nil {
1660		t.Fatalf("err: %v %#v", err, resp)
1661	}
1662	if resp != nil && (resp.IsError() || len(resp.Data) > 0) {
1663		t.Fatalf("bad: %#v", resp)
1664	}
1665
1666	// Read the policy
1667	req = logical.TestRequest(t, logical.ReadOperation, "policy/foo")
1668	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1669	if err != nil {
1670		t.Fatalf("err: %v", err)
1671	}
1672
1673	exp := map[string]interface{}{
1674		"name":  "foo",
1675		"rules": rules,
1676	}
1677	if !reflect.DeepEqual(resp.Data, exp) {
1678		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1679	}
1680
1681	// Read, and make sure that case has been normalized
1682	req = logical.TestRequest(t, logical.ReadOperation, "policy/Foo")
1683	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1684	if err != nil {
1685		t.Fatalf("err: %v", err)
1686	}
1687
1688	exp = map[string]interface{}{
1689		"name":  "foo",
1690		"rules": rules,
1691	}
1692	if !reflect.DeepEqual(resp.Data, exp) {
1693		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1694	}
1695
1696	// List the policies
1697	req = logical.TestRequest(t, logical.ReadOperation, "policy")
1698	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1699	if err != nil {
1700		t.Fatalf("err: %v", err)
1701	}
1702
1703	exp = map[string]interface{}{
1704		"keys":     []string{"default", "foo", "root"},
1705		"policies": []string{"default", "foo", "root"},
1706	}
1707	if !reflect.DeepEqual(resp.Data, exp) {
1708		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1709	}
1710
1711	// Delete the policy
1712	req = logical.TestRequest(t, logical.DeleteOperation, "policy/foo")
1713	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1714	if err != nil {
1715		t.Fatalf("err: %v", err)
1716	}
1717	if resp != nil {
1718		t.Fatalf("bad: %#v", resp)
1719	}
1720
1721	// Read the policy (deleted)
1722	req = logical.TestRequest(t, logical.ReadOperation, "policy/foo")
1723	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1724	if err != nil {
1725		t.Fatalf("err: %v", err)
1726	}
1727	if resp != nil {
1728		t.Fatalf("bad: %#v", resp)
1729	}
1730
1731	// List the policies (deleted)
1732	req = logical.TestRequest(t, logical.ReadOperation, "policy")
1733	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1734	if err != nil {
1735		t.Fatalf("err: %v", err)
1736	}
1737
1738	exp = map[string]interface{}{
1739		"keys":     []string{"default", "root"},
1740		"policies": []string{"default", "root"},
1741	}
1742	if !reflect.DeepEqual(resp.Data, exp) {
1743		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1744	}
1745}
1746
1747func TestSystemBackend_enableAudit(t *testing.T) {
1748	c, b, _ := testCoreSystemBackend(t)
1749	c.auditBackends["noop"] = func(ctx context.Context, config *audit.BackendConfig) (audit.Backend, error) {
1750		return &NoopAudit{
1751			Config: config,
1752		}, nil
1753	}
1754
1755	req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo")
1756	req.Data["type"] = "noop"
1757
1758	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1759	if err != nil {
1760		t.Fatalf("err: %v", err)
1761	}
1762	if resp != nil {
1763		t.Fatalf("bad: %v", resp)
1764	}
1765}
1766
1767func TestSystemBackend_auditHash(t *testing.T) {
1768	c, b, _ := testCoreSystemBackend(t)
1769	c.auditBackends["noop"] = func(ctx context.Context, config *audit.BackendConfig) (audit.Backend, error) {
1770		view := &logical.InmemStorage{}
1771		view.Put(namespace.RootContext(nil), &logical.StorageEntry{
1772			Key:   "salt",
1773			Value: []byte("foo"),
1774		})
1775		config.SaltView = view
1776		config.SaltConfig = &salt.Config{
1777			HMAC:     sha256.New,
1778			HMACType: "hmac-sha256",
1779			Location: salt.DefaultLocation,
1780		}
1781		return &NoopAudit{
1782			Config: config,
1783		}, nil
1784	}
1785
1786	req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo")
1787	req.Data["type"] = "noop"
1788
1789	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1790	if err != nil {
1791		t.Fatalf("err: %v", err)
1792	}
1793	if resp != nil {
1794		t.Fatalf("bad: %v", resp)
1795	}
1796
1797	req = logical.TestRequest(t, logical.UpdateOperation, "audit-hash/foo")
1798	req.Data["input"] = "bar"
1799
1800	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1801	if err != nil {
1802		t.Fatalf("err: %v", err)
1803	}
1804	if resp == nil || resp.Data == nil {
1805		t.Fatalf("response or its data was nil")
1806	}
1807	hash, ok := resp.Data["hash"]
1808	if !ok {
1809		t.Fatalf("did not get hash back in response, response was %#v", resp.Data)
1810	}
1811	if hash.(string) != "hmac-sha256:f9320baf0249169e73850cd6156ded0106e2bb6ad8cab01b7bbbebe6d1065317" {
1812		t.Fatalf("bad hash back: %s", hash.(string))
1813	}
1814}
1815
1816func TestSystemBackend_enableAudit_invalid(t *testing.T) {
1817	b := testSystemBackend(t)
1818	req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo")
1819	req.Data["type"] = "nope"
1820	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1821	if err != logical.ErrInvalidRequest {
1822		t.Fatalf("err: %v", err)
1823	}
1824	if resp.Data["error"] != `unknown backend type: "nope"` {
1825		t.Fatalf("bad: %v", resp)
1826	}
1827}
1828
1829func TestSystemBackend_auditTable(t *testing.T) {
1830	c, b, _ := testCoreSystemBackend(t)
1831	c.auditBackends["noop"] = func(ctx context.Context, config *audit.BackendConfig) (audit.Backend, error) {
1832		return &NoopAudit{
1833			Config: config,
1834		}, nil
1835	}
1836
1837	req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo")
1838	req.Data["type"] = "noop"
1839	req.Data["description"] = "testing"
1840	req.Data["options"] = map[string]interface{}{
1841		"foo": "bar",
1842	}
1843	req.Data["local"] = true
1844	b.HandleRequest(namespace.RootContext(nil), req)
1845
1846	req = logical.TestRequest(t, logical.ReadOperation, "audit")
1847	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1848	if err != nil {
1849		t.Fatalf("err: %v", err)
1850	}
1851
1852	exp := map[string]interface{}{
1853		"foo/": map[string]interface{}{
1854			"path":        "foo/",
1855			"type":        "noop",
1856			"description": "testing",
1857			"options": map[string]string{
1858				"foo": "bar",
1859			},
1860			"local": true,
1861		},
1862	}
1863	if !reflect.DeepEqual(resp.Data, exp) {
1864		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1865	}
1866}
1867
1868func TestSystemBackend_disableAudit(t *testing.T) {
1869	c, b, _ := testCoreSystemBackend(t)
1870	c.auditBackends["noop"] = func(ctx context.Context, config *audit.BackendConfig) (audit.Backend, error) {
1871		return &NoopAudit{
1872			Config: config,
1873		}, nil
1874	}
1875
1876	req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo")
1877	req.Data["type"] = "noop"
1878	req.Data["description"] = "testing"
1879	req.Data["options"] = map[string]interface{}{
1880		"foo": "bar",
1881	}
1882	b.HandleRequest(namespace.RootContext(nil), req)
1883
1884	// Deregister it
1885	req = logical.TestRequest(t, logical.DeleteOperation, "audit/foo")
1886	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1887	if err != nil {
1888		t.Fatalf("err: %v", err)
1889	}
1890	if resp != nil {
1891		t.Fatalf("bad: %v", resp)
1892	}
1893}
1894
1895func TestSystemBackend_rawRead_Compressed(t *testing.T) {
1896	b := testSystemBackendRaw(t)
1897
1898	req := logical.TestRequest(t, logical.ReadOperation, "raw/core/mounts")
1899	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1900	if err != nil {
1901		t.Fatalf("err: %v", err)
1902	}
1903	if !strings.HasPrefix(resp.Data["value"].(string), "{\"type\":\"mounts\"") {
1904		t.Fatalf("bad: %v", resp)
1905	}
1906}
1907
1908func TestSystemBackend_rawRead_Protected(t *testing.T) {
1909	b := testSystemBackendRaw(t)
1910
1911	req := logical.TestRequest(t, logical.ReadOperation, "raw/"+keyringPath)
1912	_, err := b.HandleRequest(namespace.RootContext(nil), req)
1913	if err != logical.ErrInvalidRequest {
1914		t.Fatalf("err: %v", err)
1915	}
1916}
1917
1918func TestSystemBackend_rawWrite_Protected(t *testing.T) {
1919	b := testSystemBackendRaw(t)
1920
1921	req := logical.TestRequest(t, logical.UpdateOperation, "raw/"+keyringPath)
1922	_, err := b.HandleRequest(namespace.RootContext(nil), req)
1923	if err != logical.ErrInvalidRequest {
1924		t.Fatalf("err: %v", err)
1925	}
1926}
1927
1928func TestSystemBackend_rawReadWrite(t *testing.T) {
1929	_, b, _ := testCoreSystemBackendRaw(t)
1930
1931	req := logical.TestRequest(t, logical.UpdateOperation, "raw/sys/policy/test")
1932	req.Data["value"] = `path "secret/" { policy = "read" }`
1933	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1934	if err != nil {
1935		t.Fatalf("err: %v", err)
1936	}
1937	if resp != nil {
1938		t.Fatalf("bad: %v", resp)
1939	}
1940
1941	// Read via raw API
1942	req = logical.TestRequest(t, logical.ReadOperation, "raw/sys/policy/test")
1943	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1944	if err != nil {
1945		t.Fatalf("err: %v", err)
1946	}
1947	if !strings.HasPrefix(resp.Data["value"].(string), "path") {
1948		t.Fatalf("bad: %v", resp)
1949	}
1950
1951	// Note: since the upgrade code is gone that upgraded from 0.1, we can't
1952	// simply parse this out directly via GetPolicy, so the test now ends here.
1953}
1954
1955func TestSystemBackend_rawDelete_Protected(t *testing.T) {
1956	b := testSystemBackendRaw(t)
1957
1958	req := logical.TestRequest(t, logical.DeleteOperation, "raw/"+keyringPath)
1959	_, err := b.HandleRequest(namespace.RootContext(nil), req)
1960	if err != logical.ErrInvalidRequest {
1961		t.Fatalf("err: %v", err)
1962	}
1963}
1964
1965func TestSystemBackend_rawDelete(t *testing.T) {
1966	c, b, _ := testCoreSystemBackendRaw(t)
1967
1968	// set the policy!
1969	p := &Policy{
1970		Name:      "test",
1971		Type:      PolicyTypeACL,
1972		namespace: namespace.RootNamespace,
1973	}
1974	err := c.policyStore.SetPolicy(namespace.RootContext(nil), p)
1975	if err != nil {
1976		t.Fatalf("err: %v", err)
1977	}
1978
1979	// Delete the policy
1980	req := logical.TestRequest(t, logical.DeleteOperation, "raw/sys/policy/test")
1981	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1982	if err != nil {
1983		t.Fatalf("err: %v", err)
1984	}
1985	if resp != nil {
1986		t.Fatalf("bad: %v", resp)
1987	}
1988
1989	// Policy should be gone
1990	c.policyStore.tokenPoliciesLRU.Purge()
1991	out, err := c.policyStore.GetPolicy(namespace.RootContext(nil), "test", PolicyTypeToken)
1992	if err != nil {
1993		t.Fatalf("err: %v", err)
1994	}
1995	if out != nil {
1996		t.Fatalf("policy should be gone")
1997	}
1998}
1999
2000func TestSystemBackend_keyStatus(t *testing.T) {
2001	b := testSystemBackend(t)
2002	req := logical.TestRequest(t, logical.ReadOperation, "key-status")
2003	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2004	if err != nil {
2005		t.Fatalf("err: %v", err)
2006	}
2007
2008	exp := map[string]interface{}{
2009		"term": 1,
2010	}
2011	delete(resp.Data, "install_time")
2012	if !reflect.DeepEqual(resp.Data, exp) {
2013		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
2014	}
2015}
2016
2017func TestSystemBackend_rotate(t *testing.T) {
2018	b := testSystemBackend(t)
2019
2020	req := logical.TestRequest(t, logical.UpdateOperation, "rotate")
2021	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2022	if err != nil {
2023		t.Fatalf("err: %v", err)
2024	}
2025	if resp != nil {
2026		t.Fatalf("bad: %v", resp)
2027	}
2028
2029	req = logical.TestRequest(t, logical.ReadOperation, "key-status")
2030	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2031	if err != nil {
2032		t.Fatalf("err: %v", err)
2033	}
2034
2035	exp := map[string]interface{}{
2036		"term": 2,
2037	}
2038	delete(resp.Data, "install_time")
2039	if !reflect.DeepEqual(resp.Data, exp) {
2040		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
2041	}
2042}
2043
2044func testSystemBackend(t *testing.T) logical.Backend {
2045	c, _, _ := TestCoreUnsealed(t)
2046	return c.systemBackend
2047}
2048
2049func testSystemBackendRaw(t *testing.T) logical.Backend {
2050	c, _, _ := TestCoreUnsealedRaw(t)
2051	return c.systemBackend
2052}
2053
2054func testCoreSystemBackend(t *testing.T) (*Core, logical.Backend, string) {
2055	c, _, root := TestCoreUnsealed(t)
2056	return c, c.systemBackend, root
2057}
2058
2059func testCoreSystemBackendRaw(t *testing.T) (*Core, logical.Backend, string) {
2060	c, _, root := TestCoreUnsealedRaw(t)
2061	return c, c.systemBackend, root
2062}
2063
2064func TestSystemBackend_PluginCatalog_CRUD(t *testing.T) {
2065	c, b, _ := testCoreSystemBackend(t)
2066	// Bootstrap the pluginCatalog
2067	sym, err := filepath.EvalSymlinks(os.TempDir())
2068	if err != nil {
2069		t.Fatalf("error: %v", err)
2070	}
2071	c.pluginCatalog.directory = sym
2072
2073	req := logical.TestRequest(t, logical.ListOperation, "plugins/catalog/database")
2074	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2075	if err != nil {
2076		t.Fatalf("err: %v", err)
2077	}
2078
2079	if len(resp.Data["keys"].([]string)) != len(c.builtinRegistry.Keys(consts.PluginTypeDatabase)) {
2080		t.Fatalf("Wrong number of plugins, got %d, expected %d", len(resp.Data["keys"].([]string)), len(builtinplugins.Registry.Keys(consts.PluginTypeDatabase)))
2081	}
2082
2083	req = logical.TestRequest(t, logical.ReadOperation, "plugins/catalog/database/mysql-database-plugin")
2084	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2085	if err != nil {
2086		t.Fatalf("err: %v", err)
2087	}
2088
2089	actualRespData := resp.Data
2090	expectedRespData := map[string]interface{}{
2091		"name":    "mysql-database-plugin",
2092		"command": "",
2093		"args":    []string(nil),
2094		"sha256":  "",
2095		"builtin": true,
2096	}
2097	if !reflect.DeepEqual(actualRespData, expectedRespData) {
2098		t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", actualRespData, expectedRespData)
2099	}
2100
2101	// Set a plugin
2102	file, err := ioutil.TempFile(os.TempDir(), "temp")
2103	if err != nil {
2104		t.Fatal(err)
2105	}
2106	defer file.Close()
2107
2108	// Check we can only specify args in one of command or args.
2109	command := fmt.Sprintf("%s --test", filepath.Base(file.Name()))
2110	req = logical.TestRequest(t, logical.UpdateOperation, "plugins/catalog/database/test-plugin")
2111	req.Data["args"] = []string{"--foo"}
2112	req.Data["sha_256"] = hex.EncodeToString([]byte{'1'})
2113	req.Data["command"] = command
2114	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2115	if err != nil {
2116		t.Fatalf("err: %v", err)
2117	}
2118	if resp.Error().Error() != "must not specify args in command and args field" {
2119		t.Fatalf("err: %v", resp.Error())
2120	}
2121
2122	delete(req.Data, "args")
2123	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2124	if err != nil || resp.Error() != nil {
2125		t.Fatalf("err: %v %v", err, resp.Error())
2126	}
2127
2128	req = logical.TestRequest(t, logical.ReadOperation, "plugins/catalog/database/test-plugin")
2129	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2130	if err != nil {
2131		t.Fatalf("err: %v", err)
2132	}
2133
2134	actual := resp.Data
2135	expected := map[string]interface{}{
2136		"name":    "test-plugin",
2137		"command": filepath.Base(file.Name()),
2138		"args":    []string{"--test"},
2139		"sha256":  "31",
2140		"builtin": false,
2141	}
2142	if !reflect.DeepEqual(actual, expected) {
2143		t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", actual, expected)
2144	}
2145
2146	// Delete plugin
2147	req = logical.TestRequest(t, logical.DeleteOperation, "plugins/catalog/database/test-plugin")
2148	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2149	if err != nil {
2150		t.Fatalf("err: %v", err)
2151	}
2152
2153	req = logical.TestRequest(t, logical.ReadOperation, "plugins/catalog/database/test-plugin")
2154	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2155	if resp != nil || err != nil {
2156		t.Fatalf("expected nil response, plugin not deleted correctly got resp: %v, err: %v", resp, err)
2157	}
2158}
2159
2160func TestSystemBackend_ToolsHash(t *testing.T) {
2161	b := testSystemBackend(t)
2162	req := logical.TestRequest(t, logical.UpdateOperation, "tools/hash")
2163	req.Data = map[string]interface{}{
2164		"input": "dGhlIHF1aWNrIGJyb3duIGZveA==",
2165	}
2166	_, err := b.HandleRequest(namespace.RootContext(nil), req)
2167	if err != nil {
2168		t.Fatalf("err: %v", err)
2169	}
2170
2171	doRequest := func(req *logical.Request, errExpected bool, expected string) {
2172		t.Helper()
2173		resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2174		if err != nil && !errExpected {
2175			t.Fatal(err)
2176		}
2177		if resp == nil {
2178			t.Fatal("expected non-nil response")
2179		}
2180		if errExpected {
2181			if !resp.IsError() {
2182				t.Fatalf("bad: got error response: %#v", *resp)
2183			}
2184			return
2185		}
2186		if resp.IsError() {
2187			t.Fatalf("bad: got error response: %#v", *resp)
2188		}
2189		sum, ok := resp.Data["sum"]
2190		if !ok {
2191			t.Fatal("no sum key found in returned data")
2192		}
2193		if sum.(string) != expected {
2194			t.Fatal("mismatched hashes")
2195		}
2196	}
2197
2198	// Test defaults -- sha2-256
2199	doRequest(req, false, "9ecb36561341d18eb65484e833efea61edc74b84cf5e6ae1b81c63533e25fc8f")
2200
2201	// Test algorithm selection in the path
2202	req.Path = "tools/hash/sha2-224"
2203	doRequest(req, false, "ea074a96cabc5a61f8298a2c470f019074642631a49e1c5e2f560865")
2204
2205	// Reset and test algorithm selection in the data
2206	req.Path = "tools/hash"
2207	req.Data["algorithm"] = "sha2-224"
2208	doRequest(req, false, "ea074a96cabc5a61f8298a2c470f019074642631a49e1c5e2f560865")
2209
2210	req.Data["algorithm"] = "sha2-384"
2211	doRequest(req, false, "15af9ec8be783f25c583626e9491dbf129dd6dd620466fdf05b3a1d0bb8381d30f4d3ec29f923ff1e09a0f6b337365a6")
2212
2213	req.Data["algorithm"] = "sha2-512"
2214	doRequest(req, false, "d9d380f29b97ad6a1d92e987d83fa5a02653301e1006dd2bcd51afa59a9147e9caedaf89521abc0f0b682adcd47fb512b8343c834a32f326fe9bef00542ce887")
2215
2216	// Test returning as base64
2217	req.Data["format"] = "base64"
2218	doRequest(req, false, "2dOA8puXrWodkumH2D+loCZTMB4QBt0rzVGvpZqRR+nK7a+JUhq8DwtoKtzUf7USuDQ8g0oy8yb+m+8AVCzohw==")
2219
2220	// Test bad input/format/algorithm
2221	req.Data["format"] = "base92"
2222	doRequest(req, true, "")
2223
2224	req.Data["format"] = "hex"
2225	req.Data["algorithm"] = "foobar"
2226	doRequest(req, true, "")
2227
2228	req.Data["algorithm"] = "sha2-256"
2229	req.Data["input"] = "foobar"
2230	doRequest(req, true, "")
2231}
2232
2233func TestSystemBackend_ToolsRandom(t *testing.T) {
2234	b := testSystemBackend(t)
2235	req := logical.TestRequest(t, logical.UpdateOperation, "tools/random")
2236
2237	_, err := b.HandleRequest(namespace.RootContext(nil), req)
2238	if err != nil {
2239		t.Fatalf("err: %v", err)
2240	}
2241
2242	doRequest := func(req *logical.Request, errExpected bool, format string, numBytes int) {
2243		t.Helper()
2244		getResponse := func() []byte {
2245			resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2246			if err != nil && !errExpected {
2247				t.Fatal(err)
2248			}
2249			if resp == nil {
2250				t.Fatal("expected non-nil response")
2251			}
2252			if errExpected {
2253				if !resp.IsError() {
2254					t.Fatalf("bad: got error response: %#v", *resp)
2255				}
2256				return nil
2257			}
2258			if resp.IsError() {
2259				t.Fatalf("bad: got error response: %#v", *resp)
2260			}
2261			if _, ok := resp.Data["random_bytes"]; !ok {
2262				t.Fatal("no random_bytes found in response")
2263			}
2264
2265			outputStr := resp.Data["random_bytes"].(string)
2266			var outputBytes []byte
2267			switch format {
2268			case "base64":
2269				outputBytes, err = base64.StdEncoding.DecodeString(outputStr)
2270			case "hex":
2271				outputBytes, err = hex.DecodeString(outputStr)
2272			default:
2273				t.Fatal("unknown format")
2274			}
2275			if err != nil {
2276				t.Fatal(err)
2277			}
2278
2279			return outputBytes
2280		}
2281
2282		rand1 := getResponse()
2283		// Expected error
2284		if rand1 == nil {
2285			return
2286		}
2287		rand2 := getResponse()
2288		if len(rand1) != numBytes || len(rand2) != numBytes {
2289			t.Fatal("length of output random bytes not what is expected")
2290		}
2291		if reflect.DeepEqual(rand1, rand2) {
2292			t.Fatal("found identical ouputs")
2293		}
2294	}
2295
2296	// Test defaults
2297	doRequest(req, false, "base64", 32)
2298
2299	// Test size selection in the path
2300	req.Path = "tools/random/24"
2301	req.Data["format"] = "hex"
2302	doRequest(req, false, "hex", 24)
2303
2304	// Test bad input/format
2305	req.Path = "tools/random"
2306	req.Data["format"] = "base92"
2307	doRequest(req, true, "", 0)
2308
2309	req.Data["format"] = "hex"
2310	req.Data["bytes"] = -1
2311	doRequest(req, true, "", 0)
2312
2313	req.Data["format"] = "hex"
2314	req.Data["bytes"] = maxBytes + 1
2315	doRequest(req, true, "", 0)
2316
2317}
2318
2319func TestSystemBackend_InternalUIMounts(t *testing.T) {
2320	_, b, rootToken := testCoreSystemBackend(t)
2321
2322	// Ensure no entries are in the endpoint as a starting point
2323	req := logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts")
2324	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2325	if err != nil {
2326		t.Fatalf("err: %v", err)
2327	}
2328
2329	exp := map[string]interface{}{
2330		"secret": map[string]interface{}{},
2331		"auth":   map[string]interface{}{},
2332	}
2333	if !reflect.DeepEqual(resp.Data, exp) {
2334		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
2335	}
2336
2337	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts")
2338	req.ClientToken = rootToken
2339	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2340	if err != nil {
2341		t.Fatalf("err: %v", err)
2342	}
2343
2344	exp = map[string]interface{}{
2345		"secret": map[string]interface{}{
2346			"secret/": map[string]interface{}{
2347				"type":                    "kv",
2348				"external_entropy_access": false,
2349				"description":             "key/value secret storage",
2350				"accessor":                resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["accessor"],
2351				"uuid":                    resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["uuid"],
2352				"config": map[string]interface{}{
2353					"default_lease_ttl": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
2354					"max_lease_ttl":     resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
2355					"force_no_cache":    false,
2356				},
2357				"local":     false,
2358				"seal_wrap": false,
2359				"options": map[string]string{
2360					"version": "1",
2361				},
2362			},
2363			"sys/": map[string]interface{}{
2364				"type":                    "system",
2365				"external_entropy_access": false,
2366				"description":             "system endpoints used for control, policy and debugging",
2367				"accessor":                resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["accessor"],
2368				"uuid":                    resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["uuid"],
2369				"config": map[string]interface{}{
2370					"default_lease_ttl":           resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
2371					"max_lease_ttl":               resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
2372					"force_no_cache":              false,
2373					"passthrough_request_headers": []string{"Accept"},
2374				},
2375				"local":     false,
2376				"seal_wrap": false,
2377				"options":   map[string]string(nil),
2378			},
2379			"cubbyhole/": map[string]interface{}{
2380				"description":             "per-token private secret storage",
2381				"type":                    "cubbyhole",
2382				"external_entropy_access": false,
2383				"accessor":                resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["accessor"],
2384				"uuid":                    resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["uuid"],
2385				"config": map[string]interface{}{
2386					"default_lease_ttl": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
2387					"max_lease_ttl":     resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
2388					"force_no_cache":    false,
2389				},
2390				"local":     true,
2391				"seal_wrap": false,
2392				"options":   map[string]string(nil),
2393			},
2394			"identity/": map[string]interface{}{
2395				"description":             "identity store",
2396				"type":                    "identity",
2397				"external_entropy_access": false,
2398				"accessor":                resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["accessor"],
2399				"uuid":                    resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["uuid"],
2400				"config": map[string]interface{}{
2401					"default_lease_ttl": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
2402					"max_lease_ttl":     resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
2403					"force_no_cache":    false,
2404				},
2405				"local":     false,
2406				"seal_wrap": false,
2407				"options":   map[string]string(nil),
2408			},
2409		},
2410		"auth": map[string]interface{}{
2411			"token/": map[string]interface{}{
2412				"options": map[string]string(nil),
2413				"config": map[string]interface{}{
2414					"default_lease_ttl": int64(0),
2415					"max_lease_ttl":     int64(0),
2416					"force_no_cache":    false,
2417					"token_type":        "default-service",
2418				},
2419				"type":                    "token",
2420				"external_entropy_access": false,
2421				"description":             "token based credentials",
2422				"accessor":                resp.Data["auth"].(map[string]interface{})["token/"].(map[string]interface{})["accessor"],
2423				"uuid":                    resp.Data["auth"].(map[string]interface{})["token/"].(map[string]interface{})["uuid"],
2424				"local":                   false,
2425				"seal_wrap":               false,
2426			},
2427		},
2428	}
2429	if diff := deep.Equal(resp.Data, exp); diff != nil {
2430		t.Fatal(diff)
2431	}
2432
2433	// Mount-tune an auth mount
2434	req = logical.TestRequest(t, logical.UpdateOperation, "auth/token/tune")
2435	req.Data["listing_visibility"] = "unauth"
2436	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2437	if resp.IsError() || err != nil {
2438		t.Fatalf("resp.Error: %v, err:%v", resp.Error(), err)
2439	}
2440
2441	// Mount-tune a secret mount
2442	req = logical.TestRequest(t, logical.UpdateOperation, "mounts/secret/tune")
2443	req.Data["listing_visibility"] = "unauth"
2444	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2445	if resp.IsError() || err != nil {
2446		t.Fatalf("resp.Error: %v, err:%v", resp.Error(), err)
2447	}
2448
2449	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts")
2450	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2451	if err != nil {
2452		t.Fatalf("err: %v", err)
2453	}
2454
2455	exp = map[string]interface{}{
2456		"secret": map[string]interface{}{
2457			"secret/": map[string]interface{}{
2458				"type":        "kv",
2459				"description": "key/value secret storage",
2460				"options":     map[string]string{"version": "1"},
2461			},
2462		},
2463		"auth": map[string]interface{}{
2464			"token/": map[string]interface{}{
2465				"type":        "token",
2466				"description": "token based credentials",
2467				"options":     map[string]string(nil),
2468			},
2469		},
2470	}
2471	if !reflect.DeepEqual(resp.Data, exp) {
2472		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
2473	}
2474}
2475
2476func TestSystemBackend_InternalUIMount(t *testing.T) {
2477	core, b, rootToken := testCoreSystemBackend(t)
2478
2479	req := logical.TestRequest(t, logical.UpdateOperation, "policy/secret")
2480	req.ClientToken = rootToken
2481	req.Data = map[string]interface{}{
2482		"rules": `path "secret/foo/*" {
2483    capabilities = ["create", "read", "update", "delete", "list"]
2484}`,
2485	}
2486	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2487	if err != nil || (resp != nil && resp.IsError()) {
2488		t.Fatalf("Bad %#v %#v", err, resp)
2489	}
2490
2491	req = logical.TestRequest(t, logical.UpdateOperation, "mounts/kv")
2492	req.ClientToken = rootToken
2493	req.Data = map[string]interface{}{
2494		"type": "kv",
2495	}
2496	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2497	if err != nil || (resp != nil && resp.IsError()) {
2498		t.Fatalf("Bad %#v %#v", err, resp)
2499	}
2500
2501	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/kv/bar")
2502	req.ClientToken = rootToken
2503	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2504	if err != nil || (resp != nil && resp.IsError()) {
2505		t.Fatalf("Bad %#v %#v", err, resp)
2506	}
2507	if resp.Data["type"] != "kv" {
2508		t.Fatalf("Bad Response: %#v", resp)
2509	}
2510
2511	testMakeServiceTokenViaBackend(t, core.tokenStore, rootToken, "tokenid", "", []string{"secret"})
2512
2513	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/kv")
2514	req.ClientToken = "tokenid"
2515	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2516	if err != logical.ErrPermissionDenied {
2517		t.Fatal("expected permission denied error")
2518	}
2519
2520	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/secret")
2521	req.ClientToken = "tokenid"
2522	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2523	if err != nil || (resp != nil && resp.IsError()) {
2524		t.Fatalf("Bad %#v %#v", err, resp)
2525	}
2526	if resp.Data["type"] != "kv" {
2527		t.Fatalf("Bad Response: %#v", resp)
2528	}
2529
2530	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/sys")
2531	req.ClientToken = "tokenid"
2532	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2533	if err != nil || (resp != nil && resp.IsError()) {
2534		t.Fatalf("Bad %#v %#v", err, resp)
2535	}
2536	if resp.Data["type"] != "system" {
2537		t.Fatalf("Bad Response: %#v", resp)
2538	}
2539
2540	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/non-existent")
2541	req.ClientToken = "tokenid"
2542	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2543	if err != logical.ErrPermissionDenied {
2544		t.Fatal("expected permission denied error")
2545	}
2546}
2547
2548func TestSystemBackend_OpenAPI(t *testing.T) {
2549	_, b, rootToken := testCoreSystemBackend(t)
2550	var oapi map[string]interface{}
2551
2552	// Ensure no paths are reported if there is no token
2553	req := logical.TestRequest(t, logical.ReadOperation, "internal/specs/openapi")
2554	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2555	if err != nil {
2556		t.Fatalf("err: %v", err)
2557	}
2558
2559	body := resp.Data["http_raw_body"].([]byte)
2560	err = jsonutil.DecodeJSON(body, &oapi)
2561	if err != nil {
2562		t.Fatalf("err: %v", err)
2563	}
2564	exp := map[string]interface{}{
2565		"openapi": framework.OASVersion,
2566		"info": map[string]interface{}{
2567			"title":       "HashiCorp Vault API",
2568			"description": "HTTP API that gives you full access to Vault. All API routes are prefixed with `/v1/`.",
2569			"version":     version.GetVersion().Version,
2570			"license": map[string]interface{}{
2571				"name": "Mozilla Public License 2.0",
2572				"url":  "https://www.mozilla.org/en-US/MPL/2.0",
2573			},
2574		},
2575		"paths": map[string]interface{}{},
2576	}
2577
2578	if diff := deep.Equal(oapi, exp); diff != nil {
2579		t.Fatal(diff)
2580	}
2581
2582	// Check that default paths are present with a root token
2583	req = logical.TestRequest(t, logical.ReadOperation, "internal/specs/openapi")
2584	req.ClientToken = rootToken
2585	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2586	if err != nil {
2587		t.Fatalf("err: %v", err)
2588	}
2589
2590	body = resp.Data["http_raw_body"].([]byte)
2591	err = jsonutil.DecodeJSON(body, &oapi)
2592	if err != nil {
2593		t.Fatalf("err: %v", err)
2594	}
2595
2596	doc, err := framework.NewOASDocumentFromMap(oapi)
2597	if err != nil {
2598		t.Fatal(err)
2599	}
2600
2601	pathSamples := []struct {
2602		path string
2603		tag  string
2604	}{
2605		{"/auth/token/lookup", "auth"},
2606		{"/cubbyhole/{path}", "secrets"},
2607		{"/identity/group/id", "identity"},
2608		{"/secret/.*", "secrets"}, // TODO update after kv repo update
2609		{"/sys/policy", "system"},
2610	}
2611
2612	for _, path := range pathSamples {
2613		if doc.Paths[path.path] == nil {
2614			t.Fatalf("didn't find expected path '%s'.", path)
2615		}
2616		tag := doc.Paths[path.path].Get.Tags[0]
2617		if tag != path.tag {
2618			t.Fatalf("path: %s; expected tag: %s, actual: %s", path.path, tag, path.tag)
2619		}
2620	}
2621
2622	// Simple sanity check of response size (which is much larger than most
2623	// Vault responses), mainly to catch mass omission of expected path data.
2624	minLen := 70000
2625	if len(body) < minLen {
2626		t.Fatalf("response size too small; expected: min %d, actual: %d", minLen, len(body))
2627	}
2628
2629	// Test path-help response
2630	req = logical.TestRequest(t, logical.HelpOperation, "rotate")
2631	req.ClientToken = rootToken
2632	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2633	if err != nil {
2634		t.Fatalf("err: %v", err)
2635	}
2636
2637	doc = resp.Data["openapi"].(*framework.OASDocument)
2638	if len(doc.Paths) != 1 {
2639		t.Fatalf("expected 1 path, actual: %d", len(doc.Paths))
2640	}
2641
2642	if doc.Paths["/rotate"] == nil {
2643		t.Fatalf("expected to find path '/rotate'")
2644	}
2645}
2646
2647func TestSystemBackend_PathWildcardPreflight(t *testing.T) {
2648	core, b, _ := testCoreSystemBackend(t)
2649
2650	ctx := namespace.RootContext(nil)
2651
2652	// Add another mount
2653	me := &MountEntry{
2654		Table:   mountTableType,
2655		Path:    sanitizeMountPath("kv-v1"),
2656		Type:    "kv",
2657		Options: map[string]string{"version": "1"},
2658	}
2659	if err := core.mount(ctx, me); err != nil {
2660		t.Fatal(err)
2661	}
2662
2663	// Create the policy, designed to fail
2664	rules := `path "foo" { capabilities = ["read"] }`
2665	req := logical.TestRequest(t, logical.UpdateOperation, "policy/foo")
2666	req.Data["rules"] = rules
2667	resp, err := b.HandleRequest(ctx, req)
2668	if err != nil {
2669		t.Fatalf("err: %v %#v", err, resp)
2670	}
2671	if resp != nil && (resp.IsError() || len(resp.Data) > 0) {
2672		t.Fatalf("bad: %#v", resp)
2673	}
2674
2675	if err := core.identityStore.upsertEntity(ctx, &identity.Entity{
2676		ID:        "abcd",
2677		Name:      "abcd",
2678		BucketKey: "abcd",
2679	}, nil, false); err != nil {
2680		t.Fatal(err)
2681	}
2682
2683	te := &logical.TokenEntry{
2684		TTL:         300 * time.Second,
2685		EntityID:    "abcd",
2686		Policies:    []string{"default", "foo"},
2687		NamespaceID: namespace.RootNamespaceID,
2688	}
2689	if err := core.tokenStore.create(ctx, te); err != nil {
2690		t.Fatal(err)
2691	}
2692	t.Logf("token id: %s", te.ID)
2693
2694	if err := core.expiration.RegisterAuth(ctx, te, &logical.Auth{
2695		LeaseOptions: logical.LeaseOptions{
2696			TTL: te.TTL,
2697		},
2698		ClientToken: te.ID,
2699		Accessor:    te.Accessor,
2700		Orphan:      true,
2701	}); err != nil {
2702		t.Fatal(err)
2703	}
2704
2705	// Check the mount access func
2706	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/kv-v1/baz")
2707	req.ClientToken = te.ID
2708	resp, err = b.HandleRequest(ctx, req)
2709	if err == nil || !strings.Contains(err.Error(), "permission denied") {
2710		t.Fatalf("expected 403, got err: %v", err)
2711	}
2712
2713	// Modify policy to pass
2714	rules = `path "kv-v1/+" { capabilities = ["read"] }`
2715	req = logical.TestRequest(t, logical.UpdateOperation, "policy/foo")
2716	req.Data["rules"] = rules
2717	resp, err = b.HandleRequest(ctx, req)
2718	if err != nil {
2719		t.Fatalf("err: %v %#v", err, resp)
2720	}
2721	if resp != nil && (resp.IsError() || len(resp.Data) > 0) {
2722		t.Fatalf("bad: %#v", resp)
2723	}
2724
2725	// Check the mount access func again
2726	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/kv-v1/baz")
2727	req.ClientToken = te.ID
2728	resp, err = b.HandleRequest(ctx, req)
2729	if err != nil {
2730		t.Fatalf("err: %v", err)
2731	}
2732}
2733