diff --git a/v2/internal/runner/cloud.go b/v2/internal/runner/cloud.go index f01cfe12..023867f9 100644 --- a/v2/internal/runner/cloud.go +++ b/v2/internal/runner/cloud.go @@ -4,6 +4,7 @@ import ( "io" "io/fs" "os" + "path" "path/filepath" "strconv" "strings" @@ -141,14 +142,20 @@ func (r *Runner) prettyPrintTable(header []string, values [][]string) { } func (r *Runner) deleteScan(id string) error { - ID, _ := strconv.ParseInt(id, 10, 64) + ID, parseErr := strconv.ParseInt(id, 10, 64) + if parseErr != nil { + return errors.Wrap(parseErr, "could not parse scan id") + } deleted, err := r.cloudClient.DeleteScan(ID) + if err != nil { + return errors.Wrap(err, "could not delete scan") + } if !deleted.OK { gologger.Error().Msgf("Error in deleting the scan %s.", id) } else { gologger.Info().Msgf("Scan deleted %s.", id) } - return err + return nil } func (r *Runner) getResults(id string, limit int) error { @@ -162,8 +169,13 @@ func (r *Runner) getResults(id string, limit int) error { } func (r *Runner) getTarget(id string) error { - ID, _ := strconv.ParseInt(id, 10, 64) - reader, err := r.cloudClient.GetTarget(ID) + var name string + ID, parseErr := strconv.ParseInt(id, 10, 64) + if parseErr != nil { + name = id + } + + reader, err := r.cloudClient.GetTarget(ID, name) if err != nil { return errors.Wrap(err, "could not get target") } @@ -174,8 +186,13 @@ func (r *Runner) getTarget(id string) error { } func (r *Runner) getTemplate(id string) error { - ID, _ := strconv.ParseInt(id, 10, 64) - reader, err := r.cloudClient.GetTemplate(ID) + var name string + ID, parseErr := strconv.ParseInt(id, 10, 64) + if parseErr != nil { + name = id + } + + reader, err := r.cloudClient.GetTemplate(ID, name) if err != nil { return errors.Wrap(err, "could not get template") } @@ -240,12 +257,29 @@ func (r *Runner) addTarget(location string) error { } func (r *Runner) removeTarget(item string) error { + var err error + if ID, parseErr := strconv.ParseInt(item, 10, 64); parseErr == nil { + err = r.cloudClient.RemoveTarget(ID, "") + } else if strings.EqualFold(path.Ext(item), ".txt") { + err = r.cloudClient.RemoveTarget(0, item) + } else { + return r.removeTargetPrefix(item) + } + if err != nil { + gologger.Error().Msgf("Error in deleting target %s: %s", item, err) + } else { + gologger.Info().Msgf("Target deleted %s", item) + } + return nil +} + +func (r *Runner) removeTargetPrefix(item string) error { response, err := r.cloudClient.ListTargets(item) if err != nil { return errors.Wrap(err, "could not list targets") } for _, item := range response { - if err := r.cloudClient.RemoveTarget(item.ID); err != nil { + if err := r.cloudClient.RemoveTarget(item.ID, ""); err != nil { gologger.Error().Msgf("Error in deleting target %s: %s", item.Reference, err) } else { gologger.Info().Msgf("Target deleted %s", item.Reference) @@ -255,12 +289,29 @@ func (r *Runner) removeTarget(item string) error { } func (r *Runner) removeTemplate(item string) error { + var err error + if ID, parseErr := strconv.ParseInt(item, 10, 64); parseErr == nil { + err = r.cloudClient.RemoveTemplate(ID, "") + } else if strings.EqualFold(path.Ext(item), ".yaml") { + err = r.cloudClient.RemoveTemplate(0, item) + } else { + return r.removeTemplatePrefix(item) + } + if err != nil { + gologger.Error().Msgf("Error in deleting template %s: %s", item, err) + } else { + gologger.Info().Msgf("Template deleted %s", item) + } + return nil +} + +func (r *Runner) removeTemplatePrefix(item string) error { response, err := r.cloudClient.ListTemplates(item) if err != nil { return errors.Wrap(err, "could not list templates") } for _, item := range response { - if err := r.cloudClient.RemoveTemplate(item.ID); err != nil { + if err := r.cloudClient.RemoveTemplate(item.ID, ""); err != nil { gologger.Error().Msgf("Error in deleting template %s: %s", item.Reference, err) } else { gologger.Info().Msgf("Template deleted %s", item.Reference) diff --git a/v2/internal/runner/nucleicloud/cloud.go b/v2/internal/runner/nucleicloud/cloud.go index 7a6b7a03..1876110b 100644 --- a/v2/internal/runner/nucleicloud/cloud.go +++ b/v2/internal/runner/nucleicloud/cloud.go @@ -420,8 +420,19 @@ func (c *Client) AddTarget(name, contents string) (string, error) { return item.Ok, nil } -func (c *Client) RemoveTemplate(ID int64) error { - httpReq, err := retryablehttp.NewRequest(http.MethodDelete, fmt.Sprintf("%s/templates/%d", c.baseURL, ID), nil) +func (c *Client) RemoveTemplate(ID int64, name string) error { + var builder strings.Builder + _, _ = builder.WriteString(c.baseURL) + _, _ = builder.WriteString("/templates") + + if name != "" { + _, _ = builder.WriteString("?name=") + _, _ = builder.WriteString(name) + } else if ID != 0 { + _, _ = builder.WriteString("?id=") + _, _ = builder.WriteString(strconv.FormatInt(ID, 10)) + } + httpReq, err := retryablehttp.NewRequest(http.MethodDelete, builder.String(), nil) if err != nil { return errors.Wrap(err, "could not make request") } @@ -435,8 +446,19 @@ func (c *Client) RemoveTemplate(ID int64) error { return nil } -func (c *Client) RemoveTarget(ID int64) error { - httpReq, err := retryablehttp.NewRequest(http.MethodDelete, fmt.Sprintf("%s/targets/%d", c.baseURL, ID), nil) +func (c *Client) RemoveTarget(ID int64, name string) error { + var builder strings.Builder + _, _ = builder.WriteString(c.baseURL) + _, _ = builder.WriteString("/targets") + + if name != "" { + _, _ = builder.WriteString("?name=") + _, _ = builder.WriteString(name) + } else if ID != 0 { + _, _ = builder.WriteString("?id=") + _, _ = builder.WriteString(strconv.FormatInt(ID, 10)) + } + httpReq, err := retryablehttp.NewRequest(http.MethodDelete, builder.String(), nil) if err != nil { return errors.Wrap(err, "could not make request") } @@ -450,8 +472,19 @@ func (c *Client) RemoveTarget(ID int64) error { return nil } -func (c *Client) GetTarget(ID int64) (io.ReadCloser, error) { - httpReq, err := retryablehttp.NewRequest(http.MethodGet, fmt.Sprintf("%s/targets/%d", c.baseURL, ID), nil) +func (c *Client) GetTarget(ID int64, name string) (io.ReadCloser, error) { + var builder strings.Builder + _, _ = builder.WriteString(c.baseURL) + _, _ = builder.WriteString("/targets/get") + + if name != "" { + _, _ = builder.WriteString("?name=") + _, _ = builder.WriteString(name) + } else if ID != 0 { + _, _ = builder.WriteString("?id=") + _, _ = builder.WriteString(strconv.FormatInt(ID, 10)) + } + httpReq, err := retryablehttp.NewRequest(http.MethodGet, builder.String(), nil) if err != nil { return nil, errors.Wrap(err, "could not make request") } @@ -463,8 +496,19 @@ func (c *Client) GetTarget(ID int64) (io.ReadCloser, error) { return resp.Body, nil } -func (c *Client) GetTemplate(ID int64) (io.ReadCloser, error) { - httpReq, err := retryablehttp.NewRequest(http.MethodGet, fmt.Sprintf("%s/templates/%d", c.baseURL, ID), nil) +func (c *Client) GetTemplate(ID int64, name string) (io.ReadCloser, error) { + var builder strings.Builder + _, _ = builder.WriteString(c.baseURL) + _, _ = builder.WriteString("/templates/get") + + if name != "" { + _, _ = builder.WriteString("?name=") + _, _ = builder.WriteString(name) + } else if ID != 0 { + _, _ = builder.WriteString("?id=") + _, _ = builder.WriteString(strconv.FormatInt(ID, 10)) + } + httpReq, err := retryablehttp.NewRequest(http.MethodGet, builder.String(), nil) if err != nil { return nil, errors.Wrap(err, "could not make request") } diff --git a/v2/internal/runner/runner.go b/v2/internal/runner/runner.go index 3f140883..fcb544d9 100644 --- a/v2/internal/runner/runner.go +++ b/v2/internal/runner/runner.go @@ -510,6 +510,9 @@ func (r *Runner) RunEnumeration() error { } else if r.options.RemoveTemplate != "" { err = r.removeTemplate(r.options.RemoveTemplate) } else { + if len(store.Templates())+len(store.Workflows())+len(cloudTemplates) == 0 { + return errors.New("no templates provided for scan") + } gologger.Info().Msgf("Running scan on cloud with URL %s", r.options.CloudURL) results, err = r.runCloudEnumeration(store, cloudTemplates, r.cloudTargets, r.options.NoStore, r.options.OutputLimit) enumeration = true