Skip to content

Commit

Permalink
Task # AST-31546
Browse files Browse the repository at this point in the history
  • Loading branch information
margaritalm committed Apr 7, 2024
1 parent 5b44ada commit 5cb4106
Show file tree
Hide file tree
Showing 3 changed files with 280 additions and 2 deletions.
175 changes: 173 additions & 2 deletions internal/commands/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ const (
lowLabel = "low"
infoLabel = "info"
sonarTypeLabel = "_sonar"
glSastTypeLobel = ".gl-sast-report"
glSastTypeLabel = ".gl-sast-report"
glDependencyTypeLabel = ".gl-dependency-report"
directoryPermission = 0700
infoSonar = "INFO"
lowSonar = "MINOR"
Expand Down Expand Up @@ -104,6 +105,7 @@ var summaryFormats = []string{
printer.FormatSummaryMarkdown,
printer.FormatSbom,
printer.FormatGL,
printer.FormatGLDependency,
}

var filterResultsListFlagUsage = fmt.Sprintf(
Expand Down Expand Up @@ -201,6 +203,7 @@ func resultShowSubCommand(
printer.FormatPDF,
printer.FormatSummaryMarkdown,
printer.FormatGL,
printer.FormatGLDependency,
)
resultShowCmd.PersistentFlags().String(commonParams.ReportFormatPdfToEmailFlag, "", pdfToEmailFlagDescription)
resultShowCmd.PersistentFlags().String(commonParams.ReportSbomFormatFlag, defaultSbomOption, sbomReportFlagDescription)
Expand Down Expand Up @@ -915,9 +918,14 @@ func createReport(format,
return exportJSONResults(jsonRpt, results)
}
if printer.IsFormat(format, printer.FormatGL) {
jsonRpt := createTargetName(fmt.Sprintf("%s%s", targetFile, glSastTypeLobel), targetPath, printer.FormatJSON)
jsonRpt := createTargetName(fmt.Sprintf("%s%s", targetFile, glSastTypeLabel), targetPath, printer.FormatJSON)
return exportGlSastResults(jsonRpt, results, summary)
}
if printer.IsFormat(format, printer.FormatGLDependency) {
jsonRpt := createTargetName(fmt.Sprintf("%s%s", targetFile, glDependencyTypeLabel), targetPath, printer.FormatJSON)
return exportGlDependencyResults(jsonRpt, results, summary)
}

if printer.IsFormat(format, printer.FormatSummaryConsole) {
return writeConsoleSummary(summary)
}
Expand Down Expand Up @@ -1081,6 +1089,53 @@ func exportGlSastResults(targetFile string, results *wrappers.ScanResultsCollect
defer f.Close()
return nil
}

func exportGlDependencyResults(targetFile string, results *wrappers.ScanResultsCollection, summary *wrappers.ResultSummary) error {
log.Println("Creating Gl-dependency: ", targetFile)
var glDependencyResult = new(wrappers.GlDependencyResultsCollection)
err := addScanToGlDependencyReport(summary, glDependencyResult)
convertCxResultToGlDependencyVulnerability(results, glDependencyResult, summary.BaseURI)
convertCxResultToGlDependencyFiles(results, glDependencyResult, summary.BaseURI)
resultsJSON, err := json.Marshal(glDependencyResult)
if err != nil {
return errors.Wrapf(err, "%s: failed to serialize gl sast report ", failedListingResults)
}
f, err := os.Create(targetFile)
if err != nil {
return errors.Wrapf(err, "%s: failed to create target file ", failedListingResults)
}
_, _ = fmt.Fprintln(f, string(resultsJSON))
defer f.Close()

return nil
}

func addScanToGlDependencyReport(summary *wrappers.ResultSummary, glDependencyResult *wrappers.GlDependencyResultsCollection) error {
createdAt, err := time.Parse(summaryCreatedAtLayout, summary.CreatedAt)
if err != nil {
return err
}

glDependencyResult.Schema = "https://gitlab.com/gitlab-org/gitlab/-/raw/master/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json"

Check failure on line 1119 in internal/commands/result.go

View workflow job for this annotation

GitHub Actions / lint

string `https://gitlab.com/gitlab-org/gitlab/-/raw/master/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json` has 2 occurrences, make it a constant (goconst)
glDependencyResult.Version = "15.0.0"

Check failure on line 1120 in internal/commands/result.go

View workflow job for this annotation

GitHub Actions / lint

string `15.0.0` has 2 occurrences, make it a constant (goconst)
glDependencyResult.Scan.Analyzer.VendorGlSCA.VendorGlname = wrappers.AnalyzerScaID
glDependencyResult.Scan.Analyzer.Name = wrappers.AnalyzerScaID
glDependencyResult.Scan.Analyzer.Name = wrappers.AnalyzerScaID
glDependencyResult.Scan.Analyzer.Id = wrappers.ScannerId
glDependencyResult.Scan.Scanner.Id = wrappers.ScannerId
glDependencyResult.Scan.Scanner.Name = wrappers.AnalyzerScaID
glDependencyResult.Scan.Scanner.VendorGlSCA.VendorGlname = wrappers.AnalyzerScaID
glDependencyResult.Scan.Status = commonParams.Success
glDependencyResult.Scan.Type = wrappers.ScannerType
glDependencyResult.Scan.StartTime = createdAt.Format(glTimeFormat)
glDependencyResult.Scan.EndTime = createdAt.Format(glTimeFormat)
glDependencyResult.Scan.Scanner.Name = wrappers.AnalyzerScaID
glDependencyResult.Scan.Scanner.VersionGlSca = commonParams.Version
glDependencyResult.Scan.Analyzer.VersionGlSca = commonParams.Version

return nil
}

func addScanToGlSastReport(summary *wrappers.ResultSummary, glSast *wrappers.GlSastResultsCollection) error {
createdAt, err := time.Parse(summaryCreatedAtLayout, summary.CreatedAt)
if err != nil {
Expand Down Expand Up @@ -1374,6 +1429,21 @@ func convertCxResultToGlVulnerability(results *wrappers.ScanResultsCollection, g
}
}

func convertCxResultToGlDependencyVulnerability(results *wrappers.ScanResultsCollection, glDependencyResult *wrappers.GlDependencyResultsCollection, summaryBaseURI string) {

Check failure on line 1432 in internal/commands/result.go

View workflow job for this annotation

GitHub Actions / lint

`convertCxResultToGlDependencyVulnerability` - `summaryBaseURI` is unused (unparam)
for _, result := range results.Results {
if strings.TrimSpace(result.Type) == commonParams.ScaType {
glDependencyResult = parseGlDependencyVulnerability(result, glDependencyResult)
}
}
}

func convertCxResultToGlDependencyFiles(results *wrappers.ScanResultsCollection, glDependencyResult *wrappers.GlDependencyResultsCollection, summaryBaseURI string) {

Check failure on line 1440 in internal/commands/result.go

View workflow job for this annotation

GitHub Actions / lint

`convertCxResultToGlDependencyFiles` - `summaryBaseURI` is unused (unparam)
for _, result := range results.Results {
if strings.TrimSpace(result.Type) == commonParams.ScaType {
glDependencyResult = parseGlDependencyFiles(result, glDependencyResult)
}
}
}
func parseGlSastVulnerability(result *wrappers.ScanResult, glSast *wrappers.GlSastResultsCollection, summaryBaseURI string) *wrappers.GlSastResultsCollection {
queryName := result.ScanResultData.QueryName
fileName := result.ScanResultData.Nodes[0].FileName
Expand Down Expand Up @@ -1429,6 +1499,107 @@ func parseGlSastVulnerability(result *wrappers.ScanResult, glSast *wrappers.GlSa
return glSast
}

func parseGlDependencyVulnerability(result *wrappers.ScanResult, glDependencyResult *wrappers.GlDependencyResultsCollection) *wrappers.GlDependencyResultsCollection {

if result.ScanResultData.ScaPackageCollection != nil {

glDependencyResult.Vulnerabilities = append(glDependencyResult.Vulnerabilities, wrappers.GlDepVulnerabilities{
Id: result.ID,
Name: result.VulnerabilityDetails.CveName,
Description: result.Description,
Severity: cases.Title(language.English).String(result.Severity),
Solution: result.ScanResultData.RecommendedVersion,
Identifiers: collectDependencyPackageData(result),
Links: collectDependencyPackageLinks(result),
TrackingDep: wrappers.TrackingDep{
Items: collectDependencyPackageItemsDep(result),
},
Flags: make([]string, 0),
LocationDep: wrappers.GlDepVulnerabilityLocation{
File: *(result.ScanResultData.ScaPackageCollection.Locations[0]),
Dependency: wrappers.DependencyLocation{
Package: wrappers.PackageName{Name: result.ScanResultData.PackageIdentifier},
DependencyLocationVersion: "",
Iid: "",
Direct: result.ScanResultData.ScaPackageCollection.IsDirectDependency,
DependencyPath: "",
},
},
})
}
return glDependencyResult
}

func parseGlDependencyFiles(result *wrappers.ScanResult, glDependencyResult *wrappers.GlDependencyResultsCollection) *wrappers.GlDependencyResultsCollection {
if result.ScanResultData.ScaPackageCollection != nil {
glDependencyResult.DependencyFiles = append(glDependencyResult.DependencyFiles, wrappers.DependencyFile{
Path: result.ScanResultData.ScaPackageCollection.ID, ///Need to enter correct File path
PackageManager: result.ScanResultData.ScaPackageCollection.ID, //Need to enter correct Package_manager

Check failure on line 1537 in internal/commands/result.go

View workflow job for this annotation

GitHub Actions / lint

commentFormatting: put a space between `//` and comment text (gocritic)
Dependencies: collectDependencyFileLocations(result),
})
}
return glDependencyResult
}

func collectDependencyFileLocations(result *wrappers.ScanResult) []wrappers.DependencyLocation {
allIdentifierLocations := []wrappers.DependencyLocation{}
for i := 0; i < len(result.ScanResultData.PackageData); i++ {
allIdentifierLocations = append(allIdentifierLocations, wrappers.DependencyLocation{
Package: wrappers.PackageName{
Name: result.ScanResultData.PackageData[i].Type,
},
DependencyLocationVersion: result.ScanResultData.PackageData[i].URL,
Iid: result.ScanResultData.PackageData[i].Type,
Direct: true,
DependencyPath: result.ScanResultData.PackageData[i].Type,
})
}
return allIdentifierLocations
}

func collectDependencyPackageItemsDep(result *wrappers.ScanResult) []wrappers.ItemDep {
allDependencyPackageItemDep := []wrappers.ItemDep{}
if result.ScanResultData.ScaPackageCollection != nil {
allDependencyPackageItemDep = append(allDependencyPackageItemDep, wrappers.ItemDep{
Signature: []wrappers.SignatureDep{{Algorithm: "SCA-Algorithm ", Value: "NA"}},
File: *result.ScanResultData.ScaPackageCollection.DependencyPathArray[0][0].Locations[0],
EndLine: 0,
StartLine: 0,
})
}
return allDependencyPackageItemDep

}

func collectDependencyPackageLinks(result *wrappers.ScanResult) []wrappers.LinkDep {
allDependencyPackageLinks := []wrappers.LinkDep{}
for i := 0; i < len(result.ScanResultData.PackageData); i++ {

allDependencyPackageLinks = append(allDependencyPackageLinks, wrappers.LinkDep{
Name: result.ScanResultData.PackageData[i].Type,
Url: result.ScanResultData.PackageData[i].URL,
})

}
return allDependencyPackageLinks

}

func collectDependencyPackageData(result *wrappers.ScanResult) []wrappers.IdentifierDep {
allIdentifierDep := []wrappers.IdentifierDep{}
for i := 0; i < len(result.ScanResultData.PackageData); i++ {

allIdentifierDep = append(allIdentifierDep, wrappers.IdentifierDep{
Type: result.ScanResultData.PackageData[i].Type,
Value: result.ScanResultData.PackageData[i].URL,
Name: result.ScanResultData.PackageData[i].URL,
})

}
return allIdentifierDep
}

// func IdentifiersPackageData
func convertCxResultsToSonar(results *wrappers.ScanResultsCollection) *wrappers.ScanResultsSonar {
var sonar = new(wrappers.ScanResultsSonar)
sonar.Results = parseResultsSonar(results)
Expand Down
1 change: 1 addition & 0 deletions internal/commands/util/printer/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const (
FormatSbom = "sbom"
FormatXML = "xml"
FormatGL = "gl-sast"
FormatGLDependency = "gl-dependency"
)

func Print(w io.Writer, view interface{}, format string) error {
Expand Down
106 changes: 106 additions & 0 deletions internal/wrappers/results-gl-dependency.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package wrappers

const (
AnalyzerScaName = "CxOne"
AnalyzerScaID = AnalyzerScaName + "-SCA"
ScannerId = "SCA"

Check failure on line 6 in internal/wrappers/results-gl-dependency.go

View workflow job for this annotation

GitHub Actions / lint

const `ScannerId` should be `ScannerID` (golint)
ScannerType = "dependency_scanning"
)

type GlDependencyResultsCollection struct {
Scan ScanGlDepReport `json:"scan"`
Schema string `json:"schema"`
Version string `json:"version"`
Vulnerabilities []GlDepVulnerabilities `json:"vulnerabilities"`
DependencyFiles []DependencyFile `json:"dependency_files"`
}

type GlVendor struct {
VendorGlname string `json:"name"`
}

type ScanGlDepReport struct {
EndTime string `json:"end_time,omitempty"`
Analyzer GlDepAnalyzer `json:"analyzer,omitempty"`
Scanner GlDepScanner `json:"scanner,omitempty"`
StartTime string `json:"start_time,omitempty"`
Status string `json:"status,omitempty"`
Type string `json:"type"`
}

type GlDepAnalyzer struct {
Id string `json:"id,omitempty"`

Check failure on line 32 in internal/wrappers/results-gl-dependency.go

View workflow job for this annotation

GitHub Actions / lint

struct field `Id` should be `ID` (golint)
Name string `json:"name,omitempty"`
VendorGlSCA GlVendor `json:"vendor"`
VersionGlSca string `json:"version,omitempty"`
}

type GlDepScanner struct {
Id string `json:"id,omitempty"`

Check failure on line 39 in internal/wrappers/results-gl-dependency.go

View workflow job for this annotation

GitHub Actions / lint

struct field `Id` should be `ID` (golint)
Name string `json:"name,omitempty"`
VersionGlSca string `json:"version,omitempty"`
VendorGlSCA GlVendor `json:"vendor"`
}

type GlDepVulnerabilities struct {
Id string `json:"id"`

Check failure on line 46 in internal/wrappers/results-gl-dependency.go

View workflow job for this annotation

GitHub Actions / lint

struct field `Id` should be `ID` (golint)
Name string `json:"name"`
Description string `json:"description"`
Severity string `json:"severity"`
Solution interface{} `json:"solution"`
Identifiers []IdentifierDep `json:"identifiers"`
Links []LinkDep `json:"links"`
TrackingDep TrackingDep `json:"tracking"`
Flags []string `json:"flags"`
LocationDep GlDepVulnerabilityLocation `json:"location"`
}

type IdentifierDep struct {
Type string `json:"type"`
Name string `json:"name"`
Value string `json:"value"`
}

type LinkDep struct {
Name string `json:"name,omitempty"`
Url string `json:"url,omitempty"`

Check failure on line 66 in internal/wrappers/results-gl-dependency.go

View workflow job for this annotation

GitHub Actions / lint

struct field `Url` should be `URL` (golint)
}

type TrackingDep struct {
Items []ItemDep `json:"items"`
}

type ItemDep struct {
Signature []SignatureDep `json:"signatures"`
File string `json:"file"`
EndLine uint `json:"end_line"`
StartLine uint `json:"start_line"`
}

type SignatureDep struct {
Algorithm string `json:"algorithm"`
Value string `json:"value"`
}

type GlDepVulnerabilityLocation struct {
File string `json:"file"`
Dependency DependencyLocation `json:"dependency"`
}

type DependencyLocation struct {
Package PackageName `json:"package"`
DependencyLocationVersion string `json:"version"`
Iid string `json:"iid"`
Direct bool `json:"direct"`
DependencyPath string `json:"iid"`
}

type PackageName struct {
Name string `json:"name"`
}

type DependencyFile struct {
Path string `json:"path"`
PackageManager string `json:"package_manager"`
Dependencies []DependencyLocation `json:"dependencies"`
}

0 comments on commit 5cb4106

Please sign in to comment.