diff --git a/builtin/credential/approle/path_role_test.go b/builtin/credential/approle/path_role_test.go index 885cb8e38..5cd49a024 100644 --- a/builtin/credential/approle/path_role_test.go +++ b/builtin/credential/approle/path_role_test.go @@ -12,6 +12,7 @@ import ( "github.com/go-test/deep" "github.com/hashicorp/go-sockaddr" "github.com/hashicorp/vault/sdk/helper/policyutil" + "github.com/hashicorp/vault/sdk/helper/testhelpers/schema" "github.com/hashicorp/vault/sdk/helper/tokenutil" "github.com/hashicorp/vault/sdk/logical" "github.com/mitchellh/mapstructure" @@ -22,6 +23,8 @@ func TestAppRole_LocalSecretIDsRead(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleData := map[string]interface{}{ "local_secret_ids": true, "bind_secret_id": true, @@ -36,6 +39,7 @@ func TestAppRole_LocalSecretIDsRead(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) resp, err = b.HandleRequest(context.Background(), &logical.Request{ Operation: logical.ReadOperation, @@ -45,6 +49,8 @@ func TestAppRole_LocalSecretIDsRead(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 2, logical.ReadOperation), resp, true) + if !resp.Data["local_secret_ids"].(bool) { t.Fatalf("expected local_secret_ids to be returned") } @@ -56,6 +62,8 @@ func TestAppRole_LocalNonLocalSecretIDs(t *testing.T) { b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + // Create a role with local_secret_ids set resp, err = b.HandleRequest(context.Background(), &logical.Request{ Path: "role/testrole1", @@ -70,6 +78,7 @@ func TestAppRole_LocalNonLocalSecretIDs(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: err: %v\n resp: %#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) // Create another role without setting local_secret_ids resp, err = b.HandleRequest(context.Background(), &logical.Request{ @@ -84,6 +93,7 @@ func TestAppRole_LocalNonLocalSecretIDs(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: err: %v\n resp: %#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) count := 10 // Create secret IDs on testrole1 @@ -96,6 +106,7 @@ func TestAppRole_LocalNonLocalSecretIDs(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) } // Check the number of secret IDs generated @@ -110,6 +121,7 @@ func TestAppRole_LocalNonLocalSecretIDs(t *testing.T) { if len(resp.Data["keys"].([]string)) != count { t.Fatalf("failed to list secret IDs") } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.ListOperation), resp, true) // Create secret IDs on testrole1 for i := 0; i < count; i++ { @@ -121,6 +133,7 @@ func TestAppRole_LocalNonLocalSecretIDs(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) } resp, err = b.HandleRequest(context.Background(), &logical.Request{ @@ -134,6 +147,7 @@ func TestAppRole_LocalNonLocalSecretIDs(t *testing.T) { if len(resp.Data["keys"].([]string)) != count { t.Fatalf("failed to list secret IDs") } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.ListOperation), resp, true) } func TestAppRole_UpgradeSecretIDPrefix(t *testing.T) { @@ -142,6 +156,8 @@ func TestAppRole_UpgradeSecretIDPrefix(t *testing.T) { b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + // Create a role entry directly in storage without SecretIDPrefix err = b.setRoleEntry(context.Background(), storage, "testrole", &roleStorageEntry{ RoleID: "testroleid", @@ -176,6 +192,7 @@ func TestAppRole_UpgradeSecretIDPrefix(t *testing.T) { if !ok { t.Fatalf("expected local_secret_ids to be present in the response") } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.ReadOperation), resp, true) } func TestAppRole_LocalSecretIDImmutability(t *testing.T) { @@ -184,6 +201,8 @@ func TestAppRole_LocalSecretIDImmutability(t *testing.T) { b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleData := map[string]interface{}{ "policies": []string{"default"}, "bind_secret_id": true, @@ -201,6 +220,7 @@ func TestAppRole_LocalSecretIDImmutability(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: err: %v\nresp: %#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) // Attempt to modify local_secret_ids should fail resp, err = b.HandleRequest(context.Background(), &logical.Request{ @@ -223,6 +243,8 @@ func TestAppRole_UpgradeBoundCIDRList(t *testing.T) { b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleData := map[string]interface{}{ "policies": []string{"default"}, "bind_secret_id": true, @@ -239,6 +261,7 @@ func TestAppRole_UpgradeBoundCIDRList(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: err: %v\nresp: %#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) // Read the role and check that the bound_cidr_list is set properly resp, err = b.HandleRequest(context.Background(), &logical.Request{ @@ -249,6 +272,7 @@ func TestAppRole_UpgradeBoundCIDRList(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: err: %v\nresp: %#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.ReadOperation), resp, true) expected := []string{"127.0.0.1/18", "192.178.1.2/24"} actual := resp.Data["secret_id_bound_cidrs"].([]string) @@ -280,6 +304,8 @@ func TestAppRole_UpgradeBoundCIDRList(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: err: %v\nresp: %#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.ReadOperation), resp, true) + if !reflect.DeepEqual(expected, actual) { t.Fatalf("bad: bound_cidr_list; expected: %#v\nactual: %#v\n", expected, actual) } @@ -296,6 +322,8 @@ func TestAppRole_UpgradeBoundCIDRList(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: err: %v\nresp: %#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) + if resp.Data["secret_id"].(string) == "" { t.Fatalf("failed to generate secret-id") } @@ -312,6 +340,8 @@ func TestAppRole_UpgradeBoundCIDRList(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: err: %v\nresp: %#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) + if resp.Data["secret_id"].(string) == "" { t.Fatalf("failed to generate secret-id") } @@ -324,6 +354,8 @@ func TestAppRole_RoleNameLowerCasing(t *testing.T) { b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + // Save a role with out LowerCaseRoleName set role := &roleStorageEntry{ RoleID: "testroleid", @@ -346,6 +378,8 @@ func TestAppRole_RoleNameLowerCasing(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) + secretID = resp.Data["secret_id"].(string) roleID = "testroleid" @@ -369,6 +403,8 @@ func TestAppRole_RoleNameLowerCasing(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) + secretID = resp.Data["secret_id"].(string) // Login should fail @@ -399,6 +435,7 @@ func TestAppRole_RoleNameLowerCasing(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.DeleteOperation), resp, true) roleReq := &logical.Request{ Path: "role/testRoleName", @@ -412,6 +449,7 @@ func TestAppRole_RoleNameLowerCasing(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) // Create secret id with lower cased role name resp, err = b.HandleRequest(context.Background(), &logical.Request{ @@ -422,6 +460,8 @@ func TestAppRole_RoleNameLowerCasing(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) + secretID = resp.Data["secret_id"].(string) resp, err = b.HandleRequest(context.Background(), &logical.Request{ @@ -432,6 +472,8 @@ func TestAppRole_RoleNameLowerCasing(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 14, logical.ReadOperation), resp, true) + roleID = resp.Data["role_id"].(string) // Login should pass @@ -463,6 +505,7 @@ func TestAppRole_RoleNameLowerCasing(t *testing.T) { if resp == nil { t.Fatalf("failed to lookup secret IDs") } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 16, logical.UpdateOperation), resp, true) // Listing of secret IDs should work in case-insensitive manner resp, err = b.HandleRequest(context.Background(), &logical.Request{ @@ -473,6 +516,7 @@ func TestAppRole_RoleNameLowerCasing(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.ListOperation), resp, true) if len(resp.Data["keys"].([]string)) != 1 { t.Fatalf("failed to list secret IDs") @@ -485,6 +529,8 @@ func TestAppRole_RoleReadSetIndex(t *testing.T) { b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleReq := &logical.Request{ Path: "role/testrole", Operation: logical.CreateOperation, @@ -499,6 +545,7 @@ func TestAppRole_RoleReadSetIndex(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\n err: %v\n", resp, err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) roleIDReq := &logical.Request{ Path: "role/testrole/role-id", @@ -511,6 +558,8 @@ func TestAppRole_RoleReadSetIndex(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\n err: %v\n", resp, err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 14, logical.ReadOperation), resp, true) + roleID := resp.Data["role_id"].(string) // Delete the role ID index @@ -553,11 +602,14 @@ func TestAppRole_RoleReadSetIndex(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\n err: %v\n", resp, err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.UpdateOperation), resp, true) + roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\n err: %v\n", resp, err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.ReadOperation), resp, true) } func TestAppRole_CIDRSubset(t *testing.T) { @@ -566,6 +618,8 @@ func TestAppRole_CIDRSubset(t *testing.T) { b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleData := map[string]interface{}{ "role_id": "role-id-123", "policies": "a,b", @@ -583,6 +637,7 @@ func TestAppRole_CIDRSubset(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err: %v resp: %#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) secretIDData := map[string]interface{}{ "cidr_list": "127.0.0.1/16", @@ -608,6 +663,7 @@ func TestAppRole_CIDRSubset(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err: %v resp: %#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.UpdateOperation), resp, true) secretIDData["cidr_list"] = "192.168.27.29/20,172.245.30.40/25,10.20.30.40/32" resp, err = b.HandleRequest(context.Background(), secretIDReq) @@ -617,6 +673,7 @@ func TestAppRole_CIDRSubset(t *testing.T) { if resp != nil && resp.IsError() { t.Fatalf("resp: %#v", resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) } func TestAppRole_TokenBoundCIDRSubset32Mask(t *testing.T) { @@ -625,6 +682,8 @@ func TestAppRole_TokenBoundCIDRSubset32Mask(t *testing.T) { b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleData := map[string]interface{}{ "role_id": "role-id-123", "policies": "a,b", @@ -642,6 +701,7 @@ func TestAppRole_TokenBoundCIDRSubset32Mask(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err: %v resp: %#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) secretIDData := map[string]interface{}{ "token_bound_cidrs": "127.0.0.1/32", @@ -657,6 +717,7 @@ func TestAppRole_TokenBoundCIDRSubset32Mask(t *testing.T) { if err != nil { t.Fatalf("err: %v resp: %#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) secretIDData = map[string]interface{}{ "token_bound_cidrs": "127.0.0.1/24", @@ -683,6 +744,8 @@ func TestAppRole_RoleConstraints(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleData := map[string]interface{}{ "role_id": "role-id-123", "policies": "a,b", @@ -700,6 +763,7 @@ func TestAppRole_RoleConstraints(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) // Set bound_cidr_list alone by explicitly disabling bind_secret_id roleReq.Operation = logical.UpdateOperation @@ -709,6 +773,7 @@ func TestAppRole_RoleConstraints(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.UpdateOperation), resp, true) // Remove both constraints roleReq.Operation = logical.UpdateOperation @@ -721,6 +786,7 @@ func TestAppRole_RoleConstraints(t *testing.T) { if err == nil { t.Fatalf("expected an error") } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.UpdateOperation), resp, true) } func TestAppRole_RoleIDUpdate(t *testing.T) { @@ -728,6 +794,8 @@ func TestAppRole_RoleIDUpdate(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleData := map[string]interface{}{ "role_id": "role-id-123", "policies": "a,b", @@ -746,6 +814,7 @@ func TestAppRole_RoleIDUpdate(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) roleIDUpdateReq := &logical.Request{ Operation: logical.UpdateOperation, @@ -759,6 +828,7 @@ func TestAppRole_RoleIDUpdate(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 14, logical.UpdateOperation), resp, true) secretIDReq := &logical.Request{ Operation: logical.UpdateOperation, @@ -769,6 +839,8 @@ func TestAppRole_RoleIDUpdate(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) + secretID := resp.Data["secret_id"].(string) loginData := map[string]interface{}{ @@ -799,6 +871,8 @@ func TestAppRole_RoleIDUniqueness(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleData := map[string]interface{}{ "role_id": "role-id-123", "policies": "a,b", @@ -818,6 +892,7 @@ func TestAppRole_RoleIDUniqueness(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) roleReq.Path = "role/testrole2" resp, err = b.HandleRequest(context.Background(), roleReq) @@ -830,6 +905,7 @@ func TestAppRole_RoleIDUniqueness(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) roleReq.Operation = logical.UpdateOperation roleData["role_id"] = "role-id-123" @@ -837,6 +913,7 @@ func TestAppRole_RoleIDUniqueness(t *testing.T) { if err == nil && !(resp != nil && resp.IsError()) { t.Fatalf("expected an error: got resp:%#v", resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.UpdateOperation), resp, true) roleReq.Path = "role/testrole1" roleData["role_id"] = "role-id-456" @@ -871,6 +948,7 @@ func TestAppRole_RoleIDUniqueness(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 14, logical.UpdateOperation), resp, true) roleIDData["role_id"] = "role-id-1000" roleIDReq.Path = "role/testrole1/role-id" @@ -878,6 +956,7 @@ func TestAppRole_RoleIDUniqueness(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 14, logical.UpdateOperation), resp, true) } func TestAppRole_RoleDeleteSecretID(t *testing.T) { @@ -885,6 +964,8 @@ func TestAppRole_RoleDeleteSecretID(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + createRole(t, b, storage, "role1", "a,b") secretIDReq := &logical.Request{ Operation: logical.UpdateOperation, @@ -896,14 +977,19 @@ func TestAppRole_RoleDeleteSecretID(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) + resp, err = b.HandleRequest(context.Background(), secretIDReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) + resp, err = b.HandleRequest(context.Background(), secretIDReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) listReq := &logical.Request{ Operation: logical.ListOperation, @@ -914,6 +1000,8 @@ func TestAppRole_RoleDeleteSecretID(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.ListOperation), resp, true) + secretIDAccessors := resp.Data["keys"].([]string) if len(secretIDAccessors) != 3 { t.Fatalf("bad: len of secretIDAccessors: expected:3 actual:%d", len(secretIDAccessors)) @@ -928,6 +1016,8 @@ func TestAppRole_RoleDeleteSecretID(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.DeleteOperation), resp, true) + resp, err = b.HandleRequest(context.Background(), listReq) if err != nil || resp == nil || (resp != nil && !resp.IsError()) { t.Fatalf("expected an error. err:%v resp:%#v", err, resp) @@ -939,6 +1029,8 @@ func TestAppRole_RoleSecretIDReadDelete(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + createRole(t, b, storage, "role1", "a,b") secretIDCreateReq := &logical.Request{ Operation: logical.UpdateOperation, @@ -949,6 +1041,7 @@ func TestAppRole_RoleSecretIDReadDelete(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) secretID := resp.Data["secret_id"].(string) if secretID == "" { @@ -967,6 +1060,8 @@ func TestAppRole_RoleSecretIDReadDelete(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 16, logical.UpdateOperation), resp, true) + if resp.Data == nil { t.Fatal(err) } @@ -983,6 +1078,7 @@ func TestAppRole_RoleSecretIDReadDelete(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 17, logical.DeleteOperation), resp, true) resp, err = b.HandleRequest(context.Background(), secretIDReq) if resp != nil && resp.IsError() { @@ -998,6 +1094,8 @@ func TestAppRole_RoleSecretIDAccessorReadDelete(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + createRole(t, b, storage, "role1", "a,b") secretIDReq := &logical.Request{ Operation: logical.UpdateOperation, @@ -1008,6 +1106,7 @@ func TestAppRole_RoleSecretIDAccessorReadDelete(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) listReq := &logical.Request{ Operation: logical.ListOperation, @@ -1018,6 +1117,8 @@ func TestAppRole_RoleSecretIDAccessorReadDelete(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.ListOperation), resp, true) + hmacSecretID := resp.Data["keys"].([]string)[0] hmacReq := &logical.Request{ @@ -1035,12 +1136,14 @@ func TestAppRole_RoleSecretIDAccessorReadDelete(t *testing.T) { if resp.Data == nil { t.Fatal(err) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 18, logical.UpdateOperation), resp, true) hmacReq.Path = "role/role1/secret-id-accessor/destroy" resp, err = b.HandleRequest(context.Background(), hmacReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 19, logical.UpdateOperation), resp, true) hmacReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), hmacReq) @@ -1085,6 +1188,8 @@ func TestAppRoleRoleListSecretID(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + createRole(t, b, storage, "role1", "a,b") secretIDReq := &logical.Request{ @@ -1097,22 +1202,31 @@ func TestAppRoleRoleListSecretID(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) + resp, err = b.HandleRequest(context.Background(), secretIDReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) + resp, err = b.HandleRequest(context.Background(), secretIDReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) + resp, err = b.HandleRequest(context.Background(), secretIDReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) + resp, err = b.HandleRequest(context.Background(), secretIDReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) listReq := &logical.Request{ Operation: logical.ListOperation, @@ -1123,6 +1237,8 @@ func TestAppRoleRoleListSecretID(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.ListOperation), resp, true) + secrets := resp.Data["keys"].([]string) if len(secrets) != 5 { t.Fatalf("bad: len of secrets: expected:5 actual:%d", len(secrets)) @@ -1134,6 +1250,8 @@ func TestAppRole_RoleList(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + createRole(t, b, storage, "role1", "a,b") createRole(t, b, storage, "role2", "c,d") createRole(t, b, storage, "role3", "e,f") @@ -1149,6 +1267,7 @@ func TestAppRole_RoleList(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 1, logical.ListOperation), resp, true) actual := resp.Data["keys"].([]string) expected := []string{"role1", "role2", "role3", "role4", "role5"} @@ -1162,6 +1281,8 @@ func TestAppRole_RoleSecretIDWithoutFields(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleData := map[string]interface{}{ "policies": "p,q,r,s", "secret_id_num_uses": 10, @@ -1180,6 +1301,7 @@ func TestAppRole_RoleSecretIDWithoutFields(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) roleSecretIDReq := &logical.Request{ Operation: logical.UpdateOperation, @@ -1190,6 +1312,7 @@ func TestAppRole_RoleSecretIDWithoutFields(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) if resp.Data["secret_id"].(string) == "" { t.Fatalf("failed to generate secret_id") @@ -1210,6 +1333,7 @@ func TestAppRole_RoleSecretIDWithoutFields(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 20, logical.UpdateOperation), resp, true) if resp.Data["secret_id"] != "abcd123" { t.Fatalf("failed to set specific secret_id to role") @@ -1232,6 +1356,8 @@ func TestAppRole_RoleSecretIDWithValidFields(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleData := map[string]interface{}{ "policies": "p,q,r,s", "secret_id_num_uses": 0, @@ -1250,6 +1376,7 @@ func TestAppRole_RoleSecretIDWithValidFields(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) testCases := []testCase{ { @@ -1284,6 +1411,7 @@ func TestAppRole_RoleSecretIDWithValidFields(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) if resp.Data["secret_id"].(string) == "" { t.Fatalf("failed to generate secret_id") @@ -1301,6 +1429,7 @@ func TestAppRole_RoleSecretIDWithValidFields(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 20, logical.UpdateOperation), resp, true) if resp.Data["secret_id"] != tc.payload["secret_id"] { t.Fatalf("failed to set specific secret_id to role") @@ -1400,6 +1529,8 @@ func TestAppRole_ErrorsRoleSecretIDWithInvalidFields(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + for i, rc := range roleTestCases { roleData := map[string]interface{}{ "policies": "p,q,r,s", @@ -1420,6 +1551,7 @@ func TestAppRole_ErrorsRoleSecretIDWithInvalidFields(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) for _, tc := range rc.cases { t.Run(fmt.Sprintf("%s/%s", rc.name, tc.name), func(t *testing.T) { @@ -1455,6 +1587,8 @@ func TestAppRole_RoleCRUD(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleData := map[string]interface{}{ "policies": "p,q,r,s", "secret_id_num_uses": 10, @@ -1475,12 +1609,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.ReadOperation), resp, true) expected := map[string]interface{}{ "bind_secret_id": true, @@ -1527,12 +1663,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.UpdateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.ReadOperation), resp, true) expected = map[string]interface{}{ "policies": []string{"a", "b", "c", "d"}, @@ -1562,6 +1700,8 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 14, logical.ReadOperation), resp, true) + if resp.Data["role_id"].(string) != "test_role_id" { t.Fatalf("bad: role_id: expected:test_role_id actual:%s\n", resp.Data["role_id"].(string)) } @@ -1572,12 +1712,15 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 14, logical.UpdateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 14, logical.ReadOperation), resp, true) + if resp.Data["role_id"].(string) != "custom_role_id" { t.Fatalf("bad: role_id: expected:custom_role_id actual:%s\n", resp.Data["role_id"].(string)) } @@ -1589,6 +1732,7 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 7, logical.ReadOperation), resp, true) roleReq.Data = map[string]interface{}{"bind_secret_id": false} roleReq.Operation = logical.UpdateOperation @@ -1596,12 +1740,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 7, logical.UpdateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 7, logical.ReadOperation), resp, true) if resp.Data["bind_secret_id"].(bool) { t.Fatalf("bad: bind_secret_id: expected:false actual:%t\n", resp.Data["bind_secret_id"].(bool)) @@ -1611,12 +1757,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 7, logical.DeleteOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 7, logical.ReadOperation), resp, true) if !resp.Data["bind_secret_id"].(bool) { t.Fatalf("expected the default value of 'true' to be set") @@ -1629,6 +1777,7 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 3, logical.ReadOperation), resp, true) roleReq.Data = map[string]interface{}{"policies": "a1,b1,c1,d1"} roleReq.Operation = logical.UpdateOperation @@ -1636,12 +1785,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 3, logical.UpdateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 3, logical.ReadOperation), resp, true) if !reflect.DeepEqual(resp.Data["policies"].([]string), []string{"a1", "b1", "c1", "d1"}) { t.Fatalf("bad: policies: actual:%s\n", resp.Data["policies"].([]string)) @@ -1654,12 +1805,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 3, logical.DeleteOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 3, logical.ReadOperation), resp, true) expectedPolicies := []string{} actualPolicies := resp.Data["token_policies"].([]string) @@ -1674,6 +1827,7 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 8, logical.ReadOperation), resp, true) roleReq.Data = map[string]interface{}{"secret_id_num_uses": 200} roleReq.Operation = logical.UpdateOperation @@ -1681,12 +1835,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 8, logical.UpdateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 8, logical.ReadOperation), resp, true) if resp.Data["secret_id_num_uses"].(int) != 200 { t.Fatalf("bad: secret_id_num_uses: expected:200 actual:%d\n", resp.Data["secret_id_num_uses"].(int)) @@ -1696,12 +1852,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 8, logical.DeleteOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 8, logical.ReadOperation), resp, true) if resp.Data["secret_id_num_uses"].(int) != 0 { t.Fatalf("expected value to be reset") @@ -1714,6 +1872,7 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 9, logical.ReadOperation), resp, true) roleReq.Data = map[string]interface{}{"secret_id_ttl": 3001} roleReq.Operation = logical.UpdateOperation @@ -1721,12 +1880,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 9, logical.UpdateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 9, logical.ReadOperation), resp, true) if resp.Data["secret_id_ttl"].(time.Duration) != 3001 { t.Fatalf("bad: secret_id_ttl: expected:3001 actual:%d\n", resp.Data["secret_id_ttl"].(time.Duration)) @@ -1736,12 +1897,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 9, logical.DeleteOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 9, logical.ReadOperation), resp, true) if resp.Data["secret_id_ttl"].(time.Duration) != 0 { t.Fatalf("expected value to be reset") @@ -1754,6 +1917,8 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 11, logical.ReadOperation), resp, true) + if resp.Data["token_num_uses"].(int) != 600 { t.Fatalf("bad: token_num_uses: expected:600 actual:%d\n", resp.Data["token_num_uses"].(int)) } @@ -1764,12 +1929,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 11, logical.UpdateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 11, logical.ReadOperation), resp, true) if resp.Data["token_num_uses"].(int) != 60 { t.Fatalf("bad: token_num_uses: expected:60 actual:%d\n", resp.Data["token_num_uses"].(int)) @@ -1780,12 +1947,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 11, logical.DeleteOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 11, logical.ReadOperation), resp, true) if resp.Data["token_num_uses"].(int) != 0 { t.Fatalf("expected value to be reset") @@ -1798,6 +1967,7 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 10, logical.ReadOperation), resp, true) roleReq.Data = map[string]interface{}{"period": 9001} roleReq.Operation = logical.UpdateOperation @@ -1805,12 +1975,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 10, logical.UpdateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 10, logical.ReadOperation), resp, true) if resp.Data["period"].(time.Duration) != 9001 { t.Fatalf("bad: period: expected:9001 actual:%d\n", resp.Data["9001"].(time.Duration)) @@ -1820,12 +1992,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 10, logical.DeleteOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 10, logical.ReadOperation), resp, true) if resp.Data["token_period"].(time.Duration) != 0 { t.Fatalf("expected value to be reset") @@ -1838,6 +2012,7 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 12, logical.ReadOperation), resp, true) roleReq.Data = map[string]interface{}{"token_ttl": 4001} roleReq.Operation = logical.UpdateOperation @@ -1845,12 +2020,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 12, logical.UpdateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 12, logical.ReadOperation), resp, true) if resp.Data["token_ttl"].(time.Duration) != 4001 { t.Fatalf("bad: token_ttl: expected:4001 actual:%d\n", resp.Data["token_ttl"].(time.Duration)) @@ -1860,12 +2037,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 12, logical.DeleteOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 12, logical.ReadOperation), resp, true) if resp.Data["token_ttl"].(time.Duration) != 0 { t.Fatalf("expected value to be reset") @@ -1878,6 +2057,7 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 13, logical.ReadOperation), resp, true) roleReq.Data = map[string]interface{}{"token_max_ttl": 5001} roleReq.Operation = logical.UpdateOperation @@ -1885,12 +2065,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 13, logical.UpdateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 13, logical.ReadOperation), resp, true) if resp.Data["token_max_ttl"].(time.Duration) != 5001 { t.Fatalf("bad: token_max_ttl: expected:5001 actual:%d\n", resp.Data["token_max_ttl"].(time.Duration)) @@ -1900,12 +2082,14 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 13, logical.DeleteOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 13, logical.ReadOperation), resp, true) if resp.Data["token_max_ttl"].(time.Duration) != 0 { t.Fatalf("expected value to be reset") @@ -1918,6 +2102,7 @@ func TestAppRole_RoleCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.DeleteOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) @@ -1935,6 +2120,8 @@ func TestAppRole_RoleWithTokenBoundCIDRsCRUD(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleData := map[string]interface{}{ "policies": "p,q,r,s", "secret_id_num_uses": 10, @@ -1956,12 +2143,14 @@ func TestAppRole_RoleWithTokenBoundCIDRsCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.ReadOperation), resp, true) expected := map[string]interface{}{ "bind_secret_id": true, @@ -2008,12 +2197,14 @@ func TestAppRole_RoleWithTokenBoundCIDRsCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.UpdateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.ReadOperation), resp, true) expected = map[string]interface{}{ "policies": []string{"a", "b", "c", "d"}, @@ -2043,6 +2234,8 @@ func TestAppRole_RoleWithTokenBoundCIDRsCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 5, logical.ReadOperation), resp, true) + if resp.Data["secret_id_bound_cidrs"].([]string)[0] != "127.0.0.1/32" || resp.Data["secret_id_bound_cidrs"].([]string)[1] != "127.0.0.1/16" { 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)) @@ -2054,12 +2247,14 @@ func TestAppRole_RoleWithTokenBoundCIDRsCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 5, logical.UpdateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 5, logical.ReadOperation), resp, true) if resp.Data["secret_id_bound_cidrs"].([]string)[0] != "127.0.0.1/20" { t.Fatalf("bad: secret_id_bound_cidrs: expected:127.0.0.1/20 actual:%s\n", resp.Data["secret_id_bound_cidrs"].([]string)[0]) @@ -2070,12 +2265,14 @@ func TestAppRole_RoleWithTokenBoundCIDRsCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 5, logical.DeleteOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 5, logical.ReadOperation), resp, true) if len(resp.Data["secret_id_bound_cidrs"].([]string)) != 0 { t.Fatalf("expected value to be reset") @@ -2088,6 +2285,8 @@ func TestAppRole_RoleWithTokenBoundCIDRsCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 6, logical.ReadOperation), resp, true) + if resp.Data["token_bound_cidrs"].([]*sockaddr.SockAddrMarshaler)[0].String() != "127.0.0.1" || resp.Data["token_bound_cidrs"].([]*sockaddr.SockAddrMarshaler)[1].String() != "127.0.0.1/16" { m, err := json.Marshal(resp.Data["token_bound_cidrs"].([]*sockaddr.SockAddrMarshaler)) @@ -2103,12 +2302,14 @@ func TestAppRole_RoleWithTokenBoundCIDRsCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 6, logical.UpdateOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 6, logical.ReadOperation), resp, true) if resp.Data["token_bound_cidrs"].([]*sockaddr.SockAddrMarshaler)[0].String() != "127.0.0.1/20" { t.Fatalf("bad: token_bound_cidrs: expected:127.0.0.1/20 actual:%s\n", resp.Data["token_bound_cidrs"].([]*sockaddr.SockAddrMarshaler)[0]) @@ -2119,12 +2320,14 @@ func TestAppRole_RoleWithTokenBoundCIDRsCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 6, logical.DeleteOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 6, logical.ReadOperation), resp, true) if len(resp.Data["token_bound_cidrs"].([]*sockaddr.SockAddrMarshaler)) != 0 { t.Fatalf("expected value to be reset") @@ -2137,6 +2340,7 @@ func TestAppRole_RoleWithTokenBoundCIDRsCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.DeleteOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) @@ -2154,6 +2358,8 @@ func TestAppRole_RoleWithTokenTypeCRUD(t *testing.T) { var err error b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + roleData := map[string]interface{}{ "policies": "p,q,r,s", "secret_id_num_uses": 10, @@ -2174,6 +2380,8 @@ func TestAppRole_RoleWithTokenTypeCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) + if 0 == len(resp.Warnings) { t.Fatalf("bad:\nexpected warning in resp:%#v\n", resp.Warnings) } @@ -2183,6 +2391,7 @@ func TestAppRole_RoleWithTokenTypeCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.ReadOperation), resp, true) expected := map[string]interface{}{ "bind_secret_id": true, @@ -2228,6 +2437,8 @@ func TestAppRole_RoleWithTokenTypeCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.UpdateOperation), resp, true) + if 0 == len(resp.Warnings) { t.Fatalf("bad:\nexpected a warning in resp:%#v\n", resp.Warnings) } @@ -2237,6 +2448,7 @@ func TestAppRole_RoleWithTokenTypeCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.ReadOperation), resp, true) expected = map[string]interface{}{ "policies": []string{"a", "b", "c", "d"}, @@ -2267,6 +2479,7 @@ func TestAppRole_RoleWithTokenTypeCRUD(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.DeleteOperation), resp, true) roleReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), roleReq) @@ -2294,10 +2507,13 @@ func createRole(t *testing.T, b *backend, s logical.Storage, roleName, policies Data: roleData, } + paths := rolePaths(b) + resp, err := b.HandleRequest(context.Background(), roleReq) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) } // TestAppRole_TokenutilUpgrade ensures that when we read values out that are @@ -2419,6 +2635,8 @@ func TestAppRole_SecretID_WithTTL(t *testing.T) { b, storage := createBackendWithStorage(t) + paths := rolePaths(b) + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Create role @@ -2437,6 +2655,7 @@ func TestAppRole_SecretID_WithTTL(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 0, logical.CreateOperation), resp, true) // Generate secret ID secretIDReq := &logical.Request{ @@ -2448,6 +2667,7 @@ func TestAppRole_SecretID_WithTTL(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("err:%v resp:%#v", err, resp) } + schema.ValidateResponse(t, schema.FindResponseSchema(t, paths, 15, logical.UpdateOperation), resp, true) // Extract the "ttl" value from the response data if it exists ttlRaw, okTTL := resp.Data["secret_id_ttl"] diff --git a/changelog/18636.txt b/changelog/18636.txt new file mode 100644 index 000000000..9f260e2e8 --- /dev/null +++ b/changelog/18636.txt @@ -0,0 +1,3 @@ +```release-note:improvement +sdk: Adding FindResponseSchema test helper to assist with response schema validation in tests +``` diff --git a/sdk/helper/testhelpers/schema/response_validation.go b/sdk/helper/testhelpers/schema/response_validation.go index 9597e8481..3b7f2a48a 100644 --- a/sdk/helper/testhelpers/schema/response_validation.go +++ b/sdk/helper/testhelpers/schema/response_validation.go @@ -3,6 +3,7 @@ package schema import ( "encoding/json" "fmt" + "net/http" "testing" "github.com/hashicorp/vault/sdk/framework" @@ -76,3 +77,45 @@ func validateResponseDataImpl(schema *framework.Response, data map[string]interf return fd.Validate() } + +// FindResponseSchema is a test helper to extract the response schema from a given framework path / operation +func FindResponseSchema(t *testing.T, paths []*framework.Path, pathIdx int, operation logical.Operation) *framework.Response { + t.Helper() + + if pathIdx >= len(paths) { + t.Fatalf("path index %d is out of range", pathIdx) + } + + schemaPath := paths[pathIdx] + + schemaOperation, ok := schemaPath.Operations[operation] + if !ok { + t.Fatalf( + "could not find response schema: %s: %q operation does not exist", + schemaPath.Pattern, + operation, + ) + } + + var schemaResponses []framework.Response + + for _, status := range []int{ + http.StatusOK, + http.StatusNoContent, + } { + schemaResponses, ok = schemaOperation.Properties().Responses[status] + if ok { + break + } + } + + if len(schemaResponses) == 0 { + t.Fatalf( + "could not find response schema: %s: %q operation: no responses found", + schemaPath.Pattern, + operation, + ) + } + + return &schemaResponses[0] +}