diff --git a/apps/console/src/pages/organizations/mitigations/__generated__/MitigationViewFulfillEvidenceMutation.graphql.ts b/apps/console/src/pages/organizations/mitigations/__generated__/MitigationViewFulfillEvidenceMutation.graphql.ts index 8244511e7..3e37cf5eb 100644 --- a/apps/console/src/pages/organizations/mitigations/__generated__/MitigationViewFulfillEvidenceMutation.graphql.ts +++ b/apps/console/src/pages/organizations/mitigations/__generated__/MitigationViewFulfillEvidenceMutation.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -14,6 +14,7 @@ export type EvidenceType = "FILE" | "LINK"; export type FulfillEvidenceInput = { evidenceId: string; file?: any | null | undefined; + name?: string | null | undefined; url?: string | null | undefined; }; export type MitigationViewFulfillEvidenceMutation$variables = { diff --git a/pkg/coredata/evidence.go b/pkg/coredata/evidence.go index 1b6be1ebc..373bb779e 100644 --- a/pkg/coredata/evidence.go +++ b/pkg/coredata/evidence.go @@ -210,6 +210,49 @@ WHERE return nil } +func (e Evidence) Update( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +UPDATE + evidences +SET + type = @type, + state = @state, + object_key = @object_key, + mime_type = @mime_type, + size = @size, + filename = @filename, + url = @url, + description = @description, + updated_at = @updated_at +WHERE + %s + AND id = @evidence_id +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{ + "evidence_id": e.ID, + "type": e.Type, + "state": e.State, + "object_key": e.ObjectKey, + "mime_type": e.MimeType, + "size": e.Size, + "filename": e.Filename, + "url": e.URL, + "description": e.Description, + "updated_at": e.UpdatedAt, + } + maps.Copy(args, scope.SQLArguments()) + + _, err := conn.Exec(ctx, q, args) + return err +} + func (e Evidence) Delete( ctx context.Context, conn pg.Conn, diff --git a/pkg/probo/evidence_service.go b/pkg/probo/evidence_service.go index 304419f49..fd334c74f 100644 --- a/pkg/probo/evidence_service.go +++ b/pkg/probo/evidence_service.go @@ -47,7 +47,8 @@ type ( FulfilledEvidenceRequest struct { EvidenceID gid.GID File io.Reader - URL string + URL *string + Filename *string } CreateEvidenceRequest struct { @@ -131,10 +132,59 @@ func (s EvidenceService) Fulfill( evidence.State = coredata.EvidenceStateFulfilled + if req.File != nil { + evidence.Type = coredata.EvidenceTypeFile + + contentType := "application/octet-stream" + if req.Filename != nil { + evidence.Filename = *req.Filename + if detectedType := mime.TypeByExtension(filepath.Ext(*req.Filename)); detectedType != "" { + contentType = detectedType + } + } + + objectKey, err := uuid.NewV7() + if err != nil { + return fmt.Errorf("cannot generate object key: %w", err) + } + + _, err = s.svc.s3.PutObject(ctx, &s3.PutObjectInput{ + Bucket: aws.String(s.svc.bucket), + Key: aws.String(objectKey.String()), + Body: req.File, + ContentType: aws.String(contentType), + }) + if err != nil { + return fmt.Errorf("cannot upload file to S3: %w", err) + } + + headOutput, err := s.svc.s3.HeadObject(ctx, &s3.HeadObjectInput{ + Bucket: aws.String(s.svc.bucket), + Key: aws.String(objectKey.String()), + }) + if err != nil { + return fmt.Errorf("cannot get object metadata: %w", err) + } + + evidence.ObjectKey = objectKey.String() + evidence.MimeType = contentType + evidence.Size = uint64(*headOutput.ContentLength) + } else if req.URL != nil { + evidence.Type = coredata.EvidenceTypeLink + evidence.URL = *req.URL + } + + evidence.UpdatedAt = time.Now() + return evidence.Update(ctx, conn, s.svc.scope) }, ) + if err != nil { + return nil, fmt.Errorf("cannot update evidence: %w", err) + } + + return evidence, nil } func (s EvidenceService) Create( @@ -172,7 +222,7 @@ func (s EvidenceService) Create( return nil, fmt.Errorf("cannot generate object key: %w", err) } - putObjectOutput, err := s.svc.s3.PutObject(ctx, &s3.PutObjectInput{ + _, err = s.svc.s3.PutObject(ctx, &s3.PutObjectInput{ Bucket: aws.String(s.svc.bucket), Key: aws.String(objectKey.String()), Body: req.File, @@ -190,8 +240,6 @@ func (s EvidenceService) Create( return nil, fmt.Errorf("cannot get object metadata: %w", err) } - fmt.Println("putObjectOutput", putObjectOutput) - evidence.ObjectKey = objectKey.String() evidence.MimeType = contentType evidence.Size = uint64(*headOutput.ContentLength) diff --git a/pkg/server/api/console/v1/schema.graphql b/pkg/server/api/console/v1/schema.graphql index cd75a59c1..e34020911 100644 --- a/pkg/server/api/console/v1/schema.graphql +++ b/pkg/server/api/console/v1/schema.graphql @@ -948,6 +948,7 @@ input RequestEvidenceInput { input FulfillEvidenceInput { evidenceId: ID! + name: String file: Upload url: String } diff --git a/pkg/server/api/console/v1/schema/schema.go b/pkg/server/api/console/v1/schema/schema.go index 8146c4154..7d141a6a4 100644 --- a/pkg/server/api/console/v1/schema/schema.go +++ b/pkg/server/api/console/v1/schema/schema.go @@ -3579,6 +3579,7 @@ input RequestEvidenceInput { input FulfillEvidenceInput { evidenceId: ID! + name: String file: Upload url: String } @@ -20868,7 +20869,7 @@ func (ec *executionContext) unmarshalInputFulfillEvidenceInput(ctx context.Conte asMap[k] = v } - fieldsInOrder := [...]string{"evidenceId", "file", "url"} + fieldsInOrder := [...]string{"evidenceId", "name", "file", "url"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -20882,6 +20883,13 @@ func (ec *executionContext) unmarshalInputFulfillEvidenceInput(ctx context.Conte return it, err } it.EvidenceID = data + case "name": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Name = data case "file": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("file")) data, err := ec.unmarshalOUpload2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚐUpload(ctx, v) diff --git a/pkg/server/api/console/v1/types/types.go b/pkg/server/api/console/v1/types/types.go index ba4b6b1bf..34097687b 100644 --- a/pkg/server/api/console/v1/types/types.go +++ b/pkg/server/api/console/v1/types/types.go @@ -321,6 +321,7 @@ type FrameworkEdge struct { type FulfillEvidenceInput struct { EvidenceID gid.GID `json:"evidenceId"` + Name *string `json:"name,omitempty"` File *graphql.Upload `json:"file,omitempty"` URL *string `json:"url,omitempty"` } diff --git a/pkg/server/api/console/v1/v1_resolver.go b/pkg/server/api/console/v1/v1_resolver.go index f4c089835..035630acb 100644 --- a/pkg/server/api/console/v1/v1_resolver.go +++ b/pkg/server/api/console/v1/v1_resolver.go @@ -750,10 +750,11 @@ func (r *mutationResolver) FulfillEvidence(ctx context.Context, input types.Fulf if input.File != nil { req.File = input.File.File + req.Filename = &input.File.Filename } if input.URL != nil { - req.URL = *input.URL + req.URL = input.URL } evidence, err := svc.Evidences.Fulfill(ctx, req)