Skip to content

Commit ad93864

Browse files
patrick.rissmann@l3montree.compatrick.rissmann@l3montree.com
authored andcommitted
Added all the different cases to the scanner_id in the component repository as well
1 parent a87415b commit ad93864

13 files changed

Lines changed: 75 additions & 54 deletions

internal/core/assetversion/asset_version_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ func (a *assetVersionController) Metrics(ctx core.Context) error {
248248
assetVersion := core.GetAssetVersion(ctx)
249249
scannerIds := []string{}
250250
// get the latest events of this asset per scan type
251-
err := a.assetVersionRepository.GetDB(nil).Table("dependency_vulns").Select("DISTINCT scanner_id").Where("asset_version_name = ? AND asset_id = ?", assetVersion.Name, assetVersion.AssetID).Pluck("scanner_id", &scannerIds).Error
251+
err := a.assetVersionRepository.GetDB(nil).Table("dependency_vulns").Select("DISTINCT scanner_ids").Where("asset_version_name = ? AND asset_id = ?", assetVersion.Name, assetVersion.AssetID).Pluck("scanner_ids", &scannerIds).Error
252252

253253
if err != nil {
254254
return err

internal/core/assetversion/asset_version_service.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ func buildBomRefMap(bom normalize.SBOM) map[string]cdx.Component {
336336

337337
func (s *service) UpdateSBOM(assetVersion models.AssetVersion, scannerID string, sbom normalize.SBOM) error {
338338
// load the asset components
339+
scannerID = "AdditionalScanner"
339340
assetComponents, err := s.componentRepository.LoadComponents(nil, assetVersion.Name, assetVersion.AssetID, scannerID)
340341
if err != nil {
341342
return errors.Wrap(err, "could not load asset components")
@@ -372,7 +373,7 @@ func (s *service) UpdateSBOM(assetVersion models.AssetVersion, scannerID string,
372373
dependencies = append(dependencies,
373374
models.ComponentDependency{
374375
ComponentPurl: nil, // direct dependency - therefore set it to nil
375-
ScannerID: scannerID,
376+
ScannerIDs: scannerID + " ",
376377
DependencyPurl: componentPackageUrl,
377378
},
378379
)
@@ -398,7 +399,7 @@ func (s *service) UpdateSBOM(assetVersion models.AssetVersion, scannerID string,
398399
dependencies = append(dependencies,
399400
models.ComponentDependency{
400401
ComponentPurl: utils.EmptyThenNil(compPackageUrl),
401-
ScannerID: scannerID,
402+
ScannerIDs: scannerID + " ",
402403
DependencyPurl: depPurlOrName,
403404
},
404405
)
@@ -431,7 +432,7 @@ func (s *service) UpdateSBOM(assetVersion models.AssetVersion, scannerID string,
431432
return err
432433
}
433434

434-
if err = s.componentRepository.HandleStateDiff(nil, assetVersion.Name, assetVersion.AssetID, assetComponents, dependencies); err != nil {
435+
if err = s.componentRepository.HandleStateDiff(nil, assetVersion.Name, assetVersion.AssetID, assetComponents, dependencies, scannerID); err != nil {
435436
return err
436437
}
437438

internal/core/common_interfaces.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ type ComponentRepository interface {
9292
LoadPathToComponent(tx DB, assetVersionName string, assetID uuid.UUID, pURL string, scannerID string) ([]models.ComponentDependency, error)
9393
SaveBatch(tx DB, components []models.Component) error
9494
FindByPurl(tx DB, purl string) (models.Component, error)
95-
HandleStateDiff(tx DB, assetVersionName string, assetID uuid.UUID, oldState []models.ComponentDependency, newState []models.ComponentDependency) error
95+
HandleStateDiff(tx DB, assetVersionName string, assetID uuid.UUID, oldState []models.ComponentDependency, newState []models.ComponentDependency, scannerID string) error
9696
GetDependencyCountPerScanner(assetVersionName string, assetID uuid.UUID) (map[string]int, error)
9797
GetLicenseDistribution(tx DB, assetVersionName string, assetID uuid.UUID, scannerID string) (map[string]int, error)
9898
}
@@ -107,7 +107,6 @@ type DependencyVulnRepository interface {
107107
GetDefaultDependencyVulnsByOrgIdPaged(tx DB, userAllowedProjectIds []string, pageInfo PageInfo, search string, filter []FilterQuery, sort []SortQuery) (Paged[models.DependencyVuln], error)
108108
GetDefaultDependencyVulnsByProjectIdPaged(tx DB, projectID uuid.UUID, pageInfo PageInfo, search string, filter []FilterQuery, sort []SortQuery) (Paged[models.DependencyVuln], error)
109109
GetDependencyVulnsByAssetVersionPagedAndFlat(tx DB, assetVersionName string, assetVersionID uuid.UUID, pageInfo PageInfo, search string, filter []FilterQuery, sort []SortQuery) (Paged[models.DependencyVuln], error)
110-
ListByScanner(assetVersionName string, assetID uuid.UUID, scannerID string) ([]models.DependencyVuln, error)
111110
ListByAssetAndAssetVersion(assetVersionName string, assetID uuid.UUID) ([]models.DependencyVuln, error)
112111
GetDependencyVulnsByPurl(tx DB, purls []string) ([]models.DependencyVuln, error)
113112
ApplyAndSave(tx DB, dependencyVuln *models.DependencyVuln, vulnEvent *models.VulnEvent) error

internal/core/component/component_dto.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type componentDTO struct {
1414
Dependency models.Component `json:"dependency"`
1515
DependencyPurl string `json:"dependencyPurl"` // will be nil, for direct dependencies
1616
AssetID uuid.UUID `json:"assetVersionId"`
17-
ScannerID string `json:"scannerId"` // the id of the scanner
17+
ScannerIDs string `json:"scanner"` // the id of the scanner
1818
}
1919

2020
func toDTO(m models.ComponentDependency) componentDTO {
@@ -23,6 +23,6 @@ func toDTO(m models.ComponentDependency) componentDTO {
2323
Dependency: m.Dependency,
2424
DependencyPurl: m.DependencyPurl,
2525
AssetID: m.AssetID,
26-
ScannerID: m.ScannerID,
26+
ScannerIDs: m.ScannerIDs,
2727
}
2828
}

internal/core/dependency_vuln/dependency_vuln_controller.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func (c dependencyVulnHttpController) ListPaged(ctx core.Context) error {
135135
// append the dependencyVuln to the package
136136
dependencyVulnsByPackage.DependencyVulns = append(res[*dependencyVuln.ComponentPurl].DependencyVulns, DependencyVulnDTO{
137137
ID: dependencyVuln.ID,
138-
ScannerID: dependencyVuln.ScannerIDs,
138+
ScannerIDs: dependencyVuln.ScannerIDs,
139139
Message: dependencyVuln.Message,
140140
AssetVersionName: dependencyVuln.AssetVersionName,
141141
AssetID: dependencyVuln.AssetID.String(),
@@ -296,7 +296,7 @@ func convertToDetailedDTO(dependencyVuln models.DependencyVuln) detailedDependen
296296
Priority: dependencyVuln.Priority,
297297
LastDetected: dependencyVuln.LastDetected,
298298
CreatedAt: dependencyVuln.CreatedAt,
299-
ScannerID: dependencyVuln.ScannerIDs,
299+
ScannerIDs: dependencyVuln.ScannerIDs,
300300
TicketID: dependencyVuln.TicketID,
301301
TicketURL: dependencyVuln.TicketURL,
302302
RiskRecalculatedAt: dependencyVuln.RiskRecalculatedAt,

internal/core/dependency_vuln/dependency_vuln_dto.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424

2525
type DependencyVulnDTO struct {
2626
ID string `json:"id"`
27-
ScannerID string `json:"scanner"`
27+
ScannerIDs string `json:"scanner"`
2828
Message *string `json:"message"`
2929
AssetVersionName string `json:"assetVersionId"`
3030
AssetID string `json:"assetId"`
@@ -55,7 +55,7 @@ func DependencyVulnToDto(f models.DependencyVuln) DependencyVulnDTO {
5555

5656
return DependencyVulnDTO{
5757
ID: f.ID,
58-
ScannerID: f.ScannerIDs,
58+
ScannerIDs: f.ScannerIDs,
5959
Message: f.Message,
6060
AssetVersionName: f.AssetVersionName,
6161
AssetID: f.AssetID.String(),

internal/core/vulndb/scan/scan_controller.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ func DependencyVulnScan(c core.Context, bom normalize.SBOM, s *httpController) (
9494
return scanResults, err
9595
}
9696

97-
scanner := c.Request().Header.Get("X-Scanner")
98-
if scanner == "" {
97+
scannerID := c.Request().Header.Get("X-Scanner")
98+
if scannerID == "" {
9999
slog.Error("no X-Scanner header found")
100100
return scanResults, err
101101
}
@@ -106,7 +106,7 @@ func DependencyVulnScan(c core.Context, bom normalize.SBOM, s *httpController) (
106106

107107
if doRiskManagement {
108108
// update the sbom in the database in parallel
109-
if err := s.assetVersionService.UpdateSBOM(assetVersion, scanner, normalizedBom); err != nil {
109+
if err := s.assetVersionService.UpdateSBOM(assetVersion, scannerID, normalizedBom); err != nil {
110110
slog.Error("could not update sbom", "err", err)
111111
return scanResults, err
112112
}
@@ -120,12 +120,6 @@ func DependencyVulnScan(c core.Context, bom normalize.SBOM, s *httpController) (
120120
return scanResults, err
121121
}
122122

123-
scannerID := c.Request().Header.Get("X-Scanner")
124-
if scannerID == "" {
125-
slog.Error("no scanner id provided")
126-
return scanResults, err
127-
}
128-
129123
// handle the scan result
130124
amountOpened, amountClose, newState, err := s.assetVersionService.HandleScanResult(asset, &assetVersion, vulns, scannerID, userID, doRiskManagement)
131125
if err != nil {

internal/database/models/component_model.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ type ComponentDependency struct {
8484
AssetVersionName string `json:"assetVersionName"`
8585
AssetVersion AssetVersion `json:"assetVersion" gorm:"foreignKey:AssetID,AssetVersionName;references:AssetID,Name;constraint:OnDelete:CASCADE;"`
8686

87-
ScannerID string `json:"scannerId" gorm:"column:scanner_id"` // the id of the scanner
87+
ScannerIDs string `json:"scannerId" gorm:"column:scanner_ids"` // the ids of scanner which found this component separated by white spaces
8888

8989
Depth int `json:"depth" gorm:"column:depth"`
9090
}

internal/database/models/vulnerability_model.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type Vulnerability struct {
1717
Message *string `json:"message"`
1818

1919
// the scanner which was used to detect this dependencyVuln
20-
ScannerIDs string `json:"scanner" gorm:"not null;"` //List of scanner ids separated by a white space
20+
ScannerIDs string `json:"scanner" gorm:"not null;column:scanner_ids"` //List of scanner ids separated by a white space
2121

2222
Events []VulnEvent `gorm:"foreignKey:VulnID;constraint:OnDelete:CASCADE,OnUpdate:CASCADE;" json:"events"`
2323

internal/database/repositories/component_repository.go

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ func (c *componentRepository) LoadComponents(tx core.DB, assetVersionName string
6363
query := c.GetDB(tx).Preload("Component").Preload("Dependency").Where("asset_version_name = ? AND asset_id = ?", assetVersionName, assetID)
6464

6565
if scannerID != "" {
66-
query = query.Where("scanner_id LIKE %?%", scannerID)
66+
scannerID = "%" + scannerID + "%"
67+
query = query.Where("scanner_ids LIKE ?", scannerID)
6768
}
6869

6970
err = query.Find(&components).Error
@@ -82,15 +83,16 @@ func (c *componentRepository) LoadPathToComponent(tx core.DB, assetVersionName s
8283

8384
//Find all needed components recursively until we hit the root component
8485

86+
scannerID = "%" + scannerID + "%"
8587
query := c.GetDB(tx).Raw(`WITH RECURSIVE components_cte AS (
86-
SELECT component_purl,dependency_purl,asset_id,scanner_id,depth,semver_start,semver_end
88+
SELECT component_purl,dependency_purl,asset_id,scanner_ids,depth,semver_start,semver_end
8789
FROM component_dependencies
88-
WHERE dependency_purl like ? AND asset_id = ? AND asset_version_name = ? AND scanner_id LIKE %?%
90+
WHERE dependency_purl like ? AND asset_id = ? AND asset_version_name = ? AND scanner_ids LIKE ?
8991
UNION ALL
90-
SELECT co.component_purl,co.dependency_purl,co.asset_id,co.scanner_id,co.depth,co.semver_start,co.semver_end
92+
SELECT co.component_purl,co.dependency_purl,co.asset_id,co.scanner_ids,co.depth,co.semver_start,co.semver_end
9193
FROM component_dependencies AS co
9294
INNER JOIN components_cte AS cte ON co.dependency_purl = cte.component_purl
93-
WHERE co.asset_id = ? AND co.asset_version_name = ? AND co.scanner_id LIKE %?%
95+
WHERE co.asset_id = ? AND co.asset_version_name = ? AND co.scanner_ids LIKE ?
9496
)
9597
SELECT DISTINCT * FROM components_cte`, pURL, assetID, assetVersionName, scannerID, assetID, assetVersionName, scannerID)
9698

@@ -114,7 +116,8 @@ func (c *componentRepository) GetLicenseDistribution(tx core.DB, assetVersionNam
114116
query := c.GetDB(tx).Table("components").Select("components.license as license, COUNT(components.license) as count").Joins("RIGHT JOIN component_dependencies ON components.purl = component_dependencies.dependency_purl").Where("asset_version_name = ? AND asset_id = ?", assetVersionName, assetID).Group("components.license")
115117

116118
if scannerID != "" {
117-
query = query.Where("scanner_id LIKE %?%", scannerID)
119+
scannerID = "%" + scannerID + "%"
120+
query = query.Where("scanner_ids LIKE ?", scannerID)
118121
}
119122

120123
err = query.Scan(&licenses).Error
@@ -146,7 +149,8 @@ func (c *componentRepository) LoadComponentsWithProject(tx core.DB, assetVersion
146149
query := c.GetDB(tx).Model(&models.ComponentDependency{}).Joins("Dependency").Joins("Dependency.ComponentProject").Where("asset_version_name = ? AND asset_id = ?", assetVersionName, assetID)
147150

148151
if scannerID != "" {
149-
query = query.Where("scanner_id LIKE %?%", scannerID)
152+
scannerID = "%" + scannerID + "%"
153+
query = query.Where("scanner_ids LIKE ?", scannerID)
150154
}
151155

152156
for _, f := range filter {
@@ -180,29 +184,41 @@ func (c *componentRepository) LoadComponentsWithProject(tx core.DB, assetVersion
180184
return core.NewPaged(pageInfo, total, components), err
181185
}
182186

183-
func (c *componentRepository) LoadAllLatestComponentFromAssetVersion(tx core.DB, assetVersion models.AssetVersion, scannerID string) ([]models.ComponentDependency, error) {
184-
var component []models.ComponentDependency
185-
err := c.GetDB(tx).Preload("Component").Preload("Dependency").Where("asset_version_name = ? AND asset_id AND scanner_id LIKE %?%", assetVersion.Name, assetVersion.AssetID).Find(&component).Error
186-
return component, err
187-
}
188-
189187
func (c *componentRepository) FindByPurl(tx core.DB, purl string) (models.Component, error) {
190188
var component models.Component
191189
err := c.GetDB(tx).Where("purl = ?", purl).First(&component).Error
192190
return component, err
193191
}
194192

195-
func (c *componentRepository) HandleStateDiff(tx core.DB, assetVersionName string, assetID uuid.UUID, oldState []models.ComponentDependency, newState []models.ComponentDependency) error {
193+
func (c *componentRepository) HandleStateDiff(tx core.DB, assetVersionName string, assetID uuid.UUID, oldState []models.ComponentDependency, newState []models.ComponentDependency, scannerID string) error {
196194
comparison := utils.CompareSlices(oldState, newState, func(dep models.ComponentDependency) string {
197195
return utils.SafeDereference(dep.ComponentPurl) + "->" + dep.DependencyPurl
198196
})
199197

200198
removed := comparison.OnlyInA
201199
added := comparison.OnlyInB
200+
needToBeChanged := comparison.InBoth
202201

203202
return c.GetDB(tx).Transaction(func(tx *gorm.DB) error {
204-
if len(removed) != 0 {
205-
if err := c.GetDB(tx).Delete(&removed).Error; err != nil {
203+
dependenciesToUpdate, err := removeScannerIDFromComponents(tx, c, removed, scannerID)
204+
if err != nil {
205+
return err
206+
}
207+
if len(dependenciesToUpdate) > 0 {
208+
err := c.db.Save(dependenciesToUpdate).Error
209+
if err != nil {
210+
return err
211+
}
212+
}
213+
214+
for i := range needToBeChanged {
215+
if !strings.Contains(needToBeChanged[i].ScannerIDs, scannerID) {
216+
needToBeChanged[i].ScannerIDs = needToBeChanged[i].ScannerIDs + scannerID + " "
217+
}
218+
}
219+
if len(needToBeChanged) > 0 {
220+
err := c.db.Save(needToBeChanged).Error
221+
if err != nil {
206222
return err
207223
}
208224
}
@@ -219,12 +235,12 @@ func (c *componentRepository) HandleStateDiff(tx core.DB, assetVersionName strin
219235

220236
func (c *componentRepository) GetDependencyCountPerScanner(assetVersionName string, assetID uuid.UUID) (map[string]int, error) {
221237
var results []struct {
222-
ScannerID string `gorm:"column:scanner_id"`
238+
ScannerID string `gorm:"column:scanner_ids"`
223239
Count int `gorm:"column:count"`
224240
}
225241
err := c.db.Model(&models.Component{}).
226-
Select("scanner_id , COUNT(*) as count").
227-
Group("scanner_id").
242+
Select("scanner_ids , COUNT(*) as count").
243+
Group("scanner_ids").
228244
Where("asset_version_name = ?", assetVersionName).
229245
Where("asset_id = ?", assetID).
230246
Find(&results).Error
@@ -241,3 +257,21 @@ func (c *componentRepository) GetDependencyCountPerScanner(assetVersionName stri
241257

242258
return counts, nil
243259
}
260+
261+
func removeScannerIDFromComponents(tx core.DB, c *componentRepository, components []models.ComponentDependency, scannerID string) ([]models.ComponentDependency, error) {
262+
var componentDependeciesToChange []models.ComponentDependency
263+
scannerID += " "
264+
for i := range components {
265+
266+
if components[i].ScannerIDs == scannerID {
267+
if err := c.GetDB(tx).Delete(&components[i]).Error; err != nil {
268+
return componentDependeciesToChange, err
269+
}
270+
} else {
271+
components[i].ScannerIDs = strings.Replace(components[i].ScannerIDs, scannerID, "", 1)
272+
componentDependeciesToChange = append(componentDependeciesToChange, components[i])
273+
}
274+
}
275+
276+
return componentDependeciesToChange, nil
277+
}

0 commit comments

Comments
 (0)