Skip to content

Commit

Permalink
Curation support for GitHub summary (#111)
Browse files Browse the repository at this point in the history
  • Loading branch information
asafambar authored Jul 25, 2024
1 parent cda1c4e commit b89f58d
Show file tree
Hide file tree
Showing 6 changed files with 363 additions and 40 deletions.
69 changes: 62 additions & 7 deletions commands/curation/curationaudit.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/jfrog/jfrog-cli-security/formats"
"net/http"
"os"
"path/filepath"
Expand Down Expand Up @@ -175,16 +176,20 @@ type CurationAuditCommand struct {
utils.AuditParams
}

type CurationReport struct {
packagesStatus []*PackageStatus
totalNumberOfPackages int
}

func NewCurationAuditCommand() *CurationAuditCommand {
return &CurationAuditCommand{
extractPoliciesRegex: regexp.MustCompile(extractPoliciesRegexTemplate),
AuditParams: &utils.AuditBasicParams{},
}
}

func (ca *CurationAuditCommand) setPackageManagerConfig(pkgMangerConfig *project.RepositoryConfig) *CurationAuditCommand {
func (ca *CurationAuditCommand) setPackageManagerConfig(pkgMangerConfig *project.RepositoryConfig) {
ca.PackageManagerConfig = pkgMangerConfig
return ca
}

func (ca *CurationAuditCommand) SetWorkingDirs(dirs []string) *CurationAuditCommand {
Expand All @@ -211,7 +216,7 @@ func (ca *CurationAuditCommand) Run() (err error) {
} else {
ca.workingDirs = append(ca.workingDirs, rootDir)
}
results := map[string][]*PackageStatus{}
results := map[string]*CurationReport{}
for _, workDir := range ca.workingDirs {
var absWd string
absWd, err = filepath.Abs(workDir)
Expand All @@ -234,12 +239,54 @@ func (ca *CurationAuditCommand) Run() (err error) {
}

for projectPath, packagesStatus := range results {
err = errors.Join(err, printResult(ca.OutputFormat(), projectPath, packagesStatus))
err = errors.Join(err, printResult(ca.OutputFormat(), projectPath, packagesStatus.packagesStatus))
}

err = errors.Join(err, utils.RecordSecurityCommandOutput(utils.ScanCommandSummaryResult{Results: convertResultsToSummary(results), Section: utils.Curation}))
return
}

func (ca *CurationAuditCommand) doCurateAudit(results map[string][]*PackageStatus) error {
func convertResultsToSummary(results map[string]*CurationReport) formats.SummaryResults {
summaryResults := formats.SummaryResults{}
for projectPath, packagesStatus := range results {
blocked := convertBlocked(packagesStatus.packagesStatus)
approved := packagesStatus.totalNumberOfPackages - blocked.GetCountOfKeys(false)

summaryResults.Scans = append(summaryResults.Scans, formats.ScanSummaryResult{Target: projectPath,
CuratedPackages: &formats.CuratedPackages{
Blocked: blocked,
Approved: approved,
}})
}
return summaryResults
}

func convertBlocked(pkgStatus []*PackageStatus) formats.TwoLevelSummaryCount {
blocked := formats.TwoLevelSummaryCount{}
for _, pkg := range pkgStatus {
for _, policy := range pkg.Policy {
polAndCond := formatPolicyAndCond(policy.Policy, policy.Condition)
if _, ok := blocked[polAndCond]; !ok {
blocked[polAndCond] = formats.SummaryCount{}
}
uniqId := uniqPkgAppearanceId(pkg.ParentName, pkg.ParentVersion, pkg.PackageName, pkg.PackageVersion)
blocked[polAndCond][uniqId]++
}
}
return blocked
}

func formatPolicyAndCond(policy, cond string) string {
return fmt.Sprintf("Policy: %s, Condition: %s", policy, cond)
}

// The unique identifier of a package includes both the package name with its version and the parent package with its version
func uniqPkgAppearanceId(parentName, parentVersion, packageName, packageVersion string) string {
return fmt.Sprintf("%s:%s-%s:%s",
parentName, parentVersion, packageName, packageVersion)
}

func (ca *CurationAuditCommand) doCurateAudit(results map[string]*CurationReport) error {
techs := techutils.DetectedTechnologiesList()
for _, tech := range techs {
supportedFunc, ok := supportedTech[techutils.Technology(tech)]
Expand All @@ -259,6 +306,10 @@ func (ca *CurationAuditCommand) doCurateAudit(results map[string][]*PackageStatu
if err := ca.auditTree(techutils.Technology(tech), results); err != nil {
return err
}
// clear the package manager config to avoid using the same config for the next tech
ca.setPackageManagerConfig(nil)
ca.AuditParams = ca.SetDepsRepo("")

}
return nil
}
Expand Down Expand Up @@ -293,7 +344,7 @@ func (ca *CurationAuditCommand) getAuditParamsByTech(tech techutils.Technology)
return ca.AuditParams
}

func (ca *CurationAuditCommand) auditTree(tech techutils.Technology, results map[string][]*PackageStatus) error {
func (ca *CurationAuditCommand) auditTree(tech techutils.Technology, results map[string]*CurationReport) error {
params := ca.getAuditParamsByTech(tech)
serverDetails, err := audit.SetResolutionRepoIfExists(params, tech)
if err != nil {
Expand Down Expand Up @@ -364,7 +415,11 @@ func (ca *CurationAuditCommand) auditTree(tech techutils.Technology, results map
sort.Slice(packagesStatus, func(i, j int) bool {
return packagesStatus[i].ParentName < packagesStatus[j].ParentName
})
results[strings.TrimSuffix(fmt.Sprintf("%s:%s", projectName, projectVersion), ":")] = packagesStatus
results[strings.TrimSuffix(fmt.Sprintf("%s:%s", projectName, projectVersion), ":")] = &CurationReport{
packagesStatus: packagesStatus,
// We subtract 1 because the root node is not a package.
totalNumberOfPackages: len(depTreeResult.FlatTree.Nodes) - 1,
}
return err
}

Expand Down
Loading

0 comments on commit b89f58d

Please sign in to comment.