1package approle
2
3import (
4	"context"
5	"encoding/json"
6	"fmt"
7	"reflect"
8	"strings"
9	"testing"
10	"time"
11
12	"github.com/go-test/deep"
13	"github.com/hashicorp/go-sockaddr"
14	"github.com/hashicorp/vault/sdk/helper/policyutil"
15	"github.com/hashicorp/vault/sdk/helper/tokenutil"
16	"github.com/hashicorp/vault/sdk/logical"
17	"github.com/mitchellh/mapstructure"
18)
19
20func TestAppRole_LocalSecretIDsRead(t *testing.T) {
21	var resp *logical.Response
22	var err error
23	b, storage := createBackendWithStorage(t)
24
25	roleData := map[string]interface{}{
26		"local_secret_ids": true,
27		"bind_secret_id":   true,
28	}
29
30	resp, err = b.HandleRequest(context.Background(), &logical.Request{
31		Operation: logical.CreateOperation,
32		Path:      "role/testrole",
33		Storage:   storage,
34		Data:      roleData,
35	})
36	if err != nil || (resp != nil && resp.IsError()) {
37		t.Fatalf("err:%v resp:%#v", err, resp)
38	}
39
40	resp, err = b.HandleRequest(context.Background(), &logical.Request{
41		Operation: logical.ReadOperation,
42		Storage:   storage,
43		Path:      "role/testrole/local-secret-ids",
44	})
45	if err != nil || (resp != nil && resp.IsError()) {
46		t.Fatalf("err:%v resp:%#v", err, resp)
47	}
48	if !resp.Data["local_secret_ids"].(bool) {
49		t.Fatalf("expected local_secret_ids to be returned")
50	}
51}
52
53func TestAppRole_LocalNonLocalSecretIDs(t *testing.T) {
54	var resp *logical.Response
55	var err error
56
57	b, storage := createBackendWithStorage(t)
58
59	// Create a role with local_secret_ids set
60	resp, err = b.HandleRequest(context.Background(), &logical.Request{
61		Path:      "role/testrole1",
62		Operation: logical.CreateOperation,
63		Storage:   storage,
64		Data: map[string]interface{}{
65			"policies":         []string{"default", "role1policy"},
66			"bind_secret_id":   true,
67			"local_secret_ids": true,
68		},
69	})
70	if err != nil || (resp != nil && resp.IsError()) {
71		t.Fatalf("bad: err: %v\n resp: %#v", err, resp)
72	}
73
74	// Create another role without setting local_secret_ids
75	resp, err = b.HandleRequest(context.Background(), &logical.Request{
76		Path:      "role/testrole2",
77		Operation: logical.CreateOperation,
78		Storage:   storage,
79		Data: map[string]interface{}{
80			"policies":       []string{"default", "role1policy"},
81			"bind_secret_id": true,
82		},
83	})
84	if err != nil || (resp != nil && resp.IsError()) {
85		t.Fatalf("bad: err: %v\n resp: %#v", err, resp)
86	}
87
88	count := 10
89	// Create secret IDs on testrole1
90	for i := 0; i < count; i++ {
91		resp, err = b.HandleRequest(context.Background(), &logical.Request{
92			Path:      "role/testrole1/secret-id",
93			Operation: logical.UpdateOperation,
94			Storage:   storage,
95		})
96		if err != nil || (resp != nil && resp.IsError()) {
97			t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
98		}
99	}
100
101	// Check the number of secret IDs generated
102	resp, err = b.HandleRequest(context.Background(), &logical.Request{
103		Path:      "role/testrole1/secret-id",
104		Operation: logical.ListOperation,
105		Storage:   storage,
106	})
107	if err != nil || (resp != nil && resp.IsError()) {
108		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
109	}
110	if len(resp.Data["keys"].([]string)) != count {
111		t.Fatalf("failed to list secret IDs")
112	}
113
114	// Create secret IDs on testrole1
115	for i := 0; i < count; i++ {
116		resp, err = b.HandleRequest(context.Background(), &logical.Request{
117			Path:      "role/testrole2/secret-id",
118			Operation: logical.UpdateOperation,
119			Storage:   storage,
120		})
121		if err != nil || (resp != nil && resp.IsError()) {
122			t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
123		}
124	}
125
126	resp, err = b.HandleRequest(context.Background(), &logical.Request{
127		Path:      "role/testrole2/secret-id",
128		Operation: logical.ListOperation,
129		Storage:   storage,
130	})
131	if err != nil || (resp != nil && resp.IsError()) {
132		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
133	}
134	if len(resp.Data["keys"].([]string)) != count {
135		t.Fatalf("failed to list secret IDs")
136	}
137}
138
139func TestAppRole_UpgradeSecretIDPrefix(t *testing.T) {
140	var resp *logical.Response
141	var err error
142
143	b, storage := createBackendWithStorage(t)
144
145	// Create a role entry directly in storage without SecretIDPrefix
146	err = b.setRoleEntry(context.Background(), storage, "testrole", &roleStorageEntry{
147		RoleID:           "testroleid",
148		HMACKey:          "testhmackey",
149		Policies:         []string{"default"},
150		BindSecretID:     true,
151		BoundCIDRListOld: "127.0.0.1/18,192.178.1.2/24",
152	}, "")
153	if err != nil {
154		t.Fatal(err)
155	}
156
157	// Reading the role entry should upgrade it to contain SecretIDPrefix
158	role, err := b.roleEntry(context.Background(), storage, "testrole")
159	if err != nil {
160		t.Fatal(err)
161	}
162	if role.SecretIDPrefix == "" {
163		t.Fatalf("expected SecretIDPrefix to be set")
164	}
165
166	// Ensure that the API response contains local_secret_ids
167	resp, err = b.HandleRequest(context.Background(), &logical.Request{
168		Path:      "role/testrole",
169		Operation: logical.ReadOperation,
170		Storage:   storage,
171	})
172	if err != nil || (resp != nil && resp.IsError()) {
173		t.Fatalf("bad: err: %v\n resp: %#v", err, resp)
174	}
175	_, ok := resp.Data["local_secret_ids"]
176	if !ok {
177		t.Fatalf("expected local_secret_ids to be present in the response")
178	}
179}
180
181func TestAppRole_LocalSecretIDImmutability(t *testing.T) {
182	var resp *logical.Response
183	var err error
184
185	b, storage := createBackendWithStorage(t)
186
187	roleData := map[string]interface{}{
188		"policies":         []string{"default"},
189		"bind_secret_id":   true,
190		"bound_cidr_list":  []string{"127.0.0.1/18", "192.178.1.2/24"},
191		"local_secret_ids": true,
192	}
193
194	// Create a role with local_secret_ids set
195	resp, err = b.HandleRequest(context.Background(), &logical.Request{
196		Path:      "role/testrole",
197		Operation: logical.CreateOperation,
198		Storage:   storage,
199		Data:      roleData,
200	})
201	if err != nil || (resp != nil && resp.IsError()) {
202		t.Fatalf("bad: err: %v\nresp: %#v", err, resp)
203	}
204
205	// Attempt to modify local_secret_ids should fail
206	resp, err = b.HandleRequest(context.Background(), &logical.Request{
207		Path:      "role/testrole",
208		Operation: logical.UpdateOperation,
209		Storage:   storage,
210		Data:      roleData,
211	})
212	if err != nil {
213		t.Fatal(err)
214	}
215	if resp == nil || !resp.IsError() {
216		t.Fatalf("expected an error since local_secret_ids can't be overwritten")
217	}
218}
219
220func TestAppRole_UpgradeBoundCIDRList(t *testing.T) {
221	var resp *logical.Response
222	var err error
223
224	b, storage := createBackendWithStorage(t)
225
226	roleData := map[string]interface{}{
227		"policies":        []string{"default"},
228		"bind_secret_id":  true,
229		"bound_cidr_list": []string{"127.0.0.1/18", "192.178.1.2/24"},
230	}
231
232	// Create a role with bound_cidr_list set
233	resp, err = b.HandleRequest(context.Background(), &logical.Request{
234		Path:      "role/testrole",
235		Operation: logical.CreateOperation,
236		Storage:   storage,
237		Data:      roleData,
238	})
239	if err != nil || (resp != nil && resp.IsError()) {
240		t.Fatalf("bad: err: %v\nresp: %#v", err, resp)
241	}
242
243	// Read the role and check that the bound_cidr_list is set properly
244	resp, err = b.HandleRequest(context.Background(), &logical.Request{
245		Path:      "role/testrole",
246		Operation: logical.ReadOperation,
247		Storage:   storage,
248	})
249	if err != nil || (resp != nil && resp.IsError()) {
250		t.Fatalf("bad: err: %v\nresp: %#v", err, resp)
251	}
252
253	expected := []string{"127.0.0.1/18", "192.178.1.2/24"}
254	actual := resp.Data["secret_id_bound_cidrs"].([]string)
255
256	if !reflect.DeepEqual(expected, actual) {
257		t.Fatalf("bad: secret_id_bound_cidrs; expected: %#v\nactual: %#v\n", expected, actual)
258	}
259
260	// Modify the storage entry of the role to hold the old style string typed bound_cidr_list
261	role := &roleStorageEntry{
262		RoleID:           "testroleid",
263		HMACKey:          "testhmackey",
264		Policies:         []string{"default"},
265		BindSecretID:     true,
266		BoundCIDRListOld: "127.0.0.1/18,192.178.1.2/24",
267		SecretIDPrefix:   secretIDPrefix,
268	}
269	err = b.setRoleEntry(context.Background(), storage, "testrole", role, "")
270	if err != nil {
271		t.Fatal(err)
272	}
273
274	// Read the role. The upgrade code should have migrated the old type to the new type
275	resp, err = b.HandleRequest(context.Background(), &logical.Request{
276		Path:      "role/testrole",
277		Operation: logical.ReadOperation,
278		Storage:   storage,
279	})
280	if err != nil || (resp != nil && resp.IsError()) {
281		t.Fatalf("bad: err: %v\nresp: %#v", err, resp)
282	}
283	if !reflect.DeepEqual(expected, actual) {
284		t.Fatalf("bad: bound_cidr_list; expected: %#v\nactual: %#v\n", expected, actual)
285	}
286
287	// Create a secret-id by supplying a subset of the role's CIDR blocks with the new type
288	resp, err = b.HandleRequest(context.Background(), &logical.Request{
289		Path:      "role/testrole/secret-id",
290		Operation: logical.UpdateOperation,
291		Storage:   storage,
292		Data: map[string]interface{}{
293			"cidr_list": []string{"127.0.0.1/24"},
294		},
295	})
296	if err != nil || (resp != nil && resp.IsError()) {
297		t.Fatalf("bad: err: %v\nresp: %#v", err, resp)
298	}
299	if resp.Data["secret_id"].(string) == "" {
300		t.Fatalf("failed to generate secret-id")
301	}
302
303	// Check that the backwards compatibility for the string type is not broken
304	resp, err = b.HandleRequest(context.Background(), &logical.Request{
305		Path:      "role/testrole/secret-id",
306		Operation: logical.UpdateOperation,
307		Storage:   storage,
308		Data: map[string]interface{}{
309			"cidr_list": "127.0.0.1/24",
310		},
311	})
312	if err != nil || (resp != nil && resp.IsError()) {
313		t.Fatalf("bad: err: %v\nresp: %#v", err, resp)
314	}
315	if resp.Data["secret_id"].(string) == "" {
316		t.Fatalf("failed to generate secret-id")
317	}
318}
319
320func TestAppRole_RoleNameLowerCasing(t *testing.T) {
321	var resp *logical.Response
322	var err error
323	var roleID, secretID string
324
325	b, storage := createBackendWithStorage(t)
326
327	// Save a role with out LowerCaseRoleName set
328	role := &roleStorageEntry{
329		RoleID:         "testroleid",
330		HMACKey:        "testhmackey",
331		Policies:       []string{"default"},
332		BindSecretID:   true,
333		SecretIDPrefix: secretIDPrefix,
334	}
335	err = b.setRoleEntry(context.Background(), storage, "testRoleName", role, "")
336	if err != nil {
337		t.Fatal(err)
338	}
339
340	secretIDReq := &logical.Request{
341		Path:      "role/testRoleName/secret-id",
342		Operation: logical.UpdateOperation,
343		Storage:   storage,
344	}
345	resp, err = b.HandleRequest(context.Background(), secretIDReq)
346	if err != nil || (resp != nil && resp.IsError()) {
347		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
348	}
349	secretID = resp.Data["secret_id"].(string)
350	roleID = "testroleid"
351
352	// Regular login flow. This should succeed.
353	resp, err = b.HandleRequest(context.Background(), &logical.Request{
354		Path:      "login",
355		Operation: logical.UpdateOperation,
356		Storage:   storage,
357		Data: map[string]interface{}{
358			"role_id":   roleID,
359			"secret_id": secretID,
360		},
361	})
362	if err != nil || (resp != nil && resp.IsError()) {
363		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
364	}
365
366	// Lower case the role name when generating the secret id
367	secretIDReq.Path = "role/testrolename/secret-id"
368	resp, err = b.HandleRequest(context.Background(), secretIDReq)
369	if err != nil || (resp != nil && resp.IsError()) {
370		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
371	}
372	secretID = resp.Data["secret_id"].(string)
373
374	// Login should fail
375	resp, err = b.HandleRequest(context.Background(), &logical.Request{
376		Path:      "login",
377		Operation: logical.UpdateOperation,
378		Storage:   storage,
379		Data: map[string]interface{}{
380			"role_id":   roleID,
381			"secret_id": secretID,
382		},
383	})
384	if err != nil {
385		t.Fatal(err)
386	}
387	if resp == nil || !resp.IsError() {
388		t.Fatalf("expected an error")
389	}
390
391	// Delete the role and create it again. This time don't directly persist
392	// it, but route the request to the creation handler so that it sets the
393	// LowerCaseRoleName to true.
394	resp, err = b.HandleRequest(context.Background(), &logical.Request{
395		Path:      "role/testRoleName",
396		Operation: logical.DeleteOperation,
397		Storage:   storage,
398	})
399	if err != nil || (resp != nil && resp.IsError()) {
400		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
401	}
402
403	roleReq := &logical.Request{
404		Path:      "role/testRoleName",
405		Operation: logical.CreateOperation,
406		Storage:   storage,
407		Data: map[string]interface{}{
408			"bind_secret_id": true,
409		},
410	}
411	resp, err = b.HandleRequest(context.Background(), roleReq)
412	if err != nil || (resp != nil && resp.IsError()) {
413		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
414	}
415
416	// Create secret id with lower cased role name
417	resp, err = b.HandleRequest(context.Background(), &logical.Request{
418		Path:      "role/testrolename/secret-id",
419		Operation: logical.UpdateOperation,
420		Storage:   storage,
421	})
422	if err != nil || (resp != nil && resp.IsError()) {
423		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
424	}
425	secretID = resp.Data["secret_id"].(string)
426
427	resp, err = b.HandleRequest(context.Background(), &logical.Request{
428		Path:      "role/testrolename/role-id",
429		Operation: logical.ReadOperation,
430		Storage:   storage,
431	})
432	if err != nil || (resp != nil && resp.IsError()) {
433		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
434	}
435	roleID = resp.Data["role_id"].(string)
436
437	// Login should pass
438	resp, err = b.HandleRequest(context.Background(), &logical.Request{
439		Path:      "login",
440		Operation: logical.UpdateOperation,
441		Storage:   storage,
442		Data: map[string]interface{}{
443			"role_id":   roleID,
444			"secret_id": secretID,
445		},
446	})
447	if err != nil || (resp != nil && resp.IsError()) {
448		t.Fatalf("bad: resp: %#v\nerr:%v", resp, err)
449	}
450
451	// Lookup of secret ID should work in case-insensitive manner
452	resp, err = b.HandleRequest(context.Background(), &logical.Request{
453		Path:      "role/testrolename/secret-id/lookup",
454		Operation: logical.UpdateOperation,
455		Storage:   storage,
456		Data: map[string]interface{}{
457			"secret_id": secretID,
458		},
459	})
460	if err != nil || (resp != nil && resp.IsError()) {
461		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
462	}
463	if resp == nil {
464		t.Fatalf("failed to lookup secret IDs")
465	}
466
467	// Listing of secret IDs should work in case-insensitive manner
468	resp, err = b.HandleRequest(context.Background(), &logical.Request{
469		Path:      "role/testrolename/secret-id",
470		Operation: logical.ListOperation,
471		Storage:   storage,
472	})
473	if err != nil || (resp != nil && resp.IsError()) {
474		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
475	}
476
477	if len(resp.Data["keys"].([]string)) != 1 {
478		t.Fatalf("failed to list secret IDs")
479	}
480}
481
482func TestAppRole_RoleReadSetIndex(t *testing.T) {
483	var resp *logical.Response
484	var err error
485
486	b, storage := createBackendWithStorage(t)
487
488	roleReq := &logical.Request{
489		Path:      "role/testrole",
490		Operation: logical.CreateOperation,
491		Storage:   storage,
492		Data: map[string]interface{}{
493			"bind_secret_id": true,
494		},
495	}
496
497	// Create a role
498	resp, err = b.HandleRequest(context.Background(), roleReq)
499	if err != nil || (resp != nil && resp.IsError()) {
500		t.Fatalf("bad: resp: %#v\n err: %v\n", resp, err)
501	}
502
503	roleIDReq := &logical.Request{
504		Path:      "role/testrole/role-id",
505		Operation: logical.ReadOperation,
506		Storage:   storage,
507	}
508
509	// Get the role ID
510	resp, err = b.HandleRequest(context.Background(), roleIDReq)
511	if err != nil || (resp != nil && resp.IsError()) {
512		t.Fatalf("bad: resp: %#v\n err: %v\n", resp, err)
513	}
514	roleID := resp.Data["role_id"].(string)
515
516	// Delete the role ID index
517	err = b.roleIDEntryDelete(context.Background(), storage, roleID)
518	if err != nil {
519		t.Fatal(err)
520	}
521
522	// Read the role again. This should add the index and return a warning
523	roleReq.Operation = logical.ReadOperation
524	resp, err = b.HandleRequest(context.Background(), roleReq)
525	if err != nil || (resp != nil && resp.IsError()) {
526		t.Fatalf("bad: resp: %#v\n err: %v\n", resp, err)
527	}
528
529	// Check if the warning is being returned
530	if !strings.Contains(resp.Warnings[0], "Role identifier was missing an index back to role name.") {
531		t.Fatalf("bad: expected a warning in the response")
532	}
533
534	roleIDIndex, err := b.roleIDEntry(context.Background(), storage, roleID)
535	if err != nil {
536		t.Fatal(err)
537	}
538
539	// Check if the index has been successfully created
540	if roleIDIndex == nil || roleIDIndex.Name != "testrole" {
541		t.Fatalf("bad: expected role to have an index")
542	}
543
544	roleReq.Operation = logical.UpdateOperation
545	roleReq.Data = map[string]interface{}{
546		"bind_secret_id": true,
547		"policies":       "default",
548	}
549
550	// Check if updating and reading of roles work and that there are no lock
551	// contentions dangling due to previous operation
552	resp, err = b.HandleRequest(context.Background(), roleReq)
553	if err != nil || (resp != nil && resp.IsError()) {
554		t.Fatalf("bad: resp: %#v\n err: %v\n", resp, err)
555	}
556	roleReq.Operation = logical.ReadOperation
557	resp, err = b.HandleRequest(context.Background(), roleReq)
558	if err != nil || (resp != nil && resp.IsError()) {
559		t.Fatalf("bad: resp: %#v\n err: %v\n", resp, err)
560	}
561}
562
563func TestAppRole_CIDRSubset(t *testing.T) {
564	var resp *logical.Response
565	var err error
566
567	b, storage := createBackendWithStorage(t)
568
569	roleData := map[string]interface{}{
570		"role_id":         "role-id-123",
571		"policies":        "a,b",
572		"bound_cidr_list": "127.0.0.1/24",
573	}
574
575	roleReq := &logical.Request{
576		Operation: logical.CreateOperation,
577		Path:      "role/testrole1",
578		Storage:   storage,
579		Data:      roleData,
580	}
581
582	resp, err = b.HandleRequest(context.Background(), roleReq)
583	if err != nil || (resp != nil && resp.IsError()) {
584		t.Fatalf("err: %v resp: %#v", err, resp)
585	}
586
587	secretIDData := map[string]interface{}{
588		"cidr_list": "127.0.0.1/16",
589	}
590	secretIDReq := &logical.Request{
591		Operation: logical.UpdateOperation,
592		Storage:   storage,
593		Path:      "role/testrole1/secret-id",
594		Data:      secretIDData,
595	}
596
597	resp, err = b.HandleRequest(context.Background(), secretIDReq)
598	if resp != nil || resp.IsError() {
599		t.Fatalf("resp:%#v", resp)
600	}
601	if err == nil {
602		t.Fatal("expected an error")
603	}
604
605	roleData["bound_cidr_list"] = "192.168.27.29/16,172.245.30.40/24,10.20.30.40/30"
606	roleReq.Operation = logical.UpdateOperation
607	resp, err = b.HandleRequest(context.Background(), roleReq)
608	if err != nil || (resp != nil && resp.IsError()) {
609		t.Fatalf("err: %v resp: %#v", err, resp)
610	}
611
612	secretIDData["cidr_list"] = "192.168.27.29/20,172.245.30.40/25,10.20.30.40/32"
613	resp, err = b.HandleRequest(context.Background(), secretIDReq)
614	if err != nil {
615		t.Fatal(err)
616	}
617	if resp != nil && resp.IsError() {
618		t.Fatalf("resp: %#v", resp)
619	}
620}
621
622func TestAppRole_RoleConstraints(t *testing.T) {
623	var resp *logical.Response
624	var err error
625	b, storage := createBackendWithStorage(t)
626
627	roleData := map[string]interface{}{
628		"role_id":  "role-id-123",
629		"policies": "a,b",
630	}
631
632	roleReq := &logical.Request{
633		Operation: logical.CreateOperation,
634		Path:      "role/testrole1",
635		Storage:   storage,
636		Data:      roleData,
637	}
638
639	// Set bind_secret_id, which is enabled by default
640	resp, err = b.HandleRequest(context.Background(), roleReq)
641	if err != nil || (resp != nil && resp.IsError()) {
642		t.Fatalf("err:%v resp:%#v", err, resp)
643	}
644
645	// Set bound_cidr_list alone by explicitly disabling bind_secret_id
646	roleReq.Operation = logical.UpdateOperation
647	roleData["bind_secret_id"] = false
648	roleData["bound_cidr_list"] = "0.0.0.0/0"
649	resp, err = b.HandleRequest(context.Background(), roleReq)
650	if err != nil || (resp != nil && resp.IsError()) {
651		t.Fatalf("err:%v resp:%#v", err, resp)
652	}
653
654	// Remove both constraints
655	roleReq.Operation = logical.UpdateOperation
656	roleData["bound_cidr_list"] = ""
657	roleData["bind_secret_id"] = false
658	resp, err = b.HandleRequest(context.Background(), roleReq)
659	if resp != nil && resp.IsError() {
660		t.Fatalf("err:%v, resp:%#v", err, resp)
661	}
662	if err == nil {
663		t.Fatalf("expected an error")
664	}
665}
666
667func TestAppRole_RoleIDUpdate(t *testing.T) {
668	var resp *logical.Response
669	var err error
670	b, storage := createBackendWithStorage(t)
671
672	roleData := map[string]interface{}{
673		"role_id":            "role-id-123",
674		"policies":           "a,b",
675		"secret_id_num_uses": 10,
676		"secret_id_ttl":      300,
677		"token_ttl":          400,
678		"token_max_ttl":      500,
679	}
680	roleReq := &logical.Request{
681		Operation: logical.CreateOperation,
682		Path:      "role/testrole1",
683		Storage:   storage,
684		Data:      roleData,
685	}
686	resp, err = b.HandleRequest(context.Background(), roleReq)
687	if err != nil || (resp != nil && resp.IsError()) {
688		t.Fatalf("err:%v resp:%#v", err, resp)
689	}
690
691	roleIDUpdateReq := &logical.Request{
692		Operation: logical.UpdateOperation,
693		Path:      "role/testrole1/role-id",
694		Storage:   storage,
695		Data: map[string]interface{}{
696			"role_id": "customroleid",
697		},
698	}
699	resp, err = b.HandleRequest(context.Background(), roleIDUpdateReq)
700	if err != nil || (resp != nil && resp.IsError()) {
701		t.Fatalf("err:%v resp:%#v", err, resp)
702	}
703
704	secretIDReq := &logical.Request{
705		Operation: logical.UpdateOperation,
706		Storage:   storage,
707		Path:      "role/testrole1/secret-id",
708	}
709	resp, err = b.HandleRequest(context.Background(), secretIDReq)
710	if err != nil || (resp != nil && resp.IsError()) {
711		t.Fatalf("err:%v resp:%#v", err, resp)
712	}
713	secretID := resp.Data["secret_id"].(string)
714
715	loginData := map[string]interface{}{
716		"role_id":   "customroleid",
717		"secret_id": secretID,
718	}
719	loginReq := &logical.Request{
720		Operation: logical.UpdateOperation,
721		Path:      "login",
722		Storage:   storage,
723		Data:      loginData,
724		Connection: &logical.Connection{
725			RemoteAddr: "127.0.0.1",
726		},
727	}
728	resp, err = b.HandleRequest(context.Background(), loginReq)
729	if err != nil || (resp != nil && resp.IsError()) {
730		t.Fatalf("err:%v resp:%#v", err, resp)
731	}
732
733	if resp.Auth == nil {
734		t.Fatalf("expected a non-nil auth object in the response")
735	}
736}
737
738func TestAppRole_RoleIDUniqueness(t *testing.T) {
739	var resp *logical.Response
740	var err error
741	b, storage := createBackendWithStorage(t)
742
743	roleData := map[string]interface{}{
744		"role_id":            "role-id-123",
745		"policies":           "a,b",
746		"secret_id_num_uses": 10,
747		"secret_id_ttl":      300,
748		"token_ttl":          400,
749		"token_max_ttl":      500,
750	}
751	roleReq := &logical.Request{
752		Operation: logical.CreateOperation,
753		Path:      "role/testrole1",
754		Storage:   storage,
755		Data:      roleData,
756	}
757
758	resp, err = b.HandleRequest(context.Background(), roleReq)
759	if err != nil || (resp != nil && resp.IsError()) {
760		t.Fatalf("err:%v resp:%#v", err, resp)
761	}
762
763	roleReq.Path = "role/testrole2"
764	resp, err = b.HandleRequest(context.Background(), roleReq)
765	if err == nil && !(resp != nil && resp.IsError()) {
766		t.Fatalf("expected an error: got resp:%#v", resp)
767	}
768
769	roleData["role_id"] = "role-id-456"
770	resp, err = b.HandleRequest(context.Background(), roleReq)
771	if err != nil || (resp != nil && resp.IsError()) {
772		t.Fatalf("err:%v resp:%#v", err, resp)
773	}
774
775	roleReq.Operation = logical.UpdateOperation
776	roleData["role_id"] = "role-id-123"
777	resp, err = b.HandleRequest(context.Background(), roleReq)
778	if err == nil && !(resp != nil && resp.IsError()) {
779		t.Fatalf("expected an error: got resp:%#v", resp)
780	}
781
782	roleReq.Path = "role/testrole1"
783	roleData["role_id"] = "role-id-456"
784	resp, err = b.HandleRequest(context.Background(), roleReq)
785	if err == nil && !(resp != nil && resp.IsError()) {
786		t.Fatalf("expected an error: got resp:%#v", resp)
787	}
788
789	roleIDData := map[string]interface{}{
790		"role_id": "role-id-456",
791	}
792	roleIDReq := &logical.Request{
793		Operation: logical.UpdateOperation,
794		Path:      "role/testrole1/role-id",
795		Storage:   storage,
796		Data:      roleIDData,
797	}
798	resp, err = b.HandleRequest(context.Background(), roleIDReq)
799	if err == nil && !(resp != nil && resp.IsError()) {
800		t.Fatalf("expected an error: got resp:%#v", resp)
801	}
802
803	roleIDData["role_id"] = "role-id-123"
804	roleIDReq.Path = "role/testrole2/role-id"
805	resp, err = b.HandleRequest(context.Background(), roleIDReq)
806	if err == nil && !(resp != nil && resp.IsError()) {
807		t.Fatalf("expected an error: got resp:%#v", resp)
808	}
809
810	roleIDData["role_id"] = "role-id-2000"
811	resp, err = b.HandleRequest(context.Background(), roleIDReq)
812	if err != nil || (resp != nil && resp.IsError()) {
813		t.Fatalf("err:%v resp:%#v", err, resp)
814	}
815
816	roleIDData["role_id"] = "role-id-1000"
817	roleIDReq.Path = "role/testrole1/role-id"
818	resp, err = b.HandleRequest(context.Background(), roleIDReq)
819	if err != nil || (resp != nil && resp.IsError()) {
820		t.Fatalf("err:%v resp:%#v", err, resp)
821	}
822}
823
824func TestAppRole_RoleDeleteSecretID(t *testing.T) {
825	var resp *logical.Response
826	var err error
827	b, storage := createBackendWithStorage(t)
828
829	createRole(t, b, storage, "role1", "a,b")
830	secretIDReq := &logical.Request{
831		Operation: logical.UpdateOperation,
832		Storage:   storage,
833		Path:      "role/role1/secret-id",
834	}
835	// Create 3 secrets on the role
836	resp, err = b.HandleRequest(context.Background(), secretIDReq)
837	if err != nil || (resp != nil && resp.IsError()) {
838		t.Fatalf("err:%v resp:%#v", err, resp)
839	}
840	resp, err = b.HandleRequest(context.Background(), secretIDReq)
841	if err != nil || (resp != nil && resp.IsError()) {
842		t.Fatalf("err:%v resp:%#v", err, resp)
843	}
844	resp, err = b.HandleRequest(context.Background(), secretIDReq)
845	if err != nil || (resp != nil && resp.IsError()) {
846		t.Fatalf("err:%v resp:%#v", err, resp)
847	}
848
849	listReq := &logical.Request{
850		Operation: logical.ListOperation,
851		Storage:   storage,
852		Path:      "role/role1/secret-id",
853	}
854	resp, err = b.HandleRequest(context.Background(), listReq)
855	if err != nil || (resp != nil && resp.IsError()) {
856		t.Fatalf("err:%v resp:%#v", err, resp)
857	}
858	secretIDAccessors := resp.Data["keys"].([]string)
859	if len(secretIDAccessors) != 3 {
860		t.Fatalf("bad: len of secretIDAccessors: expected:3 actual:%d", len(secretIDAccessors))
861	}
862
863	roleReq := &logical.Request{
864		Operation: logical.DeleteOperation,
865		Storage:   storage,
866		Path:      "role/role1",
867	}
868	resp, err = b.HandleRequest(context.Background(), roleReq)
869	if err != nil || (resp != nil && resp.IsError()) {
870		t.Fatalf("err:%v resp:%#v", err, resp)
871	}
872	resp, err = b.HandleRequest(context.Background(), listReq)
873	if err != nil || resp == nil || (resp != nil && !resp.IsError()) {
874		t.Fatalf("expected an error. err:%v resp:%#v", err, resp)
875	}
876}
877
878func TestAppRole_RoleSecretIDReadDelete(t *testing.T) {
879	var resp *logical.Response
880	var err error
881	b, storage := createBackendWithStorage(t)
882
883	createRole(t, b, storage, "role1", "a,b")
884	secretIDCreateReq := &logical.Request{
885		Operation: logical.UpdateOperation,
886		Storage:   storage,
887		Path:      "role/role1/secret-id",
888	}
889	resp, err = b.HandleRequest(context.Background(), secretIDCreateReq)
890	if err != nil || (resp != nil && resp.IsError()) {
891		t.Fatalf("err:%v resp:%#v", err, resp)
892	}
893
894	secretID := resp.Data["secret_id"].(string)
895	if secretID == "" {
896		t.Fatal("expected non empty secret ID")
897	}
898
899	secretIDReq := &logical.Request{
900		Operation: logical.UpdateOperation,
901		Storage:   storage,
902		Path:      "role/role1/secret-id/lookup",
903		Data: map[string]interface{}{
904			"secret_id": secretID,
905		},
906	}
907	resp, err = b.HandleRequest(context.Background(), secretIDReq)
908	if err != nil || (resp != nil && resp.IsError()) {
909		t.Fatalf("err:%v resp:%#v", err, resp)
910	}
911	if resp.Data == nil {
912		t.Fatal(err)
913	}
914
915	deleteSecretIDReq := &logical.Request{
916		Operation: logical.DeleteOperation,
917		Storage:   storage,
918		Path:      "role/role1/secret-id/destroy",
919		Data: map[string]interface{}{
920			"secret_id": secretID,
921		},
922	}
923	resp, err = b.HandleRequest(context.Background(), deleteSecretIDReq)
924	if err != nil || (resp != nil && resp.IsError()) {
925		t.Fatalf("err:%v resp:%#v", err, resp)
926	}
927
928	resp, err = b.HandleRequest(context.Background(), secretIDReq)
929	if resp != nil && resp.IsError() {
930		t.Fatalf("error response:%#v", resp)
931	}
932	if err != nil {
933		t.Fatal(err)
934	}
935}
936
937func TestAppRole_RoleSecretIDAccessorReadDelete(t *testing.T) {
938	var resp *logical.Response
939	var err error
940	b, storage := createBackendWithStorage(t)
941
942	createRole(t, b, storage, "role1", "a,b")
943	secretIDReq := &logical.Request{
944		Operation: logical.UpdateOperation,
945		Storage:   storage,
946		Path:      "role/role1/secret-id",
947	}
948	resp, err = b.HandleRequest(context.Background(), secretIDReq)
949	if err != nil || (resp != nil && resp.IsError()) {
950		t.Fatalf("err:%v resp:%#v", err, resp)
951	}
952
953	listReq := &logical.Request{
954		Operation: logical.ListOperation,
955		Storage:   storage,
956		Path:      "role/role1/secret-id",
957	}
958	resp, err = b.HandleRequest(context.Background(), listReq)
959	if err != nil || (resp != nil && resp.IsError()) {
960		t.Fatalf("err:%v resp:%#v", err, resp)
961	}
962	hmacSecretID := resp.Data["keys"].([]string)[0]
963
964	hmacReq := &logical.Request{
965		Operation: logical.UpdateOperation,
966		Storage:   storage,
967		Path:      "role/role1/secret-id-accessor/lookup",
968		Data: map[string]interface{}{
969			"secret_id_accessor": hmacSecretID,
970		},
971	}
972	resp, err = b.HandleRequest(context.Background(), hmacReq)
973	if err != nil || (resp != nil && resp.IsError()) {
974		t.Fatalf("err:%v resp:%#v", err, resp)
975	}
976	if resp.Data == nil {
977		t.Fatal(err)
978	}
979
980	hmacReq.Path = "role/role1/secret-id-accessor/destroy"
981	resp, err = b.HandleRequest(context.Background(), hmacReq)
982	if err != nil || (resp != nil && resp.IsError()) {
983		t.Fatalf("err:%v resp:%#v", err, resp)
984	}
985
986	hmacReq.Operation = logical.ReadOperation
987	resp, err = b.HandleRequest(context.Background(), hmacReq)
988	if resp != nil && resp.IsError() {
989		t.Fatalf("err:%v resp:%#v", err, resp)
990	}
991	if err == nil {
992		t.Fatalf("expected an error")
993	}
994}
995
996func TestAppRoleRoleListSecretID(t *testing.T) {
997	var resp *logical.Response
998	var err error
999	b, storage := createBackendWithStorage(t)
1000
1001	createRole(t, b, storage, "role1", "a,b")
1002
1003	secretIDReq := &logical.Request{
1004		Operation: logical.UpdateOperation,
1005		Storage:   storage,
1006		Path:      "role/role1/secret-id",
1007	}
1008	// Create 5 'secret_id's
1009	resp, err = b.HandleRequest(context.Background(), secretIDReq)
1010	if err != nil || (resp != nil && resp.IsError()) {
1011		t.Fatalf("err:%v resp:%#v", err, resp)
1012	}
1013	resp, err = b.HandleRequest(context.Background(), secretIDReq)
1014	if err != nil || (resp != nil && resp.IsError()) {
1015		t.Fatalf("err:%v resp:%#v", err, resp)
1016	}
1017	resp, err = b.HandleRequest(context.Background(), secretIDReq)
1018	if err != nil || (resp != nil && resp.IsError()) {
1019		t.Fatalf("err:%v resp:%#v", err, resp)
1020	}
1021	resp, err = b.HandleRequest(context.Background(), secretIDReq)
1022	if err != nil || (resp != nil && resp.IsError()) {
1023		t.Fatalf("err:%v resp:%#v", err, resp)
1024	}
1025	resp, err = b.HandleRequest(context.Background(), secretIDReq)
1026	if err != nil || (resp != nil && resp.IsError()) {
1027		t.Fatalf("err:%v resp:%#v", err, resp)
1028	}
1029
1030	listReq := &logical.Request{
1031		Operation: logical.ListOperation,
1032		Storage:   storage,
1033		Path:      "role/role1/secret-id/",
1034	}
1035	resp, err = b.HandleRequest(context.Background(), listReq)
1036	if err != nil || (resp != nil && resp.IsError()) {
1037		t.Fatalf("err:%v resp:%#v", err, resp)
1038	}
1039	secrets := resp.Data["keys"].([]string)
1040	if len(secrets) != 5 {
1041		t.Fatalf("bad: len of secrets: expected:5 actual:%d", len(secrets))
1042	}
1043}
1044
1045func TestAppRole_RoleList(t *testing.T) {
1046	var resp *logical.Response
1047	var err error
1048	b, storage := createBackendWithStorage(t)
1049
1050	createRole(t, b, storage, "role1", "a,b")
1051	createRole(t, b, storage, "role2", "c,d")
1052	createRole(t, b, storage, "role3", "e,f")
1053	createRole(t, b, storage, "role4", "g,h")
1054	createRole(t, b, storage, "role5", "i,j")
1055
1056	listReq := &logical.Request{
1057		Operation: logical.ListOperation,
1058		Path:      "role",
1059		Storage:   storage,
1060	}
1061	resp, err = b.HandleRequest(context.Background(), listReq)
1062	if err != nil || (resp != nil && resp.IsError()) {
1063		t.Fatalf("err:%v resp:%#v", err, resp)
1064	}
1065
1066	actual := resp.Data["keys"].([]string)
1067	expected := []string{"role1", "role2", "role3", "role4", "role5"}
1068	if !policyutil.EquivalentPolicies(actual, expected) {
1069		t.Fatalf("bad: listed roles: expected:%s\nactual:%s", expected, actual)
1070	}
1071}
1072
1073func TestAppRole_RoleSecretID(t *testing.T) {
1074	var resp *logical.Response
1075	var err error
1076	b, storage := createBackendWithStorage(t)
1077
1078	roleData := map[string]interface{}{
1079		"policies":           "p,q,r,s",
1080		"secret_id_num_uses": 10,
1081		"secret_id_ttl":      300,
1082		"token_ttl":          400,
1083		"token_max_ttl":      500,
1084	}
1085	roleReq := &logical.Request{
1086		Operation: logical.CreateOperation,
1087		Path:      "role/role1",
1088		Storage:   storage,
1089		Data:      roleData,
1090	}
1091
1092	resp, err = b.HandleRequest(context.Background(), roleReq)
1093	if err != nil || (resp != nil && resp.IsError()) {
1094		t.Fatalf("err:%v resp:%#v", err, resp)
1095	}
1096
1097	roleSecretIDReq := &logical.Request{
1098		Operation: logical.UpdateOperation,
1099		Path:      "role/role1/secret-id",
1100		Storage:   storage,
1101	}
1102	resp, err = b.HandleRequest(context.Background(), roleSecretIDReq)
1103	if err != nil || (resp != nil && resp.IsError()) {
1104		t.Fatalf("err:%v resp:%#v", err, resp)
1105	}
1106
1107	if resp.Data["secret_id"].(string) == "" {
1108		t.Fatalf("failed to generate secret_id")
1109	}
1110
1111	roleSecretIDReq.Path = "role/role1/custom-secret-id"
1112	roleCustomSecretIDData := map[string]interface{}{
1113		"secret_id": "abcd123",
1114	}
1115	roleSecretIDReq.Data = roleCustomSecretIDData
1116	roleSecretIDReq.Operation = logical.UpdateOperation
1117	resp, err = b.HandleRequest(context.Background(), roleSecretIDReq)
1118	if err != nil || (resp != nil && resp.IsError()) {
1119		t.Fatalf("err:%v resp:%#v", err, resp)
1120	}
1121
1122	if resp.Data["secret_id"] != "abcd123" {
1123		t.Fatalf("failed to set specific secret_id to role")
1124	}
1125}
1126
1127func TestAppRole_RoleCRUD(t *testing.T) {
1128	var resp *logical.Response
1129	var err error
1130	b, storage := createBackendWithStorage(t)
1131
1132	roleData := map[string]interface{}{
1133		"policies":              "p,q,r,s",
1134		"secret_id_num_uses":    10,
1135		"secret_id_ttl":         300,
1136		"token_ttl":             400,
1137		"token_max_ttl":         500,
1138		"token_num_uses":        600,
1139		"secret_id_bound_cidrs": "127.0.0.1/32,127.0.0.1/16",
1140	}
1141	roleReq := &logical.Request{
1142		Operation: logical.CreateOperation,
1143		Path:      "role/role1",
1144		Storage:   storage,
1145		Data:      roleData,
1146	}
1147
1148	resp, err = b.HandleRequest(context.Background(), roleReq)
1149	if err != nil || (resp != nil && resp.IsError()) {
1150		t.Fatalf("err:%v resp:%#v", err, resp)
1151	}
1152
1153	roleReq.Operation = logical.ReadOperation
1154	resp, err = b.HandleRequest(context.Background(), roleReq)
1155	if err != nil || (resp != nil && resp.IsError()) {
1156		t.Fatalf("err:%v resp:%#v", err, resp)
1157	}
1158
1159	expected := map[string]interface{}{
1160		"bind_secret_id":        true,
1161		"policies":              []string{"p", "q", "r", "s"},
1162		"secret_id_num_uses":    10,
1163		"secret_id_ttl":         300,
1164		"token_ttl":             400,
1165		"token_max_ttl":         500,
1166		"token_num_uses":        600,
1167		"secret_id_bound_cidrs": []string{"127.0.0.1/32", "127.0.0.1/16"},
1168		"token_bound_cidrs":     []string{},
1169		"token_type":            "default",
1170	}
1171
1172	var expectedStruct roleStorageEntry
1173	err = mapstructure.Decode(expected, &expectedStruct)
1174	if err != nil {
1175		t.Fatal(err)
1176	}
1177
1178	var actualStruct roleStorageEntry
1179	err = mapstructure.Decode(resp.Data, &actualStruct)
1180	if err != nil {
1181		t.Fatal(err)
1182	}
1183
1184	expectedStruct.RoleID = actualStruct.RoleID
1185	if diff := deep.Equal(expectedStruct, actualStruct); diff != nil {
1186		t.Fatal(diff)
1187	}
1188
1189	roleData = map[string]interface{}{
1190		"role_id":            "test_role_id",
1191		"policies":           "a,b,c,d",
1192		"secret_id_num_uses": 100,
1193		"secret_id_ttl":      3000,
1194		"token_ttl":          4000,
1195		"token_max_ttl":      5000,
1196	}
1197	roleReq.Data = roleData
1198	roleReq.Operation = logical.UpdateOperation
1199
1200	resp, err = b.HandleRequest(context.Background(), roleReq)
1201	if err != nil || (resp != nil && resp.IsError()) {
1202		t.Fatalf("err:%v resp:%#v", err, resp)
1203	}
1204
1205	roleReq.Operation = logical.ReadOperation
1206	resp, err = b.HandleRequest(context.Background(), roleReq)
1207	if err != nil || (resp != nil && resp.IsError()) {
1208		t.Fatalf("err:%v resp:%#v", err, resp)
1209	}
1210
1211	expected = map[string]interface{}{
1212		"policies":           []string{"a", "b", "c", "d"},
1213		"secret_id_num_uses": 100,
1214		"secret_id_ttl":      3000,
1215		"token_ttl":          4000,
1216		"token_max_ttl":      5000,
1217	}
1218	err = mapstructure.Decode(expected, &expectedStruct)
1219	if err != nil {
1220		t.Fatal(err)
1221	}
1222
1223	err = mapstructure.Decode(resp.Data, &actualStruct)
1224	if err != nil {
1225		t.Fatal(err)
1226	}
1227
1228	if !reflect.DeepEqual(expectedStruct, actualStruct) {
1229		t.Fatalf("bad:\nexpected:%#v\nactual:%#v\n", expectedStruct, actualStruct)
1230	}
1231
1232	// RU for role_id field
1233	roleReq.Path = "role/role1/role-id"
1234	roleReq.Operation = logical.ReadOperation
1235	resp, err = b.HandleRequest(context.Background(), roleReq)
1236	if err != nil || (resp != nil && resp.IsError()) {
1237		t.Fatalf("err:%v resp:%#v", err, resp)
1238	}
1239	if resp.Data["role_id"].(string) != "test_role_id" {
1240		t.Fatalf("bad: role_id: expected:test_role_id actual:%s\n", resp.Data["role_id"].(string))
1241	}
1242
1243	roleReq.Data = map[string]interface{}{"role_id": "custom_role_id"}
1244	roleReq.Operation = logical.UpdateOperation
1245	resp, err = b.HandleRequest(context.Background(), roleReq)
1246	if err != nil || (resp != nil && resp.IsError()) {
1247		t.Fatalf("err:%v resp:%#v", err, resp)
1248	}
1249
1250	roleReq.Operation = logical.ReadOperation
1251	resp, err = b.HandleRequest(context.Background(), roleReq)
1252	if err != nil || (resp != nil && resp.IsError()) {
1253		t.Fatalf("err:%v resp:%#v", err, resp)
1254	}
1255	if resp.Data["role_id"].(string) != "custom_role_id" {
1256		t.Fatalf("bad: role_id: expected:custom_role_id actual:%s\n", resp.Data["role_id"].(string))
1257	}
1258
1259	// RUD for bind_secret_id field
1260	roleReq.Path = "role/role1/bind-secret-id"
1261	roleReq.Operation = logical.ReadOperation
1262	resp, err = b.HandleRequest(context.Background(), roleReq)
1263	if err != nil || (resp != nil && resp.IsError()) {
1264		t.Fatalf("err:%v resp:%#v", err, resp)
1265	}
1266
1267	roleReq.Data = map[string]interface{}{"bind_secret_id": false}
1268	roleReq.Operation = logical.UpdateOperation
1269	resp, err = b.HandleRequest(context.Background(), roleReq)
1270	if err != nil || (resp != nil && resp.IsError()) {
1271		t.Fatalf("err:%v resp:%#v", err, resp)
1272	}
1273
1274	roleReq.Operation = logical.ReadOperation
1275	resp, err = b.HandleRequest(context.Background(), roleReq)
1276	if err != nil || (resp != nil && resp.IsError()) {
1277		t.Fatalf("err:%v resp:%#v", err, resp)
1278	}
1279
1280	if resp.Data["bind_secret_id"].(bool) {
1281		t.Fatalf("bad: bind_secret_id: expected:false actual:%t\n", resp.Data["bind_secret_id"].(bool))
1282	}
1283	roleReq.Operation = logical.DeleteOperation
1284	resp, err = b.HandleRequest(context.Background(), roleReq)
1285	if err != nil || (resp != nil && resp.IsError()) {
1286		t.Fatalf("err:%v resp:%#v", err, resp)
1287	}
1288
1289	roleReq.Operation = logical.ReadOperation
1290	resp, err = b.HandleRequest(context.Background(), roleReq)
1291	if err != nil || (resp != nil && resp.IsError()) {
1292		t.Fatalf("err:%v resp:%#v", err, resp)
1293	}
1294
1295	if !resp.Data["bind_secret_id"].(bool) {
1296		t.Fatalf("expected the default value of 'true' to be set")
1297	}
1298
1299	// RUD for policies field
1300	roleReq.Path = "role/role1/policies"
1301	roleReq.Operation = logical.ReadOperation
1302	resp, err = b.HandleRequest(context.Background(), roleReq)
1303	if err != nil || (resp != nil && resp.IsError()) {
1304		t.Fatalf("err:%v resp:%#v", err, resp)
1305	}
1306
1307	roleReq.Data = map[string]interface{}{"policies": "a1,b1,c1,d1"}
1308	roleReq.Operation = logical.UpdateOperation
1309	resp, err = b.HandleRequest(context.Background(), roleReq)
1310	if err != nil || (resp != nil && resp.IsError()) {
1311		t.Fatalf("err:%v resp:%#v", err, resp)
1312	}
1313
1314	roleReq.Operation = logical.ReadOperation
1315	resp, err = b.HandleRequest(context.Background(), roleReq)
1316	if err != nil || (resp != nil && resp.IsError()) {
1317		t.Fatalf("err:%v resp:%#v", err, resp)
1318	}
1319
1320	if !reflect.DeepEqual(resp.Data["policies"].([]string), []string{"a1", "b1", "c1", "d1"}) {
1321		t.Fatalf("bad: policies: actual:%s\n", resp.Data["policies"].([]string))
1322	}
1323	if !reflect.DeepEqual(resp.Data["token_policies"].([]string), []string{"a1", "b1", "c1", "d1"}) {
1324		t.Fatalf("bad: policies: actual:%s\n", resp.Data["policies"].([]string))
1325	}
1326	roleReq.Operation = logical.DeleteOperation
1327	resp, err = b.HandleRequest(context.Background(), roleReq)
1328	if err != nil || (resp != nil && resp.IsError()) {
1329		t.Fatalf("err:%v resp:%#v", err, resp)
1330	}
1331
1332	roleReq.Operation = logical.ReadOperation
1333	resp, err = b.HandleRequest(context.Background(), roleReq)
1334	if err != nil || (resp != nil && resp.IsError()) {
1335		t.Fatalf("err:%v resp:%#v", err, resp)
1336	}
1337
1338	expectedPolicies := []string{}
1339	actualPolicies := resp.Data["token_policies"].([]string)
1340	if !policyutil.EquivalentPolicies(expectedPolicies, actualPolicies) {
1341		t.Fatalf("bad: token_policies: expected:%s actual:%s", expectedPolicies, actualPolicies)
1342	}
1343
1344	// RUD for secret-id-num-uses field
1345	roleReq.Path = "role/role1/secret-id-num-uses"
1346	roleReq.Operation = logical.ReadOperation
1347	resp, err = b.HandleRequest(context.Background(), roleReq)
1348	if err != nil || (resp != nil && resp.IsError()) {
1349		t.Fatalf("err:%v resp:%#v", err, resp)
1350	}
1351
1352	roleReq.Data = map[string]interface{}{"secret_id_num_uses": 200}
1353	roleReq.Operation = logical.UpdateOperation
1354	resp, err = b.HandleRequest(context.Background(), roleReq)
1355	if err != nil || (resp != nil && resp.IsError()) {
1356		t.Fatalf("err:%v resp:%#v", err, resp)
1357	}
1358
1359	roleReq.Operation = logical.ReadOperation
1360	resp, err = b.HandleRequest(context.Background(), roleReq)
1361	if err != nil || (resp != nil && resp.IsError()) {
1362		t.Fatalf("err:%v resp:%#v", err, resp)
1363	}
1364
1365	if resp.Data["secret_id_num_uses"].(int) != 200 {
1366		t.Fatalf("bad: secret_id_num_uses: expected:200 actual:%d\n", resp.Data["secret_id_num_uses"].(int))
1367	}
1368	roleReq.Operation = logical.DeleteOperation
1369	resp, err = b.HandleRequest(context.Background(), roleReq)
1370	if err != nil || (resp != nil && resp.IsError()) {
1371		t.Fatalf("err:%v resp:%#v", err, resp)
1372	}
1373
1374	roleReq.Operation = logical.ReadOperation
1375	resp, err = b.HandleRequest(context.Background(), roleReq)
1376	if err != nil || (resp != nil && resp.IsError()) {
1377		t.Fatalf("err:%v resp:%#v", err, resp)
1378	}
1379
1380	if resp.Data["secret_id_num_uses"].(int) != 0 {
1381		t.Fatalf("expected value to be reset")
1382	}
1383
1384	// RUD for secret_id_ttl field
1385	roleReq.Path = "role/role1/secret-id-ttl"
1386	roleReq.Operation = logical.ReadOperation
1387	resp, err = b.HandleRequest(context.Background(), roleReq)
1388	if err != nil || (resp != nil && resp.IsError()) {
1389		t.Fatalf("err:%v resp:%#v", err, resp)
1390	}
1391
1392	roleReq.Data = map[string]interface{}{"secret_id_ttl": 3001}
1393	roleReq.Operation = logical.UpdateOperation
1394	resp, err = b.HandleRequest(context.Background(), roleReq)
1395	if err != nil || (resp != nil && resp.IsError()) {
1396		t.Fatalf("err:%v resp:%#v", err, resp)
1397	}
1398
1399	roleReq.Operation = logical.ReadOperation
1400	resp, err = b.HandleRequest(context.Background(), roleReq)
1401	if err != nil || (resp != nil && resp.IsError()) {
1402		t.Fatalf("err:%v resp:%#v", err, resp)
1403	}
1404
1405	if resp.Data["secret_id_ttl"].(time.Duration) != 3001 {
1406		t.Fatalf("bad: secret_id_ttl: expected:3001 actual:%d\n", resp.Data["secret_id_ttl"].(time.Duration))
1407	}
1408	roleReq.Operation = logical.DeleteOperation
1409	resp, err = b.HandleRequest(context.Background(), roleReq)
1410	if err != nil || (resp != nil && resp.IsError()) {
1411		t.Fatalf("err:%v resp:%#v", err, resp)
1412	}
1413
1414	roleReq.Operation = logical.ReadOperation
1415	resp, err = b.HandleRequest(context.Background(), roleReq)
1416	if err != nil || (resp != nil && resp.IsError()) {
1417		t.Fatalf("err:%v resp:%#v", err, resp)
1418	}
1419
1420	if resp.Data["secret_id_ttl"].(time.Duration) != 0 {
1421		t.Fatalf("expected value to be reset")
1422	}
1423
1424	// RUD for secret-id-num-uses field
1425	roleReq.Path = "role/role1/token-num-uses"
1426	roleReq.Operation = logical.ReadOperation
1427	resp, err = b.HandleRequest(context.Background(), roleReq)
1428	if err != nil || (resp != nil && resp.IsError()) {
1429		t.Fatalf("err:%v resp:%#v", err, resp)
1430	}
1431	if resp.Data["token_num_uses"].(int) != 600 {
1432		t.Fatalf("bad: token_num_uses: expected:600 actual:%d\n", resp.Data["token_num_uses"].(int))
1433	}
1434
1435	roleReq.Data = map[string]interface{}{"token_num_uses": 60}
1436	roleReq.Operation = logical.UpdateOperation
1437	resp, err = b.HandleRequest(context.Background(), roleReq)
1438	if err != nil || (resp != nil && resp.IsError()) {
1439		t.Fatalf("err:%v resp:%#v", err, resp)
1440	}
1441
1442	roleReq.Operation = logical.ReadOperation
1443	resp, err = b.HandleRequest(context.Background(), roleReq)
1444	if err != nil || (resp != nil && resp.IsError()) {
1445		t.Fatalf("err:%v resp:%#v", err, resp)
1446	}
1447
1448	if resp.Data["token_num_uses"].(int) != 60 {
1449		t.Fatalf("bad: token_num_uses: expected:60 actual:%d\n", resp.Data["token_num_uses"].(int))
1450	}
1451
1452	roleReq.Operation = logical.DeleteOperation
1453	resp, err = b.HandleRequest(context.Background(), roleReq)
1454	if err != nil || (resp != nil && resp.IsError()) {
1455		t.Fatalf("err:%v resp:%#v", err, resp)
1456	}
1457
1458	roleReq.Operation = logical.ReadOperation
1459	resp, err = b.HandleRequest(context.Background(), roleReq)
1460	if err != nil || (resp != nil && resp.IsError()) {
1461		t.Fatalf("err:%v resp:%#v", err, resp)
1462	}
1463
1464	if resp.Data["token_num_uses"].(int) != 0 {
1465		t.Fatalf("expected value to be reset")
1466	}
1467
1468	// RUD for 'period' field
1469	roleReq.Path = "role/role1/period"
1470	roleReq.Operation = logical.ReadOperation
1471	resp, err = b.HandleRequest(context.Background(), roleReq)
1472	if err != nil || (resp != nil && resp.IsError()) {
1473		t.Fatalf("err:%v resp:%#v", err, resp)
1474	}
1475
1476	roleReq.Data = map[string]interface{}{"period": 9001}
1477	roleReq.Operation = logical.UpdateOperation
1478	resp, err = b.HandleRequest(context.Background(), roleReq)
1479	if err != nil || (resp != nil && resp.IsError()) {
1480		t.Fatalf("err:%v resp:%#v", err, resp)
1481	}
1482
1483	roleReq.Operation = logical.ReadOperation
1484	resp, err = b.HandleRequest(context.Background(), roleReq)
1485	if err != nil || (resp != nil && resp.IsError()) {
1486		t.Fatalf("err:%v resp:%#v", err, resp)
1487	}
1488
1489	if resp.Data["period"].(time.Duration) != 9001 {
1490		t.Fatalf("bad: period: expected:9001 actual:%d\n", resp.Data["9001"].(time.Duration))
1491	}
1492	roleReq.Operation = logical.DeleteOperation
1493	resp, err = b.HandleRequest(context.Background(), roleReq)
1494	if err != nil || (resp != nil && resp.IsError()) {
1495		t.Fatalf("err:%v resp:%#v", err, resp)
1496	}
1497
1498	roleReq.Operation = logical.ReadOperation
1499	resp, err = b.HandleRequest(context.Background(), roleReq)
1500	if err != nil || (resp != nil && resp.IsError()) {
1501		t.Fatalf("err:%v resp:%#v", err, resp)
1502	}
1503
1504	if resp.Data["token_period"].(time.Duration) != 0 {
1505		t.Fatalf("expected value to be reset")
1506	}
1507
1508	// RUD for token_ttl field
1509	roleReq.Path = "role/role1/token-ttl"
1510	roleReq.Operation = logical.ReadOperation
1511	resp, err = b.HandleRequest(context.Background(), roleReq)
1512	if err != nil || (resp != nil && resp.IsError()) {
1513		t.Fatalf("err:%v resp:%#v", err, resp)
1514	}
1515
1516	roleReq.Data = map[string]interface{}{"token_ttl": 4001}
1517	roleReq.Operation = logical.UpdateOperation
1518	resp, err = b.HandleRequest(context.Background(), roleReq)
1519	if err != nil || (resp != nil && resp.IsError()) {
1520		t.Fatalf("err:%v resp:%#v", err, resp)
1521	}
1522
1523	roleReq.Operation = logical.ReadOperation
1524	resp, err = b.HandleRequest(context.Background(), roleReq)
1525	if err != nil || (resp != nil && resp.IsError()) {
1526		t.Fatalf("err:%v resp:%#v", err, resp)
1527	}
1528
1529	if resp.Data["token_ttl"].(time.Duration) != 4001 {
1530		t.Fatalf("bad: token_ttl: expected:4001 actual:%d\n", resp.Data["token_ttl"].(time.Duration))
1531	}
1532	roleReq.Operation = logical.DeleteOperation
1533	resp, err = b.HandleRequest(context.Background(), roleReq)
1534	if err != nil || (resp != nil && resp.IsError()) {
1535		t.Fatalf("err:%v resp:%#v", err, resp)
1536	}
1537
1538	roleReq.Operation = logical.ReadOperation
1539	resp, err = b.HandleRequest(context.Background(), roleReq)
1540	if err != nil || (resp != nil && resp.IsError()) {
1541		t.Fatalf("err:%v resp:%#v", err, resp)
1542	}
1543
1544	if resp.Data["token_ttl"].(time.Duration) != 0 {
1545		t.Fatalf("expected value to be reset")
1546	}
1547
1548	// RUD for token_max_ttl field
1549	roleReq.Path = "role/role1/token-max-ttl"
1550	roleReq.Operation = logical.ReadOperation
1551	resp, err = b.HandleRequest(context.Background(), roleReq)
1552	if err != nil || (resp != nil && resp.IsError()) {
1553		t.Fatalf("err:%v resp:%#v", err, resp)
1554	}
1555
1556	roleReq.Data = map[string]interface{}{"token_max_ttl": 5001}
1557	roleReq.Operation = logical.UpdateOperation
1558	resp, err = b.HandleRequest(context.Background(), roleReq)
1559	if err != nil || (resp != nil && resp.IsError()) {
1560		t.Fatalf("err:%v resp:%#v", err, resp)
1561	}
1562
1563	roleReq.Operation = logical.ReadOperation
1564	resp, err = b.HandleRequest(context.Background(), roleReq)
1565	if err != nil || (resp != nil && resp.IsError()) {
1566		t.Fatalf("err:%v resp:%#v", err, resp)
1567	}
1568
1569	if resp.Data["token_max_ttl"].(time.Duration) != 5001 {
1570		t.Fatalf("bad: token_max_ttl: expected:5001 actual:%d\n", resp.Data["token_max_ttl"].(time.Duration))
1571	}
1572	roleReq.Operation = logical.DeleteOperation
1573	resp, err = b.HandleRequest(context.Background(), roleReq)
1574	if err != nil || (resp != nil && resp.IsError()) {
1575		t.Fatalf("err:%v resp:%#v", err, resp)
1576	}
1577
1578	roleReq.Operation = logical.ReadOperation
1579	resp, err = b.HandleRequest(context.Background(), roleReq)
1580	if err != nil || (resp != nil && resp.IsError()) {
1581		t.Fatalf("err:%v resp:%#v", err, resp)
1582	}
1583
1584	if resp.Data["token_max_ttl"].(time.Duration) != 0 {
1585		t.Fatalf("expected value to be reset")
1586	}
1587
1588	// Delete test for role
1589	roleReq.Path = "role/role1"
1590	roleReq.Operation = logical.DeleteOperation
1591	resp, err = b.HandleRequest(context.Background(), roleReq)
1592	if err != nil || (resp != nil && resp.IsError()) {
1593		t.Fatalf("err:%v resp:%#v", err, resp)
1594	}
1595
1596	roleReq.Operation = logical.ReadOperation
1597	resp, err = b.HandleRequest(context.Background(), roleReq)
1598	if err != nil || (resp != nil && resp.IsError()) {
1599		t.Fatalf("err:%v resp:%#v", err, resp)
1600	}
1601
1602	if resp != nil {
1603		t.Fatalf("expected a nil response")
1604	}
1605}
1606
1607func TestAppRole_RoleWithTokenBoundCIDRsCRUD(t *testing.T) {
1608	var resp *logical.Response
1609	var err error
1610	b, storage := createBackendWithStorage(t)
1611
1612	roleData := map[string]interface{}{
1613		"policies":              "p,q,r,s",
1614		"secret_id_num_uses":    10,
1615		"secret_id_ttl":         300,
1616		"token_ttl":             400,
1617		"token_max_ttl":         500,
1618		"token_num_uses":        600,
1619		"secret_id_bound_cidrs": "127.0.0.1/32,127.0.0.1/16",
1620		"token_bound_cidrs":     "127.0.0.1/32,127.0.0.1/16",
1621	}
1622	roleReq := &logical.Request{
1623		Operation: logical.CreateOperation,
1624		Path:      "role/role1",
1625		Storage:   storage,
1626		Data:      roleData,
1627	}
1628
1629	resp, err = b.HandleRequest(context.Background(), roleReq)
1630	if err != nil || (resp != nil && resp.IsError()) {
1631		t.Fatalf("err:%v resp:%#v", err, resp)
1632	}
1633
1634	roleReq.Operation = logical.ReadOperation
1635	resp, err = b.HandleRequest(context.Background(), roleReq)
1636	if err != nil || (resp != nil && resp.IsError()) {
1637		t.Fatalf("err:%v resp:%#v", err, resp)
1638	}
1639
1640	expected := map[string]interface{}{
1641		"bind_secret_id":        true,
1642		"policies":              []string{"p", "q", "r", "s"},
1643		"secret_id_num_uses":    10,
1644		"secret_id_ttl":         300,
1645		"token_ttl":             400,
1646		"token_max_ttl":         500,
1647		"token_num_uses":        600,
1648		"token_bound_cidrs":     []string{"127.0.0.1/32", "127.0.0.1/16"},
1649		"secret_id_bound_cidrs": []string{"127.0.0.1/32", "127.0.0.1/16"},
1650		"token_type":            "default",
1651	}
1652
1653	var expectedStruct roleStorageEntry
1654	err = mapstructure.Decode(expected, &expectedStruct)
1655	if err != nil {
1656		t.Fatal(err)
1657	}
1658
1659	var actualStruct roleStorageEntry
1660	err = mapstructure.Decode(resp.Data, &actualStruct)
1661	if err != nil {
1662		t.Fatal(err)
1663	}
1664
1665	expectedStruct.RoleID = actualStruct.RoleID
1666	if !reflect.DeepEqual(expectedStruct, actualStruct) {
1667		t.Fatalf("bad:\nexpected:%#v\nactual:%#v\n", expectedStruct, actualStruct)
1668	}
1669
1670	roleData = map[string]interface{}{
1671		"role_id":            "test_role_id",
1672		"policies":           "a,b,c,d",
1673		"secret_id_num_uses": 100,
1674		"secret_id_ttl":      3000,
1675		"token_ttl":          4000,
1676		"token_max_ttl":      5000,
1677	}
1678	roleReq.Data = roleData
1679	roleReq.Operation = logical.UpdateOperation
1680
1681	resp, err = b.HandleRequest(context.Background(), roleReq)
1682	if err != nil || (resp != nil && resp.IsError()) {
1683		t.Fatalf("err:%v resp:%#v", err, resp)
1684	}
1685
1686	roleReq.Operation = logical.ReadOperation
1687	resp, err = b.HandleRequest(context.Background(), roleReq)
1688	if err != nil || (resp != nil && resp.IsError()) {
1689		t.Fatalf("err:%v resp:%#v", err, resp)
1690	}
1691
1692	expected = map[string]interface{}{
1693		"policies":           []string{"a", "b", "c", "d"},
1694		"secret_id_num_uses": 100,
1695		"secret_id_ttl":      3000,
1696		"token_ttl":          4000,
1697		"token_max_ttl":      5000,
1698	}
1699	err = mapstructure.Decode(expected, &expectedStruct)
1700	if err != nil {
1701		t.Fatal(err)
1702	}
1703
1704	err = mapstructure.Decode(resp.Data, &actualStruct)
1705	if err != nil {
1706		t.Fatal(err)
1707	}
1708
1709	if !reflect.DeepEqual(expectedStruct, actualStruct) {
1710		t.Fatalf("bad:\nexpected:%#v\nactual:%#v\n", expectedStruct, actualStruct)
1711	}
1712
1713	// RUD for secret-id-bound-cidrs field
1714	roleReq.Path = "role/role1/secret-id-bound-cidrs"
1715	roleReq.Operation = logical.ReadOperation
1716	resp, err = b.HandleRequest(context.Background(), roleReq)
1717	if err != nil || (resp != nil && resp.IsError()) {
1718		t.Fatalf("err:%v resp:%#v", err, resp)
1719	}
1720	if resp.Data["secret_id_bound_cidrs"].([]string)[0] != "127.0.0.1/32" ||
1721		resp.Data["secret_id_bound_cidrs"].([]string)[1] != "127.0.0.1/16" {
1722		t.Fatalf("bad: secret_id_bound_cidrs: expected:127.0.0.1/32,127.0.0.1/16 actual:%d\n", resp.Data["secret_id_bound_cidrs"].(int))
1723	}
1724
1725	roleReq.Data = map[string]interface{}{"secret_id_bound_cidrs": []string{"127.0.0.1/20"}}
1726	roleReq.Operation = logical.UpdateOperation
1727	resp, err = b.HandleRequest(context.Background(), roleReq)
1728	if err != nil || (resp != nil && resp.IsError()) {
1729		t.Fatalf("err:%v resp:%#v", err, resp)
1730	}
1731
1732	roleReq.Operation = logical.ReadOperation
1733	resp, err = b.HandleRequest(context.Background(), roleReq)
1734	if err != nil || (resp != nil && resp.IsError()) {
1735		t.Fatalf("err:%v resp:%#v", err, resp)
1736	}
1737
1738	if resp.Data["secret_id_bound_cidrs"].([]string)[0] != "127.0.0.1/20" {
1739		t.Fatalf("bad: secret_id_bound_cidrs: expected:127.0.0.1/20 actual:%s\n", resp.Data["secret_id_bound_cidrs"].([]string)[0])
1740	}
1741
1742	roleReq.Operation = logical.DeleteOperation
1743	resp, err = b.HandleRequest(context.Background(), roleReq)
1744	if err != nil || (resp != nil && resp.IsError()) {
1745		t.Fatalf("err:%v resp:%#v", err, resp)
1746	}
1747
1748	roleReq.Operation = logical.ReadOperation
1749	resp, err = b.HandleRequest(context.Background(), roleReq)
1750	if err != nil || (resp != nil && resp.IsError()) {
1751		t.Fatalf("err:%v resp:%#v", err, resp)
1752	}
1753
1754	if len(resp.Data["secret_id_bound_cidrs"].([]string)) != 0 {
1755		t.Fatalf("expected value to be reset")
1756	}
1757
1758	// RUD for token-bound-cidrs field
1759	roleReq.Path = "role/role1/token-bound-cidrs"
1760	roleReq.Operation = logical.ReadOperation
1761	resp, err = b.HandleRequest(context.Background(), roleReq)
1762	if err != nil || (resp != nil && resp.IsError()) {
1763		t.Fatalf("err:%v resp:%#v", err, resp)
1764	}
1765	if resp.Data["token_bound_cidrs"].([]*sockaddr.SockAddrMarshaler)[0].String() != "127.0.0.1" ||
1766		resp.Data["token_bound_cidrs"].([]*sockaddr.SockAddrMarshaler)[1].String() != "127.0.0.1/16" {
1767		m, err := json.Marshal(resp.Data["token_bound_cidrs"].([]*sockaddr.SockAddrMarshaler))
1768		if err != nil {
1769			t.Fatal(err)
1770		}
1771		t.Fatalf("bad: token_bound_cidrs: expected:127.0.0.1/32,127.0.0.1/16 actual:%s\n", string(m))
1772	}
1773
1774	roleReq.Data = map[string]interface{}{"token_bound_cidrs": []string{"127.0.0.1/20"}}
1775	roleReq.Operation = logical.UpdateOperation
1776	resp, err = b.HandleRequest(context.Background(), roleReq)
1777	if err != nil || (resp != nil && resp.IsError()) {
1778		t.Fatalf("err:%v resp:%#v", err, resp)
1779	}
1780
1781	roleReq.Operation = logical.ReadOperation
1782	resp, err = b.HandleRequest(context.Background(), roleReq)
1783	if err != nil || (resp != nil && resp.IsError()) {
1784		t.Fatalf("err:%v resp:%#v", err, resp)
1785	}
1786
1787	if resp.Data["token_bound_cidrs"].([]*sockaddr.SockAddrMarshaler)[0].String() != "127.0.0.1/20" {
1788		t.Fatalf("bad: token_bound_cidrs: expected:127.0.0.1/20 actual:%s\n", resp.Data["token_bound_cidrs"].([]*sockaddr.SockAddrMarshaler)[0])
1789	}
1790
1791	roleReq.Operation = logical.DeleteOperation
1792	resp, err = b.HandleRequest(context.Background(), roleReq)
1793	if err != nil || (resp != nil && resp.IsError()) {
1794		t.Fatalf("err:%v resp:%#v", err, resp)
1795	}
1796
1797	roleReq.Operation = logical.ReadOperation
1798	resp, err = b.HandleRequest(context.Background(), roleReq)
1799	if err != nil || (resp != nil && resp.IsError()) {
1800		t.Fatalf("err:%v resp:%#v", err, resp)
1801	}
1802
1803	if len(resp.Data["token_bound_cidrs"].([]*sockaddr.SockAddrMarshaler)) != 0 {
1804		t.Fatalf("expected value to be reset")
1805	}
1806
1807	// Delete test for role
1808	roleReq.Path = "role/role1"
1809	roleReq.Operation = logical.DeleteOperation
1810	resp, err = b.HandleRequest(context.Background(), roleReq)
1811	if err != nil || (resp != nil && resp.IsError()) {
1812		t.Fatalf("err:%v resp:%#v", err, resp)
1813	}
1814
1815	roleReq.Operation = logical.ReadOperation
1816	resp, err = b.HandleRequest(context.Background(), roleReq)
1817	if err != nil || (resp != nil && resp.IsError()) {
1818		t.Fatalf("err:%v resp:%#v", err, resp)
1819	}
1820
1821	if resp != nil {
1822		t.Fatalf("expected a nil response")
1823	}
1824}
1825
1826func TestAppRole_RoleWithTokenTypeCRUD(t *testing.T) {
1827	var resp *logical.Response
1828	var err error
1829	b, storage := createBackendWithStorage(t)
1830
1831	roleData := map[string]interface{}{
1832		"policies":           "p,q,r,s",
1833		"secret_id_num_uses": 10,
1834		"secret_id_ttl":      300,
1835		"token_ttl":          400,
1836		"token_max_ttl":      500,
1837		"token_num_uses":     600,
1838		"token_type":         "default-service",
1839	}
1840	roleReq := &logical.Request{
1841		Operation: logical.CreateOperation,
1842		Path:      "role/role1",
1843		Storage:   storage,
1844		Data:      roleData,
1845	}
1846
1847	resp, err = b.HandleRequest(context.Background(), roleReq)
1848	if err != nil || (resp != nil && resp.IsError()) {
1849		t.Fatalf("err:%v resp:%#v", err, resp)
1850	}
1851	if 0 == len(resp.Warnings) {
1852		t.Fatalf("bad:\nexpected warning in resp:%#v\n", resp.Warnings)
1853	}
1854
1855	roleReq.Operation = logical.ReadOperation
1856	resp, err = b.HandleRequest(context.Background(), roleReq)
1857	if err != nil || (resp != nil && resp.IsError()) {
1858		t.Fatalf("err:%v resp:%#v", err, resp)
1859	}
1860
1861	expected := map[string]interface{}{
1862		"bind_secret_id":     true,
1863		"policies":           []string{"p", "q", "r", "s"},
1864		"secret_id_num_uses": 10,
1865		"secret_id_ttl":      300,
1866		"token_ttl":          400,
1867		"token_max_ttl":      500,
1868		"token_num_uses":     600,
1869		"token_type":         "service",
1870	}
1871
1872	var expectedStruct roleStorageEntry
1873	err = mapstructure.Decode(expected, &expectedStruct)
1874	if err != nil {
1875		t.Fatal(err)
1876	}
1877
1878	var actualStruct roleStorageEntry
1879	err = mapstructure.Decode(resp.Data, &actualStruct)
1880	if err != nil {
1881		t.Fatal(err)
1882	}
1883
1884	expectedStruct.RoleID = actualStruct.RoleID
1885	if !reflect.DeepEqual(expectedStruct, actualStruct) {
1886		t.Fatalf("bad:\nexpected:%#v\nactual:%#v\n", expectedStruct, actualStruct)
1887	}
1888
1889	roleData = map[string]interface{}{
1890		"role_id":            "test_role_id",
1891		"policies":           "a,b,c,d",
1892		"secret_id_num_uses": 100,
1893		"secret_id_ttl":      3000,
1894		"token_ttl":          4000,
1895		"token_max_ttl":      5000,
1896		"token_type":         "default-service",
1897	}
1898	roleReq.Data = roleData
1899	roleReq.Operation = logical.UpdateOperation
1900
1901	resp, err = b.HandleRequest(context.Background(), roleReq)
1902	if err != nil || (resp != nil && resp.IsError()) {
1903		t.Fatalf("err:%v resp:%#v", err, resp)
1904	}
1905	if 0 == len(resp.Warnings) {
1906		t.Fatalf("bad:\nexpected a warning in resp:%#v\n", resp.Warnings)
1907	}
1908
1909	roleReq.Operation = logical.ReadOperation
1910	resp, err = b.HandleRequest(context.Background(), roleReq)
1911	if err != nil || (resp != nil && resp.IsError()) {
1912		t.Fatalf("err:%v resp:%#v", err, resp)
1913	}
1914
1915	expected = map[string]interface{}{
1916		"policies":           []string{"a", "b", "c", "d"},
1917		"secret_id_num_uses": 100,
1918		"secret_id_ttl":      3000,
1919		"token_ttl":          4000,
1920		"token_max_ttl":      5000,
1921		"token_type":         "service",
1922	}
1923	err = mapstructure.Decode(expected, &expectedStruct)
1924	if err != nil {
1925		t.Fatal(err)
1926	}
1927
1928	err = mapstructure.Decode(resp.Data, &actualStruct)
1929	if err != nil {
1930		t.Fatal(err)
1931	}
1932
1933	if !reflect.DeepEqual(expectedStruct, actualStruct) {
1934		t.Fatalf("bad:\nexpected:%#v\nactual:%#v\n", expectedStruct, actualStruct)
1935	}
1936
1937	// Delete test for role
1938	roleReq.Path = "role/role1"
1939	roleReq.Operation = logical.DeleteOperation
1940	resp, err = b.HandleRequest(context.Background(), roleReq)
1941	if err != nil || (resp != nil && resp.IsError()) {
1942		t.Fatalf("err:%v resp:%#v", err, resp)
1943	}
1944
1945	roleReq.Operation = logical.ReadOperation
1946	resp, err = b.HandleRequest(context.Background(), roleReq)
1947	if err != nil || (resp != nil && resp.IsError()) {
1948		t.Fatalf("err:%v resp:%#v", err, resp)
1949	}
1950
1951	if resp != nil {
1952		t.Fatalf("expected a nil response")
1953	}
1954}
1955
1956func createRole(t *testing.T, b *backend, s logical.Storage, roleName, policies string) {
1957	roleData := map[string]interface{}{
1958		"policies":           policies,
1959		"secret_id_num_uses": 10,
1960		"secret_id_ttl":      300,
1961		"token_ttl":          400,
1962		"token_max_ttl":      500,
1963	}
1964	roleReq := &logical.Request{
1965		Operation: logical.CreateOperation,
1966		Path:      "role/" + roleName,
1967		Storage:   s,
1968		Data:      roleData,
1969	}
1970
1971	resp, err := b.HandleRequest(context.Background(), roleReq)
1972	if err != nil || (resp != nil && resp.IsError()) {
1973		t.Fatalf("err:%v resp:%#v", err, resp)
1974	}
1975}
1976
1977// TestAppRole_TokenutilUpgrade ensures that when we read values out that are
1978// values with upgrade logic we see the correct struct entries populated
1979func TestAppRole_TokenutilUpgrade(t *testing.T) {
1980	tests := []struct {
1981		name              string
1982		storageValMissing bool
1983		storageVal        string
1984		expectedTokenType logical.TokenType
1985	}{
1986		{
1987			"token_type_missing",
1988			true,
1989			"",
1990			logical.TokenTypeDefault,
1991		},
1992		{
1993			"token_type_empty",
1994			false,
1995			"",
1996			logical.TokenTypeDefault,
1997		},
1998		{
1999			"token_type_service",
2000			false,
2001			"service",
2002			logical.TokenTypeService,
2003		},
2004	}
2005
2006	s := &logical.InmemStorage{}
2007
2008	config := logical.TestBackendConfig()
2009	config.StorageView = s
2010
2011	ctx := context.Background()
2012
2013	b, err := Backend(config)
2014	if err != nil {
2015		t.Fatal(err)
2016	}
2017	if b == nil {
2018		t.Fatalf("failed to create backend")
2019	}
2020	if err := b.Setup(ctx, config); err != nil {
2021		t.Fatal(err)
2022	}
2023
2024	for _, tt := range tests {
2025		t.Run(tt.name, func(t *testing.T) {
2026			// Construct the storage entry object based on our test case.
2027			tokenTypeKV := ""
2028			if !tt.storageValMissing {
2029				tokenTypeKV = fmt.Sprintf(`, "token_type": "%s"`, tt.storageVal)
2030			}
2031			entryVal := fmt.Sprintf(`{"policies": ["foo"], "period": 300000000000, "token_bound_cidrs": ["127.0.0.1", "10.10.10.10/24"]%s}`, tokenTypeKV)
2032
2033			// Hand craft JSON because there is overlap between fields
2034			if err := s.Put(ctx, &logical.StorageEntry{
2035				Key:   "role/" + tt.name,
2036				Value: []byte(entryVal),
2037			}); err != nil {
2038				t.Fatal(err)
2039			}
2040
2041			resEntry, err := b.roleEntry(ctx, s, tt.name)
2042			if err != nil {
2043				t.Fatal(err)
2044			}
2045
2046			exp := &roleStorageEntry{
2047				SecretIDPrefix: "secret_id/",
2048				Policies:       []string{"foo"},
2049				Period:         300 * time.Second,
2050				TokenParams: tokenutil.TokenParams{
2051					TokenPolicies: []string{"foo"},
2052					TokenPeriod:   300 * time.Second,
2053					TokenBoundCIDRs: []*sockaddr.SockAddrMarshaler{
2054						{SockAddr: sockaddr.MustIPAddr("127.0.0.1")},
2055						{SockAddr: sockaddr.MustIPAddr("10.10.10.10/24")},
2056					},
2057					TokenType: tt.expectedTokenType,
2058				},
2059			}
2060			if diff := deep.Equal(resEntry, exp); diff != nil {
2061				t.Fatal(diff)
2062			}
2063		})
2064	}
2065}
2066
2067func TestAppRole_SecretID_WithTTL(t *testing.T) {
2068	tests := []struct {
2069		name      string
2070		roleName  string
2071		ttl       int64
2072		sysTTLCap bool
2073	}{
2074		{
2075			"zero ttl",
2076			"role-zero-ttl",
2077			0,
2078			false,
2079		},
2080		{
2081			"custom ttl",
2082			"role-custom-ttl",
2083			60,
2084			false,
2085		},
2086		{
2087			"system ttl capped",
2088			"role-sys-ttl-cap",
2089			700000000,
2090			true,
2091		},
2092	}
2093
2094	b, storage := createBackendWithStorage(t)
2095
2096	for _, tt := range tests {
2097		t.Run(tt.name, func(t *testing.T) {
2098			// Create role
2099			roleData := map[string]interface{}{
2100				"policies":      "default",
2101				"secret_id_ttl": tt.ttl,
2102			}
2103
2104			roleReq := &logical.Request{
2105				Operation: logical.CreateOperation,
2106				Path:      "role/" + tt.roleName,
2107				Storage:   storage,
2108				Data:      roleData,
2109			}
2110			resp, err := b.HandleRequest(context.Background(), roleReq)
2111			if err != nil || (resp != nil && resp.IsError()) {
2112				t.Fatalf("err:%v resp:%#v", err, resp)
2113			}
2114
2115			// Generate secret ID
2116			secretIDReq := &logical.Request{
2117				Operation: logical.UpdateOperation,
2118				Path:      "role/" + tt.roleName + "/secret-id",
2119				Storage:   storage,
2120			}
2121			resp, err = b.HandleRequest(context.Background(), secretIDReq)
2122			if err != nil || (resp != nil && resp.IsError()) {
2123				t.Fatalf("err:%v resp:%#v", err, resp)
2124			}
2125
2126			// Extract the "ttl" value from the response data if it exists
2127			ttlRaw, okTTL := resp.Data["secret_id_ttl"]
2128			if !okTTL {
2129				t.Fatalf("expected TTL value in response")
2130			}
2131
2132			var (
2133				respTTL int64
2134				ok      bool
2135			)
2136			respTTL, ok = ttlRaw.(int64)
2137			if !ok {
2138				t.Fatalf("expected ttl to be an integer, got: %s", err)
2139			}
2140
2141			// Verify secret ID response for different cases
2142			switch {
2143			case tt.sysTTLCap:
2144				if respTTL != int64(b.System().MaxLeaseTTL().Seconds()) {
2145					t.Fatalf("expected TTL value to be system's max lease TTL, got: %d", respTTL)
2146				}
2147			default:
2148				if respTTL != tt.ttl {
2149					t.Fatalf("expected TTL value to be %d, got: %d", tt.ttl, respTTL)
2150				}
2151			}
2152		})
2153	}
2154}
2155