@@ -28,22 +28,26 @@ import (
|
||||
|
||||
type (
|
||||
Control struct {
|
||||
ID gid.GID `db:"id"`
|
||||
SectionTitle string `db:"section_title"`
|
||||
TenantID gid.TenantID `db:"tenant_id"`
|
||||
FrameworkID gid.GID `db:"framework_id"`
|
||||
Name string `db:"name"`
|
||||
Description string `db:"description"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
ID gid.GID `db:"id"`
|
||||
SectionTitle string `db:"section_title"`
|
||||
TenantID gid.TenantID `db:"tenant_id"`
|
||||
FrameworkID gid.GID `db:"framework_id"`
|
||||
Name string `db:"name"`
|
||||
Description string `db:"description"`
|
||||
Status ControlStatus `db:"status"`
|
||||
ExclusionJustification *string `db:"exclusion_justification"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
Controls []*Control
|
||||
|
||||
UpdateControlParams struct {
|
||||
Name *string
|
||||
Description *string
|
||||
SectionTitle *string
|
||||
Name *string
|
||||
Description *string
|
||||
SectionTitle *string
|
||||
Status *ControlStatus
|
||||
ExclusionJustification *string
|
||||
}
|
||||
)
|
||||
|
||||
@@ -117,6 +121,8 @@ WITH ctrl AS (
|
||||
c.tenant_id,
|
||||
c.name,
|
||||
c.description,
|
||||
c.status,
|
||||
c.exclusion_justification,
|
||||
c.created_at,
|
||||
c.updated_at,
|
||||
c.search_vector
|
||||
@@ -134,6 +140,8 @@ SELECT
|
||||
tenant_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -223,6 +231,8 @@ WITH ctrl AS (
|
||||
c.tenant_id,
|
||||
c.name,
|
||||
c.description,
|
||||
c.status,
|
||||
c.exclusion_justification,
|
||||
c.created_at,
|
||||
c.updated_at,
|
||||
c.search_vector
|
||||
@@ -240,6 +250,8 @@ SELECT
|
||||
tenant_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -335,6 +347,8 @@ WITH ctrl AS (
|
||||
c.tenant_id,
|
||||
c.name,
|
||||
c.description,
|
||||
c.status,
|
||||
c.exclusion_justification,
|
||||
c.created_at,
|
||||
c.updated_at,
|
||||
c.search_vector
|
||||
@@ -358,6 +372,8 @@ SELECT
|
||||
tenant_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -400,8 +416,8 @@ SELECT
|
||||
COUNT(id)
|
||||
FROM
|
||||
controls
|
||||
WHERE %s
|
||||
AND framework_id = @framework_id
|
||||
WHERE %s
|
||||
AND framework_id = @framework_id
|
||||
AND %s
|
||||
`
|
||||
q = fmt.Sprintf(q, scope.SQLFragment(), filter.SQLFragment())
|
||||
@@ -436,6 +452,8 @@ SELECT
|
||||
tenant_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -528,6 +546,8 @@ WITH ctrl AS (
|
||||
c.tenant_id,
|
||||
c.name,
|
||||
c.description,
|
||||
c.status,
|
||||
c.exclusion_justification,
|
||||
c.created_at,
|
||||
c.updated_at,
|
||||
c.search_vector
|
||||
@@ -545,6 +565,8 @@ SELECT
|
||||
tenant_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -590,6 +612,8 @@ SELECT
|
||||
tenant_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -633,6 +657,8 @@ SELECT
|
||||
tenant_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -675,6 +701,8 @@ INSERT INTO
|
||||
section_title,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
@@ -685,20 +713,24 @@ VALUES (
|
||||
@section_title,
|
||||
@name,
|
||||
@description,
|
||||
@status,
|
||||
@exclusion_justification,
|
||||
@created_at,
|
||||
@updated_at
|
||||
);
|
||||
`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"control_id": c.ID,
|
||||
"framework_id": c.FrameworkID,
|
||||
"section_title": c.SectionTitle,
|
||||
"name": c.Name,
|
||||
"description": c.Description,
|
||||
"created_at": c.CreatedAt,
|
||||
"updated_at": c.UpdatedAt,
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"control_id": c.ID,
|
||||
"framework_id": c.FrameworkID,
|
||||
"section_title": c.SectionTitle,
|
||||
"name": c.Name,
|
||||
"description": c.Description,
|
||||
"status": c.Status,
|
||||
"exclusion_justification": c.ExclusionJustification,
|
||||
"created_at": c.CreatedAt,
|
||||
"updated_at": c.UpdatedAt,
|
||||
}
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
@@ -737,6 +769,8 @@ UPDATE controls SET
|
||||
name = COALESCE(@name, name),
|
||||
description = COALESCE(@description, description),
|
||||
section_title = COALESCE(@section_title, section_title),
|
||||
status = COALESCE(@status, status),
|
||||
exclusion_justification = COALESCE(@exclusion_justification, exclusion_justification),
|
||||
updated_at = @updated_at
|
||||
WHERE %s
|
||||
AND id = @control_id
|
||||
@@ -747,15 +781,19 @@ RETURNING
|
||||
name,
|
||||
description,
|
||||
section_title,
|
||||
status,
|
||||
exclusion_justification,
|
||||
created_at,
|
||||
updated_at
|
||||
`
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"control_id": c.ID,
|
||||
"section_title": params.SectionTitle,
|
||||
"updated_at": time.Now(),
|
||||
"control_id": c.ID,
|
||||
"section_title": params.SectionTitle,
|
||||
"status": params.Status,
|
||||
"exclusion_justification": params.ExclusionJustification,
|
||||
"updated_at": time.Now(),
|
||||
}
|
||||
|
||||
if params.Name != nil {
|
||||
@@ -765,6 +803,13 @@ RETURNING
|
||||
args["description"] = *params.Description
|
||||
}
|
||||
|
||||
if params.Status != nil {
|
||||
args["status"] = *params.Status
|
||||
}
|
||||
if params.ExclusionJustification != nil {
|
||||
args["exclusion_justification"] = *params.ExclusionJustification
|
||||
}
|
||||
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
|
||||
52
pkg/coredata/control_status.go
Normal file
52
pkg/coredata/control_status.go
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package coredata
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ControlStatus string
|
||||
|
||||
const (
|
||||
ControlStatusIncluded ControlStatus = "INCLUDED"
|
||||
ControlStatusExcluded ControlStatus = "EXCLUDED"
|
||||
)
|
||||
|
||||
func (cs ControlStatus) String() string {
|
||||
return string(cs)
|
||||
}
|
||||
|
||||
func (cs *ControlStatus) Scan(value interface{}) error {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
switch v {
|
||||
case "INCLUDED":
|
||||
*cs = ControlStatusIncluded
|
||||
case "EXCLUDED":
|
||||
*cs = ControlStatusExcluded
|
||||
default:
|
||||
return fmt.Errorf("invalid ControlStatus value: %q", v)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unsupported type for ControlStatus: %T", value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cs ControlStatus) Value() (driver.Value, error) {
|
||||
return cs.String(), nil
|
||||
}
|
||||
5
pkg/coredata/migrations/20250717T122222Z.sql
Normal file
5
pkg/coredata/migrations/20250717T122222Z.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
CREATE TYPE control_status AS ENUM ('INCLUDED', 'EXCLUDED');
|
||||
|
||||
ALTER TABLE controls ADD COLUMN status control_status NOT NULL DEFAULT 'INCLUDED';
|
||||
ALTER TABLE controls ALTER COLUMN status DROP DEFAULT;
|
||||
ALTER TABLE controls ADD COLUMN exclusion_justification TEXT;
|
||||
@@ -39,10 +39,12 @@ type (
|
||||
}
|
||||
|
||||
UpdateControlRequest struct {
|
||||
ID gid.GID
|
||||
Name *string
|
||||
Description *string
|
||||
SectionTitle *string
|
||||
ID gid.GID
|
||||
Name *string
|
||||
Description *string
|
||||
SectionTitle *string
|
||||
Status *coredata.ControlStatus
|
||||
ExclusionJustification *string
|
||||
}
|
||||
|
||||
ConnectControlToMitigationRequest struct {
|
||||
@@ -551,9 +553,11 @@ func (s ControlService) Update(
|
||||
req UpdateControlRequest,
|
||||
) (*coredata.Control, error) {
|
||||
params := coredata.UpdateControlParams{
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
SectionTitle: req.SectionTitle,
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
SectionTitle: req.SectionTitle,
|
||||
Status: req.Status,
|
||||
ExclusionJustification: req.ExclusionJustification,
|
||||
}
|
||||
|
||||
control := &coredata.Control{ID: req.ID}
|
||||
|
||||
@@ -253,6 +253,7 @@ func (s FrameworkService) Import(
|
||||
SectionTitle: control.ID,
|
||||
Name: control.Name,
|
||||
Description: control.Description,
|
||||
Status: coredata.ControlStatusIncluded,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
@@ -306,18 +307,41 @@ func (s FrameworkService) StateOfApplicability(ctx context.Context, frameworkID
|
||||
}
|
||||
|
||||
for _, control := range controls {
|
||||
exclusionJustification := ""
|
||||
if control.Status == coredata.ControlStatusExcluded {
|
||||
if control.ExclusionJustification == nil {
|
||||
return fmt.Errorf("exclusion justification is required for excluded controls")
|
||||
}
|
||||
exclusionJustification = *control.ExclusionJustification
|
||||
}
|
||||
|
||||
applicability := soagen.NewApplicability("Yes", true)
|
||||
if control.Status == coredata.ControlStatusExcluded {
|
||||
applicability = soagen.NewApplicability("No", false)
|
||||
}
|
||||
|
||||
bestPractice := ref.Ref(true)
|
||||
if control.Status == coredata.ControlStatusExcluded {
|
||||
bestPractice = ref.Ref(false)
|
||||
}
|
||||
|
||||
row := soagen.SOARowData{
|
||||
SectionTitle: control.SectionTitle,
|
||||
ControlName: control.Name,
|
||||
Applicability: soagen.NewApplicability("Yes", true),
|
||||
JustificationExclusion: "",
|
||||
Applicability: applicability,
|
||||
ExclusionJustification: exclusionJustification,
|
||||
Regulatory: ref.Ref(false),
|
||||
Contractual: ref.Ref(false),
|
||||
BestPractice: ref.Ref(true),
|
||||
BestPractice: bestPractice,
|
||||
RiskAssessment: ref.Ref(false),
|
||||
SecurityMeasures: []string{},
|
||||
}
|
||||
|
||||
if control.Status == coredata.ControlStatusExcluded {
|
||||
rows = append(rows, row)
|
||||
continue
|
||||
}
|
||||
|
||||
measures := coredata.Measures{}
|
||||
err = measures.LoadByControlID(
|
||||
ctx,
|
||||
|
||||
@@ -509,6 +509,18 @@ enum DataClassification
|
||||
value: "github.com/getprobo/probo/pkg/coredata.DataClassificationSecret"
|
||||
)
|
||||
}
|
||||
|
||||
enum ControlStatus
|
||||
@goModel(model: "github.com/getprobo/probo/pkg/coredata.ControlStatus") {
|
||||
INCLUDED
|
||||
@goEnum(
|
||||
value: "github.com/getprobo/probo/pkg/coredata.ControlStatusIncluded"
|
||||
)
|
||||
EXCLUDED
|
||||
@goEnum(
|
||||
value: "github.com/getprobo/probo/pkg/coredata.ControlStatusExcluded"
|
||||
)
|
||||
}
|
||||
# Input Types
|
||||
input UserOrder
|
||||
@goModel(
|
||||
@@ -859,6 +871,8 @@ type Control implements Node {
|
||||
sectionTitle: String!
|
||||
name: String!
|
||||
description: String!
|
||||
status: ControlStatus!
|
||||
exclusionJustification: String
|
||||
|
||||
framework: Framework! @goField(forceResolver: true)
|
||||
|
||||
@@ -1747,6 +1761,8 @@ input CreateControlInput {
|
||||
sectionTitle: String!
|
||||
name: String!
|
||||
description: String!
|
||||
status: ControlStatus
|
||||
exclusionJustification: String
|
||||
}
|
||||
|
||||
input UpdateControlInput {
|
||||
@@ -1754,6 +1770,8 @@ input UpdateControlInput {
|
||||
sectionTitle: String
|
||||
name: String
|
||||
description: String
|
||||
status: ControlStatus
|
||||
exclusionJustification: String
|
||||
}
|
||||
|
||||
input DeleteControlInput {
|
||||
|
||||
@@ -147,15 +147,17 @@ type ComplexityRoot struct {
|
||||
}
|
||||
|
||||
Control struct {
|
||||
CreatedAt func(childComplexity int) int
|
||||
Description func(childComplexity int) int
|
||||
Documents func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) int
|
||||
Framework func(childComplexity int) int
|
||||
ID func(childComplexity int) int
|
||||
Measures func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) int
|
||||
Name func(childComplexity int) int
|
||||
SectionTitle func(childComplexity int) int
|
||||
UpdatedAt func(childComplexity int) int
|
||||
CreatedAt func(childComplexity int) int
|
||||
Description func(childComplexity int) int
|
||||
Documents func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) int
|
||||
ExclusionJustification func(childComplexity int) int
|
||||
Framework func(childComplexity int) int
|
||||
ID func(childComplexity int) int
|
||||
Measures func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) int
|
||||
Name func(childComplexity int) int
|
||||
SectionTitle func(childComplexity int) int
|
||||
Status func(childComplexity int) int
|
||||
UpdatedAt func(childComplexity int) int
|
||||
}
|
||||
|
||||
ControlConnection struct {
|
||||
@@ -1390,6 +1392,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
|
||||
return e.complexity.Control.Documents(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey), args["orderBy"].(*types.DocumentOrderBy), args["filter"].(*types.DocumentFilter)), true
|
||||
|
||||
case "Control.exclusionJustification":
|
||||
if e.complexity.Control.ExclusionJustification == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Control.ExclusionJustification(childComplexity), true
|
||||
|
||||
case "Control.framework":
|
||||
if e.complexity.Control.Framework == nil {
|
||||
break
|
||||
@@ -1430,6 +1439,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
|
||||
return e.complexity.Control.SectionTitle(childComplexity), true
|
||||
|
||||
case "Control.status":
|
||||
if e.complexity.Control.Status == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Control.Status(childComplexity), true
|
||||
|
||||
case "Control.updatedAt":
|
||||
if e.complexity.Control.UpdatedAt == nil {
|
||||
break
|
||||
@@ -5450,6 +5466,18 @@ enum DataClassification
|
||||
value: "github.com/getprobo/probo/pkg/coredata.DataClassificationSecret"
|
||||
)
|
||||
}
|
||||
|
||||
enum ControlStatus
|
||||
@goModel(model: "github.com/getprobo/probo/pkg/coredata.ControlStatus") {
|
||||
INCLUDED
|
||||
@goEnum(
|
||||
value: "github.com/getprobo/probo/pkg/coredata.ControlStatusIncluded"
|
||||
)
|
||||
EXCLUDED
|
||||
@goEnum(
|
||||
value: "github.com/getprobo/probo/pkg/coredata.ControlStatusExcluded"
|
||||
)
|
||||
}
|
||||
# Input Types
|
||||
input UserOrder
|
||||
@goModel(
|
||||
@@ -5800,6 +5828,8 @@ type Control implements Node {
|
||||
sectionTitle: String!
|
||||
name: String!
|
||||
description: String!
|
||||
status: ControlStatus!
|
||||
exclusionJustification: String
|
||||
|
||||
framework: Framework! @goField(forceResolver: true)
|
||||
|
||||
@@ -6688,6 +6718,8 @@ input CreateControlInput {
|
||||
sectionTitle: String!
|
||||
name: String!
|
||||
description: String!
|
||||
status: ControlStatus
|
||||
exclusionJustification: String
|
||||
}
|
||||
|
||||
input UpdateControlInput {
|
||||
@@ -6695,6 +6727,8 @@ input UpdateControlInput {
|
||||
sectionTitle: String
|
||||
name: String
|
||||
description: String
|
||||
status: ControlStatus
|
||||
exclusionJustification: String
|
||||
}
|
||||
|
||||
input DeleteControlInput {
|
||||
@@ -14015,6 +14049,91 @@ func (ec *executionContext) fieldContext_Control_description(_ context.Context,
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Control_status(ctx context.Context, field graphql.CollectedField, obj *types.Control) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_Control_status(ctx, field)
|
||||
if err != nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.Status, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(coredata.ControlStatus)
|
||||
fc.Result = res
|
||||
return ec.marshalNControlStatus2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Control_status(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "Control",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type ControlStatus does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Control_exclusionJustification(ctx context.Context, field graphql.CollectedField, obj *types.Control) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_Control_exclusionJustification(ctx, field)
|
||||
if err != nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.ExclusionJustification, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*string)
|
||||
fc.Result = res
|
||||
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Control_exclusionJustification(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "Control",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type String does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Control_framework(ctx context.Context, field graphql.CollectedField, obj *types.Control) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_Control_framework(ctx, field)
|
||||
if err != nil {
|
||||
@@ -14528,6 +14647,10 @@ func (ec *executionContext) fieldContext_ControlEdge_node(_ context.Context, fie
|
||||
return ec.fieldContext_Control_name(ctx, field)
|
||||
case "description":
|
||||
return ec.fieldContext_Control_description(ctx, field)
|
||||
case "status":
|
||||
return ec.fieldContext_Control_status(ctx, field)
|
||||
case "exclusionJustification":
|
||||
return ec.fieldContext_Control_exclusionJustification(ctx, field)
|
||||
case "framework":
|
||||
return ec.fieldContext_Control_framework(ctx, field)
|
||||
case "measures":
|
||||
@@ -31252,6 +31375,10 @@ func (ec *executionContext) fieldContext_UpdateControlPayload_control(_ context.
|
||||
return ec.fieldContext_Control_name(ctx, field)
|
||||
case "description":
|
||||
return ec.fieldContext_Control_description(ctx, field)
|
||||
case "status":
|
||||
return ec.fieldContext_Control_status(ctx, field)
|
||||
case "exclusionJustification":
|
||||
return ec.fieldContext_Control_exclusionJustification(ctx, field)
|
||||
case "framework":
|
||||
return ec.fieldContext_Control_framework(ctx, field)
|
||||
case "measures":
|
||||
@@ -37986,7 +38113,7 @@ func (ec *executionContext) unmarshalInputCreateControlInput(ctx context.Context
|
||||
asMap[k] = v
|
||||
}
|
||||
|
||||
fieldsInOrder := [...]string{"frameworkId", "sectionTitle", "name", "description"}
|
||||
fieldsInOrder := [...]string{"frameworkId", "sectionTitle", "name", "description", "status", "exclusionJustification"}
|
||||
for _, k := range fieldsInOrder {
|
||||
v, ok := asMap[k]
|
||||
if !ok {
|
||||
@@ -38021,6 +38148,20 @@ func (ec *executionContext) unmarshalInputCreateControlInput(ctx context.Context
|
||||
return it, err
|
||||
}
|
||||
it.Description = data
|
||||
case "status":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("status"))
|
||||
data, err := ec.unmarshalOControlStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
it.Status = data
|
||||
case "exclusionJustification":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("exclusionJustification"))
|
||||
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
it.ExclusionJustification = data
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40368,7 +40509,7 @@ func (ec *executionContext) unmarshalInputUpdateControlInput(ctx context.Context
|
||||
asMap[k] = v
|
||||
}
|
||||
|
||||
fieldsInOrder := [...]string{"id", "sectionTitle", "name", "description"}
|
||||
fieldsInOrder := [...]string{"id", "sectionTitle", "name", "description", "status", "exclusionJustification"}
|
||||
for _, k := range fieldsInOrder {
|
||||
v, ok := asMap[k]
|
||||
if !ok {
|
||||
@@ -40403,6 +40544,20 @@ func (ec *executionContext) unmarshalInputUpdateControlInput(ctx context.Context
|
||||
return it, err
|
||||
}
|
||||
it.Description = data
|
||||
case "status":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("status"))
|
||||
data, err := ec.unmarshalOControlStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
it.Status = data
|
||||
case "exclusionJustification":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("exclusionJustification"))
|
||||
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
it.ExclusionJustification = data
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42241,6 +42396,13 @@ func (ec *executionContext) _Control(ctx context.Context, sel ast.SelectionSet,
|
||||
if out.Values[i] == graphql.Null {
|
||||
atomic.AddUint32(&out.Invalids, 1)
|
||||
}
|
||||
case "status":
|
||||
out.Values[i] = ec._Control_status(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
atomic.AddUint32(&out.Invalids, 1)
|
||||
}
|
||||
case "exclusionJustification":
|
||||
out.Values[i] = ec._Control_exclusionJustification(ctx, field, obj)
|
||||
case "framework":
|
||||
field := field
|
||||
|
||||
@@ -51248,6 +51410,34 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func (ec *executionContext) unmarshalNControlStatus2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus(ctx context.Context, v any) (coredata.ControlStatus, error) {
|
||||
tmp, err := graphql.UnmarshalString(v)
|
||||
res := unmarshalNControlStatus2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus[tmp]
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNControlStatus2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus(ctx context.Context, sel ast.SelectionSet, v coredata.ControlStatus) graphql.Marshaler {
|
||||
_ = sel
|
||||
res := graphql.MarshalString(marshalNControlStatus2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus[v])
|
||||
if res == graphql.Null {
|
||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
var (
|
||||
unmarshalNControlStatus2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus = map[string]coredata.ControlStatus{
|
||||
"INCLUDED": coredata.ControlStatusIncluded,
|
||||
"EXCLUDED": coredata.ControlStatusExcluded,
|
||||
}
|
||||
marshalNControlStatus2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus = map[coredata.ControlStatus]string{
|
||||
coredata.ControlStatusIncluded: "INCLUDED",
|
||||
coredata.ControlStatusExcluded: "EXCLUDED",
|
||||
}
|
||||
)
|
||||
|
||||
func (ec *executionContext) unmarshalNCreateAssetInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateAssetInput(ctx context.Context, v any) (types.CreateAssetInput, error) {
|
||||
res, err := ec.unmarshalInputCreateAssetInput(ctx, v)
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
@@ -55014,6 +55204,36 @@ func (ec *executionContext) unmarshalOControlOrder2ᚖgithubᚗcomᚋgetproboᚋ
|
||||
return &res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalOControlStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus(ctx context.Context, v any) (*coredata.ControlStatus, error) {
|
||||
if v == nil {
|
||||
return nil, nil
|
||||
}
|
||||
tmp, err := graphql.UnmarshalString(v)
|
||||
res := unmarshalOControlStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus[tmp]
|
||||
return &res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOControlStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus(ctx context.Context, sel ast.SelectionSet, v *coredata.ControlStatus) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
_ = sel
|
||||
_ = ctx
|
||||
res := graphql.MarshalString(marshalOControlStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus[*v])
|
||||
return res
|
||||
}
|
||||
|
||||
var (
|
||||
unmarshalOControlStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus = map[string]coredata.ControlStatus{
|
||||
"INCLUDED": coredata.ControlStatusIncluded,
|
||||
"EXCLUDED": coredata.ControlStatusExcluded,
|
||||
}
|
||||
marshalOControlStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐControlStatus = map[coredata.ControlStatus]string{
|
||||
coredata.ControlStatusIncluded: "INCLUDED",
|
||||
coredata.ControlStatusExcluded: "EXCLUDED",
|
||||
}
|
||||
)
|
||||
|
||||
func (ec *executionContext) unmarshalOCriticityLevel2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐCriticityLevel(ctx context.Context, v any) (*coredata.CriticityLevel, error) {
|
||||
if v == nil {
|
||||
return nil, nil
|
||||
|
||||
@@ -65,11 +65,13 @@ func NewControlEdge(c *coredata.Control, orderBy coredata.ControlOrderField) *Co
|
||||
|
||||
func NewControl(c *coredata.Control) *Control {
|
||||
return &Control{
|
||||
ID: c.ID,
|
||||
SectionTitle: c.SectionTitle,
|
||||
Name: c.Name,
|
||||
Description: c.Description,
|
||||
CreatedAt: c.CreatedAt,
|
||||
UpdatedAt: c.UpdatedAt,
|
||||
ID: c.ID,
|
||||
SectionTitle: c.SectionTitle,
|
||||
Name: c.Name,
|
||||
Description: c.Description,
|
||||
Status: c.Status,
|
||||
ExclusionJustification: c.ExclusionJustification,
|
||||
CreatedAt: c.CreatedAt,
|
||||
UpdatedAt: c.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,15 +118,17 @@ type ConnectorOrder struct {
|
||||
}
|
||||
|
||||
type Control struct {
|
||||
ID gid.GID `json:"id"`
|
||||
SectionTitle string `json:"sectionTitle"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Framework *Framework `json:"framework"`
|
||||
Measures *MeasureConnection `json:"measures"`
|
||||
Documents *DocumentConnection `json:"documents"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ID gid.GID `json:"id"`
|
||||
SectionTitle string `json:"sectionTitle"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Status coredata.ControlStatus `json:"status"`
|
||||
ExclusionJustification *string `json:"exclusionJustification,omitempty"`
|
||||
Framework *Framework `json:"framework"`
|
||||
Measures *MeasureConnection `json:"measures"`
|
||||
Documents *DocumentConnection `json:"documents"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
func (Control) IsNode() {}
|
||||
@@ -167,10 +169,12 @@ type CreateControlDocumentMappingPayload struct {
|
||||
}
|
||||
|
||||
type CreateControlInput struct {
|
||||
FrameworkID gid.GID `json:"frameworkId"`
|
||||
SectionTitle string `json:"sectionTitle"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
FrameworkID gid.GID `json:"frameworkId"`
|
||||
SectionTitle string `json:"sectionTitle"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Status *coredata.ControlStatus `json:"status,omitempty"`
|
||||
ExclusionJustification *string `json:"exclusionJustification,omitempty"`
|
||||
}
|
||||
|
||||
type CreateControlMeasureMappingInput struct {
|
||||
@@ -948,10 +952,12 @@ type UpdateAssetPayload struct {
|
||||
}
|
||||
|
||||
type UpdateControlInput struct {
|
||||
ID gid.GID `json:"id"`
|
||||
SectionTitle *string `json:"sectionTitle,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
ID gid.GID `json:"id"`
|
||||
SectionTitle *string `json:"sectionTitle,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Status *coredata.ControlStatus `json:"status,omitempty"`
|
||||
ExclusionJustification *string `json:"exclusionJustification,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateControlPayload struct {
|
||||
|
||||
@@ -1220,10 +1220,12 @@ func (r *mutationResolver) UpdateControl(ctx context.Context, input types.Update
|
||||
prb := r.ProboService(ctx, input.ID.TenantID())
|
||||
|
||||
control, err := prb.Controls.Update(ctx, probo.UpdateControlRequest{
|
||||
ID: input.ID,
|
||||
Name: input.Name,
|
||||
Description: input.Description,
|
||||
SectionTitle: input.SectionTitle,
|
||||
ID: input.ID,
|
||||
Name: input.Name,
|
||||
Description: input.Description,
|
||||
SectionTitle: input.SectionTitle,
|
||||
Status: input.Status,
|
||||
ExclusionJustification: input.ExclusionJustification,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -50,7 +50,7 @@ var (
|
||||
HasFilter: true,
|
||||
},
|
||||
{
|
||||
Field: "JustificationExclusion",
|
||||
Field: "ExclusionJustification",
|
||||
Columns: []string{"D"},
|
||||
FilterColumns: []string{},
|
||||
Width: []float64{25},
|
||||
|
||||
@@ -103,7 +103,7 @@ func writeSOARow(f *excelize.File, sheetName string, row int, data SOARowData, i
|
||||
{"Contractual", data.Contractual},
|
||||
{"BestPractice", data.BestPractice},
|
||||
{"RiskAssessment", data.RiskAssessment},
|
||||
{"JustificationExclusion", data.JustificationExclusion},
|
||||
{"ExclusionJustification", data.ExclusionJustification},
|
||||
{"SecurityMeasures", data.SecurityMeasures},
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ type SOARowData struct {
|
||||
Contractual *bool
|
||||
BestPractice *bool
|
||||
RiskAssessment *bool
|
||||
JustificationExclusion string
|
||||
ExclusionJustification string
|
||||
SecurityMeasures []string
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user