@@ -31,6 +31,7 @@ type (
|
|||||||
ID gid.GID `db:"id"`
|
ID gid.GID `db:"id"`
|
||||||
TaskID gid.GID `db:"task_id"`
|
TaskID gid.GID `db:"task_id"`
|
||||||
State EvidenceState `db:"state"`
|
State EvidenceState `db:"state"`
|
||||||
|
ReferenceID string `db:"reference_id"`
|
||||||
Type EvidenceType `db:"type"`
|
Type EvidenceType `db:"type"`
|
||||||
ObjectKey string `db:"object_key"`
|
ObjectKey string `db:"object_key"`
|
||||||
MimeType string `db:"mime_type"`
|
MimeType string `db:"mime_type"`
|
||||||
@@ -54,7 +55,7 @@ func (e Evidence) CursorKey(orderBy EvidenceOrderField) page.CursorKey {
|
|||||||
panic(fmt.Sprintf("unsupported order by: %s", orderBy))
|
panic(fmt.Sprintf("unsupported order by: %s", orderBy))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e Evidence) Insert(
|
func (e Evidence) Upsert(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
conn pg.Conn,
|
conn pg.Conn,
|
||||||
scope Scoper,
|
scope Scoper,
|
||||||
@@ -65,6 +66,7 @@ INSERT INTO
|
|||||||
tenant_id,
|
tenant_id,
|
||||||
id,
|
id,
|
||||||
task_id,
|
task_id,
|
||||||
|
reference_id,
|
||||||
object_key,
|
object_key,
|
||||||
mime_type,
|
mime_type,
|
||||||
size,
|
size,
|
||||||
@@ -80,6 +82,73 @@ VALUES (
|
|||||||
@tenant_id,
|
@tenant_id,
|
||||||
@evidence_id,
|
@evidence_id,
|
||||||
@task_id,
|
@task_id,
|
||||||
|
@reference_id,
|
||||||
|
@object_key,
|
||||||
|
@mime_type,
|
||||||
|
@size,
|
||||||
|
@state,
|
||||||
|
@type,
|
||||||
|
@filename,
|
||||||
|
@url,
|
||||||
|
@description,
|
||||||
|
@created_at,
|
||||||
|
@updated_at
|
||||||
|
)
|
||||||
|
ON CONFLICT (task_id, reference_id) DO UPDATE SET
|
||||||
|
description = @description,
|
||||||
|
type = @type,
|
||||||
|
updated_at = @updated_at
|
||||||
|
WHERE evidences.state = 'REQUESTED';
|
||||||
|
`
|
||||||
|
|
||||||
|
args := pgx.StrictNamedArgs{
|
||||||
|
"tenant_id": scope.GetTenantID(),
|
||||||
|
"evidence_id": e.ID,
|
||||||
|
"task_id": e.TaskID,
|
||||||
|
"reference_id": e.ReferenceID,
|
||||||
|
"object_key": e.ObjectKey,
|
||||||
|
"mime_type": e.MimeType,
|
||||||
|
"size": e.Size,
|
||||||
|
"filename": e.Filename,
|
||||||
|
"created_at": e.CreatedAt,
|
||||||
|
"updated_at": e.UpdatedAt,
|
||||||
|
"state": e.State,
|
||||||
|
"type": e.Type,
|
||||||
|
"url": e.URL,
|
||||||
|
"description": e.Description,
|
||||||
|
}
|
||||||
|
_, err := conn.Exec(ctx, q, args)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Evidence) Insert(
|
||||||
|
ctx context.Context,
|
||||||
|
conn pg.Conn,
|
||||||
|
scope Scoper,
|
||||||
|
) error {
|
||||||
|
q := `
|
||||||
|
INSERT INTO
|
||||||
|
evidences (
|
||||||
|
tenant_id,
|
||||||
|
id,
|
||||||
|
task_id,
|
||||||
|
reference_id,
|
||||||
|
object_key,
|
||||||
|
mime_type,
|
||||||
|
size,
|
||||||
|
state,
|
||||||
|
type,
|
||||||
|
filename,
|
||||||
|
url,
|
||||||
|
description,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
@tenant_id,
|
||||||
|
@evidence_id,
|
||||||
|
@task_id,
|
||||||
|
@reference_id,
|
||||||
@object_key,
|
@object_key,
|
||||||
@mime_type,
|
@mime_type,
|
||||||
@size,
|
@size,
|
||||||
@@ -94,19 +163,20 @@ VALUES (
|
|||||||
`
|
`
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
args := pgx.StrictNamedArgs{
|
||||||
"tenant_id": scope.GetTenantID(),
|
"tenant_id": scope.GetTenantID(),
|
||||||
"evidence_id": e.ID,
|
"evidence_id": e.ID,
|
||||||
"task_id": e.TaskID,
|
"task_id": e.TaskID,
|
||||||
"object_key": e.ObjectKey,
|
"reference_id": e.ReferenceID,
|
||||||
"mime_type": e.MimeType,
|
"object_key": e.ObjectKey,
|
||||||
"size": e.Size,
|
"mime_type": e.MimeType,
|
||||||
"filename": e.Filename,
|
"size": e.Size,
|
||||||
"created_at": e.CreatedAt,
|
"filename": e.Filename,
|
||||||
"updated_at": e.UpdatedAt,
|
"created_at": e.CreatedAt,
|
||||||
"state": e.State,
|
"updated_at": e.UpdatedAt,
|
||||||
"type": e.Type,
|
"state": e.State,
|
||||||
"url": e.URL,
|
"type": e.Type,
|
||||||
"description": e.Description,
|
"url": e.URL,
|
||||||
|
"description": e.Description,
|
||||||
}
|
}
|
||||||
_, err := conn.Exec(ctx, q, args)
|
_, err := conn.Exec(ctx, q, args)
|
||||||
return err
|
return err
|
||||||
@@ -122,6 +192,7 @@ func (e *Evidence) LoadByID(
|
|||||||
SELECT
|
SELECT
|
||||||
id,
|
id,
|
||||||
task_id,
|
task_id,
|
||||||
|
reference_id,
|
||||||
state,
|
state,
|
||||||
type,
|
type,
|
||||||
object_key,
|
object_key,
|
||||||
@@ -171,6 +242,7 @@ func (e *Evidences) LoadByTaskID(
|
|||||||
SELECT
|
SELECT
|
||||||
id,
|
id,
|
||||||
task_id,
|
task_id,
|
||||||
|
reference_id,
|
||||||
state,
|
state,
|
||||||
type,
|
type,
|
||||||
object_key,
|
object_key,
|
||||||
|
|||||||
7
pkg/coredata/migrations/20250403T093800Z.sql
Normal file
7
pkg/coredata/migrations/20250403T093800Z.sql
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
ALTER TABLE evidences ADD COLUMN reference_id TEXT;
|
||||||
|
|
||||||
|
UPDATE evidences SET reference_id = 'custom-evidence-' || gen_random_uuid()::text WHERE reference_id IS NULL;
|
||||||
|
|
||||||
|
ALTER TABLE evidences ALTER COLUMN reference_id SET NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE evidences ADD CONSTRAINT evidences_reference_id_key UNIQUE (task_id, reference_id);
|
||||||
@@ -197,10 +197,16 @@ func (s EvidenceService) Create(
|
|||||||
return nil, fmt.Errorf("cannot create evidence global id: %w", err)
|
return nil, fmt.Errorf("cannot create evidence global id: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
referenceID, err := uuid.NewV4()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot generate reference id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
evidence := &coredata.Evidence{
|
evidence := &coredata.Evidence{
|
||||||
ID: evidenceID,
|
ID: evidenceID,
|
||||||
TaskID: req.TaskID,
|
TaskID: req.TaskID,
|
||||||
State: coredata.EvidenceStateFulfilled,
|
State: coredata.EvidenceStateFulfilled,
|
||||||
|
ReferenceID: "custom-evidence-" + referenceID.String(),
|
||||||
Type: req.Type,
|
Type: req.Type,
|
||||||
Filename: req.Name,
|
Filename: req.Name,
|
||||||
URL: req.URL,
|
URL: req.URL,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/getprobo/probo/pkg/coredata"
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
"github.com/getprobo/probo/pkg/gid"
|
||||||
"github.com/getprobo/probo/pkg/page"
|
"github.com/getprobo/probo/pkg/page"
|
||||||
|
"go.gearno.de/crypto/uuid"
|
||||||
"go.gearno.de/kit/pg"
|
"go.gearno.de/kit/pg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -59,9 +60,14 @@ type (
|
|||||||
Control string `json:"control"`
|
Control string `json:"control"`
|
||||||
} `json:"standards"`
|
} `json:"standards"`
|
||||||
Tasks []struct {
|
Tasks []struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
ReferenceID string `json:"reference-id"`
|
ReferenceID string `json:"reference-id"`
|
||||||
|
RequestedEvidences []struct {
|
||||||
|
ReferenceID string `json:"reference-id"`
|
||||||
|
Type coredata.EvidenceType `json:"type"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
} `json:"requested-evidences"`
|
||||||
} `json:"tasks"`
|
} `json:"tasks"`
|
||||||
} `json:"mitigations"`
|
} `json:"mitigations"`
|
||||||
}
|
}
|
||||||
@@ -186,6 +192,28 @@ func (s MitigationService) Import(
|
|||||||
if err := task.Upsert(ctx, tx, s.svc.scope); err != nil {
|
if err := task.Upsert(ctx, tx, s.svc.scope); err != nil {
|
||||||
return fmt.Errorf("cannot upsert task: %w", err)
|
return fmt.Errorf("cannot upsert task: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for k := range req.Mitigations[i].Tasks[j].RequestedEvidences {
|
||||||
|
evidenceID, err := gid.NewGID(organizationID.TenantID(), coredata.EvidenceEntityType)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot create global id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
evidence := &coredata.Evidence{
|
||||||
|
State: coredata.EvidenceStateRequested,
|
||||||
|
ID: evidenceID,
|
||||||
|
TaskID: taskID,
|
||||||
|
ReferenceID: req.Mitigations[i].Tasks[j].RequestedEvidences[k].ReferenceID,
|
||||||
|
Type: req.Mitigations[i].Tasks[j].RequestedEvidences[k].Type,
|
||||||
|
Description: req.Mitigations[i].Tasks[j].RequestedEvidences[k].Name,
|
||||||
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := evidence.Upsert(ctx, tx, s.svc.scope); err != nil {
|
||||||
|
return fmt.Errorf("cannot upsert evidence: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, standard := range req.Mitigations[i].Standards {
|
for _, standard := range req.Mitigations[i].Standards {
|
||||||
@@ -318,12 +346,18 @@ func (s MitigationService) Create(
|
|||||||
return nil, fmt.Errorf("cannot create mitigation global id: %w", err)
|
return nil, fmt.Errorf("cannot create mitigation global id: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
referenceID, err := uuid.NewV4()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot generate reference id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
mitigation := &coredata.Mitigation{
|
mitigation := &coredata.Mitigation{
|
||||||
ID: mitigationID,
|
ID: mitigationID,
|
||||||
OrganizationID: req.OrganizationID,
|
OrganizationID: req.OrganizationID,
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
Description: req.Description,
|
Description: req.Description,
|
||||||
Category: req.Category,
|
Category: req.Category,
|
||||||
|
ReferenceID: "custom-mitigation-" + referenceID.String(),
|
||||||
State: coredata.MitigationStateNotStarted,
|
State: coredata.MitigationStateNotStarted,
|
||||||
Importance: req.Importance,
|
Importance: req.Importance,
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import (
|
|||||||
"github.com/getprobo/probo/pkg/coredata"
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
"github.com/getprobo/probo/pkg/gid"
|
||||||
"github.com/getprobo/probo/pkg/page"
|
"github.com/getprobo/probo/pkg/page"
|
||||||
"github.com/getprobo/probo/pkg/slug"
|
"go.gearno.de/crypto/uuid"
|
||||||
"go.gearno.de/kit/pg"
|
"go.gearno.de/kit/pg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -58,6 +58,11 @@ func (s TaskService) Create(
|
|||||||
return nil, fmt.Errorf("cannot generate id: %w", err)
|
return nil, fmt.Errorf("cannot generate id: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
referenceID, err := uuid.NewV4()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot generate reference id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
task := &coredata.Task{
|
task := &coredata.Task{
|
||||||
ID: taskID,
|
ID: taskID,
|
||||||
MitigationID: req.MitigationID,
|
MitigationID: req.MitigationID,
|
||||||
@@ -66,7 +71,7 @@ func (s TaskService) Create(
|
|||||||
TimeEstimate: req.TimeEstimate,
|
TimeEstimate: req.TimeEstimate,
|
||||||
AssignedToID: req.AssignedToID,
|
AssignedToID: req.AssignedToID,
|
||||||
State: coredata.TaskStateTodo,
|
State: coredata.TaskStateTodo,
|
||||||
ReferenceID: slug.Make(req.Name),
|
ReferenceID: "custom-task-" + referenceID.String(),
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user