Skip to content

Commit

Permalink
change asset version id
Browse files Browse the repository at this point in the history
Signed-off-by: Rafi <[email protected]>
  • Loading branch information
refoo0 committed Feb 11, 2025
1 parent 147b8c6 commit f08b745
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 67 deletions.
39 changes: 20 additions & 19 deletions internal/core/statistics/statistics_asset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ import (
)

type statisticsService interface {
GetComponentRisk(assetVersionID uuid.UUID) (map[string]float64, error)
GetAssetVersionRiskDistribution(assetVersionID uuid.UUID, assetName string) (models.AssetRiskDistribution, error)
GetAssetVersionRiskHistory(assetVersionID uuid.UUID, start time.Time, end time.Time) ([]models.AssetRiskHistory, error)
GetFlawAggregationStateAndChangeSince(assetVersionID uuid.UUID, calculateChangeTo time.Time) (FlawAggregationStateAndChange, error)
GetComponentRisk(assetVersionName string, assetID uuid.UUID) (map[string]float64, error)
GetAssetVersionRiskDistribution(assetVersionName string, assetID uuid.UUID) (models.AssetRiskDistribution, error)
GetAssetVersionRiskHistory(assetVersionName string, assetID uuid.UUID, start time.Time, end time.Time) ([]models.AssetRiskHistory, error)
GetFlawAggregationStateAndChangeSince(assetVersionName string, assetID uuid.UUID, calculateChangeTo time.Time) (FlawAggregationStateAndChange, error)

GetFlawCountByScannerId(assetVersionID uuid.UUID) (map[string]int, error)
GetDependencyCountPerscanner(assetVersionID uuid.UUID) (map[string]int, error)
GetAverageFixingTime(assetVersionID uuid.UUID, severity string) (time.Duration, error)
UpdateAssetRiskAggregation(assetVersionID uuid.UUID, start time.Time, end time.Time, updateProject bool) error
GetFlawCountByScannerId(assetVersionName string, assetID uuid.UUID) (map[string]int, error)
GetDependencyCountPerscanner(assetVersionName string, assetID uuid.UUID) (map[string]int, error)
GetAverageFixingTime(assetVersionName string, assetID uuid.UUID, severity string) (time.Duration, error)
UpdateAssetRiskAggregation(assetVersionName string, assetID uuid.UUID, start time.Time, end time.Time, updateProject bool) error

GetProjectRiskHistory(projectID uuid.UUID, start time.Time, end time.Time) ([]models.ProjectRiskHistory, error)
}
Expand Down Expand Up @@ -50,7 +50,7 @@ func NewHttpController(statisticsService statisticsService, assetRepository asse

func (c *httpController) GetComponentRisk(ctx core.Context) error {
assetVersion := core.GetAssetVersion(ctx)
results, err := c.statisticsService.GetComponentRisk(assetVersion.ID)
results, err := c.statisticsService.GetComponentRisk(assetVersion.Name, assetVersion.AssetId)

if err != nil {
return err
Expand All @@ -61,7 +61,7 @@ func (c *httpController) GetComponentRisk(ctx core.Context) error {

func (c *httpController) GetDependencyCountPerScanner(ctx core.Context) error {
assetVersion := core.GetAssetVersion(ctx)
results, err := c.statisticsService.GetDependencyCountPerscanner(assetVersion.ID)
results, err := c.statisticsService.GetDependencyCountPerscanner(assetVersion.Name, assetVersion.AssetId)

if err != nil {
return err
Expand All @@ -72,7 +72,7 @@ func (c *httpController) GetDependencyCountPerScanner(ctx core.Context) error {

func (c *httpController) GetFlawCountByScannerId(ctx core.Context) error {
assetVersion := core.GetAssetVersion(ctx)
results, err := c.statisticsService.GetFlawCountByScannerId(assetVersion.ID)
results, err := c.statisticsService.GetFlawCountByScannerId(assetVersion.Name, assetVersion.AssetId)

if err != nil {
return err
Expand All @@ -83,7 +83,7 @@ func (c *httpController) GetFlawCountByScannerId(ctx core.Context) error {

func (c *httpController) GetAssetVersionRiskDistribution(ctx core.Context) error {
assetVersion := core.GetAssetVersion(ctx)
results, err := c.statisticsService.GetAssetVersionRiskDistribution(assetVersion.ID, assetVersion.Name)
results, err := c.statisticsService.GetAssetVersionRiskDistribution(assetVersion.Name, assetVersion.AssetId)
if err != nil {
return err
}
Expand All @@ -108,7 +108,7 @@ func (c *httpController) GetAverageAssetVersionFixingTime(ctx core.Context) erro
})
}

duration, err := c.statisticsService.GetAverageFixingTime(assetVersion.ID, severity)
duration, err := c.statisticsService.GetAverageFixingTime(assetVersion.Name, assetVersion.AssetId, severity)
if err != nil {
return ctx.JSON(500, nil)
}
Expand Down Expand Up @@ -136,12 +136,13 @@ func aggregateRiskDistribution(results []models.AssetRiskDistribution, id uuid.U
}

return models.AssetRiskDistribution{
ID: id,
Label: label,
Low: lowCount,
Medium: mediumCount,
High: highCount,
Critical: criticalCount,
AssetID: assetID,

Check failure on line 139 in internal/core/statistics/statistics_asset_controller.go

View workflow job for this annotation

GitHub Actions / Check for unapproved licenses

undefined: assetID
AssetVersionName: assetVersionName,

Check failure on line 140 in internal/core/statistics/statistics_asset_controller.go

View workflow job for this annotation

GitHub Actions / Check for unapproved licenses

undefined: assetVersionName
Label: label,
Low: lowCount,
Medium: mediumCount,
High: highCount,
Critical: criticalCount,
}
}

Expand Down
2 changes: 1 addition & 1 deletion internal/core/statistics/statistics_project_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (c *httpController) GetProjectRiskDistribution(ctx core.Context) error {
group := utils.ErrGroup[models.AssetRiskDistribution](10)
for _, assetVersion := range assetVersions {
group.Go(func() (models.AssetRiskDistribution, error) {
return c.statisticsService.GetAssetVersionRiskDistribution(assetVersion.ID, assetVersion.Name)
return c.statisticsService.GetAssetVersionRiskDistribution(assetVersion.Name, assetVersion.AssetId)
})
}

Expand Down
36 changes: 19 additions & 17 deletions internal/core/statistics/statistics_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ type assetRepository interface {
}

type statisticsRepository interface {
TimeTravelFlawState(assetVersionID uuid.UUID, time time.Time) ([]models.Flaw, error)
GetAssetRiskDistribution(assetVersionID uuid.UUID, assetVersionName string) (models.AssetRiskDistribution, error)
TimeTravelFlawState(assetVersionName string, assetID uuid.UUID, time time.Time) ([]models.Flaw, error)
GetAssetRiskDistribution(assetVersionName string, assetID uuid.UUID) (models.AssetRiskDistribution, error)
GetFlawCountByScannerId(assetVersionID uuid.UUID) (map[string]int, error)
AverageFixingTime(assetVersionID uuid.UUID, riskIntervalStart, riskIntervalEnd float64) (time.Duration, error)
}
Expand All @@ -39,12 +39,12 @@ type assetRiskHistoryRepository interface {
}

type flawRepository interface {
GetAllOpenFlawsByAssetVersionID(tx core.DB, assetVersionID uuid.UUID) ([]models.Flaw, error)
GetFlawsByAssetVersionId(tx core.DB, assetVersionID uuid.UUID) ([]models.Flaw, error)
GetAllOpenFlawsByAssetVersionID(tx core.DB, assetVersionName string, assetID uuid.UUID) ([]models.Flaw, error)
GetFlawsByAssetVersionId(tx core.DB, assetVersionName string, assetID uuid.UUID) ([]models.Flaw, error)
}

type projectRepository interface {
GetProjectByAssetVersionID(assetVersionID uuid.UUID) (models.Project, error)
GetProjectByAssetID(assetID uuid.UUID) (models.Project, error)
RecursivelyGetChildProjects(projectID uuid.UUID) ([]models.Project, error)
Read(id uuid.UUID) (models.Project, error)
}
Expand Down Expand Up @@ -181,14 +181,14 @@ func (s *service) updateProjectRiskAggregation(projectID uuid.UUID, begin, end t
return nil
}

func (s *service) UpdateAssetRiskAggregation(assetVersionID uuid.UUID, begin time.Time, end time.Time, propagateToProject bool) error {
func (s *service) UpdateAssetRiskAggregation(assetVersionName string, assetID uuid.UUID, begin time.Time, end time.Time, propagateToProject bool) error {
// set begin to last second of date
begin = time.Date(begin.Year(), begin.Month(), begin.Day(), 23, 59, 59, 0, time.UTC)
// set end to last second of date
end = time.Date(end.Year(), end.Month(), end.Day(), 23, 59, 59, 0, time.UTC)

for time := begin; time.Before(end) || time.Equal(end); time = time.AddDate(0, 0, 1) {
flaws, err := s.statisticsRepository.TimeTravelFlawState(assetVersionID, time)
flaws, err := s.statisticsRepository.TimeTravelFlawState(assetVersionName, assetID, time)
if err != nil {
return err
}
Expand Down Expand Up @@ -255,8 +255,9 @@ func (s *service) UpdateAssetRiskAggregation(assetVersionID uuid.UUID, begin tim
}

result := models.AssetRiskHistory{
AssetVersionID: assetVersionID,
Day: time,
AssetVersionName: assetVersionName,
AssetID: assetID,
Day: time,

SumOpenRisk: openRisk.Sum,
AvgOpenRisk: openRisk.Avg,
Expand All @@ -280,7 +281,7 @@ func (s *service) UpdateAssetRiskAggregation(assetVersionID uuid.UUID, begin tim
// we ALWAYS need to propagate the risk aggregation to the project. The only exception is in the statistics daemon. There
// we update all assets and afterwards do a one time project update. This is just optimization.
if propagateToProject {
currentProject, err := s.projectRepository.GetProjectByAssetVersionID(assetVersionID)
currentProject, err := s.projectRepository.GetProjectByAssetID(assetID)

if err != nil {
return fmt.Errorf("could not get project id by asset id: %w", err)
Expand Down Expand Up @@ -308,16 +309,17 @@ func (s *service) UpdateAssetRiskAggregation(assetVersionID uuid.UUID, begin tim

}

func (s *service) GetAssetVersionRiskDistribution(assetVersionID uuid.UUID, assetVersionName string) (models.AssetRiskDistribution, error) {
return s.statisticsRepository.GetAssetRiskDistribution(assetVersionID, assetVersionName)
func (s *service) GetAssetVersionRiskDistribution(assetVersionName string, assetID uuid.UUID) (models.AssetRiskDistribution, error) {
return s.statisticsRepository.GetAssetRiskDistribution(assetVersionName, assetID)
}

func (s *service) GetProjectRiskHistory(projectID uuid.UUID, start time.Time, end time.Time) ([]models.ProjectRiskHistory, error) {
return s.projectRiskHistoryRepository.GetRiskHistory(projectID, start, end)
}

func (s *service) GetComponentRisk(assetVersionID uuid.UUID) (map[string]float64, error) {
flaws, err := s.flawRepository.GetAllOpenFlawsByAssetVersionID(nil, assetVersionID)
func (s *service) GetComponentRisk(assetVersionName string, assetID uuid.UUID) (map[string]float64, error) {

flaws, err := s.flawRepository.GetAllOpenFlawsByAssetVersionID(nil, assetVersionName, assetID)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -361,18 +363,18 @@ func (s *service) GetAverageFixingTime(assetVersionID uuid.UUID, severity string
return s.statisticsRepository.AverageFixingTime(assetVersionID, riskIntervalStart, riskIntervalEnd)
}

func (s *service) GetFlawAggregationStateAndChangeSince(assetVersionID uuid.UUID, calculateChangeTo time.Time) (FlawAggregationStateAndChange, error) {
func (s *service) GetFlawAggregationStateAndChangeSince(assetVersionName string, assetID uuid.UUID, calculateChangeTo time.Time) (FlawAggregationStateAndChange, error) {
// check if calculateChangeTo is in the future
if calculateChangeTo.After(time.Now()) {
return FlawAggregationStateAndChange{}, fmt.Errorf("Cannot calculate change to the future")
}

results := utils.Concurrently(
func() (any, error) {
return s.flawRepository.GetFlawsByAssetVersionId(nil, assetVersionID)
return s.flawRepository.GetFlawsByAssetVersionId(nil, assetVersionName, assetID)
},
func() (any, error) {
return s.statisticsRepository.TimeTravelFlawState(assetVersionID, calculateChangeTo)
return s.statisticsRepository.TimeTravelFlawState(assetVersionName, assetID, calculateChangeTo)
},
)

Expand Down
6 changes: 3 additions & 3 deletions internal/core/vulndb/scan/scan_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type assetVersionRepository interface {
}

type statisticsService interface {
UpdateAssetRiskAggregation(assetID uuid.UUID, begin time.Time, end time.Time, updateProject bool) error
UpdateAssetRiskAggregation(assetVersionName string, assetID uuid.UUID, begin time.Time, end time.Time, updateProject bool) error
}

type httpController struct {
Expand Down Expand Up @@ -172,8 +172,8 @@ func (s *httpController) Scan(c core.Context) error {
}

if doRiskManagement {
slog.Info("recalculating risk history for asset", "asset", assetVersion.ID)
if err := s.statisticsService.UpdateAssetRiskAggregation(assetVersion.ID, utils.OrDefault(assetVersion.LastHistoryUpdate, assetVersion.CreatedAt), time.Now(), true); err != nil {
slog.Info("recalculating risk history for asset", "asset version", assetVersion.Name, "assetID", asset.ID)
if err := s.statisticsService.UpdateAssetRiskAggregation(assetVersion.Name, asset.ID, utils.OrDefault(assetVersion.LastHistoryUpdate, assetVersion.CreatedAt), time.Now(), true); err != nil {
slog.Error("could not recalculate risk history", "err", err)
return c.JSON(500, map[string]string{"error": "could not recalculate risk history"})
}
Expand Down
10 changes: 7 additions & 3 deletions internal/database/models/asset_version_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"time"

"github.com/google/uuid"
"gorm.io/gorm"
)

type AssetVersionType string
Expand All @@ -14,14 +15,17 @@ const (
)

type AssetVersion struct {
Model
Name string `json:"name" gorm:"type:text"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`

Name string `json:"name" gorm:"primarykey;type:text;not null;"`

DefaultBranch bool `json:"defaultBranch" gorm:"default:false;"`

Slug string `json:"slug" gorm:"type:text;uniqueIndex:idx_ver_asset_slug;not null;type:text;"`

AssetId uuid.UUID `json:"assetId" gorm:"uniqueIndex:idx_ver_asset_slug;not null;type:uuid;"`
AssetId uuid.UUID `json:"assetId" gorm:"primarykey;uniqueIndex:idx_ver_asset_slug;not null;type:uuid;"`
Flaws []Flaw `json:"flaws" gorm:"foreignKey:AssetVersionID;constraint:OnDelete:CASCADE;"`

Type AssetVersionType `json:"type" gorm:"type:text;not null;"`
Expand Down
15 changes: 7 additions & 8 deletions internal/database/models/flaw_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"time"

"github.com/google/uuid"
"gorm.io/gorm"

"github.com/l3montree-dev/devguard/internal/utils"
Expand All @@ -27,13 +26,13 @@ type Flaw struct {
ScannerID string `json:"scanner" gorm:"not null;"`

//TODO: add not null constraint
FlawAssetID string `json:"flawAssetId"`
AssetID string `json:"flawAssetId" gorm:"not null;"`

Message *string `json:"message"`
Comments []Comment `gorm:"foreignKey:FlawID;constraint:OnDelete:CASCADE;" json:"comments"`
Events []FlawEvent `gorm:"foreignKey:FlawID;constraint:OnDelete:CASCADE,OnUpdate:CASCADE;" json:"events"`
AssetVersionID uuid.UUID `json:"assetVersionId" gorm:"not null;type:uuid;"`
State FlawState `json:"state" gorm:"default:'open';not null;type:text;"`
Message *string `json:"message"`
Comments []Comment `gorm:"foreignKey:FlawID;constraint:OnDelete:CASCADE;" json:"comments"`
Events []FlawEvent `gorm:"foreignKey:FlawID;constraint:OnDelete:CASCADE,OnUpdate:CASCADE;" json:"events"`
AssetVersionName string `json:"assetVersionName" gorm:"not null;"`
State FlawState `json:"state" gorm:"default:'open';not null;type:text;"`

CVE *CVE `json:"cve"`
CVEID *string `json:"cveId" gorm:"null;type:text;default:null;"`
Expand Down Expand Up @@ -79,7 +78,7 @@ func (m *Flaw) CalculateHash(id string) string {

// hook to calculate the hash before creating the flaw
func (f *Flaw) BeforeSave(tx *gorm.DB) (err error) {
hash := f.CalculateHash(string(f.AssetVersionID.String()))
hash := f.CalculateHash(string(f.AssetVersionName + f.AssetID))
f.ID = hash
return nil
}
8 changes: 5 additions & 3 deletions internal/database/models/statistic_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ type AssetRiskDistribution struct {
Medium int `json:"medium"`
Critical int `json:"critical"`

ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid"`
Label string `json:"label"`
AssetID uuid.UUID `json:"assetId" gorm:"primaryKey;type:uuid"`
AssetVersionName string `json:"assetVersionName" gorm:"primaryKey;type:text;"`
Label string `json:"label"`
}

type AssetRiskHistory struct {
AssetVersionID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid"`
AssetVersionName string `json:"assetVersionName" gorm:"primaryKey;type:text;"`
AssetID uuid.UUID `json:"assetId" gorm:"primaryKey;type:uuid"`
// on the day 2024-08-12 the asset had a sumRisk of 25.
Day time.Time `json:"day" gorm:"primaryKey;type:date"`

Expand Down
2 changes: 1 addition & 1 deletion internal/database/repositories/flaw_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func (g flawRepository) ReadFlawWithAssetEvents(id string) (models.Flaw, error)
return models.Flaw{}, err
}

flawEvents, err := g.GetFlawEventsByFlawAssetID(g.db, t.FlawAssetID)
flawEvents, err := g.GetFlawEventsByFlawAssetID(g.db, t.AssetID)
if err != nil {
return models.Flaw{}, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/database/repositories/project_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (g *projectRepository) GetByOrgID(organizationID uuid.UUID) ([]models.Proje
return projects, err
}

func (g *projectRepository) GetProjectByAssetVersionID(assetVersionID uuid.UUID) (models.Project, error) {
func (g *projectRepository) GetProjectByAssetVersionID(assetVersionName string, assetID uuid.UUID) (models.Project, error) {
var project models.Project
err := g.db.Model(&models.AssetVersion{}).Select("assets.*").Joins("JOIN assets ON assets.id = asset_versions.asset_id").Joins("JOIN projects ON projects.id = assets.project_id").Where("asset_versions.id = ?", assetVersionID).First(&project).Error
return project, err
Expand Down
23 changes: 12 additions & 11 deletions internal/database/repositories/statistics_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ func NewStatisticsRepository(db core.DB) *statisticsRepository {
}

// returns all flaws for the asset including the events, which were created before the given time
func (r *statisticsRepository) TimeTravelFlawState(assetVersionID uuid.UUID, time time.Time) ([]models.Flaw, error) {
func (r *statisticsRepository) TimeTravelFlawState(assetVersionName string, assetID uuid.UUID, time time.Time) ([]models.Flaw, error) {
flaws := []models.Flaw{}

err := r.db.Model(&models.Flaw{}).Preload("Events", func(db core.DB) core.DB {
return db.Where("created_at <= ?", time).Order("created_at ASC")
}).
Where("asset_version_id = ?", assetVersionID).Where("created_at <= ?", time).
Where("asset_version_id = ?", assetVersionName).Where("asset_id = ?", assetID).Where("created_at <= ?", time).
Find(&flaws).Error

if err != nil {
Expand Down Expand Up @@ -73,7 +73,7 @@ func (r *statisticsRepository) GetFlawCountByScannerId(assetVersionID uuid.UUID)
return counts, nil
}

func (r *statisticsRepository) GetAssetRiskDistribution(assetVersionID uuid.UUID, assetName string) (models.AssetRiskDistribution, error) {
func (r *statisticsRepository) GetAssetRiskDistribution(assetVersionName string, assetID uuid.UUID, assetName string) (models.AssetRiskDistribution, error) {
var results []struct {
Severity string `gorm:"column:severity"`
Count int `gorm:"column:count"`
Expand All @@ -90,9 +90,9 @@ func (r *statisticsRepository) GetAssetRiskDistribution(assetVersionID uuid.UUID
END AS severity,
COUNT(*) as count
FROM flaws
WHERE asset_version_id = ? AND state = 'open'
WHERE asset_version_name = ? AND asset_id = ? AND state = 'open'
GROUP BY severity
`, assetVersionID).Scan(&results).Error
`, assetVersionName, assetID).Scan(&results).Error

if err != nil {
return models.AssetRiskDistribution{}, err
Expand All @@ -105,12 +105,13 @@ func (r *statisticsRepository) GetAssetRiskDistribution(assetVersionID uuid.UUID
}

return models.AssetRiskDistribution{
ID: assetVersionID,
Label: assetName,
Low: counts["LOW"],
Medium: counts["MEDIUM"],
High: counts["HIGH"],
Critical: counts["CRITICAL"],
AssetID: assetID,
AssetVersionName: assetVersionName,
Label: assetName,
Low: counts["LOW"],
Medium: counts["MEDIUM"],
High: counts["HIGH"],
Critical: counts["CRITICAL"],
}, nil
}

Expand Down

0 comments on commit f08b745

Please sign in to comment.