Skip to content

Commit

Permalink
feat(url_scanner)!: move list method under scans (#3248)
Browse files Browse the repository at this point in the history
  • Loading branch information
stainless-app[bot] authored and stainless-bot committed Sep 25, 2024
1 parent e90044e commit e9deafb
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 279 deletions.
10 changes: 2 additions & 8 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5768,26 +5768,20 @@ Methods:

# URLScanner

Response Types:

- <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#URLScannerScanResponse">URLScannerScanResponse</a>

Methods:

- <code title="get /accounts/{accountId}/urlscanner/scan">client.URLScanner.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#URLScannerService.Scan">Scan</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, accountID <a href="https://pkg.go.dev/builtin#string">string</a>, query <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#URLScannerScanParams">URLScannerScanParams</a>) (<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#URLScannerScanResponse">URLScannerScanResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>

## Scans

Response Types:

- <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#URLScannerDomain">URLScannerDomain</a>
- <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanNewResponse">ScanNewResponse</a>
- <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanListResponse">ScanListResponse</a>
- <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanGetResponse">ScanGetResponse</a>
- <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanHarResponse">ScanHarResponse</a>

Methods:

- <code title="post /accounts/{accountId}/urlscanner/scan">client.URLScanner.Scans.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanService.New">New</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, accountID <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanNewParams">ScanNewParams</a>) (<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanNewResponse">ScanNewResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /accounts/{accountId}/urlscanner/scan">client.URLScanner.Scans.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanService.List">List</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, accountID <a href="https://pkg.go.dev/builtin#string">string</a>, query <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanListParams">ScanListParams</a>) (<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanListResponse">ScanListResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /accounts/{accountId}/urlscanner/scan/{scanId}">client.URLScanner.Scans.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanService.Get">Get</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, accountID <a href="https://pkg.go.dev/builtin#string">string</a>, scanID <a href="https://pkg.go.dev/builtin#string">string</a>, query <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanGetParams">ScanGetParams</a>) (<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanGetResponse">ScanGetResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /accounts/{accountId}/urlscanner/scan/{scanId}/har">client.URLScanner.Scans.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanService.Har">Har</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, accountID <a href="https://pkg.go.dev/builtin#string">string</a>, scanID <a href="https://pkg.go.dev/builtin#string">string</a>) (<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanHarResponse">ScanHarResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /accounts/{accountId}/urlscanner/scan/{scanId}/screenshot">client.URLScanner.Scans.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanService.Screenshot">Screenshot</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, accountID <a href="https://pkg.go.dev/builtin#string">string</a>, scanID <a href="https://pkg.go.dev/builtin#string">string</a>, query <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner">url_scanner</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/url_scanner#ScanScreenshotParams">ScanScreenshotParams</a>) (http.Response, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
Expand Down
198 changes: 198 additions & 0 deletions url_scanner/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,28 @@ func (r *ScanService) New(ctx context.Context, accountID string, body ScanNewPar
return
}

// Search scans by date and webpages' requests, including full URL (after
// redirects), hostname, and path. <br/> A successful scan will appear in search
// results a few minutes after finishing but may take much longer if the system in
// under load. By default, only successfully completed scans will appear in search
// results, unless searching by `scanId`. Please take into account that older scans
// may be removed from the search index at an unspecified time.
func (r *ScanService) List(ctx context.Context, accountID string, query ScanListParams, opts ...option.RequestOption) (res *ScanListResponse, err error) {
var env ScanListResponseEnvelope
opts = append(r.Options[:], opts...)
if accountID == "" {
err = errors.New("missing required accountId parameter")
return
}
path := fmt.Sprintf("accounts/%s/urlscanner/scan", accountID)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &env, opts...)
if err != nil {
return
}
res = &env.Result
return
}

