Skip to content

Commit eaa2c12

Browse files
committed
feat: create method working for real inputs
1 parent 834c626 commit eaa2c12

9 files changed

Lines changed: 155 additions & 64 deletions

File tree

controllers/advisory_controller.go

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
package controllers
1717

1818
import (
19-
"github.com/google/uuid"
2019
"github.com/l3montree-dev/devguard/dtos"
2120
"github.com/l3montree-dev/devguard/shared"
21+
"github.com/l3montree-dev/devguard/transformer"
2222
"github.com/labstack/echo/v4"
2323
)
2424

@@ -32,66 +32,66 @@ func NewAdvisoryController(advisoryService shared.AdvisoryService) *AdvisoryCont
3232
}
3333
}
3434

35-
func (controller *AdvisoryController) CreateName(ctx shared.Context) error {
36-
var req dtos.AdvisoryCreateName
35+
func (controller *AdvisoryController) Create(ctx shared.Context) error {
36+
var req dtos.AdvisoryCreate
3737
if err := ctx.Bind(&req); err != nil {
3838
return echo.NewHTTPError(400, "unable to process request").WithInternal(err)
3939
}
4040

41-
newName := req.Name
41+
newAdvisory := transformer.AdvisoryCreateRequestToModel(req)
4242

43-
err := controller.advisoryService.CreateName(ctx.Request().Context(), newName)
43+
err := controller.advisoryService.Create(ctx.Request().Context(), &newAdvisory)
4444

4545
if err != nil {
4646
return echo.NewHTTPError(409, "could not set name").WithInternal(err)
4747
}
4848

49-
return ctx.JSON(200, newName)
49+
return ctx.NoContent(200)
5050
}
5151

52-
func (controller *AdvisoryController) ReadName(ctx shared.Context) error {
53-
advisory_names, 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, advisory_names)
58-
}
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+
// }
5959

60-
func (controller *AdvisoryController) UpdateName(ctx shared.Context) error {
61-
var req dtos.AdvisoryCreateName // Change to own struct
62-
if err := ctx.Bind(&req); err != nil {
63-
return echo.NewHTTPError(400, "unable to process request").WithInternal(err)
64-
}
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+
// }
6565

66-
updateName := req.Name
66+
// updateName := req.Name
6767

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

74-
err = controller.advisoryService.UpdateName(ctx.Request().Context(), parsedID, updateName)
74+
// err = controller.advisoryService.UpdateName(ctx.Request().Context(), parsedID, updateName)
7575

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

80-
return ctx.JSON(200, updateName)
81-
}
80+
// return ctx.JSON(200, updateName)
81+
// }
8282

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-
}
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+
// }
8989

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

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

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

database/migrations/20260623101120_add_advisory_table.up.sql

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,25 @@ CREATE TABLE public.advisories (
22
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
33
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
44
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
5-
advisory_name TEXT NOT NULL
6-
)
5+
title TEXT NOT NULL,
6+
description TEXT NOT NULL,
7+
severity TEXT,
8+
vector_string TEXT
9+
);
10+
11+
CREATE TABLE public.affected_packages (
12+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
13+
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
14+
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
15+
ecosystem TEXT NOT NULL,
16+
package_name TEXT,
17+
semver_introduced public.semver,
18+
semver_fixed public.semver
19+
);
20+
21+
CREATE TABLE public.advisories_affected_packages (
22+
advisory_id UUID NOT NULL REFERENCES public.advisories(id) ON DELETE CASCADE,
23+
affected_package_id UUID NOT NULL REFERENCES public.affected_packages(id) ON DELETE CASCADE,
24+
CONSTRAINT advisories_affected_packages_pkey PRIMARY KEY (advisory_id, affected_package_id)
25+
);
26+

database/models/advisory_model.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,26 @@ package models
22

33
type Advisory struct {
44
Model
5-
AdvisoryName string `json:"name" gorm:"type:text;column:advisory_name"`
5+
Title string `json:"title" gorm:"type:text;column:title"`
6+
Description string `json:"description" gorm:"type:text;column:description"`
7+
AffectedPackages []AffectedPackage `json:"affectedPackages" gorm:"many2many:advisories_affected_packages;constraint:OnDelete:CASCADE"`
8+
Severity string `json:"severity" gorm:"type:text;column:severity"`
9+
VectorString string `json:"vectorstring" gorm:"type:text;column:vector_string"`
10+
}
11+
12+
type AffectedPackage struct {
13+
Model
14+
Ecosystem string `json:"ecosystem" gorm:"type:text;column:ecosystem"`
15+
PackageName string `json:"packagename" gorm:"type:text;column:package_name"`
16+
SemverIntroduced *string `json:"semverStart" gorm:"type:semver;index"`
17+
SemverFixed *string `json:"semverEnd" gorm:"type:semver;index"`
18+
Advisory []Advisory `json:"advisory" gorm:"many2many:advisories_affected_packages;constraint:OnDelete:CASCADE"`
619
}
720

821
func (m Advisory) TableName() string {
922
return "advisories"
1023
}
24+
25+
func (m AffectedPackage) TableName() string {
26+
return "affected_packages"
27+
}

