From ce2b27fff909a073a684911518018ec0be1ff1d0 Mon Sep 17 00:00:00 2001 From: Daniel Harper <529730+djhworld@users.noreply.github.com> Date: Mon, 9 Oct 2023 16:50:00 +0100 Subject: [PATCH] APISHI-2361 Add support for Get/Update API Shield Schema Validation Settings This change adds support for the following API Shield related endpoints related to API Shield Schema Validation Settings: - Retrieve API Shield Schema Validation Settings - Update All API Shield Schema Validation Settings - Update API Shield Schema Validation Settings --- .changelog/1418.txt | 3 + api_shield_schemas.go | 111 +++++++++++++++++++++++++++++++++ api_shield_schemas_test.go | 122 +++++++++++++++++++++++++++++++++++++ 3 files changed, 236 insertions(+) create mode 100644 .changelog/1418.txt diff --git a/.changelog/1418.txt b/.changelog/1418.txt new file mode 100644 index 00000000000..4cc578265de --- /dev/null +++ b/.changelog/1418.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +api_shield_schema: Add support for Get/Update API Shield Schema Validation Settings +``` diff --git a/api_shield_schemas.go b/api_shield_schemas.go index 45e557cd58e..3e2ca3fdb74 100644 --- a/api_shield_schemas.go +++ b/api_shield_schemas.go @@ -333,3 +333,114 @@ func (api *API) UpdateAPIShieldSchema(ctx context.Context, rc *ResourceContainer return &asResponse.Result, nil } + +// Schema Validation Settings + +// APIShieldSchemaValidationSettings represents zone level schema validation settings for +// API Shield Schema Validation 2.0. +type APIShieldSchemaValidationSettings struct { + // DefaultMitigationAction is the mitigation to apply when there is no operation-level + // mitigation action defined + DefaultMitigationAction string `json:"validation_default_mitigation_action" url:"-"` + // OverrideMitigationAction when set, will apply to all requests regardless of + // zone-level/operation-level setting + OverrideMitigationAction *string `json:"validation_override_mitigation_action" url:"-"` +} + +// UpdateAllAPIShieldSchemaValidationSettingsParams represents the parameters to pass to update all +// schema validation settings on the zone +// +// API documentation: TODO. +type UpdateAllAPIShieldSchemaValidationSettingsParams struct { + APIShieldSchemaValidationSettings +} + +// UpdateAPIShieldSchemaValidationSettingsParams represents the parameters to pass to update certain fields +// on schema validation settings on the zone +// +// API documentation: TODO. +type UpdateAPIShieldSchemaValidationSettingsParams struct { + // DefaultMitigationAction is the mitigation to apply when there is no operation-level + // mitigation action defined + // + // passing a `nil` value will have no effect on this setting + DefaultMitigationAction *string `json:"validation_default_mitigation_action" url:"-"` + + // OverrideMitigationAction when set, will apply to all requests regardless of + // zone-level/operation-level setting + // + // passing a `nil` value will have no effect on this setting + OverrideMitigationAction *string `json:"validation_override_mitigation_action" url:"-"` +} + +// APIShieldSchemaValidationSettingsResponse represents the response from the GET api_gateway/settings/schema_validation endpoint. +type APIShieldSchemaValidationSettingsResponse struct { + Result APIShieldSchemaValidationSettings `json:"result"` + Response +} + +// GetAPIShieldSchemaValidationSettings retrieves zone level schema validation settings +// +// API documentation: TODO. +func (api *API) GetAPIShieldSchemaValidationSettings(ctx context.Context, rc *ResourceContainer) (*APIShieldSchemaValidationSettings, error) { + path := fmt.Sprintf("/zones/%s/api_gateway/settings/schema_validation", rc.Identifier) + + uri := buildURI(path, nil) + + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return nil, err + } + + var asResponse APIShieldSchemaValidationSettingsResponse + err = json.Unmarshal(res, &asResponse) + if err != nil { + return nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + + return &asResponse.Result, nil +} + +// UpdateAllAPIShieldSchemaValidationSettings updates zone level schema validation settings +// +// API documentation: TODO. +func (api *API) UpdateAllAPIShieldSchemaValidationSettings(ctx context.Context, rc *ResourceContainer, params UpdateAllAPIShieldSchemaValidationSettingsParams) (*APIShieldSchemaValidationSettings, error) { + path := fmt.Sprintf("/zones/%s/api_gateway/settings/schema_validation", rc.Identifier) + + uri := buildURI(path, params) + + res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params) + if err != nil { + return nil, err + } + + var asResponse APIShieldSchemaValidationSettingsResponse + err = json.Unmarshal(res, &asResponse) + if err != nil { + return nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + + return &asResponse.Result, nil +} + +// UpdateAPIShieldSchemaValidationSettings updates certain fields on zone level schema validation settings +// +// API documentation: TODO. +func (api *API) UpdateAPIShieldSchemaValidationSettings(ctx context.Context, rc *ResourceContainer, params UpdateAPIShieldSchemaValidationSettingsParams) (*APIShieldSchemaValidationSettings, error) { + path := fmt.Sprintf("/zones/%s/api_gateway/settings/schema_validation", rc.Identifier) + + uri := buildURI(path, params) + + res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params) + if err != nil { + return nil, err + } + + var asResponse APIShieldSchemaValidationSettingsResponse + err = json.Unmarshal(res, &asResponse) + if err != nil { + return nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + + return &asResponse.Result, nil +} diff --git a/api_shield_schemas_test.go b/api_shield_schemas_test.go index 5d2f2199039..daeb64c2a74 100644 --- a/api_shield_schemas_test.go +++ b/api_shield_schemas_test.go @@ -502,3 +502,125 @@ func TestMustProvideSchemaID(t *testing.T) { err = client.DeleteAPIShieldSchema(context.Background(), ZoneIdentifier(testZoneID), DeleteAPIShieldSchemaParams{}) require.ErrorContains(t, err, "schema ID must be provided") } + +func TestGetAPIShieldSchemaValidationSettings(t *testing.T) { + endpoint := fmt.Sprintf("/zones/%s/api_gateway/settings/schema_validation", testZoneID) + response := `{ + "success" : true, + "errors": [], + "messages": [], + "result": { + "validation_default_mitigation_action": "log", + "validation_override_mitigation_action": "none" + } + }` + + setup() + t.Cleanup(teardown) + handler := func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method) + require.Empty(t, r.URL.Query()) + w.Header().Set("content-type", "application/json") + fmt.Fprint(w, response) + } + + mux.HandleFunc(endpoint, handler) + + actual, err := client.GetAPIShieldSchemaValidationSettings( + context.Background(), + ZoneIdentifier(testZoneID), + ) + + none := "none" + expected := &APIShieldSchemaValidationSettings{ + DefaultMitigationAction: "log", + OverrideMitigationAction: &none, + } + + if assert.NoError(t, err) { + assert.Equal(t, expected, actual) + } +} + +func TestUpdateAllAPIShieldSchemaValidationSettings(t *testing.T) { + endpoint := fmt.Sprintf("/zones/%s/api_gateway/settings/schema_validation", testZoneID) + response := `{ + "success" : true, + "errors": [], + "messages": [], + "result": { + "validation_default_mitigation_action": "log", + "validation_override_mitigation_action": null + } + }` + + setup() + t.Cleanup(teardown) + handler := func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method) + require.Empty(t, r.URL.Query()) + w.Header().Set("content-type", "application/json") + fmt.Fprint(w, response) + } + + mux.HandleFunc(endpoint, handler) + + actual, err := client.UpdateAllAPIShieldSchemaValidationSettings( + context.Background(), + ZoneIdentifier(testZoneID), + UpdateAllAPIShieldSchemaValidationSettingsParams{ + APIShieldSchemaValidationSettings{ + DefaultMitigationAction: "log", + OverrideMitigationAction: nil, + }, + }, + ) + + expected := &APIShieldSchemaValidationSettings{ + DefaultMitigationAction: "log", + OverrideMitigationAction: nil, + } + + if assert.NoError(t, err) { + assert.Equal(t, expected, actual) + } +} + +func TestUpdateAPIShieldSchemaValidationSettings(t *testing.T) { + endpoint := fmt.Sprintf("/zones/%s/api_gateway/settings/schema_validation", testZoneID) + response := `{ + "success" : true, + "errors": [], + "messages": [], + "result": { + "validation_default_mitigation_action": "log", + "validation_override_mitigation_action": null + } + }` + + setup() + t.Cleanup(teardown) + handler := func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, http.MethodPatch, r.Method, "Expected method 'PATCH', got %s", r.Method) + require.Empty(t, r.URL.Query()) + w.Header().Set("content-type", "application/json") + fmt.Fprint(w, response) + } + + mux.HandleFunc(endpoint, handler) + + actual, err := client.UpdateAPIShieldSchemaValidationSettings( + context.Background(), + ZoneIdentifier(testZoneID), + UpdateAPIShieldSchemaValidationSettingsParams{}, // specifying nil is ok for fields + ) + + expected := &APIShieldSchemaValidationSettings{ + DefaultMitigationAction: "log", + OverrideMitigationAction: nil, + } + + if assert.NoError(t, err) { + assert.Equal(t, expected, actual) + } +}