Repository: cloudflare/cloudflare-go
Pull request #982 (2022-07-09 17:01:39)

Add miscategorization API
Adds support for the miscategorization API

https://api.cloudflare.com/#miscategorization-create-miscategorization

## Has your change been tested?

Unit tests created and passed for all new endpoints.

## Types of changes

What sort of change does your code introduce/modify?

- [ ] Bug fix (non-breaking change which fixes an issue)
- [X] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:

- [X] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [X] I have added tests to cover my changes.
- [X] All new and existing tests passed.
- [X] This change is using publicly documented (api.cloudflare.com or developers.cloudflare.com) and stable APIs.





Patch:
diff --git a/miscategorization.go b/miscategorization.go
new file mode 100644
index 000000000..5164c530d
--- /dev/null
+++ b/miscategorization.go
@@ -0,0 +1,50 @@
+package cloudflare
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"net/http"
+)
+
+var (
+	// ErrMissingIP is for when ipv4 or ipv6 indicator was given but ip is missing.
+	ErrMissingIP = errors.New("ip is required when using 'ipv4' or 'ipv6' indicator type and is missing")
+	// ErrMissingURL is for when url or domain indicator was given but url is missing.
+	ErrMissingURL = errors.New("url is required when using 'domain' or 'url' indicator type and is missing")
+)
+
+// MisCategorizationParameters represents the parameters for a miscategorization request.
+type MisCategorizationParameters struct {
+	AccountID       string
+	IndicatorType   string `json:"indicator_type,omitempty"`
+	IP              string `json:"ip,omitempty"`
+	URL             string `json:"url,omitempty"`
+	ContentAdds     []int  `json:"content_adds,omitempty"`
+	ContentRemoves  []int  `json:"content_removes,omitempty"`
+	SecurityAdds    []int  `json:"security_adds,omitempty"`
+	SecurityRemoves []int  `json:"security_removes,omitempty"`
+}
+
+// CreateMiscategorization creates a miscatergorization.
+//
+// API Reference: https://api.cloudflare.com/#miscategorization-create-miscategorization
+func (api *API) CreateMiscategorization(ctx context.Context, params MisCategorizationParameters) error {
+	if params.AccountID == "" {
+		return ErrMissingAccountID
+	}
+	if (params.IndicatorType == "ipv6" || params.IndicatorType == "ipv4") && params.IP == "" {
+		return ErrMissingIP
+	}
+	if (params.IndicatorType == "domain" || params.IndicatorType == "url") && params.URL == "" {
+		return ErrMissingURL
+	}
+
+	uri := fmt.Sprintf("/accounts/%s/intel/miscategorization", params.AccountID)
+	_, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}


Test patch:
diff --git a/miscategorization_test.go b/miscategorization_test.go
new file mode 100644
index 000000000..bf4928f0f
--- /dev/null
+++ b/miscategorization_test.go
@@ -0,0 +1,61 @@
+package cloudflare
+
+import (
+	"context"
+	"fmt"
+	"github.com/stretchr/testify/assert"
+	"net/http"
+	"testing"
+)
+
+func TestCreateMiscategorization(t *testing.T) {
+	setup()
+	defer teardown()
+
+	mux.HandleFunc(fmt.Sprintf("/accounts/%s/intel/miscategorization", testAccountID), func(w http.ResponseWriter, r *http.Request) {
+		assert.Equal(t, http.MethodPost, r.Method, "Expected method 'POST', got %s", r.Method)
+		w.Header().Set("content-type", "application/json")
+		fmt.Fprintf(w, `{
+  "success": true,
+  "errors": [],
+  "messages": []
+}`)
+	})
+	ctx := context.Background()
+	err := client.CreateMiscategorization(ctx, MisCategorizationParameters{})
+	if assert.Error(t, err) {
+		assert.Equal(t, ErrMissingAccountID, err)
+	}
+
+	err = client.CreateMiscategorization(ctx, MisCategorizationParameters{AccountID: testAccountID, IndicatorType: "ipv4"})
+	if assert.Error(t, err) {
+		assert.Equal(t, ErrMissingIP, err)
+	}
+
+	err = client.CreateMiscategorization(ctx, MisCategorizationParameters{AccountID: testAccountID, IndicatorType: "ipv6"})
+	if assert.Error(t, err) {
+		assert.Equal(t, ErrMissingIP, err)
+	}
+
+	err = client.CreateMiscategorization(ctx, MisCategorizationParameters{AccountID: testAccountID, IndicatorType: "url"})
+	if assert.Error(t, err) {
+		assert.Equal(t, ErrMissingURL, err)
+	}
+
+	err = client.CreateMiscategorization(ctx, MisCategorizationParameters{AccountID: testAccountID, IndicatorType: "domain"})
+	if assert.Error(t, err) {
+		assert.Equal(t, ErrMissingURL, err)
+	}
+
+	err = client.CreateMiscategorization(ctx, MisCategorizationParameters{AccountID: testAccountID, IndicatorType: "ipv4", IP: "192.0.2.0"})
+	assert.NoError(t, err, "Got error for creating miscategorization for ipv4")
+
+	err = client.CreateMiscategorization(ctx, MisCategorizationParameters{AccountID: testAccountID, IndicatorType: "ipv6", IP: "2400:cb00::/32"})
+	assert.NoError(t, err, "Got error for creating miscategorization for ipv6")
+
+	err = client.CreateMiscategorization(ctx, MisCategorizationParameters{AccountID: testAccountID, IndicatorType: "domain", URL: "example.com"})
+	assert.NoError(t, err, "Got error for creating miscategorization for domain")
+
+	err = client.CreateMiscategorization(ctx, MisCategorizationParameters{AccountID: testAccountID, IndicatorType: "url", URL: "https://example.com/news/"})
+	assert.NoError(t, err, "Got error for creating miscategorization for url")
+}