Skip to content

Commit 68aa203

Browse files
xafpatryk
authored andcommitted
waf: read all pages for ListWAFRules, ListWtWAFGroups and ListWAFPackages (#389)
1 parent 7caa8e4 commit 68aa203

File tree

2 files changed

+374
-55
lines changed

2 files changed

+374
-55
lines changed

waf.go

Lines changed: 108 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package cloudflare
22

33
import (
44
"encoding/json"
5+
"net/url"
6+
"strconv"
57

68
"github.com/pkg/errors"
79
)
@@ -101,26 +103,46 @@ type WAFRuleOptions struct {
101103
//
102104
// API Reference: https://api.cloudflare.com/#waf-rule-packages-list-firewall-packages
103105
func (api *API) ListWAFPackages(zoneID string) ([]WAFPackage, error) {
104-
var p WAFPackagesResponse
106+
// Construct a query string
107+
v := url.Values{}
108+
// Request as many WAF packages as possible per page - API max is 100
109+
v.Set("per_page", "100")
110+
105111
var packages []WAFPackage
106112
var res []byte
107113
var err error
108-
uri := "/zones/" + zoneID + "/firewall/waf/packages"
109-
res, err = api.makeRequest("GET", uri, nil)
110-
if err != nil {
111-
return []WAFPackage{}, errors.Wrap(err, errMakeRequestError)
112-
}
113-
err = json.Unmarshal(res, &p)
114-
if err != nil {
115-
return []WAFPackage{}, errors.Wrap(err, errUnmarshalError)
116-
}
117-
if !p.Success {
118-
// TODO: Provide an actual error message instead of always returning nil
119-
return []WAFPackage{}, err
120-
}
121-
for pi := range p.Result {
122-
packages = append(packages, p.Result[pi])
114+
page := 1
115+
116+
// Loop over makeRequest until what we've fetched all records
117+
for {
118+
v.Set("page", strconv.Itoa(page))
119+
query := "?" + v.Encode()
120+
uri := "/zones/" + zoneID + "/firewall/waf/packages" + query
121+
res, err = api.makeRequest("GET", uri, nil)
122+
if err != nil {
123+
return []WAFPackage{}, errors.Wrap(err, errMakeRequestError)
124+
}
125+
126+
var p WAFPackagesResponse
127+
err = json.Unmarshal(res, &p)
128+
if err != nil {
129+
return []WAFPackage{}, errors.Wrap(err, errUnmarshalError)
130+
}
131+
132+
if !p.Success {
133+
// TODO: Provide an actual error message instead of always returning nil
134+
return []WAFPackage{}, err
135+
}
136+
137+
packages = append(packages, p.Result...)
138+
if p.ResultInfo.Page >= p.ResultInfo.TotalPages {
139+
break
140+
}
141+
142+
// Loop around and fetch the next page
143+
page++
123144
}
145+
124146
return packages, nil
125147
}
126148

@@ -165,29 +187,44 @@ func (api *API) UpdateWAFPackage(zoneID, packageID string, opts WAFPackageOption
165187
//
166188
// API Reference: https://api.cloudflare.com/#waf-rule-groups-list-rule-groups
167189
func (api *API) ListWAFGroups(zoneID, packageID string) ([]WAFGroup, error) {
190+
// Construct a query string
191+
v := url.Values{}
192+
// Request as many WAF groups as possible per page - API max is 100
193+
v.Set("per_page", "100")
194+
168195
var groups []WAFGroup
169196
var res []byte
170197
var err error
171-
172-
uri := "/zones/" + zoneID + "/firewall/waf/packages/" + packageID + "/groups"
173-
res, err = api.makeRequest("GET", uri, nil)
174-
if err != nil {
175-
return []WAFGroup{}, errors.Wrap(err, errMakeRequestError)
176-
}
177-
178-
var r WAFGroupsResponse
179-
err = json.Unmarshal(res, &r)
180-
if err != nil {
181-
return []WAFGroup{}, errors.Wrap(err, errUnmarshalError)
182-
}
183-
184-
if !r.Success {
185-
// TODO: Provide an actual error message instead of always returning nil
186-
return []WAFGroup{}, err
187-
}
188-
189-
for gi := range r.Result {
190-
groups = append(groups, r.Result[gi])
198+
page := 1
199+
200+
// Loop over makeRequest until what we've fetched all records
201+
for {
202+
v.Set("page", strconv.Itoa(page))
203+
query := "?" + v.Encode()
204+
uri := "/zones/" + zoneID + "/firewall/waf/packages/" + packageID + "/groups" + query
205+
res, err = api.makeRequest("GET", uri, nil)
206+
if err != nil {
207+
return []WAFGroup{}, errors.Wrap(err, errMakeRequestError)
208+
}
209+
210+
var r WAFGroupsResponse
211+
err = json.Unmarshal(res, &r)
212+
if err != nil {
213+
return []WAFGroup{}, errors.Wrap(err, errUnmarshalError)
214+
}
215+
216+
if !r.Success {
217+
// TODO: Provide an actual error message instead of always returning nil
218+
return []WAFGroup{}, err
219+
}
220+
221+
groups = append(groups, r.Result...)
222+
if r.ResultInfo.Page >= r.ResultInfo.TotalPages {
223+
break
224+
}
225+
226+
// Loop around and fetch the next page
227+
page++
191228
}
192229
return groups, nil
193230
}
@@ -234,30 +271,46 @@ func (api *API) UpdateWAFGroup(zoneID, packageID, groupID, mode string) (WAFGrou
234271
//
235272
// API Reference: https://api.cloudflare.com/#waf-rules-list-rules
236273
func (api *API) ListWAFRules(zoneID, packageID string) ([]WAFRule, error) {
274+
// Construct a query string
275+
v := url.Values{}
276+
// Request as many WAF rules as possible per page - API max is 100
277+
v.Set("per_page", "100")
278+
237279
var rules []WAFRule
238280
var res []byte
239281
var err error
240-
241-
uri := "/zones/" + zoneID + "/firewall/waf/packages/" + packageID + "/rules"
242-
res, err = api.makeRequest("GET", uri, nil)
243-
if err != nil {
244-
return []WAFRule{}, errors.Wrap(err, errMakeRequestError)
282+
page := 1
283+
284+
// Loop over makeRequest until what we've fetched all records
285+
for {
286+
v.Set("page", strconv.Itoa(page))
287+
query := "?" + v.Encode()
288+
uri := "/zones/" + zoneID + "/firewall/waf/packages/" + packageID + "/rules" + query
289+
res, err = api.makeRequest("GET", uri, nil)
290+
if err != nil {
291+
return []WAFRule{}, errors.Wrap(err, errMakeRequestError)
292+
}
293+
294+
var r WAFRulesResponse
295+
err = json.Unmarshal(res, &r)
296+
if err != nil {
297+
return []WAFRule{}, errors.Wrap(err, errUnmarshalError)
298+
}
299+
300+
if !r.Success {
301+
// TODO: Provide an actual error message instead of always returning nil
302+
return []WAFRule{}, err
303+
}
304+
305+
rules = append(rules, r.Result...)
306+
if r.ResultInfo.Page >= r.ResultInfo.TotalPages {
307+
break
308+
}
309+
310+
// Loop around and fetch the next page
311+
page++
245312
}
246313

247-
var r WAFRulesResponse
248-
err = json.Unmarshal(res, &r)
249-
if err != nil {
250-
return []WAFRule{}, errors.Wrap(err, errUnmarshalError)
251-
}
252-
253-
if !r.Success {
254-
// TODO: Provide an actual error message instead of always returning nil
255-
return []WAFRule{}, err
256-
}
257-
258-
for ri := range r.Result {
259-
rules = append(rules, r.Result[ri])
260-
}
261314
return rules, nil
262315
}
263316

0 commit comments

Comments
 (0)