Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/devguard/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func main() {
}

fx.New(
fx.NopLogger,
// fx.NopLogger,
fx.Supply(db),
fx.Provide(database.BrokerFactory),
fx.Provide(api.NewServer),
Expand Down
3 changes: 2 additions & 1 deletion controllers/dependency_vuln_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/l3montree-dev/devguard/dtos"
"github.com/l3montree-dev/devguard/shared"
"github.com/l3montree-dev/devguard/statemachine"
"github.com/l3montree-dev/devguard/transformer"
"github.com/l3montree-dev/devguard/vulndb"

Expand Down Expand Up @@ -319,7 +320,7 @@ func (controller DependencyVulnController) SyncDependencyVulns(ctx shared.Contex
}

dependencyVuln.Events = events
events[len(events)-1].Apply(&dependencyVuln)
statemachine.Apply(&dependencyVuln, events[len(events)-1])

//update the dependencyVuln and its events
err = controller.dependencyVulnRepository.Save(nil, &dependencyVuln)
Expand Down
2 changes: 2 additions & 0 deletions database/models/vulnerability_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type Vuln interface {
GetTicketID() *string
GetTicketURL() *string
GetManualTicketCreation() bool
AssetVersionIndependentHash() string
GetEvents() []VulnEvent
}

type Vulnerability struct {
Expand Down
56 changes: 0 additions & 56 deletions database/models/vulnevent_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"
"log/slog"
"time"

"github.com/l3montree-dev/devguard/dtos"
)
Expand Down Expand Up @@ -82,61 +81,6 @@ func (event VulnEvent) TableName() string {
return "vuln_events"
}

func (event VulnEvent) Apply(vuln Vuln) {
if event.Upstream != dtos.UpstreamStateInternal && event.Type == dtos.EventTypeAccepted {
// its an external accepted event that should not modify state
return
}

switch event.Type {
case dtos.EventTypeLicenseDecision:
finalLicenseDecision, ok := (event.GetArbitraryJSONData()["finalLicenseDecision"]).(string)
if !ok {
slog.Error("could not parse final license decision", "dependencyVulnID",

event.VulnID)
return
}
v := vuln.(*LicenseRisk)
v.SetFinalLicenseDecision(finalLicenseDecision)
v.SetState(dtos.VulnStateFixed)
case dtos.EventTypeFixed:
vuln.SetState(dtos.VulnStateFixed)
case dtos.EventTypeReopened:
if event.Upstream == dtos.UpstreamStateExternal {
return
}
vuln.SetState(dtos.VulnStateOpen)
case dtos.EventTypeDetected:
// event type detected will always be applied!
f, ok := (event.GetArbitraryJSONData()["risk"]).(float64)
if !ok {
f = vuln.GetRawRiskAssessment()
}
vuln.SetRawRiskAssessment(f)
vuln.SetRiskRecalculatedAt(time.Now())
vuln.SetState(dtos.VulnStateOpen)
case dtos.EventTypeAccepted:
vuln.SetState(dtos.VulnStateAccepted)
case dtos.EventTypeFalsePositive:
if event.Upstream == dtos.UpstreamStateExternal {
return
}
vuln.SetState(dtos.VulnStateFalsePositive)
case dtos.EventTypeMarkedForTransfer:
vuln.SetState(dtos.VulnStateMarkedForTransfer)
case dtos.EventTypeRawRiskAssessmentUpdated:
f, ok := (event.GetArbitraryJSONData()["risk"]).(float64)
if !ok {
slog.Error("could not parse risk assessment", "dependencyVulnID", event.VulnID)
return
}
vuln.SetRawRiskAssessment(f)
vuln.SetRiskRecalculatedAt(time.Now())
}

}

func NewAcceptedEvent(vulnID string, vulnType dtos.VulnType, userID, justification string, upstream dtos.UpstreamState) VulnEvent {

return VulnEvent{
Expand Down
17 changes: 9 additions & 8 deletions database/models/vulnevent_model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/l3montree-dev/devguard/database/models"
"github.com/l3montree-dev/devguard/dtos"
"github.com/l3montree-dev/devguard/statemachine"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -36,15 +37,15 @@ func TestVulnEvent_Apply(t *testing.T) {
vuln := models.DependencyVuln{}
event := models.VulnEvent{Type: dtos.EventTypeFixed}

event.Apply(&vuln)
statemachine.Apply(&vuln, event)

assert.Equal(t, dtos.VulnStateFixed, vuln.State)
})
t.Run("should set state to false positive for EventTypeFalsePositive", func(t *testing.T) {
vuln := models.DependencyVuln{}
event := models.VulnEvent{Type: dtos.EventTypeFalsePositive}

event.Apply(&vuln)
statemachine.Apply(&vuln, event)

assert.Equal(t, dtos.VulnStateFalsePositive, vuln.State)
})
Expand All @@ -55,7 +56,7 @@ func TestVulnEvent_Apply(t *testing.T) {
ArbitraryJSONData: `{"risk": 0.5 }`,
}

event.Apply(&vuln)
statemachine.Apply(&vuln, event)

assert.Equal(t, 0.5, vuln.GetRawRiskAssessment())
})
Expand All @@ -67,15 +68,15 @@ func TestVulnEvent_Apply(t *testing.T) {
ArbitraryJSONData: `{"risk": 0.5 }`,
}

