Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Get/Update API Shield Operation Schema Validation settings #1422

Merged
merged 1 commit into from
Oct 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
```
89 changes: 89 additions & 0 deletions api_shield_schemas.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,3 +414,92 @@ 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:"-"`
}

// UpdateAPIShieldOperationSchemaValidationSettings maps operation IDs to APIShieldOperationSchemaValidationSettings
//
// # This can be used to bulk update operations in one call
//
// Example:
//
// UpdateAPIShieldOperationSchemaValidationSettings{
// "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 UpdateAPIShieldOperationSchemaValidationSettings 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
}

// UpdateAPIShieldOperationSchemaValidationSettingsResponse represents the response from the PATCH api_gateway/operations/schema_validation endpoint.
type UpdateAPIShieldOperationSchemaValidationSettingsResponse struct {
Result UpdateAPIShieldOperationSchemaValidationSettings `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 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) UpdateAPIShieldOperationSchemaValidationSettings(ctx context.Context, rc *ResourceContainer, params UpdateAPIShieldOperationSchemaValidationSettings) (*UpdateAPIShieldOperationSchemaValidationSettings, 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 UpdateAPIShieldOperationSchemaValidationSettingsResponse
err = json.Unmarshal(res, &asResponse)
if err != nil {
return nil, fmt.Errorf("%s: %w", errUnmarshalError, err)
}

return &asResponse.Result, nil
}
87 changes: 87 additions & 0 deletions api_shield_schemas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -580,3 +580,90 @@ 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/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.UpdateAPIShieldOperationSchemaValidationSettings(
context.Background(),
ZoneIdentifier(testZoneID),
UpdateAPIShieldOperationSchemaValidationSettings{
testAPIShieldOperationId: APIShieldOperationSchemaValidationSettings{
MitigationAction: nil,
},
},
)

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

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