// Get URL scan by uuid
func (r *ScanService) Get(ctx context.Context, accountID string, scanID string, query ScanGetParams, opts ...option.RequestOption) (res *ScanGetResponse, err error) {
var env ScanGetResponseEnvelope
Expand Down Expand Up @@ -170,6 +192,64 @@ func (r scanNewResponseJSON) RawJSON() string {
return r.raw
}

type ScanListResponse struct {
Tasks []ScanListResponseTask `json:"tasks,required"`
JSON scanListResponseJSON `json:"-"`
}

// scanListResponseJSON contains the JSON metadata for the struct
// [ScanListResponse]
type scanListResponseJSON struct {
Tasks apijson.Field
raw string
ExtraFields map[string]apijson.Field
}

func (r *ScanListResponse) UnmarshalJSON(data []byte) (err error) {
return apijson.UnmarshalRoot(data, r)
}

func (r scanListResponseJSON) RawJSON() string {
return r.raw
}

type ScanListResponseTask struct {
// Alpha-2 country code
Country string `json:"country,required"`
// Whether scan was successful or not
Success bool `json:"success,required"`
// When scan was submitted (UTC)
Time time.Time `json:"time,required" format:"date-time"`
// Scan url (after redirects)
URL string `json:"url,required"`
// Scan id
UUID string `json:"uuid,required" format:"uuid"`
// Visibility status.
Visibility string `json:"visibility,required"`
JSON scanListResponseTaskJSON `json:"-"`
}

// scanListResponseTaskJSON contains the JSON metadata for the struct
// [ScanListResponseTask]
type scanListResponseTaskJSON struct {
Country apijson.Field
Success apijson.Field
Time apijson.Field
URL apijson.Field
UUID apijson.Field
Visibility apijson.Field
raw string
ExtraFields map[string]apijson.Field
}

func (r *ScanListResponseTask) UnmarshalJSON(data []byte) (err error) {
return apijson.UnmarshalRoot(data, r)
}

func (r scanListResponseTaskJSON) RawJSON() string {
return r.raw
}

type ScanGetResponse struct {
Scan ScanGetResponseScan `json:"scan,required"`
JSON scanGetResponseJSON `json:"-"`
Expand Down Expand Up @@ -1815,6 +1895,124 @@ func (r scanNewResponseEnvelopeMessagesJSON) RawJSON() string {
return r.raw
}

type ScanListParams struct {
// Return only scans created by account.
AccountScans param.Field[bool] `query:"account_scans"`
// Filter scans by Autonomous System Number (ASN) of _any_ request made by the
// webpage.
ASN param.Field[string] `query:"asn"`
// Filter scans requested before date (inclusive).
DateEnd param.Field[time.Time] `query:"date_end" format:"date-time"`
// Filter scans requested after date (inclusive).
DateStart param.Field[time.Time] `query:"date_start" format:"date-time"`
// Filter scans by hash of any html/js/css request made by the webpage.
Hash param.Field[string] `query:"hash"`
// Filter scans by hostname of _any_ request made by the webpage.
Hostname param.Field[string] `query:"hostname"`
// Filter scans by IP address (IPv4 or IPv6) of _any_ request made by the webpage.
IP param.Field[string] `query:"ip"`
// Filter scans by malicious verdict.
IsMalicious param.Field[bool] `query:"is_malicious"`
// Limit the number of objects in the response.
Limit param.Field[int64] `query:"limit"`
// Pagination cursor to get the next set of results.
NextCursor param.Field[string] `query:"next_cursor"`
// Filter scans by main page Autonomous System Number (ASN).
PageASN param.Field[string] `query:"page_asn"`
// Filter scans by main page hostname (domain of effective URL).
PageHostname param.Field[string] `query:"page_hostname"`
// Filter scans by main page IP address (IPv4 or IPv6).
PageIP param.Field[string] `query:"page_ip"`
// Filter scans by exact match of effective URL path (also supports suffix search).
PagePath param.Field[string] `query:"page_path"`
// Filter scans by submitted or scanned URL
PageURL param.Field[string] `query:"page_url"`
// Filter scans by url path of _any_ request made by the webpage.
Path param.Field[string] `query:"path"`
// Scan uuid
ScanID param.Field[string] `query:"scanId" format:"uuid"`
// Filter scans by URL of _any_ request made by the webpage
URL param.Field[string] `query:"url"`
}

// URLQuery serializes [ScanListParams]'s query parameters as `url.Values`.
func (r ScanListParams) URLQuery() (v url.Values) {
return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{
ArrayFormat: apiquery.ArrayQueryFormatRepeat,
NestedFormat: apiquery.NestedQueryFormatDots,
})
}

type ScanListResponseEnvelope struct {
Errors []ScanListResponseEnvelopeErrors `json:"errors,required"`
Messages []ScanListResponseEnvelopeMessages `json:"messages,required"`
Result ScanListResponse `json:"result,required"`
// Whether search request was successful or not
Success bool `json:"success,required"`
JSON scanListResponseEnvelopeJSON `json:"-"`
}

// scanListResponseEnvelopeJSON contains the JSON metadata for the struct
// [ScanListResponseEnvelope]
type scanListResponseEnvelopeJSON struct {
Errors apijson.Field
Messages apijson.Field
Result apijson.Field
Success apijson.Field
raw string
ExtraFields map[string]apijson.Field
}

func (r *ScanListResponseEnvelope) UnmarshalJSON(data []byte) (err error) {
return apijson.UnmarshalRoot(data, r)
}

func (r scanListResponseEnvelopeJSON) RawJSON() string {
return r.raw
}

type ScanListResponseEnvelopeErrors struct {
Message string `json:"message,required"`
JSON scanListResponseEnvelopeErrorsJSON `json:"-"`
}

// scanListResponseEnvelopeErrorsJSON contains the JSON metadata for the struct
// [ScanListResponseEnvelopeErrors]
type scanListResponseEnvelopeErrorsJSON struct {
Message apijson.Field
raw string
ExtraFields map[string]apijson.Field
}

func (r *ScanListResponseEnvelopeErrors) UnmarshalJSON(data []byte) (err error) {
return apijson.UnmarshalRoot(data, r)
}

func (r scanListResponseEnvelopeErrorsJSON) RawJSON() string {
return r.raw
}

type ScanListResponseEnvelopeMessages struct {
Message string `json:"message,required"`
JSON scanListResponseEnvelopeMessagesJSON `json:"-"`
}

// scanListResponseEnvelopeMessagesJSON contains the JSON metadata for the struct
// [ScanListResponseEnvelopeMessages]
type scanListResponseEnvelopeMessagesJSON struct {
Message apijson.Field
raw string
ExtraFields map[string]apijson.Field
}

func (r *ScanListResponseEnvelopeMessages) UnmarshalJSON(data []byte) (err error) {
return apijson.UnmarshalRoot(data, r)
}

func (r scanListResponseEnvelopeMessagesJSON) RawJSON() string {
return r.raw
}

type ScanGetParams struct {
// Whether to return full report (scan summary and network log).
Full param.Field[bool] `query:"full"`
Expand Down
47 changes: 47 additions & 0 deletions url_scanner/scan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/http/httptest"
"os"
"testing"
"time"

"github.com/cloudflare/cloudflare-go/v3"
"github.com/cloudflare/cloudflare-go/v3/internal/testutil"
Expand Down Expand Up @@ -52,6 +53,52 @@ func TestScanNewWithOptionalParams(t *testing.T) {
}
}

func TestScanListWithOptionalParams(t *testing.T) {
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
}
if !testutil.CheckTestServer(t, baseURL) {
return
}
client := cloudflare.NewClient(
option.WithBaseURL(baseURL),
option.WithAPIKey("144c9defac04969c7bfad8efaa8ea194"),
option.WithAPIEmail("user@example.com"),
)
_, err := client.URLScanner.Scans.List(
context.TODO(),
"accountId",
url_scanner.ScanListParams{
AccountScans: cloudflare.F(true),
ASN: cloudflare.F("13335"),
DateEnd: cloudflare.F(time.Now()),
DateStart: cloudflare.F(time.Now()),
Hash: cloudflare.F("hash"),
Hostname: cloudflare.F("example.com"),
IP: cloudflare.F("1.1.1.1"),
IsMalicious: cloudflare.F(true),
Limit: cloudflare.F(int64(100)),
NextCursor: cloudflare.F("next_cursor"),
PageASN: cloudflare.F("page_asn"),
PageHostname: cloudflare.F("page_hostname"),
PageIP: cloudflare.F("page_ip"),
PagePath: cloudflare.F("page_path"),
PageURL: cloudflare.F("page_url"),
Path: cloudflare.F("/samples/subresource-integrity/"),
ScanID: cloudflare.F("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"),
URL: cloudflare.F("https://example.com/?hello"),
},
)
if err != nil {
var apierr *cloudflare.Error
if errors.As(err, &apierr) {
t.Log(string(apierr.DumpRequest(true)))
}
t.Fatalf("err should be nil: %s", err.Error())
}
}

func TestScanGetWithOptionalParams(t *testing.T) {
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
Expand Down
Loading

0 comments on commit e9deafb

Please sign in to comment.