From f3f2a103d9e2a7d10cbfe65fda12a7590e770205 Mon Sep 17 00:00:00 2001 From: Dipesh Singhal Date: Mon, 4 Sep 2023 12:34:27 +0530 Subject: [PATCH] New report scan of licenses and violations (#775) --- README.md | 206 +++++++++++++++++- .../services/utils/tests/xray/consts.go | 69 +++++- .../services/utils/tests/xray/server.go | 16 +- tests/xrayreport_test.go | 75 +++++-- xray/manager.go | 16 +- xray/services/report.go | 115 ++++++++-- 6 files changed, 444 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 43ca83755..ef0c690df 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,14 @@ - [Get Vulnerabilities Report Details](#get-vulnerabilities-report-details) - [Get Vulnerabilities Report Content](#get-vulnerabilities-report-content) - [Delete Vulnerabilities Report](#delete-vulnerabilities-report) + - [Generate Licences Report](#generate-licences-report) + - [Get Licences Report Details](#get-licences-report-details) + - [Get Licences Report Content](#get-licences-report-content) + - [Delete Licences Report](#delete-licences-report) + - [Generate Violations Report](#generate-violations-report) + - [Get Violations Report Details](#get-violations-report-details) + - [Get Violations Report Content](#get-violations-report-content) + - [Delete Violations Report](#delete-violations-report) - [Get Artifact Summary](#get-artifact-summary) - [Get Entitlement info](#get-entitlement-info) - [Pipelines APIs](#pipelines-apis) @@ -1916,11 +1924,30 @@ scanResults, err := xrayManager.GetScanGraphResults(scanId) #### Generate Vulnerabilities Report ```go -reportRequest := services.ReportRequestParams{ +vulnerabilitiesReportRequest := services.VulnerabilitiesReportRequestParams{ Name: "example-report", - Filters: services.Filter{ - HasRemediation: &trueValue, - Severity: []string{ "High" }, + Filters: services.VulnerabilitiesFilter{ + VulnerableComponent: "*vulnerable:component*", + ImpactedArtifact: "some://impacted*artifact", + HasRemediation: &falseValue, + Cve: "CVE-1234-1234", + IssueId: "XRAY-1234", + Severity: []string{ + "High", + "Medium" + }, + CvssScore: services.CvssScore { + MinScore: float64(6.3), + MaxScore: float64(9) + }, + Published: services.DateTimeRange { + Start: "2020-06-29T12:22:16Z", + End: "2020-06-29T12:22:16Z" + }, + ScanDate: services.DateTimeRange { + Start: "2020-06-29T12:22:16Z", + End: "2020-06-29T12:22:16Z" + } }, Resources: services.Resource{ IncludePathPatterns: []string{ "/example-sub-dir/**" }, @@ -1933,7 +1960,7 @@ reportRequest := services.ReportRequestParams{ } // The reportRequestResponse will contain the report ID to use in subsequent requests -reportRequestResponse, err := xrayManager.GenerateVulnerabilitiesReport(reportRequest) +reportRequestResponse, err := xrayManager.GenerateVulnerabilitiesReport(vulnerabilitiesReportRequest) ``` #### Get Vulnerabilities Report Details @@ -1963,6 +1990,175 @@ reportContent, err := xrayManager.ReportContent(reportContentRequest) // The reportId argument value is returned as part of the xrayManager.GenerateVulnerabilitiesReport API response. err := xrayManager.DeleteReport(reportId) ``` +#### Generate Licences Report + +```go +licensesReportRequest := services.LicensesReportRequestParams{ + Name: "example-report", + Filters: services.LicensesFilter{ + Component: "*gav:component*", + Artifact: "some://impacted*artifact", + Unknown: &falseValue, + Unrecognized: &trueValue, + LicenseNames: []string{ + "Apache", + "MIT", + "AFL" + }, + LicensePatterns: []string{ + "*Apache*", + "The Apache*", + "AFL*" + }, + ScanDate: services.DateTimeRange { + Start: "2020-06-29T12:22:16Z", + End: "2020-06-29T12:22:16Z" + } + }, + Resources: services.Resource{ + IncludePathPatterns: []string{ "/example-sub-dir/**" }, + Repositories: []services.Repository{ + { + Name: "example-repository", + }, + }, + }, +} + +// The reportRequestResponse will contain the report ID to use in subsequent requests +reportRequestResponse, err := xrayManager.GenerateLicencesReport(licensesReportRequest) +``` + +#### Get Licences Report Details + +```go +// The reportId argument value is returned as part of the xrayManager.GenerateLicencesReport API response. +reportDetails, err := xrayManager.ReportDetails(reportId) +``` + +#### Get Licences Report Content + +```go +// The ReportId value is returned as part of the xrayManager.GenerateLicencesReport API response. +reportContentRequest := services.ReportContentRequestParams{ + ReportId: "example-report-id", + Direction: "asc", + PageNum: 0, + NumRows: 0, + OrderBy: "severity", +} +reportContent, err := xrayManager.ReportContent(reportContentRequest) +``` + +#### Delete Licences Report + +```go +// The reportId argument value is returned as part of the xrayManager.GenerateLicencesReport API response. +err := xrayManager.DeleteReport(reportId) +``` + +#### Generate Violations Report + +```go +violationsReportRequest := services.ViolationsReportRequestParams{ + Name: "example-report", + Filters: Type: "security|license|operational_risk", + WatchNames: []string{ + "NameOfWatch1", + "NameOfWatch2" + }, + WatchPatterns: []string{ + "WildcardWatch*" + }, + Component: "*vulnerable:component*", + Artifact: "some://impacted*artifact", + PolicyNames: []string{ + "NameOfPolicy" + }, + Severities: []string{ + "High", + "Medium" + }, + Updated: services.DateTimeRange { + Start: "2020-01-02T15:00:00Z", + End: "2020-12-15T00:00:00Z" + }, + SecurityFilters: services.VulnerabilitiesFilter{ + Cve: "CVE-2020-10693", + IssueId: "XRAY-87343", + Severity: []string{ + "High", + "Medium" + }, + CvssScore: services.CvssScore { + MinScore: float64(6.3), + MaxScore: float64(9) + }, + Published: services.DateTimeRange { + Start: "2020-06-29T12:22:16Z", + End: "2020-06-29T12:22:16Z" + }, + ScanDate: services.DateTimeRange { + Start: "2020-06-29T12:22:16Z", + End: "2020-06-29T12:22:16Z" + }, + SummaryContains: "kernel", + HasRemediation: &falseValue, + }, + LicenseFilters: services.LicensesFilter { + Unknown: &falseValue, + Unrecognized: &trueValue, + LicenseNames: []string{ + "Apache", + "MIT", + "AFL" + }, + LicensePatterns: []string{ + "*Apache*", + "AFL*" + }, + } + Resources: services.Resource{ + IncludePathPatterns: []string{ "/example-sub-dir/**" }, + Repositories: []services.Repository{ + { + Name: "example-repository", + }, + }, + }, +} + +// The reportRequestResponse will contain the report ID to use in subsequent requests +reportRequestResponse, err := xrayManager.GenerateViolationsReport(violationsReportRequest) +``` + +#### Get Violations Report Details + +```go +// The reportId argument value is returned as part of the xrayManager.GenerateViolationsReport API response. +reportDetails, err := xrayManager.ReportDetails(reportId) +``` + +#### Get Violations Report Content + +```go +// The ReportId value is returned as part of the xrayManager.GenerateViolationsReport API response. +reportContentRequest := services.ReportContentRequestParams{ + ReportId: "example-report-id", + Direction: "asc", + PageNum: 0, + NumRows: 0, + OrderBy: "severity", +} +reportContent, err := xrayManager.ReportContent(reportContentRequest) +``` + +#### Delete Violations Report + +```go +// The reportId argument value is returned as part of the xrayManager.GenerateViolationsReport API response. +err := xrayManager.DeleteReport(reportId) +``` #### Get Artifact Summary diff --git a/artifactory/services/utils/tests/xray/consts.go b/artifactory/services/utils/tests/xray/consts.go index 05c836653..59ba85151 100644 --- a/artifactory/services/utils/tests/xray/consts.go +++ b/artifactory/services/utils/tests/xray/consts.go @@ -1105,13 +1105,20 @@ const VulnerableXrayScanResponse = `{ } ` -const VulnerabilityRequestResponse = ` +const VulnerabilityXrayReportRequestResponse = ` { "report_id": 777, "status": "pending" } ` +const LicensesXrayReportRequestResponse = ` +{ + "report_id": 888, + "status": "pending" +} +` + const VulnerabilityReportStatusResponse = ` { "id": 301, @@ -1128,7 +1135,23 @@ const VulnerabilityReportStatusResponse = ` } ` -const VulnerabilityReportDeleteResponse = ` +const LicensesReportStatusResponse = ` +{ + "id": 301, + "name": "test-generic", + "report_type": "license", + "status": "completed", + "total_artifacts": 4, + "num_of_processed_artifacts": 4, + "progress": 100, + "number_of_rows": 64, + "start_time": "2021-09-03T21:17:41Z", + "end_time": "2021-09-03T21:17:42Z", + "author": "test" +} +` + +const XrayReportDeleteResponse = ` { "info": "report deleted successfully" } @@ -1221,6 +1244,29 @@ const VulnerabilityReportDetailsResponse = ` } ` +const LicensesReportDetailsResponse = ` +{ + "total_rows": 1, + "rows" :[ + { + "license": "MIT", + "license_name" : "The MIT License", + "component": "deb://debian:buster:glibc:2.28-10", + "artifact": "docker://redis:latest-07142020122937", + "path": "repo1/folder1/artifact", + "artifact_scan_time": "2020-07-14T09:32:00Z", + "unknown" : false, + "unrecognized" : false, + "custom" : false, + "references": [ + "https://spdx.org/licenses/AFL-1.1.html", + "https://spdx.org/licenses/AFL-1.1" + ] + } + ] +} +` + const VulnerableXraySummaryArtifactResponse = ` { "artifacts": [ @@ -1368,3 +1414,22 @@ const BuildScanResultsResponse = ` ] } ` + + +var MapReportIdEndpoint = map[int]string { + 777: VulnerabilitiesEndpoint, + 888: LicensesEndpoint, +} + +var MapResponse = map[string]map[string]string { + VulnerabilitiesEndpoint: { + "XrayReportRequest": VulnerabilityXrayReportRequestResponse, + "ReportStatus": VulnerabilityReportStatusResponse, + "ReportDetails": VulnerabilityReportDetailsResponse, + }, + LicensesEndpoint: { + "XrayReportRequest": LicensesXrayReportRequestResponse, + "ReportStatus": LicensesReportStatusResponse, + "ReportDetails": LicensesReportDetailsResponse, + }, +} diff --git a/artifactory/services/utils/tests/xray/server.go b/artifactory/services/utils/tests/xray/server.go index b584b0477..ea8840caa 100644 --- a/artifactory/services/utils/tests/xray/server.go +++ b/artifactory/services/utils/tests/xray/server.go @@ -19,6 +19,7 @@ const ( FatalScanBuildName = "fatalBuildName" VulnerableBuildName = "vulnerableBuildName" VulnerabilitiesEndpoint = "vulnerabilities" + LicensesEndpoint = "licenses" ContextualAnalysisFeatureId = "contextual_analysis" BadFeatureId = "unknown" ) @@ -73,22 +74,23 @@ func reportHandler(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: if numSegments == 1 { - _, err := strconv.Atoi(addlSegments[0]) + id, err := strconv.Atoi(addlSegments[0]) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - _, err = fmt.Fprint(w, VulnerabilityReportStatusResponse) + _, err = fmt.Fprint(w, MapResponse[MapReportIdEndpoint[id]]["ReportStatus"]) if err != nil { log.Error(err) http.Error(w, err.Error(), http.StatusInternalServerError) } + return } case http.MethodPost: if numSegments == 1 { - if addlSegments[0] == VulnerabilitiesEndpoint { - _, err := fmt.Fprint(w, VulnerabilityRequestResponse) + if addlSegments[0] == VulnerabilitiesEndpoint || addlSegments[0] == LicensesEndpoint { + _, err := fmt.Fprint(w, MapResponse[addlSegments[0]]["XrayReportRequest"]) if err != nil { log.Error(err) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -101,8 +103,8 @@ func reportHandler(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) return } - if addlSegments[0] == VulnerabilitiesEndpoint { - _, err := fmt.Fprint(w, VulnerabilityReportDetailsResponse) + if addlSegments[0] == VulnerabilitiesEndpoint || addlSegments[0] == LicensesEndpoint { + _, err := fmt.Fprint(w, MapResponse[addlSegments[0]]["ReportDetails"]) if err != nil { log.Error(err) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -112,7 +114,7 @@ func reportHandler(w http.ResponseWriter, r *http.Request) { } case http.MethodDelete: if numSegments == 0 { - _, err := fmt.Fprint(w, VulnerabilityReportDeleteResponse) + _, err := fmt.Fprint(w, XrayReportDeleteResponse) if err != nil { log.Error(err) http.Error(w, err.Error(), http.StatusInternalServerError) diff --git a/tests/xrayreport_test.go b/tests/xrayreport_test.go index 2ebd41dc8..81c767b00 100644 --- a/tests/xrayreport_test.go +++ b/tests/xrayreport_test.go @@ -32,10 +32,9 @@ func TestXrayReport(t *testing.T) { t.Run("reportAll", reportAll) } -func reportAll(t *testing.T) { - request := services.ReportRequestParams{ +var vulnerabilitiesReportRequestParams = services.VulnerabilitiesReportRequestParams { Name: "test-report", - Filters: services.Filter{ + Filters: services.VulnerabilitiesFilter{ HasRemediation: &trueValue, Severity: []string{"high"}, }, @@ -47,28 +46,60 @@ func reportAll(t *testing.T) { }, }, } - report, err := testXrayReportService.Vulnerabilities(request) - assert.NoError(t, err) - validateResponse(t, xray.VulnerabilityRequestResponse, report) +var licensesReportRequestParams = services.LicensesReportRequestParams { + Name: "test-report", + Filters: services.LicensesFilter{ + LicensePatterns: []string{"*"}, + }, + Resources: services.Resource{ + Repositories: []services.Repository{ + { + Name: "dummy-repo", + }, + }, + }, + } +var reportTypes = []string { + xray.VulnerabilitiesEndpoint, + xray.LicensesEndpoint, +} - var reportId = strconv.Itoa(report.ReportId) - details, err := testXrayReportService.Details(reportId) - assert.NoError(t, err) - validateResponse(t, xray.VulnerabilityReportStatusResponse, details) +func reportAll(t *testing.T) { + for _, ep := range reportTypes { + var report *services.ReportResponse + var err error + if ep == xray.VulnerabilitiesEndpoint { + report, err = testXrayReportService.Vulnerabilities(vulnerabilitiesReportRequestParams) + } else if ep == xray.LicensesEndpoint { + report, err = testXrayReportService.Licenses(licensesReportRequestParams) + } + assert.NoError(t, err) + validateResponse(t, xray.MapResponse[xray.MapReportIdEndpoint[report.ReportId]]["XrayReportRequest"], report) - reportReqCont := services.ReportContentRequestParams{ - ReportId: reportId, - Direction: "asc", - PageNum: 0, - NumRows: 7, - OrderBy: "severity", - } - content, err := testXrayReportService.Content(reportReqCont) - assert.NoError(t, err) - validateResponse(t, xray.VulnerabilityReportDetailsResponse, content) + var reportId = strconv.Itoa(report.ReportId) + details, err := testXrayReportService.Details(reportId) + assert.NoError(t, err) + validateResponse(t, xray.MapResponse[xray.MapReportIdEndpoint[report.ReportId]]["ReportStatus"], details) - err = testXrayReportService.Delete(reportId) - assert.NoError(t, err) + reportReqCont := services.ReportContentRequestParams{ + ReportType: ep, + ReportId: reportId, + Direction: "asc", + PageNum: 0, + NumRows: 7, + } + if ep == xray.VulnerabilitiesEndpoint { + reportReqCont.OrderBy = "severity" + } else if ep == xray.LicensesEndpoint { + reportReqCont.OrderBy = "license" + } + content, err := testXrayReportService.Content(reportReqCont) + assert.NoError(t, err) + validateResponse(t, xray.MapResponse[ep]["ReportDetails"], content) + + err = testXrayReportService.Delete(reportId) + assert.NoError(t, err) + } } func validateResponse(t *testing.T, expects string, payload interface{}) { diff --git a/xray/manager.go b/xray/manager.go index 676fe1585..c847644c0 100644 --- a/xray/manager.go +++ b/xray/manager.go @@ -143,12 +143,26 @@ func (sm *XrayServicesManager) BuildScan(params services.XrayBuildParams, includ } // GenerateVulnerabilitiesReport returns a Xray report response of the requested report -func (sm *XrayServicesManager) GenerateVulnerabilitiesReport(params services.ReportRequestParams) (resp *services.ReportResponse, err error) { +func (sm *XrayServicesManager) GenerateVulnerabilitiesReport(params services.VulnerabilitiesReportRequestParams) (resp *services.ReportResponse, err error) { reportService := services.NewReportService(sm.client) reportService.XrayDetails = sm.config.GetServiceDetails() return reportService.Vulnerabilities(params) } +// GenerateLicensesReport returns a Xray report response of the requested report +func (sm *XrayServicesManager) GenerateLicensesReport(params services.LicensesReportRequestParams) (resp *services.ReportResponse, err error) { + reportService := services.NewReportService(sm.client) + reportService.XrayDetails = sm.config.GetServiceDetails() + return reportService.Licenses(params) +} + +// GenerateVoilationsReport returns a Xray report response of the requested report +func (sm *XrayServicesManager) GenerateViolationsReport(params services.ViolationsReportRequestParams) (resp *services.ReportResponse, err error) { + reportService := services.NewReportService(sm.client) + reportService.XrayDetails = sm.config.GetServiceDetails() + return reportService.Violations(params) +} + // ReportDetails returns a Xray details response for the requested report func (sm *XrayServicesManager) ReportDetails(reportId string) (details *services.ReportDetails, err error) { reportService := services.NewReportService(sm.client) diff --git a/xray/services/report.go b/xray/services/report.go index 526bd2cb8..d159c9c0d 100644 --- a/xray/services/report.go +++ b/xray/services/report.go @@ -13,7 +13,10 @@ import ( const ( // ReportsAPI refer to: https://www.jfrog.com/confluence/display/JFROG/Xray+REST+API#XrayRESTAPI-REPORTS ReportsAPI = "api/v1/reports" - VulnerabilitiesAPI = ReportsAPI + "/vulnerabilities" + Vulnerabilities = "vulnerabilities" + Licenses = "licenses" + Violations = "violations" + ) // ReportService defines the Http client and Xray details @@ -39,6 +42,7 @@ type ReportDetails struct { // ReportContentRequestParams defines a report content request type ReportContentRequestParams struct { + ReportType string ReportId string Direction string PageNum int @@ -54,6 +58,7 @@ type ReportContent struct { // Row defines an entry of the report content type Row struct { + // Vulnerability Report field Cves []ReportCve `json:"cves,omitempty"` Cvsv2MaxScore float64 `json:"cvss2_max_score,omitempty"` Cvsv3MaxScore float64 `json:"cvss3_max_score,omitempty"` @@ -63,18 +68,32 @@ type Row struct { VulnerableComponent string `json:"vulnerable_component,omitempty"` ImpactedArtifact string `json:"impacted_artifact,omitempty"` ImpactPath []string `json:"impact_path,omitempty"` - Path string `json:"path,omitempty"` FixedVersions []string `json:"fixed_versions,omitempty"` Published string `json:"published,omitempty"` IssueId string `json:"issue_id,omitempty"` PackageType string `json:"package_type,omitempty"` Provider string `json:"provider,omitempty"` Description string `json:"description,omitempty"` - References []string `json:"references,omitempty"` ExternalAdvisorySource string `json:"external_advisory_source,omitempty"` ExternalAdvisorySeverity string `json:"external_advisory_severity,omitempty"` + // Licenses Report field + License string `json:"license,omitempty"` + LicenseName string `json:"license_name,omitempty"` + Component string `json:"component,omitempty"` + Artifact string `json:"artifact,omitempty"` + ArtifactScanTime string `json:"artifact_scan_time,omitempty"` + Unknown *bool `json:"unknown,omitempty"` + Unrecognized *bool `json:"unrecognized,omitempty"` + Custom *bool `json:"custom,omitempty"` + // Common field + Path string `json:"path,omitempty"` + References []string `json:"references,omitempty"` } +// For backwork compatibility keeping old struct name +type Filter VulnerabilitiesFilter +type ReportRequestParams VulnerabilitiesReportRequestParams + type ReportCve struct { Id string `json:"cve,omitempty"` CvssV2Score float64 `json:"cvss_v2_score,omitempty"` @@ -83,17 +102,66 @@ type ReportCve struct { CvssV3Vector string `json:"cvss_v3_vector,omitempty"` } -// ReportRequestParams defines a report request -type ReportRequestParams struct { - Name string `json:"name,omitempty"` - Filters Filter `json:"filters,omitempty"` - Resources Resource `json:"resources,omitempty"` +// VulnerabilitiesReportRequestParams defines a report request +type VulnerabilitiesReportRequestParams struct { + Name string `json:"name,omitempty"` + Filters VulnerabilitiesFilter `json:"filters,omitempty"` + Resources Resource `json:"resources,omitempty"` +} + +// LicensesReportRequestParams defines a report request +type LicensesReportRequestParams struct { + Name string `json:"name,omitempty"` + Filters LicensesFilter `json:"filters,omitempty"` + Resources Resource `json:"resources,omitempty"` +} + +// ViolationsReportRequestParams defines a report request +type ViolationsReportRequestParams struct { + Name string `json:"name,omitempty"` + Filters ViolationsFilter `json:"filters,omitempty"` + Resources Resource `json:"resources,omitempty"` +} + +type VulnerabilitiesFilter struct { + VulnerableComponent string `json:"vulnerable_component,omitempty"` + ImpactedArtifact string `json:"impacted_artifact,omitempty"` + SummaryContains string `json:"summary_contains,omitempty"` + HasRemediation *bool `json:"has_remediation,omitempty"` + Cve string `json:"cve,omitempty"` + IssueId string `json:"issue_id,omitempty"` + Severity []string `json:"severities,omitempty"` + CvssScore CvssScore `json:"cvss_score,omitempty"` + Published DateTimeRange `json:"published,omitempty"` + ScanDate DateTimeRange `json:"scan_date,omitempty"` +} + +type DateTimeRange struct { + Start string `json:"start,omitempty"` + End string `json:"end,omitempty"` } -type Filter struct { - HasRemediation *bool `json:"has_remediation,omitempty"` - CvssScore CvssScore `json:"cvss_score,omitempty"` - Severity []string `json:"severities,omitempty"` +type LicensesFilter struct { + Component string `json:"component,omitempty"` + Artifact string `json:"artifact,omitempty"` + Unknown *bool `json:"unknown,omitempty"` + Unrecognized *bool `json:"unrecognized,omitempty"` + LicenseNames []string `json:"license_names,omitempty"` + LicensePatterns []string `json:"license_patterns,omitempty"` + ScanDate DateTimeRange `json:"scan_date,omitempty"` +} + +type ViolationsFilter struct { + Type string `json:"type,omitempty"` + WatchNames string `json:"watch_names,omitempty"` + WatchPatterns string `json:"watch_patterns,omitempty"` + Component string `json:"component,omitempty"` + Artifact string `json:"artifact,omitempty"` + PolicyNames []string `json:"policy_names,omitempty"` + Severities []string `json:"severities,omitempty"` + Updated DateTimeRange `json:"updated,omitempty"` + SecurityFilters VulnerabilitiesFilter `json:"security_filters,omitempty"` + LicenseFilters LicensesFilter `json:"license_filters,omitempty"` } type CvssScore struct { @@ -122,12 +190,27 @@ func NewReportService(client *jfroghttpclient.JfrogHttpClient) *ReportService { } // Vulnerabilities requests a new Xray scan for vulnerabilities -func (rs *ReportService) Vulnerabilities(req ReportRequestParams) (*ReportResponse, error) { +func (rs *ReportService) Vulnerabilities(req VulnerabilitiesReportRequestParams) (*ReportResponse, error) { + return rs.requestReport(req, Vulnerabilities) +} + +// Licenses requests a new Xray scan for licenses +func (rs *ReportService) Licenses(req LicensesReportRequestParams) (*ReportResponse, error) { + return rs.requestReport(req, Licenses) +} + +// Violations requests a new Xray scan for violations +func (rs *ReportService) Violations(req ViolationsReportRequestParams) (*ReportResponse, error) { + return rs.requestReport(req, Violations) +} + +// Internal function to requests a new Xray scan for Report of type (vulnerabilities/licenses/voilations) +func (rs *ReportService) requestReport(req any, reportType string) (*ReportResponse, error) { retVal := ReportResponse{} httpClientsDetails := rs.XrayDetails.CreateHttpClientDetails() utils.SetContentType("application/json", &httpClientsDetails.Headers) - url := fmt.Sprintf("%s/%s", rs.XrayDetails.GetUrl(), VulnerabilitiesAPI) + url := fmt.Sprintf("%s/%s", rs.XrayDetails.GetUrl(), ReportsAPI+"/"+reportType) content, err := json.Marshal(req) if err != nil { return &retVal, errorutils.CheckError(err) @@ -178,8 +261,8 @@ func (rs *ReportService) Content(request ReportContentRequestParams) (*ReportCon httpClientsDetails := rs.XrayDetails.CreateHttpClientDetails() utils.SetContentType("application/json", &httpClientsDetails.Headers) - url := fmt.Sprintf("%s/%s/%s?direction=%s&page_num=%d&num_of_rows=%d&order_by=%s", - rs.XrayDetails.GetUrl(), VulnerabilitiesAPI, request.ReportId, request.Direction, request.PageNum, request.NumRows, request.OrderBy) + url := fmt.Sprintf("%s/%s/%s/%s?direction=%s&page_num=%d&num_of_rows=%d&order_by=%s", + rs.XrayDetails.GetUrl(), ReportsAPI, request.ReportType, request.ReportId, request.Direction, request.PageNum, request.NumRows, request.OrderBy) resp, body, err := rs.client.SendPost(url, nil, &httpClientsDetails) if err != nil { return nil, err