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

New API for Managed Headers #923

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
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -47,6 +47,7 @@ The current feature list includes:
- [x] Zone cache settings
- [x] Zone Lockdown and User-Agent Block rules
- [x] Zones
- [x] Managed Headers

Pull Requests are welcome, but please open an issue (or comment in an existing
issue) to discuss any non-trivial changes before submitting code.
Expand Down
81 changes: 81 additions & 0 deletions managed_headers.go
@@ -0,0 +1,81 @@
package cloudflare

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

"github.com/pkg/errors"
)

type ListManagedHeadersResponse struct {
Response
Result ManagedHeaders `json:"result"`
}

type UpdateManagedHeadersParams struct {
ZoneID string
ManagedHeaders
}

type ManagedHeaders struct {
ManagedRequestHeaders []ManagedHeader `json:"managed_request_headers"`
ManagedResponseHeaders []ManagedHeader `json:"managed_response_headers"`
}

type ManagedHeader struct {
ID string `json:"id"`
Enabled bool `json:"enabled"`
HasCoflict bool `json:"has_conflict,omitempty"`
ConflictsWith []string `json:"conflicts_with,omitempty"`
}

type ListManagedHeadersParams struct {
ZoneID string
}

func (api *API) ListZoneManagedHeaders(ctx context.Context, params ListManagedHeadersParams) (ManagedHeaders, error) {
if params.ZoneID == "" {
return ManagedHeaders{}, ErrMissingZoneID
}

uri := fmt.Sprintf("/zones/%s/managed_headers", params.ZoneID)

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

result := ListManagedHeadersResponse{}
if err := json.Unmarshal(res, &result); err != nil {
return ManagedHeaders{}, errors.Wrap(err, errUnmarshalError)
}

return result.Result, nil
}

func (api *API) UpdateZoneManagedHeaders(ctx context.Context, params UpdateManagedHeadersParams) (ManagedHeaders, error) {
if params.ZoneID == "" {
return ManagedHeaders{}, ErrMissingZoneID
}

uri := fmt.Sprintf("/zones/%s/managed_headers", params.ZoneID)

payload, err := json.Marshal(params.ManagedHeaders)
if err != nil {
return ManagedHeaders{}, err
}

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

result := ListManagedHeadersResponse{}
if err := json.Unmarshal(res, &result); err != nil {
return ManagedHeaders{}, errors.Wrap(err, errUnmarshalError)
}

return result.Result, nil
}
180 changes: 180 additions & 0 deletions managed_headers_test.go
@@ -0,0 +1,180 @@
package cloudflare

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

"github.com/stretchr/testify/assert"
)

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

handler := 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")
fmt.Fprint(w, `{
"result": {
"managed_request_headers": [
{
"id": "add_true_client_ip_headers",
"enabled": false,
"has_conflict": false,
"conflicts_with": ["remove_visitor_ip_headers"]
},
{
"id": "add_visitor_location_headers",
"enabled": true,
"has_conflict": false
}
],
"managed_response_headers": [
{
"id": "add_security_headers",
"enabled": false,
"has_conflict": false
},
{
"id": "remove_x-powered-by_header",
"enabled": true,
"has_conflict": false
}
]
},
"success": true,
"errors": [],
"messages": []
}`)
}
mux.HandleFunc("/zones/"+testZoneID+"/managed_headers", handler)

want := ManagedHeaders{
ManagedRequestHeaders: []ManagedHeader{
{
ID: "add_true_client_ip_headers",
Enabled: false,
HasCoflict: false,
ConflictsWith: []string{"remove_visitor_ip_headers"},
},
{
ID: "add_visitor_location_headers",
Enabled: true,
HasCoflict: false,
},
},
ManagedResponseHeaders: []ManagedHeader{
{
ID: "add_security_headers",
Enabled: false,
HasCoflict: false,
},
{
ID: "remove_x-powered-by_header",
Enabled: true,
HasCoflict: false,
},
},
}

zoneActual, err := client.ListZoneManagedHeaders(context.Background(), ListManagedHeadersParams{
ZoneID: testZoneID,
})
if assert.NoError(t, err) {
assert.Equal(t, want, zoneActual)
}
}

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

handler := func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodPatch, r.Method, "Expected method 'PATCH', got %s", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprint(w, `{
"result": {
"managed_request_headers": [
{
"id": "add_true_client_ip_headers",
"enabled": true,
"has_conflict": false,
"conflicts_with": ["remove_visitor_ip_headers"]
},
{
"id": "add_visitor_location_headers",
"enabled": true,
"has_conflict": false
}
],
"managed_response_headers": [
{
"id": "add_security_headers",
"enabled": false,
"has_conflict": false
},
{
"id": "remove_x-powered-by_header",
"enabled": false,
"has_conflict": false
}
]
},
"success": true,
"errors": [],
"messages": []
}`)
}

mux.HandleFunc("/zones/"+testZoneID+"/managed_headers", handler)
managedHeadersForUpdate := ManagedHeaders{
ManagedRequestHeaders: []ManagedHeader{
{
ID: "add_visitor_location_headers",
Enabled: true,
},
},
ManagedResponseHeaders: []ManagedHeader{
{
ID: "remove_x-powered-by_header",
Enabled: false,
},
},
}
want := ManagedHeaders{
ManagedRequestHeaders: []ManagedHeader{
{
ID: "add_true_client_ip_headers",
Enabled: true,
HasCoflict: false,
ConflictsWith: []string{"remove_visitor_ip_headers"},
},
{
ID: "add_visitor_location_headers",
Enabled: true,
HasCoflict: false,
},
},
ManagedResponseHeaders: []ManagedHeader{
{
ID: "add_security_headers",
Enabled: false,
HasCoflict: false,
},
{
ID: "remove_x-powered-by_header",
Enabled: false,
HasCoflict: false,
},
},
}
zoneActual, err := client.UpdateZoneManagedHeaders(context.Background(), UpdateManagedHeadersParams{
ZoneID: testZoneID,
ManagedHeaders: managedHeadersForUpdate,
})
if assert.NoError(t, err) {
assert.Equal(t, want, zoneActual)
}
}