database/repositories/advisory_repository.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,22 @@ func NewAdvisoryRepository(db *gorm.DB) *AdvisoryRepository {
2424

2525
var _ shared.AdvisoryRepository = (*AdvisoryRepository)(nil)
2626

27-
func (advisoryRepository *AdvisoryRepository) CreateName(ctx context.Context, tx *gorm.DB, name string) error {
28-
err := advisoryRepository.GetDB(ctx, tx).Create(&models.Advisory{AdvisoryName: name}).Error
27+
func (advisoryRepository *AdvisoryRepository) Create(ctx context.Context, tx *gorm.DB, advisory *models.Advisory) error {
28+
err := advisoryRepository.GetDB(ctx, tx).Create(advisory).Error
2929
if err != nil {
3030
return err
3131
}
3232
return nil
3333
}
3434

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

4545
func (advisoryRepository *AdvisoryRepository) UpdateName(ctx context.Context, tx *gorm.DB, id uuid.UUID, name string) error {

dtos/advisory_dto.go

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,34 @@ package dtos
1717

1818
import "github.com/google/uuid"
1919

20-
type AdvisoryCreateName struct {
21-
Name string `json:"name" validate:"required"`
20+
type AdvisoryCreate struct {
21+
Title string `json:"title" validate:"required"`
22+
Description string `json:"description" validate:"required"`
23+
AffectedPackages []AffectedPackage `json:"affectedPackages"`
24+
Severity string `json:"severity"`
25+
VectorString string `json:"vectorString"`
26+
}
27+
type AdvisoryUpdate struct {
28+
Title *string `json:"title"`
29+
Description *string `json:"description"`
30+
AffectedPackages []AffectedPackage `json:"affectedPackages"`
31+
Severity *string `json:"severity"`
32+
VectorString *string `json:"vectorString"`
2233
}
2334

2435
type AdvisoryDTO struct {
25-
ID uuid.UUID `json:"id"`
26-
Name string `json:"name"`
36+
ID uuid.UUID `json:"id"`
37+
Title string `json:"title" validate:"required"`
38+
Description string `json:"description" validate:"required"`
39+
AffectedPackages []AffectedPackage `json:"affectedPackages"`
40+
Severity string `json:"severity"`
41+
VectorString string `json:"vectorString"`
42+
}
43+
44+
type AffectedPackage struct {
45+
ID uuid.UUID `json:"id,omitempty"`
46+
Ecosystem string `json:"ecosystem"`
47+
PackageName string `json:"packageName"`
48+
SemverIntroduced *string `json:"semverStart"`
49+
SemverFixed *string `json:"semverEnd"`
2750
}

router/advisory_router.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ func NewAdvisoryRouter(
3131
advisoryController *controllers.AdvisoryController,
3232
) AdvisoryRouter {
3333
advisoryRouter := assetVersionGroup.Group.Group("/advisory")
34-
advisoryRouter.POST("/", advisoryController.CreateName)
35-
advisoryRouter.GET("/", advisoryController.ReadName)
36-
advisoryRouter.PATCH("/:id/", advisoryController.UpdateName)
37-
advisoryRouter.DELETE("/:id/", advisoryController.DeleteName)
34+
advisoryRouter.POST("/", advisoryController.Create)
35+
// advisoryRouter.GET("/", advisoryController.Read)
36+
// advisoryRouter.PATCH("/:id/", advisoryController.Update)
37+
// advisoryRouter.DELETE("/:id/", advisoryController.Delete)
3838

3939
return AdvisoryRouter{Group: advisoryRouter}
4040
}

services/advisory_service.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ func NewAdvisoryService(advisoryRepository shared.AdvisoryRepository) *AdvisoryS
2020

2121
var _ shared.AdvisoryService = (*AdvisoryService)(nil)
2222

23-
func (s *AdvisoryService) CreateName(ctx context.Context, name string) error {
24-
return s.advisoryRepository.CreateName(ctx, nil, name)
23+
func (s *AdvisoryService) Create(ctx context.Context, advisory *models.Advisory) error {
24+
return s.advisoryRepository.Create(ctx, nil, advisory)
2525
}
2626

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

3535
func (s *AdvisoryService) UpdateName(ctx context.Context, id uuid.UUID, name string) error {

shared/common_interfaces.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -762,14 +762,14 @@ type RBACProvider interface {
762762
}
763763

764764
type AdvisoryService interface {
765-
CreateName(ctx context.Context, name string) error
765+
Create(ctx context.Context, advisory *models.Advisory) error
766766
ReadName(ctx context.Context) ([]models.Advisory, error)
767767
UpdateName(ctx context.Context, id uuid.UUID, name string) error
768768
DeleteName(ctx context.Context, id uuid.UUID) error
769769
}
770770

771771
type AdvisoryRepository interface {
772-
CreateName(ctx context.Context, tx DB, name string) error
772+
Create(ctx context.Context, tx DB, advisory *models.Advisory) error
773773
ReadName(ctx context.Context, tx DB) ([]models.Advisory, error)
774774
UpdateName(ctx context.Context, tx DB, id uuid.UUID, name string) error
775775
DeleteName(ctx context.Context, tx DB, id uuid.UUID) error
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package transformer
2+
3+
import (
4+
"github.com/l3montree-dev/devguard/database/models"
5+
"github.com/l3montree-dev/devguard/dtos"
6+
)
7+
8+
func AdvisoryCreateRequestToModel(c dtos.AdvisoryCreate) models.Advisory {
9+
10+
components := make([]models.AffectedPackage, len(c.AffectedPackages))
11+
for i, asset := range c.AffectedPackages {
12+
components[i] = AffectedPackageToModel(asset)
13+
}
14+
15+
return models.Advisory{
16+
Title: c.Title,
17+
Description: c.Description,
18+
AffectedPackages: components,
19+
Severity: c.Severity,
20+
VectorString: c.VectorString,
21+
}
22+
}
23+
24+
func AffectedPackageToModel(c dtos.AffectedPackage) models.AffectedPackage {
25+
return models.AffectedPackage{
26+
Ecosystem: c.Ecosystem,
27+
PackageName: c.PackageName,
28+
SemverIntroduced: c.SemverIntroduced,
29+
SemverFixed: c.SemverFixed,
30+
}
31+
}

0 commit comments

Comments
 (0)