44 "fmt"
55 "log/slog"
66 "math"
7+ "math/rand/v2"
78 "net/http"
89 "strings"
910 "time"
@@ -72,7 +73,7 @@ func (s *service) HandleFirstPartyVulnResult(asset models.Asset, assetVersion *m
7273 AssetVersionName : assetVersion .Name ,
7374 AssetID : asset .ID ,
7475 Message : & result .Message .Text ,
75- ScannerIDs : scannerID ,
76+ ScannerID : scannerID ,
7677 },
7778 RuleID : result .RuleId ,
7879 Uri : result .Locations [0 ].PhysicalLocation .ArtifactLocation .Uri ,
@@ -183,7 +184,7 @@ func (s *service) HandleScanResult(asset models.Asset, assetVersion *models.Asse
183184 Vulnerability : models.Vulnerability {
184185 AssetVersionName : assetVersion .Name ,
185186 AssetID : asset .ID ,
186- ScannerIDs : scannerID ,
187+ ScannerID : scannerID + " " ,
187188 },
188189 CVEID : utils .Ptr (v .CVEID ),
189190 ComponentPurl : utils .Ptr (v .Purl ),
@@ -221,6 +222,10 @@ func (s *service) HandleScanResult(asset models.Asset, assetVersion *models.Asse
221222
222223func (s * service ) handleScanResult (userID string , scannerID string , assetVersion * models.AssetVersion , dependencyVulns []models.DependencyVuln , doRiskManagement bool , asset models.Asset ) (int , int , []models.DependencyVuln , error ) {
223224 // get all existing dependencyVulns from the database - this is the old state
225+
226+ number := rand .IntN (len (dependencyVulns ))
227+ dependencyVulns = dependencyVulns [:number ]
228+ scannerID = scannerID + " "
224229 existingDependencyVulns , err := s .dependencyVulnRepository .ListByAssetAndAssetVersion (assetVersion .Name , assetVersion .AssetID )
225230 if err != nil {
226231 slog .Error ("could not get existing dependencyVulns" , "err" , err )
@@ -240,31 +245,64 @@ func (s *service) handleScanResult(userID string, scannerID string, assetVersion
240245 foundByScannerAndExisting := comparison .InBoth //We have to check if it was already found by this scanner or only by other scanners
241246 notFoundByScannerAndExisting := comparison .OnlyInA //We have to update all vulnerabilities which were previously found by this scanner and now aren't
242247
248+ var vulnerabilitiesToFix []models.DependencyVuln //We should collect all vulnerabilities we want to fix so we can do it all at once
249+ var vulnerabilitiesToUpdate []models.DependencyVuln
243250 // get a transaction
244251 if err := s .dependencyVulnRepository .Transaction (func (tx core.DB ) error {
245252 // We can create the newly found one without checking anything
246253 if err := s .dependencyVulnService .UserDetectedDependencyVulns (tx , userID , foundByScannerAndNotExisting , * assetVersion , asset , true ); err != nil {
247254 return err // this will cancel the transaction
248255 }
256+
249257 // Now we work on the vulnerabilities found in both sets -> has the vulnerability this scanner id already in his scanner_ids
250- for _ , existingVulnerability := range foundByScannerAndExisting {
251- if ! strings .Contains (existingVulnerability .ScannerID , scannerID ) {
252- existingVulnerability .ScannerID = existingVulnerability .ScannerID + " " + scannerID
258+ for i := range foundByScannerAndExisting {
259+ if ! strings .Contains (foundByScannerAndExisting [i ].ScannerID , scannerID ) {
260+ fmt .Printf ("\n The Scanner ID before : %s\n " , foundByScannerAndExisting [i ].ScannerID )
261+ foundByScannerAndExisting [i ].ScannerID = foundByScannerAndExisting [i ].ScannerID + scannerID
262+ fmt .Printf ("\n The Scanner ID after : %s\n " , foundByScannerAndExisting [i ].ScannerID )
263+ }
264+ }
265+ err := s .dependencyVulnRepository .SaveBatch (tx , foundByScannerAndExisting )
266+ if err != nil {
267+ slog .Error ("error when trying to update vulnerabilities" )
268+ return err
269+ }
270+
271+ //Last we have to change the already existing vulnerabilities which were not found this time
272+
273+ for i := range notFoundByScannerAndExisting {
274+ if notFoundByScannerAndExisting [i ].ScannerID == scannerID {
275+ notFoundByScannerAndExisting [i ].ScannerID = ""
276+ vulnerabilitiesToFix = append (vulnerabilitiesToFix , notFoundByScannerAndExisting [i ])
277+ } else if strings .Contains (notFoundByScannerAndExisting [i ].ScannerID , scannerID ) {
278+ removeScannerFromVulnerability (& notFoundByScannerAndExisting [i ], scannerID )
279+ vulnerabilitiesToUpdate = append (vulnerabilitiesToUpdate , notFoundByScannerAndExisting [i ])
253280 }
254281 }
255- s .dependencyVulnRepository .ApplyAndSave (tx , & existingDependencyVulns )
256282
257- return s .dependencyVulnService .UserFixedDependencyVulns (tx , userID , fixedDependencyVulns , * assetVersion , asset , true )
283+ err = s .dependencyVulnRepository .SaveBatch (tx , vulnerabilitiesToUpdate )
284+ if err != nil {
285+ slog .Error ("error when trying to update vulnerabilities" )
286+ return err
287+ }
288+
289+ return s .dependencyVulnService .UserFixedDependencyVulns (tx , userID , vulnerabilitiesToFix , * assetVersion , asset , true )
258290 }); err != nil {
259291 slog .Error ("could not save dependencyVulns" , "err" , err )
260292 return 0 , 0 , []models.DependencyVuln {}, err
261293 }
262294
263295 // the amount we actually fixed, is the amount that was open before
264- fixedDependencyVulns = utils .Filter (fixedDependencyVulns , func (dependencyVuln models.DependencyVuln ) bool {
296+ vulnerabilitiesToFix = utils .Filter (vulnerabilitiesToFix , func (dependencyVuln models.DependencyVuln ) bool {
265297 return dependencyVuln .State == models .VulnStateOpen
266298 })
267- return len (foundByScannerAndNotExisting ), len (fixedDependencyVulns ), append (foundByScannerAndNotExisting , comparison .InBoth ... ), nil
299+ return len (foundByScannerAndNotExisting /* maybe also return vulns newly found by this scanner*/ ), len (vulnerabilitiesToFix ), append (foundByScannerAndNotExisting , comparison .InBoth ... ), nil
300+ }
301+
302+ // pass by reference to edit the actual vulnerability and not a copy
303+ func removeScannerFromVulnerability (vulnerability * models.DependencyVuln , scannerID string ) {
304+
305+ vulnerability .ScannerID = strings .Replace (vulnerability .ScannerID , scannerID , "" , 1 )
268306}
269307
270308func recursiveBuildBomRefMap (component cdx.Component ) map [string ]cdx.Component {
0 commit comments