Skip to content

Commit dd7b87c

Browse files
committed
feat: added crud methods
1 parent eaa2c12 commit dd7b87c

9 files changed

Lines changed: 141 additions & 69 deletions

File tree

controllers/advisory_controller.go

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package controllers
1717

1818
import (
19+
"github.com/google/uuid"
1920
"github.com/l3montree-dev/devguard/dtos"
2021
"github.com/l3montree-dev/devguard/shared"
2122
"github.com/l3montree-dev/devguard/transformer"
@@ -43,55 +44,77 @@ func (controller *AdvisoryController) Create(ctx shared.Context) error {
4344
err := controller.advisoryService.Create(ctx.Request().Context(), &newAdvisory)
4445

4546
if err != nil {
46-
return echo.NewHTTPError(409, "could not set name").WithInternal(err)
47+
return echo.NewHTTPError(409, "could not set advisory").WithInternal(err)
4748
}
4849

4950
return ctx.NoContent(200)
5051
}
5152

52-
// func (controller *advisoryController) ReadName(ctx shared.Context) error {
53-
// advisoryNames, err := controller.advisoryService.ReadName(ctx.Request().Context())
54-
// if err != nil {
55-
// return echo.NewHTTPError(500, "could not get any name").WithInternal(err)
56-
// }
57-
// return ctx.JSON(200, advisoryNames)
58-
// }
53+
func (controller *AdvisoryController) ReadAll(ctx shared.Context) error {
54+
asset := shared.GetAsset(ctx)
55+
advisories, err := controller.advisoryService.ReadAll(ctx.Request().Context(), asset.ID)
56+
if err != nil {
57+
return echo.NewHTTPError(500, "could not get any data").WithInternal(err)
58+
}
59+
return ctx.JSON(200, advisories)
60+
}
61+
62+
func (controller *AdvisoryController) ReadAdvisory(ctx shared.Context) error {
63+
advisoryID := ctx.Param("id")
64+
parsedID, err := uuid.Parse(advisoryID)
65+
if err != nil {
66+
return echo.NewHTTPError(400, "invalid uuid provided")
67+
}
68+
69+
advisory, err := controller.advisoryService.ReadAdvisory(ctx.Request().Context(), parsedID)
70+
71+
if err != nil {
72+
return echo.NewHTTPError(409, "could not get any data").WithInternal(err)
73+
}
74+
75+
return ctx.JSON(200, advisory)
76+
}
77+
78+
func (controller *AdvisoryController) Update(ctx shared.Context) error {
79+
var req dtos.AdvisoryUpdate
80+
if err := ctx.Bind(&req); err != nil {
81+
return echo.NewHTTPError(400, "unable to process request").WithInternal(err)
82+
}
5983

60-
// func (controller *advisoryController) UpdateName(ctx shared.Context) error {
61-
// var req dtos.AdvisoryUpdate // Change to own struct
62-
// if err := ctx.Bind(&req); err != nil {
63-
// return echo.NewHTTPError(400, "unable to process request").WithInternal(err)
64-
// }
84+
advisoryID := ctx.Param("id")
85+
parsedID, err := uuid.Parse(advisoryID)
86+
if err != nil {
87+
return echo.NewHTTPError(400, "invalid uuid provided")
88+
}
6589

66-
// updateName := req.Name
90+
advisory, err := controller.advisoryService.ReadAdvisory(ctx.Request().Context(), parsedID)
91+
if err != nil {
92+
return echo.NewHTTPError(404, "advisory not found").WithInternal(err)
93+
}
6794

68-
// advisoryID := ctx.Param("id")
69-
// parsedID, err := uuid.Parse(advisoryID)
70-
// if err != nil {
71-
// return echo.NewHTTPError(400, "invalid uuid provided")
72-
// }
95+
advisory = transformer.AdvisoryUpdateRequestToModel(req, advisory)
7396

74-
// err = controller.advisoryService.UpdateName(ctx.Request().Context(), parsedID, updateName)
97+
err = controller.advisoryService.Update(ctx.Request().Context(), parsedID, &advisory)
7598

76-
// if err != nil {
77-
// return echo.NewHTTPError(409, "could not update name").WithInternal(err)
78-
// }
99+
if err != nil {
100+
return echo.NewHTTPError(409, "could not update advisory").WithInternal(err)
101+
}
79102

80-
// return ctx.JSON(200, updateName)
81-
// }
103+
return ctx.NoContent(200)
104+
}
82105

83-
// func (controller *advisoryController) DeleteName(ctx shared.Context) error {
84-
// advisoryID := ctx.Param("id")
85-
// parsedID, err := uuid.Parse(advisoryID)
86-
// if err != nil {
87-
// return echo.NewHTTPError(400, "invalid uuid provided")
88-
// }
106+
func (controller *AdvisoryController) Delete(ctx shared.Context) error {
107+
advisoryID := ctx.Param("id")
108+
parsedID, err := uuid.Parse(advisoryID)
109+
if err != nil {
110+
return echo.NewHTTPError(400, "invalid uuid provided")
111+
}
89112

90-
// err = controller.advisoryService.DeleteName(ctx.Request().Context(), parsedID)
113+
err = controller.advisoryService.Delete(ctx.Request().Context(), parsedID)
91114

92-
// if err != nil {
93-
// return echo.NewHTTPError(409, "could not remove name").WithInternal(err)
94-
// }
115+
if err != nil {
116+
return echo.NewHTTPError(409, "could not remove name").WithInternal(err)
117+
}
95118

96-
// return ctx.NoContent(200)
97-
// }
119+
return ctx.NoContent(200)
120+
}

database/migrations/20260623101120_add_advisory_table.up.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ CREATE TABLE public.advisories (
55
title TEXT NOT NULL,
66
description TEXT NOT NULL,
77
severity TEXT,
8-
vector_string TEXT
8+
vector_string TEXT,
9+
asset_id UUID
910
);
1011

1112
CREATE TABLE public.affected_packages (

database/models/advisory_model.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package models
22

3+
import "github.com/google/uuid"
4+
35
type Advisory struct {
46
Model
57
Title string `json:"title" gorm:"type:text;column:title"`
68
Description string `json:"description" gorm:"type:text;column:description"`
7-
AffectedPackages []AffectedPackage `json:"affectedPackages" gorm:"many2many:advisories_affected_packages;constraint:OnDelete:CASCADE"`
9+
AffectedPackages []AffectedPackage `json:"affectedPackages" gorm:"many2many:advisories_affected_packages;foreignKey:ID;joinForeignKey:advisory_id;References:ID;joinReferences:affected_package_id;constraint:OnDelete:CASCADE"`
810
Severity string `json:"severity" gorm:"type:text;column:severity"`
911
VectorString string `json:"vectorstring" gorm:"type:text;column:vector_string"`
12+
AssetID uuid.UUID `json:"assetID" gorm:"type:uuid;column:asset_id"`
1013
}
11-
1214
type AffectedPackage struct {
1315
Model
1416
Ecosystem string `json:"ecosystem" gorm:"type:text;column:ecosystem"`

database/repositories/advisory_repository.go

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,36 @@ func (advisoryRepository *AdvisoryRepository) Create(ctx context.Context, tx *go
3232
return nil
3333
}
3434

35-
func (advisoryRepository *AdvisoryRepository) ReadName(ctx context.Context, tx *gorm.DB) ([]models.Advisory, error) {
36-
advisoryNames := []models.Advisory{}
35+
func (advisoryRepository *AdvisoryRepository) ReadAll(ctx context.Context, tx *gorm.DB, assetID uuid.UUID) ([]models.Advisory, error) {
36+
advisories := []models.Advisory{}
3737
db := advisoryRepository.db.WithContext(ctx)
3838
if tx != nil {
3939
db = tx
4040
}
41-
err := db.Raw(`SELECT * FROM advisories;`).Find(&advisoryNames).Error
42-
return advisoryNames, err
41+
err := db.Preload("AffectedPackages").Where("asset_id = ?", assetID).Find(&advisories).Error
42+
return advisories, err
4343
}
4444

45-
func (advisoryRepository *AdvisoryRepository) UpdateName(ctx context.Context, tx *gorm.DB, id uuid.UUID, name string) error {
46-
err := advisoryRepository.GetDB(ctx, tx).
47-
Model(&models.Advisory{Model: models.Model{ID: id}}).
48-
Update("advisory_name", name).Error
49-
if err != nil {
50-
return err
45+
func (advisoryRepository *AdvisoryRepository) ReadAdvisory(ctx context.Context, tx *gorm.DB, id uuid.UUID) (models.Advisory, error) {
46+
advisory := models.Advisory{}
47+
db := advisoryRepository.db.WithContext(ctx)
48+
if tx != nil {
49+
db = tx
5150
}
52-
return nil
51+
err := db.Preload("AffectedPackages").Where("id = ?", id).Find(&advisory).Error
52+
return advisory, err
5353
}
5454

55-
func (advisoryRepository *AdvisoryRepository) DeleteName(ctx context.Context, tx *gorm.DB, id uuid.UUID) error {
56-
err := advisoryRepository.GetDB(ctx, tx).Delete(&models.Advisory{Model: models.Model{ID: id}}).Error
55+
func (advisoryRepository *AdvisoryRepository) Update(ctx context.Context, tx *gorm.DB, id uuid.UUID, advisory *models.Advisory) error {
56+
return advisoryRepository.GetDB(ctx, tx).Session(&gorm.Session{FullSaveAssociations: true}).Save(advisory).Error
57+
}
58+
59+
func (advisoryRepository *AdvisoryRepository) Delete(ctx context.Context, tx *gorm.DB, id uuid.UUID) error {
60+
db := advisoryRepository.db.WithContext(ctx)
61+
if tx != nil {
62+
db = tx
63+
}
64+
err := db.Preload("AffectedPackages").Delete(&models.Advisory{Model: models.Model{ID: id}}).Error
5765
if err != nil {
5866
return err
5967
}

dtos/advisory_dto.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ type AdvisoryCreate struct {
2323
AffectedPackages []AffectedPackage `json:"affectedPackages"`
2424
Severity string `json:"severity"`
2525
VectorString string `json:"vectorString"`
26+
AssetID uuid.UUID `json:"assetID"`
2627
}
2728
type AdvisoryUpdate struct {
2829
Title *string `json:"title"`
2930
Description *string `json:"description"`
3031
AffectedPackages []AffectedPackage `json:"affectedPackages"`
3132
Severity *string `json:"severity"`
3233
VectorString *string `json:"vectorString"`
34+
AssetID *uuid.UUID `json:"assetID"`
3335
}
3436

3537
type AdvisoryDTO struct {
@@ -39,6 +41,7 @@ type AdvisoryDTO struct {
3941
AffectedPackages []AffectedPackage `json:"affectedPackages"`
4042
Severity string `json:"severity"`
4143
VectorString string `json:"vectorString"`
44+
AssetID uuid.UUID `json:"assetID"`
4245
}
4346

4447
type AffectedPackage struct {

router/advisory_router.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@ func NewAdvisoryRouter(
3232
) AdvisoryRouter {
3333
advisoryRouter := assetVersionGroup.Group.Group("/advisory")
3434
advisoryRouter.POST("/", advisoryController.Create)
35-
// advisoryRouter.GET("/", advisoryController.Read)
36-
// advisoryRouter.PATCH("/:id/", advisoryController.Update)
37-
// advisoryRouter.DELETE("/:id/", advisoryController.Delete)
35+
advisoryRouter.GET("/", advisoryController.ReadAll)
36+
advisoryRouter.GET("/:id/", advisoryController.ReadAdvisory)
37+
advisoryRouter.PATCH("/:id/", advisoryController.Update)
38+
advisoryRouter.DELETE("/:id/", advisoryController.Delete)
3839

3940
return AdvisoryRouter{Group: advisoryRouter}
4041
}

services/advisory_service.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,22 @@ func (s *AdvisoryService) Create(ctx context.Context, advisory *models.Advisory)
2424
return s.advisoryRepository.Create(ctx, nil, advisory)
2525
}
2626

27-
func (s *AdvisoryService) ReadName(ctx context.Context) ([]models.Advisory, error) {
28-
advisoryNames, err := s.advisoryRepository.ReadName(ctx, nil)
27+
func (s *AdvisoryService) ReadAll(ctx context.Context, assetID uuid.UUID) ([]models.Advisory, error) {
28+
advisories, err := s.advisoryRepository.ReadAll(ctx, nil, assetID)
2929
if err != nil {
3030
return nil, err
3131
}
32-
return advisoryNames, nil
32+
return advisories, nil
3333
}
3434

35-
func (s *AdvisoryService) UpdateName(ctx context.Context, id uuid.UUID, name string) error {
36-
return s.advisoryRepository.UpdateName(ctx, nil, id, name)
35+
func (s *AdvisoryService) ReadAdvisory(ctx context.Context, id uuid.UUID) (models.Advisory, error) {
36+
return s.advisoryRepository.ReadAdvisory(ctx, nil, id)
3737
}
3838

39-
func (s *AdvisoryService) DeleteName(ctx context.Context, id uuid.UUID) error {
40-
return s.advisoryRepository.DeleteName(ctx, nil, id)
39+
func (s *AdvisoryService) Update(ctx context.Context, id uuid.UUID, advisory *models.Advisory) error {
40+
return s.advisoryRepository.Update(ctx, nil, id, advisory)
41+
}
42+
43+
func (s *AdvisoryService) Delete(ctx context.Context, id uuid.UUID) error {
44+
return s.advisoryRepository.Delete(ctx, nil, id)
4145
}

shared/common_interfaces.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -763,16 +763,18 @@ type RBACProvider interface {
763763

764764
type AdvisoryService interface {
765765
Create(ctx context.Context, advisory *models.Advisory) error
766-
ReadName(ctx context.Context) ([]models.Advisory, error)
767-
UpdateName(ctx context.Context, id uuid.UUID, name string) error
768-
DeleteName(ctx context.Context, id uuid.UUID) error
766+
ReadAll(ctx context.Context, assetID uuid.UUID) ([]models.Advisory, error)
767+
ReadAdvisory(ctx context.Context, id uuid.UUID) (models.Advisory, error)
768+
Update(ctx context.Context, id uuid.UUID, advisory *models.Advisory) error
769+
Delete(ctx context.Context, id uuid.UUID) error
769770
}
770771

771772
type AdvisoryRepository interface {
772773
Create(ctx context.Context, tx DB, advisory *models.Advisory) error
773-
ReadName(ctx context.Context, tx DB) ([]models.Advisory, error)
774-
UpdateName(ctx context.Context, tx DB, id uuid.UUID, name string) error
775-
DeleteName(ctx context.Context, tx DB, id uuid.UUID) error
774+
ReadAll(ctx context.Context, tx DB, assetID uuid.UUID) ([]models.Advisory, error)
775+
ReadAdvisory(ctx context.Context, tx DB, id uuid.UUID) (models.Advisory, error)
776+
Update(ctx context.Context, tx DB, id uuid.UUID, advisory *models.Advisory) error
777+
Delete(ctx context.Context, tx DB, id uuid.UUID) error
776778
}
777779

778780
type RBACMiddleware = func(obj Object, act Action) echo.MiddlewareFunc

transformer/advisory_transformer.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,39 @@ func AdvisoryCreateRequestToModel(c dtos.AdvisoryCreate) models.Advisory {
1818
AffectedPackages: components,
1919
Severity: c.Severity,
2020
VectorString: c.VectorString,
21+
AssetID: c.AssetID,
2122
}
2223
}
2324

25+
func AdvisoryUpdateRequestToModel(c dtos.AdvisoryUpdate, advisory models.Advisory) models.Advisory {
26+
if c.Title != nil {
27+
advisory.Title = *c.Title
28+
}
29+
if c.Description != nil {
30+
advisory.Description = *c.Description
31+
}
32+
if c.Severity != nil {
33+
advisory.Severity = *c.Severity
34+
}
35+
if c.VectorString != nil {
36+
advisory.VectorString = *c.VectorString
37+
}
38+
if c.AffectedPackages != nil {
39+
components := make([]models.AffectedPackage, len(c.AffectedPackages))
40+
for i, asset := range c.AffectedPackages {
41+
components[i] = AffectedPackageToModel(asset)
42+
}
43+
advisory.AffectedPackages = components
44+
}
45+
if c.AssetID != nil {
46+
advisory.AssetID = *c.AssetID
47+
}
48+
return advisory
49+
}
50+
2451
func AffectedPackageToModel(c dtos.AffectedPackage) models.AffectedPackage {
2552
return models.AffectedPackage{
53+
Model: models.Model{ID: c.ID},
2654
Ecosystem: c.Ecosystem,
2755
PackageName: c.PackageName,
2856
SemverIntroduced: c.SemverIntroduced,

0 commit comments

Comments
 (0)