Skip to content

Commit

Permalink
APISHI-2373 Add support for Get/Update API Shield Operation Schema Va…
Browse files Browse the repository at this point in the history
…lidation Settings

Adds support for the following endpoints

- Retrieve operation level schema validation settings
- Update operation level schema validation settings
- Update multiple operation level schema validation settings
  • Loading branch information
djhworld committed Oct 16, 2023
1 parent 3117cc8 commit 5f0ca00
Show file tree
Hide file tree
Showing 3 changed files with 263 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/1422.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
api_shield_schema: Add support for Get/Update API Shield Operation Schema Validation Settings
```
125 changes: 125 additions & 0 deletions api_shield_schemas.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,3 +414,128 @@ func (api *API) UpdateAPIShieldSchemaValidationSettings(ctx context.Context, rc

return &asResponse.Result, nil
}

// APIShieldOperationSchemaValidationSettings represents operation level schema validation settings for
// API Shield Schema Validation 2.0.
type APIShieldOperationSchemaValidationSettings struct {
// MitigationAction is the mitigation to apply to the operation
MitigationAction *string `json:"mitigation_action" url:"-"`
}

// GetAPIShieldOperationSchemaValidationSettingsParams represents the parameters to pass to retrieve
// the schema validation settings set on the operation.
//
// API documentation: https://developers.cloudflare.com/api/operations/api-shield-schema-validation-retrieve-operation-level-settings
type GetAPIShieldOperationSchemaValidationSettingsParams struct {
// The Operation ID to apply the mitigation action to
OperationID string `url:"-"`
}

// UpdateAPIShieldOperationSchemaValidationSettingsParams represents the parameters to pass to update certain fields
// on schema validation settings on the zone
//
// API documentation: https://developers.cloudflare.com/api/operations/api-shield-schema-validation-update-operation-level-settings
type UpdateAPIShieldOperationSchemaValidationSettingsParams struct {
// The Operation ID to apply the mitigation action to
OperationID string `json:"-" url:"-"`
APIShieldOperationSchemaValidationSettings
}

// UpdateMultipleAPIShieldOperationSchemaValidationSettings maps operation IDs to APIShieldOperationSchemaValidationSettings
//
// # This can be used to bulk update operations in one call
//
// Example:
//
// UpdateMultipleAPIShieldOperationSchemaValidationSettings{
// "99522293-a505-45e5-bbad-bbc339f5dc40": APIShieldOperationSchemaValidationSettings{ MitigationAction: nil },
// }
//
// API documentation: https://developers.cloudflare.com/api/operations/api-shield-schema-validation-update-multiple-operation-level-settings
type UpdateMultipleAPIShieldOperationSchemaValidationSettings map[string]APIShieldOperationSchemaValidationSettings

// APIShieldOperationSchemaValidationSettingsResponse represents the response from the GET api_gateway/operation/{operationID}/schema_validation endpoint.
type APIShieldOperationSchemaValidationSettingsResponse struct {
Result APIShieldOperationSchemaValidationSettings `json:"result"`
Response
}

// UpdateMultipleAPIShieldOperationSchemaValidationSettingsResponse represents the response from the PATCH api_gateway/operations/schema_validation endpoint.
type UpdateMultipleAPIShieldOperationSchemaValidationSettingsResponse struct {
Result UpdateMultipleAPIShieldOperationSchemaValidationSettings `json:"result"`
Response
}

// GetAPIShieldOperationSchemaValidationSettings retrieves operation level schema validation settings
//
// API documentation: https://developers.cloudflare.com/api/operations/api-shield-schema-validation-retrieve-operation-level-settings
func (api *API) GetAPIShieldOperationSchemaValidationSettings(ctx context.Context, rc *ResourceContainer, params GetAPIShieldOperationSchemaValidationSettingsParams) (*APIShieldOperationSchemaValidationSettings, error) {
if params.OperationID == "" {
return nil, fmt.Errorf("operation ID must be provided")
}

path := fmt.Sprintf("/zones/%s/api_gateway/operations/%s/schema_validation", rc.Identifier, params.OperationID)

uri := buildURI(path, nil)

res, err := api.makeRequestContext(ctx, http.MethodGet, uri, params)
if err != nil {
return nil, err
}

var asResponse APIShieldOperationSchemaValidationSettingsResponse
err = json.Unmarshal(res, &asResponse)
if err != nil {
return nil, fmt.Errorf("%s: %w", errUnmarshalError, err)
}

return &asResponse.Result, nil
}

// UpdateAPIShieldOperationSchemaValidationSettings updates operation level schema validation settings
//
// API documentation: https://developers.cloudflare.com/api/operations/api-shield-schema-validation-update-operation-level-settings
func (api *API) UpdateAPIShieldOperationSchemaValidationSettings(ctx context.Context, rc *ResourceContainer, params UpdateAPIShieldOperationSchemaValidationSettingsParams) (*APIShieldOperationSchemaValidationSettings, error) {
if params.OperationID == "" {
return nil, fmt.Errorf("operation ID must be provided")
}

path := fmt.Sprintf("/zones/%s/api_gateway/operations/%s/schema_validation", rc.Identifier, params.OperationID)

uri := buildURI(path, nil)

res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params)
if err != nil {
return nil, err
}

var asResponse APIShieldOperationSchemaValidationSettingsResponse
err = json.Unmarshal(res, &asResponse)
if err != nil {
return nil, fmt.Errorf("%s: %w", errUnmarshalError, err)
}

return &asResponse.Result, nil
}

// UpdateMultipleAPIShieldOperationSchemaValidationSettings update multiple operation level schema validation settings
//
// API documentation: https://developers.cloudflare.com/api/operations/api-shield-schema-validation-update-multiple-operation-level-settings
func (api *API) UpdateMultipleAPIShieldOperationSchemaValidationSettings(ctx context.Context, rc *ResourceContainer, params UpdateMultipleAPIShieldOperationSchemaValidationSettings) (*UpdateMultipleAPIShieldOperationSchemaValidationSettings, error) {
path := fmt.Sprintf("/zones/%s/api_gateway/operations/schema_validation", rc.Identifier)

uri := buildURI(path, nil)

res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
if err != nil {
return nil, err
}

var asResponse UpdateMultipleAPIShieldOperationSchemaValidationSettingsResponse
err = json.Unmarshal(res, &asResponse)
if err != nil {
return nil, fmt.Errorf("%s: %w", errUnmarshalError, err)
}

return &asResponse.Result, nil
}
135 changes: 135 additions & 0 deletions api_shield_schemas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -580,3 +580,138 @@ func TestUpdateAPIShieldSchemaValidationSettings(t *testing.T) {
assert.Equal(t, expected, actual)
}
}

func TestGetAPIShieldOperationSchemaValidationSettings(t *testing.T) {
endpoint := fmt.Sprintf("/zones/%s/api_gateway/operations/%s/schema_validation", testZoneID, testAPIShieldOperationId)
response := `{
"success" : true,
"errors": [],
"messages": [],
"result": {
"mitigation_action": "log"
}
}`

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.GetAPIShieldOperationSchemaValidationSettings(
context.Background(),
ZoneIdentifier(testZoneID),
GetAPIShieldOperationSchemaValidationSettingsParams{OperationID: testAPIShieldOperationId},
)

log := "log"
expected := &APIShieldOperationSchemaValidationSettings{
MitigationAction: &log,
}

if assert.NoError(t, err) {
assert.Equal(t, expected, actual)
}
}

func TestUpdateAPIShieldOperationSchemaValidationSettings(t *testing.T) {
endpoint := fmt.Sprintf("/zones/%s/api_gateway/operations/%s/schema_validation", testZoneID, testAPIShieldOperationId)
response := `{
"success" : true,
"errors": [],
"messages": [],
"result": {
"mitigation_action": "block"
}
}`

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())

body, err := io.ReadAll(r.Body)
require.NoError(t, err)
require.Equal(t, `{"mitigation_action":"block"}`, string(body))

w.Header().Set("content-type", "application/json")
fmt.Fprint(w, response)
}

mux.HandleFunc(endpoint, handler)

block := "block"
actual, err := client.UpdateAPIShieldOperationSchemaValidationSettings(
context.Background(),
ZoneIdentifier(testZoneID),
UpdateAPIShieldOperationSchemaValidationSettingsParams{
OperationID: testAPIShieldOperationId,
APIShieldOperationSchemaValidationSettings: APIShieldOperationSchemaValidationSettings{
MitigationAction: &block,
},
},
)

expected := &APIShieldOperationSchemaValidationSettings{
MitigationAction: &block,
}

if assert.NoError(t, err) {
assert.Equal(t, expected, actual)
}
}

func TestUpdateMultipleAPIShieldOperationSchemaValidationSettings(t *testing.T) {
endpoint := fmt.Sprintf("/zones/%s/api_gateway/operations/schema_validation", testZoneID)
response := fmt.Sprintf(`{
"success" : true,
"errors": [],
"messages": [],
"result": {
"%s": null
}
}`, testAPIShieldOperationId)

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())

body, err := io.ReadAll(r.Body)
require.NoError(t, err)
expected := fmt.Sprintf(`{"%s":{"mitigation_action":null}}`, testAPIShieldOperationId)
require.Equal(t, expected, string(body))

w.Header().Set("content-type", "application/json")
fmt.Fprint(w, response)
}

mux.HandleFunc(endpoint, handler)

actual, err := client.UpdateMultipleAPIShieldOperationSchemaValidationSettings(
context.Background(),
ZoneIdentifier(testZoneID),
UpdateMultipleAPIShieldOperationSchemaValidationSettings{
testAPIShieldOperationId: APIShieldOperationSchemaValidationSettings{
MitigationAction: nil,
},
},
)

expected := &UpdateMultipleAPIShieldOperationSchemaValidationSettings{
testAPIShieldOperationId: APIShieldOperationSchemaValidationSettings{
MitigationAction: nil,
},
}

if assert.NoError(t, err) {
assert.Equal(t, expected, actual)
}
}

0 comments on commit 5f0ca00

Please sign in to comment.