Skip to content

Commit

Permalink
Merge pull request #1459 from wiremanb/page_shield
Browse files Browse the repository at this point in the history
Adding Page Shield support
  • Loading branch information
jacobbednarz committed Dec 7, 2023
2 parents 569dfef + 71a7e82 commit 1dd0bb9
Show file tree
Hide file tree
Showing 9 changed files with 810 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/1459.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
page_shield: added support for page shield
```
76 changes: 76 additions & 0 deletions page_shield.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package cloudflare

import (
"context"
"fmt"
"net/http"

"github.com/goccy/go-json"
)

// PageShield represents the page shield object minus any timestamps.
type PageShield struct {
Enabled *bool `json:"enabled,omitempty"`
UseCloudflareReportingEndpoint *bool `json:"use_cloudflare_reporting_endpoint,omitempty"`
UseConnectionURLPath *bool `json:"use_connection_url_path,omitempty"`
}

type UpdatePageShieldSettingsParams struct {
Enabled *bool `json:"enabled,omitempty"`
UseCloudflareReportingEndpoint *bool `json:"use_cloudflare_reporting_endpoint,omitempty"`
UseConnectionURLPath *bool `json:"use_connection_url_path,omitempty"`
}

// PageShieldSettings represents the page shield settings for a zone.
type PageShieldSettings struct {
PageShield
UpdatedAt string `json:"updated_at"`
}

// PageShieldSettingsResponse represents the response from the page shield settings endpoint.
type PageShieldSettingsResponse struct {
PageShield PageShieldSettings `json:"result"`
Response
}

type GetPageShieldSettingsParams struct{}

// GetPageShieldSettings returns the page shield settings for a zone.
//
// API documentation: https://developers.cloudflare.com/api/operations/page-shield-get-page-shield-settings
func (api *API) GetPageShieldSettings(ctx context.Context, rc *ResourceContainer, params GetPageShieldSettingsParams) (*PageShieldSettingsResponse, error) {
uri := fmt.Sprintf("/zones/%s/page_shield", rc.Identifier)

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

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

return &psResponse, nil
}

// UpdatePageShieldSettings updates the page shield settings for a zone.
//
// API documentation: https://developers.cloudflare.com/api/operations/page-shield-update-page-shield-settings
func (api *API) UpdatePageShieldSettings(ctx context.Context, rc *ResourceContainer, params UpdatePageShieldSettingsParams) (*PageShieldSettingsResponse, error) {
uri := fmt.Sprintf("/zones/%s/page_shield", rc.Identifier)

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

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

return &psResponse, nil
}
88 changes: 88 additions & 0 deletions page_shield_connections.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package cloudflare

import (
"context"
"fmt"
"net/http"

"github.com/goccy/go-json"
)

// ListPageShieldConnectionsParams represents parameters for a page shield connection request.
type ListPageShieldConnectionsParams struct {
Direction string `url:"direction"`
ExcludeCdnCgi *bool `url:"exclude_cdn_cgi,omitempty"`
ExcludeUrls string `url:"exclude_urls"`
Export string `url:"export"`
Hosts string `url:"hosts"`
OrderBy string `url:"order_by"`
Page string `url:"page"`
PageURL string `url:"page_url"`
PerPage int `url:"per_page"`
PrioritizeMalicious *bool `url:"prioritize_malicious,omitempty"`
Status string `url:"status"`
URLs string `url:"urls"`
}

// PageShieldConnection represents a page shield connection.
type PageShieldConnection struct {
AddedAt string `json:"added_at"`
DomainReportedMalicious *bool `json:"domain_reported_malicious,omitempty"`
FirstPageURL string `json:"first_page_url"`
FirstSeenAt string `json:"first_seen_at"`
Host string `json:"host"`
ID string `json:"id"`
LastSeenAt string `json:"last_seen_at"`
PageURLs []string `json:"page_urls"`
URL string `json:"url"`
URLContainsCdnCgiPath *bool `json:"url_contains_cdn_cgi_path,omitempty"`
}

// ListPageShieldConnectionsResponse represents the response from the list page shield connections endpoint.
type ListPageShieldConnectionsResponse struct {
Result []PageShieldConnection `json:"result"`
Response
ResultInfo `json:"result_info"`
}

// ListPageShieldConnections lists all page shield connections for a zone.
//
// API documentation: https://developers.cloudflare.com/api/operations/page-shield-list-page-shield-connections
func (api *API) ListPageShieldConnections(ctx context.Context, rc *ResourceContainer, params ListPageShieldConnectionsParams) ([]PageShieldConnection, ResultInfo, error) {
path := fmt.Sprintf("/zones/%s/page_shield/connections", rc.Identifier)

uri := buildURI(path, params)

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

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

return psResponse.Result, psResponse.ResultInfo, nil
}

// GetPageShieldConnection gets a page shield connection for a zone.
//
// API documentation: https://developers.cloudflare.com/api/operations/page-shield-get-a-page-shield-connection
func (api *API) GetPageShieldConnection(ctx context.Context, rc *ResourceContainer, connectionID string) (*PageShieldConnection, error) {
path := fmt.Sprintf("/zones/%s/page_shield/connections/%s", rc.Identifier, connectionID)

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

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

return &psResponse, nil
}
90 changes: 90 additions & 0 deletions page_shield_connections_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package cloudflare

import (
"context"
"fmt"
"net/http"
"testing"

"github.com/goccy/go-json"
"github.com/stretchr/testify/assert"
)

// Mock data for PageShieldConnections.
var mockPageShieldConnections = []PageShieldConnection{
{
AddedAt: "2021-08-18T10:51:10.09615Z",
DomainReportedMalicious: BoolPtr(false),
FirstPageURL: "blog.cloudflare.com/page",
FirstSeenAt: "2021-08-18T10:51:08Z",
Host: "blog.cloudflare.com",
ID: "c9ef84a6bf5e47138c75d95e2f933e8f",
LastSeenAt: "2021-09-02T09:57:54Z",
PageURLs: []string{"blog.cloudflare.com/page1", "blog.cloudflare.com/page2"},
URL: "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/js/bootstrap.min.js",
URLContainsCdnCgiPath: BoolPtr(false),
},
{
AddedAt: "2021-09-18T10:51:10.09615Z",
DomainReportedMalicious: BoolPtr(false),
FirstPageURL: "blog.cloudflare.com/page02",
FirstSeenAt: "2021-08-18T10:51:08Z",
Host: "blog.cloudflare.com",
ID: "c9ef84a6bf5e47138c75d95e2f933e8f",
LastSeenAt: "2021-09-02T09:57:54Z",
PageURLs: []string{"blog.cloudflare.com/page1", "blog.cloudflare.com/page2"},
URL: "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/js/bootstrap.min.js",
URLContainsCdnCgiPath: BoolPtr(false),
},
{
AddedAt: "2021-10-18T10:51:10.09615Z",
DomainReportedMalicious: BoolPtr(false),
FirstPageURL: "blog.cloudflare.com/page03",
FirstSeenAt: "2021-08-18T10:51:08Z",
Host: "blog.cloudflare.com",
ID: "c9ef84a6bf5e47138c75d95e2f933e8f",
LastSeenAt: "2021-09-02T09:57:54Z",
PageURLs: []string{"blog.cloudflare.com/page1", "blog.cloudflare.com/page2"},
URL: "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/js/bootstrap.min.js",
URLContainsCdnCgiPath: BoolPtr(false),
},
}

func TestListPageShieldConnections(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/zones/"+testZoneID+"/page_shield/connections", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
w.Header().Set("content-type", "application/json")
response := ListPageShieldConnectionsResponse{
Result: mockPageShieldConnections,
}
err := json.NewEncoder(w).Encode(response)
if err != nil {
t.Fatal(err)
}
})
result, _, err := client.ListPageShieldConnections(context.Background(), ZoneIdentifier(testZoneID), ListPageShieldConnectionsParams{})
assert.NoError(t, err)
assert.Equal(t, mockPageShieldConnections, result)
}

func TestGetPageShieldConnection(t *testing.T) {
setup()
defer teardown()

connectionID := "c9ef84a6bf5e47138c75d95e2f933e8f" //nolint
mux.HandleFunc(fmt.Sprintf("/zones/"+testZoneID+"/page_shield/connections/%s", connectionID), func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
w.Header().Set("content-type", "application/json")
response := mockPageShieldConnections[0] // Assuming it's the first mock connection
err := json.NewEncoder(w).Encode(response)
if err != nil {
t.Fatal(err)
}
})
result, err := client.GetPageShieldConnection(context.Background(), ZoneIdentifier(testZoneID), connectionID)
assert.NoError(t, err)
assert.Equal(t, &mockPageShieldConnections[0], result)
}

0 comments on commit 1dd0bb9

Please sign in to comment.