event.Apply(&vuln)
statemachine.Apply(&vuln, event)

assert.NotZero(t, vuln.RiskRecalculatedAt)
})
t.Run("should set state to open for EventTypeDetected", func(t *testing.T) {
vuln := models.DependencyVuln{}
event := models.VulnEvent{Type: dtos.EventTypeDetected}

event.Apply(&vuln)
statemachine.Apply(&vuln, event)

assert.Equal(t, dtos.VulnStateOpen, vuln.State)
})
Expand All @@ -87,7 +88,7 @@ func TestVulnEvent_Apply(t *testing.T) {
ArbitraryJSONData: `{"risk": 0.5 }`,
}

event.Apply(&vuln)
statemachine.Apply(&vuln, event)

assert.NotZero(t, vuln.RiskRecalculatedAt)
})
Expand All @@ -96,15 +97,15 @@ func TestVulnEvent_Apply(t *testing.T) {
vuln := models.DependencyVuln{}
event := models.VulnEvent{Type: dtos.EventTypeReopened}

event.Apply(&vuln)
statemachine.Apply(&vuln, event)

assert.Equal(t, dtos.VulnStateOpen, vuln.State)
})
t.Run("should set state to accepted for EventTypeAccepted", func(t *testing.T) {
vuln := models.DependencyVuln{}
event := models.VulnEvent{Type: dtos.EventTypeAccepted}

event.Apply(&vuln)
statemachine.Apply(&vuln, event)

assert.Equal(t, dtos.VulnStateAccepted, vuln.State)
})
Expand Down
3 changes: 2 additions & 1 deletion database/repositories/dependency_vuln_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/google/uuid"
"github.com/l3montree-dev/devguard/dtos"
"github.com/l3montree-dev/devguard/shared"
"github.com/l3montree-dev/devguard/statemachine"
"github.com/l3montree-dev/devguard/utils"

