@@ -183,7 +183,7 @@ func (s *service) HandleScanResult(asset models.Asset, assetVersion *models.Asse
183183 Vulnerability : models.Vulnerability {
184184 AssetVersionName : assetVersion .Name ,
185185 AssetID : asset .ID ,
186- ScannerIDs : scannerID + " " ,
186+ ScannerIDs : scannerID ,
187187 },
188188 CVEID : utils .Ptr (v .CVEID ),
189189 ComponentPurl : utils .Ptr (v .Purl ),
@@ -209,7 +209,6 @@ func (s *service) HandleScanResult(asset models.Asset, assetVersion *models.Asse
209209 devguardScanner := "github.com/l3montree-dev/devguard/cmd/devguard-scanner" + "/"
210210
211211 switch scannerID {
212-
213212 case devguardScanner + "sca" :
214213 assetVersion .LastScaScan = utils .Ptr (time .Now ())
215214 case devguardScanner + "container-scanning" :
@@ -219,12 +218,43 @@ func (s *service) HandleScanResult(asset models.Asset, assetVersion *models.Asse
219218 return amountOpened , amountClosed , amountExisting , nil
220219}
221220
221+ func diffScanResults (currentScanner string , foundVulnerabilities []models.DependencyVuln , existingDependencyVulns []models.DependencyVuln ) ([]models.DependencyVuln , []models.DependencyVuln , []models.DependencyVuln , []models.DependencyVuln ) {
222+ comparison := utils .CompareSlices (existingDependencyVulns , foundVulnerabilities , func (dependencyVuln models.DependencyVuln ) string {
223+ return dependencyVuln .CalculateHash ()
224+ })
225+
226+ foundByScannerAndNotExisting := comparison .OnlyInB //We want to create new vulnerabilities for these
227+ foundByScannerAndExisting := comparison .InBoth //We have to check if it was already found by this scanner or only by other scanners
228+ notFoundByScannerAndExisting := comparison .OnlyInA //We have to update all vulnerabilities which were previously found by this scanner and now aren't
229+
230+ var detectedByOtherScanner []models.DependencyVuln
231+ var notDetectedByScannerAnymore []models.DependencyVuln
232+
233+ var fixedVulns []models.DependencyVuln //We should collect all vulnerabilities we want to fix so we can do it all at once
234+
235+ // Now we work on the vulnerabilities found in both sets -> has the vulnerability this scanner id already in his scanner_ids
236+ for i := range foundByScannerAndExisting {
237+ if ! strings .Contains (foundByScannerAndExisting [i ].ScannerIDs , currentScanner ) {
238+ detectedByOtherScanner = append (detectedByOtherScanner , foundByScannerAndExisting [i ])
239+ }
240+ }
241+
242+ // Last we have to change the already existing vulnerabilities which were not found this time
243+ for i := range notFoundByScannerAndExisting {
244+ if strings .TrimSpace (notFoundByScannerAndExisting [i ].ScannerIDs ) == currentScanner {
245+ fixedVulns = append (fixedVulns , notFoundByScannerAndExisting [i ])
246+ } else if strings .Contains (notFoundByScannerAndExisting [i ].ScannerIDs , currentScanner ) {
247+ notDetectedByScannerAnymore = append (notDetectedByScannerAnymore , notFoundByScannerAndExisting [i ])
248+ }
249+ }
250+
251+ return foundByScannerAndNotExisting , fixedVulns , detectedByOtherScanner , notDetectedByScannerAnymore
252+ }
253+
222254func (s * service ) handleScanResult (userID string , scannerID string , assetVersion * models.AssetVersion , dependencyVulns []models.DependencyVuln , doRiskManagement bool , asset models.Asset ) (int , int , []models.DependencyVuln , error ) {
223255 // get all existing dependencyVulns from the database - this is the old state
224-
225256 //number := rand.IntN(len(dependencyVulns))
226257 //dependencyVulns = dependencyVulns[:0]
227- scannerID = scannerID + " "
228258 existingDependencyVulns , err := s .dependencyVulnRepository .ListByAssetAndAssetVersion (assetVersion .Name , assetVersion .AssetID )
229259 if err != nil {
230260 slog .Error ("could not get existing dependencyVulns" , "err" , err )
@@ -236,84 +266,36 @@ func (s *service) handleScanResult(userID string, scannerID string, assetVersion
236266 return dependencyVuln .State != models .VulnStateFixed
237267 })
238268
239- comparison := utils .CompareSlices (existingDependencyVulns , dependencyVulns , func (dependencyVuln models.DependencyVuln ) string {
240- return dependencyVuln .CalculateHash ()
241- })
242-
243- foundByScannerAndNotExisting := comparison .OnlyInB //We want to create new vulnerabilities for these
244- foundByScannerAndExisting := comparison .InBoth //We have to check if it was already found by this scanner or only by other scanners
245- notFoundByScannerAndExisting := comparison .OnlyInA //We have to update all vulnerabilities which were previously found by this scanner and now aren't
269+ newDetectedVulns , fixedVulns , firstTimeDetectedByCurrentScanner , notDetectedByCurrentScannerAnymore := diffScanResults (scannerID , dependencyVulns , existingDependencyVulns )
270+ amountFixed := len (utils .Filter (fixedVulns , func (dependencyVuln models.DependencyVuln ) bool {
271+ return dependencyVuln .State == models .VulnStateOpen
272+ }))
246273
247- var vulnerabilitiesToFix []models.DependencyVuln //We should collect all vulnerabilities we want to fix so we can do it all at once
248- var vulnerabilitiesToUpdate []models.DependencyVuln //We should do the same
249- // get a transaction
250274 if err := s .dependencyVulnRepository .Transaction (func (tx core.DB ) error {
251275 // We can create the newly found one without checking anything
252- if err := s .dependencyVulnService .UserDetectedDependencyVulns (tx , userID , foundByScannerAndNotExisting , * assetVersion , asset , true ); err != nil {
276+ if err := s .dependencyVulnService .UserDetectedDependencyVulns (tx , userID , newDetectedVulns , * assetVersion , asset , true ); err != nil {
253277 return err // this will cancel the transaction
254278 }
255279
256- // Now we work on the vulnerabilities found in both sets -> has the vulnerability this scanner id already in his scanner_ids
257- for i := range foundByScannerAndExisting {
258- if ! strings .Contains (foundByScannerAndExisting [i ].ScannerIDs , scannerID ) {
259- foundByScannerAndExisting [i ].ScannerIDs = foundByScannerAndExisting [i ].ScannerIDs + " " + scannerID
260- vulnerabilitiesToUpdate = append (vulnerabilitiesToUpdate , foundByScannerAndExisting [i ])
261- }
262- }
263- err = s .dependencyVulnRepository .SaveBatch (tx , foundByScannerAndExisting )
264- if err != nil {
265- slog .Error ("error when trying to update vulnerabilities" )
266- return err
267- }
268-
269- err = s .dependencyVulnService .MakeAddedScannerEvent (tx , vulnerabilitiesToUpdate , userID )
280+ err = s .dependencyVulnService .UserDetectedDependencyVulnWithAnotherScanner (tx , firstTimeDetectedByCurrentScanner , userID , scannerID )
270281 if err != nil {
271282 slog .Error ("error when trying to add events for adding scanner to vulnerability" )
272283 return err
273284 }
274285
275- vulnerabilitiesToUpdate = nil
276-
277- //Last we have to change the already existing vulnerabilities which were not found this time
278- for i := range notFoundByScannerAndExisting {
279- if notFoundByScannerAndExisting [i ].ScannerIDs == scannerID {
280- notFoundByScannerAndExisting [i ].ScannerIDs = ""
281- vulnerabilitiesToFix = append (vulnerabilitiesToFix , notFoundByScannerAndExisting [i ])
282- } else if strings .Contains (notFoundByScannerAndExisting [i ].ScannerIDs , scannerID ) {
283- removeScannerFromVulnerability (& notFoundByScannerAndExisting [i ], scannerID )
284- vulnerabilitiesToUpdate = append (vulnerabilitiesToUpdate , notFoundByScannerAndExisting [i ])
285- }
286- }
287-
288- err = s .dependencyVulnRepository .SaveBatch (tx , vulnerabilitiesToUpdate )
289- if err != nil {
290- slog .Error ("error when trying to update vulnerabilities" )
291- return err
292- }
293-
294- err := s .dependencyVulnService .MakeRemoveScannerEvent (tx , vulnerabilitiesToUpdate , userID )
286+ err := s .dependencyVulnService .UserDidNotDetectDependencyVulnWithScannerAnymore (tx , notDetectedByCurrentScannerAnymore , userID , scannerID )
295287 if err != nil {
296288 slog .Error ("error when trying to add events for removing scanner from vulnerability" )
297289 return err
298290 }
299291
300- return s .dependencyVulnService .UserFixedDependencyVulns (tx , userID , vulnerabilitiesToFix , * assetVersion , asset , true )
292+ return s .dependencyVulnService .UserFixedDependencyVulns (tx , userID , fixedVulns , * assetVersion , asset , true )
301293 }); err != nil {
302294 slog .Error ("could not save dependencyVulns" , "err" , err )
303295 return 0 , 0 , []models.DependencyVuln {}, err
304296 }
305297
306- // the amount we actually fixed, is the amount that was open before
307- vulnerabilitiesToFix = utils .Filter (vulnerabilitiesToFix , func (dependencyVuln models.DependencyVuln ) bool {
308- return dependencyVuln .State == models .VulnStateOpen
309- })
310- return len (foundByScannerAndNotExisting /* maybe also return vulns newly found by this scanner*/ ), len (vulnerabilitiesToFix ), append (foundByScannerAndNotExisting , comparison .InBoth ... ), nil
311- }
312-
313- // pass by reference to edit the actual vulnerability and not a copy
314- func removeScannerFromVulnerability (vulnerability * models.DependencyVuln , scannerID string ) {
315-
316- vulnerability .ScannerIDs = strings .Replace (vulnerability .ScannerIDs , scannerID , "" , 1 )
298+ return len (newDetectedVulns ) + len (firstTimeDetectedByCurrentScanner ), amountFixed , append (newDetectedVulns , firstTimeDetectedByCurrentScanner ... ), nil
317299}
318300
319301func recursiveBuildBomRefMap (component cdx.Component ) map [string ]cdx.Component {
@@ -348,7 +330,6 @@ func buildBomRefMap(bom normalize.SBOM) map[string]cdx.Component {
348330
349331func (s * service ) UpdateSBOM (assetVersion models.AssetVersion , scannerID string , sbom normalize.SBOM ) error {
350332 // load the asset components
351-
352333 assetComponents , err := s .componentRepository .LoadComponents (nil , assetVersion .Name , assetVersion .AssetID , "" )
353334 if err != nil {
354335 return errors .Wrap (err , "could not load asset components" )
@@ -385,7 +366,7 @@ func (s *service) UpdateSBOM(assetVersion models.AssetVersion, scannerID string,
385366 dependencies = append (dependencies ,
386367 models.ComponentDependency {
387368 ComponentPurl : nil , // direct dependency - therefore set it to nil
388- ScannerIDs : scannerID + " " ,
369+ ScannerIDs : scannerID ,
389370 DependencyPurl : componentPackageUrl ,
390371 },
391372 )
@@ -411,7 +392,7 @@ func (s *service) UpdateSBOM(assetVersion models.AssetVersion, scannerID string,
411392 dependencies = append (dependencies ,
412393 models.ComponentDependency {
413394 ComponentPurl : utils .EmptyThenNil (compPackageUrl ),
414- ScannerIDs : scannerID + " " ,
395+ ScannerIDs : scannerID ,
415396 DependencyPurl : depPurlOrName ,
416397 },
417398 )
0 commit comments