"github.com/l3montree-dev/devguard/database/models"
Expand Down Expand Up @@ -40,7 +41,7 @@ func (repository *dependencyVulnRepository) ApplyAndSave(tx *gorm.DB, dependency

func (repository *dependencyVulnRepository) applyAndSave(tx *gorm.DB, dependencyVuln *models.DependencyVuln, ev *models.VulnEvent) (models.VulnEvent, error) {
// apply the event on the dependencyVuln
ev.Apply(dependencyVuln)
statemachine.Apply(dependencyVuln, *ev)

// run the updates in the transaction to keep a valid state
err := repository.Save(tx, dependencyVuln)
Expand Down
3 changes: 2 additions & 1 deletion database/repositories/first_party_vuln_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/l3montree-dev/devguard/database/models"
"github.com/l3montree-dev/devguard/dtos"
"github.com/l3montree-dev/devguard/shared"
"github.com/l3montree-dev/devguard/statemachine"
"gorm.io/gorm"
)

Expand Down Expand Up @@ -186,7 +187,7 @@ func (repository *firstPartyVulnerabilityRepository) ApplyAndSave(tx *gorm.DB, f

func (repository *firstPartyVulnerabilityRepository) applyAndSave(tx *gorm.DB, firstPartyVuln *models.FirstPartyVuln, ev *models.VulnEvent) (models.VulnEvent, error) {
// apply the event on the dependencyVuln
ev.Apply(firstPartyVuln)
statemachine.Apply(firstPartyVuln, *ev)
// save the event
if err := repository.Save(tx, firstPartyVuln); err != nil {
return models.VulnEvent{}, err
Expand Down
4 changes: 2 additions & 2 deletions database/repositories/license_risk_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/l3montree-dev/devguard/database/models"
"github.com/l3montree-dev/devguard/dtos"
"github.com/l3montree-dev/devguard/shared"
"github.com/l3montree-dev/devguard/statemachine"
"github.com/l3montree-dev/devguard/utils"
"github.com/package-url/packageurl-go"
"gorm.io/gorm"
Expand Down Expand Up @@ -133,8 +134,7 @@ func (repository *LicenseRiskRepository) ApplyAndSave(tx *gorm.DB, licenseRisk *
}

func (repository *LicenseRiskRepository) applyAndSave(tx *gorm.DB, licenseRisk *models.LicenseRisk, ev *models.VulnEvent) (models.VulnEvent, error) {
ev.Apply(licenseRisk)

statemachine.Apply(licenseRisk, *ev)
// run the updates in the transaction to keep a valid state
err := repository.Save(tx, licenseRisk)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion database/repositories/statistics_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/l3montree-dev/devguard/database/models"
"github.com/l3montree-dev/devguard/dtos"
"github.com/l3montree-dev/devguard/statemachine"
)

type statisticsRepository struct {
Expand Down Expand Up @@ -56,7 +57,7 @@ func (r *statisticsRepository) TimeTravelDependencyVulnState(artifactName *strin
events := dependencyVuln.Events
// iterate through all events and apply them
for _, event := range events {
event.Apply(&tmpDependencyVuln)
statemachine.Apply(&tmpDependencyVuln, event)
}
}
return dependencyVulns, nil
Expand Down
4 changes: 3 additions & 1 deletion integrations/githubint/github_integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/l3montree-dev/devguard/dtos"
"github.com/l3montree-dev/devguard/integrations/commonint"
"github.com/l3montree-dev/devguard/shared"
"github.com/l3montree-dev/devguard/statemachine"
"github.com/l3montree-dev/devguard/utils"
"github.com/l3montree-dev/devguard/vulndb"
)
Expand Down Expand Up @@ -363,7 +364,8 @@ func (githubIntegration *GithubIntegration) HandleWebhook(ctx shared.Context) er
// create a new event based on the comment
vulnEvent := commonint.CreateNewVulnEventBasedOnComment(vuln.GetID(), vuln.GetType(), fmt.Sprintf("github:%d", event.Comment.User.GetID()), comment, vuln.GetScannerIDsOrArtifactNames())

vulnEvent.Apply(vuln)
statemachine.Apply(vuln, vulnEvent)

// save the vuln and the event in a transaction
err = githubIntegration.aggregatedVulnRepository.Transaction(func(tx shared.DB) error {
err := githubIntegration.aggregatedVulnRepository.Save(tx, &vuln)
Expand Down
4 changes: 3 additions & 1 deletion integrations/gitlabint/gitlab_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/l3montree-dev/devguard/database/models"
"github.com/l3montree-dev/devguard/dtos"
"github.com/l3montree-dev/devguard/integrations/commonint"
"github.com/l3montree-dev/devguard/statemachine"

"github.com/l3montree-dev/devguard/shared"
"github.com/pkg/errors"
Expand Down Expand Up @@ -223,7 +224,8 @@ func (g *GitlabIntegration) HandleWebhook(ctx shared.Context) error {
// create a new event based on the comment
vulnEvent = commonint.CreateNewVulnEventBasedOnComment(vuln.GetID(), vuln.GetType(), fmt.Sprintf("gitlab:%d", event.User.ID), comment, vuln.GetScannerIDsOrArtifactNames())

vulnEvent.Apply(vuln)
statemachine.Apply(vuln, vulnEvent)

// save the dependencyVuln and the event in a transaction
err = g.aggregatedVulnRepository.Transaction(func(tx shared.DB) error {
err := g.aggregatedVulnRepository.Save(tx, &vuln)
Expand Down
3 changes: 2 additions & 1 deletion integrations/jiraint/jira_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/l3montree-dev/devguard/dtos"
"github.com/l3montree-dev/devguard/integrations/commonint"
"github.com/l3montree-dev/devguard/shared"
"github.com/l3montree-dev/devguard/statemachine"
)

func (i *JiraIntegration) HandleWebhook(ctx shared.Context) error {
Expand Down Expand Up @@ -136,8 +137,8 @@ func (i *JiraIntegration) HandleWebhook(ctx shared.Context) error {

// create a new event based on the comment
vulnEvent := commonint.CreateNewVulnEventBasedOnComment(vuln.GetID(), vuln.GetType(), fmt.Sprintf("jira:%s", userID), comment, vuln.GetScannerIDsOrArtifactNames())
statemachine.Apply(vuln, vulnEvent)

vulnEvent.Apply(vuln)
// save the vuln and the event in a transaction
err = i.aggregatedVulnRepository.Transaction(func(tx shared.DB) error {
err := i.aggregatedVulnRepository.Save(tx, &vuln)
Expand Down
Loading
Loading