diff --git a/.task/checksum/generate-ent-smart b/.task/checksum/generate-ent-smart index ddf55544b5..c4a23e0092 100644 --- a/.task/checksum/generate-ent-smart +++ b/.task/checksum/generate-ent-smart @@ -1 +1 @@ -c6b25036c8c31992fb717adc1a079f77 +4c64f3f331549a093e39318c14d1a15 diff --git a/.task/checksum/generate-graphql-smart b/.task/checksum/generate-graphql-smart index 3b9f58ef6c..80cf92b5f4 100644 --- a/.task/checksum/generate-graphql-smart +++ b/.task/checksum/generate-graphql-smart @@ -1 +1 @@ -5811c37439be5e024f83a9105568990c +90ad196d067073bdf9caf8672951bcb2 diff --git a/internal/ent/checksum/.history_schema_checksum b/internal/ent/checksum/.history_schema_checksum index f09f62fc35..d08ad23566 100644 --- a/internal/ent/checksum/.history_schema_checksum +++ b/internal/ent/checksum/.history_schema_checksum @@ -1 +1 @@ -756dab20acaccaa9e8d3a1a828e98f941860c80351db020ead63fa42c9246cd1 \ No newline at end of file +774a1b2017f36008a59d7336286eefb77000cdbb07b9095d74747602001e0b88 \ No newline at end of file diff --git a/internal/ent/checksum/.schema_checksum b/internal/ent/checksum/.schema_checksum index aaeaf16658..683ae4aeed 100644 --- a/internal/ent/checksum/.schema_checksum +++ b/internal/ent/checksum/.schema_checksum @@ -1 +1 @@ -078bb7642ac976c08a11add82250e09a0b8675d0c570d0c1b8e6f35fc56943bd \ No newline at end of file +998757daa7ac08acccd5ed9bab8efc4cfe6df3a0505db74c35f322050e74c330 \ No newline at end of file diff --git a/internal/ent/generated/control/control.go b/internal/ent/generated/control/control.go index 67c09b8c16..bf54523b2c 100644 --- a/internal/ent/generated/control/control.go +++ b/internal/ent/generated/control/control.go @@ -574,7 +574,7 @@ func ValidColumn(column string) bool { // // import _ "github.com/theopenlane/core/internal/ent/generated/runtime" var ( - Hooks [19]ent.Hook + Hooks [20]ent.Hook Interceptors [6]ent.Interceptor Policy ent.Policy // DefaultCreatedAt holds the default value on creation for the "created_at" field. diff --git a/internal/ent/generated/control_update.go b/internal/ent/generated/control_update.go index a73a7368ac..24a8dafec6 100644 --- a/internal/ent/generated/control_update.go +++ b/internal/ent/generated/control_update.go @@ -965,6 +965,26 @@ func (_u *ControlUpdate) ClearTrustCenterVisibility() *ControlUpdate { return _u } +// SetIsTrustCenterControl sets the "is_trust_center_control" field. +func (_u *ControlUpdate) SetIsTrustCenterControl(v bool) *ControlUpdate { + _u.mutation.SetIsTrustCenterControl(v) + return _u +} + +// SetNillableIsTrustCenterControl sets the "is_trust_center_control" field if the given value is not nil. +func (_u *ControlUpdate) SetNillableIsTrustCenterControl(v *bool) *ControlUpdate { + if v != nil { + _u.SetIsTrustCenterControl(*v) + } + return _u +} + +// ClearIsTrustCenterControl clears the value of the "is_trust_center_control" field. +func (_u *ControlUpdate) ClearIsTrustCenterControl() *ControlUpdate { + _u.mutation.ClearIsTrustCenterControl() + return _u +} + // AddEvidenceIDs adds the "evidence" edge to the Evidence entity by IDs. func (_u *ControlUpdate) AddEvidenceIDs(ids ...string) *ControlUpdate { _u.mutation.AddEvidenceIDs(ids...) @@ -2492,6 +2512,9 @@ func (_u *ControlUpdate) sqlSave(ctx context.Context) (_node int, err error) { if _u.mutation.TrustCenterVisibilityCleared() { _spec.ClearField(control.FieldTrustCenterVisibility, field.TypeEnum) } + if value, ok := _u.mutation.IsTrustCenterControl(); ok { + _spec.SetField(control.FieldIsTrustCenterControl, field.TypeBool, value) + } if _u.mutation.IsTrustCenterControlCleared() { _spec.ClearField(control.FieldIsTrustCenterControl, field.TypeBool) } @@ -5051,6 +5074,26 @@ func (_u *ControlUpdateOne) ClearTrustCenterVisibility() *ControlUpdateOne { return _u } +// SetIsTrustCenterControl sets the "is_trust_center_control" field. +func (_u *ControlUpdateOne) SetIsTrustCenterControl(v bool) *ControlUpdateOne { + _u.mutation.SetIsTrustCenterControl(v) + return _u +} + +// SetNillableIsTrustCenterControl sets the "is_trust_center_control" field if the given value is not nil. +func (_u *ControlUpdateOne) SetNillableIsTrustCenterControl(v *bool) *ControlUpdateOne { + if v != nil { + _u.SetIsTrustCenterControl(*v) + } + return _u +} + +// ClearIsTrustCenterControl clears the value of the "is_trust_center_control" field. +func (_u *ControlUpdateOne) ClearIsTrustCenterControl() *ControlUpdateOne { + _u.mutation.ClearIsTrustCenterControl() + return _u +} + // AddEvidenceIDs adds the "evidence" edge to the Evidence entity by IDs. func (_u *ControlUpdateOne) AddEvidenceIDs(ids ...string) *ControlUpdateOne { _u.mutation.AddEvidenceIDs(ids...) @@ -6608,6 +6651,9 @@ func (_u *ControlUpdateOne) sqlSave(ctx context.Context) (_node *Control, err er if _u.mutation.TrustCenterVisibilityCleared() { _spec.ClearField(control.FieldTrustCenterVisibility, field.TypeEnum) } + if value, ok := _u.mutation.IsTrustCenterControl(); ok { + _spec.SetField(control.FieldIsTrustCenterControl, field.TypeBool, value) + } if _u.mutation.IsTrustCenterControlCleared() { _spec.ClearField(control.FieldIsTrustCenterControl, field.TypeBool) } diff --git a/internal/ent/generated/gql_mutation_input.go b/internal/ent/generated/gql_mutation_input.go index c87a585848..8548601750 100644 --- a/internal/ent/generated/gql_mutation_input.go +++ b/internal/ent/generated/gql_mutation_input.go @@ -2831,6 +2831,7 @@ type CreateControlInput struct { WorkflowEligibleMarker *bool RefCode string TrustCenterVisibility *enums.TrustCenterControlVisibility + IsTrustCenterControl *bool EvidenceIDs []string ControlObjectiveIDs []string TaskIDs []string @@ -2975,6 +2976,9 @@ func (i *CreateControlInput) Mutate(m *ControlMutation) { if v := i.TrustCenterVisibility; v != nil { m.SetTrustCenterVisibility(*v) } + if v := i.IsTrustCenterControl; v != nil { + m.SetIsTrustCenterControl(*v) + } if v := i.EvidenceIDs; len(v) > 0 { m.AddEvidenceIDs(v...) } @@ -3168,6 +3172,8 @@ type UpdateControlInput struct { RefCode *string ClearTrustCenterVisibility bool TrustCenterVisibility *enums.TrustCenterControlVisibility + ClearIsTrustCenterControl bool + IsTrustCenterControl *bool ClearEvidence bool AddEvidenceIDs []string RemoveEvidenceIDs []string @@ -3507,6 +3513,12 @@ func (i *UpdateControlInput) Mutate(m *ControlMutation) { if v := i.TrustCenterVisibility; v != nil { m.SetTrustCenterVisibility(*v) } + if i.ClearIsTrustCenterControl { + m.ClearIsTrustCenterControl() + } + if v := i.IsTrustCenterControl; v != nil { + m.SetIsTrustCenterControl(*v) + } if i.ClearEvidence { m.ClearEvidence() } diff --git a/internal/ent/generated/runtime/runtime.go b/internal/ent/generated/runtime/runtime.go index 61d3496188..1e8a2d0131 100644 --- a/internal/ent/generated/runtime/runtime.go +++ b/internal/ent/generated/runtime/runtime.go @@ -992,6 +992,8 @@ func init() { control.Hooks[17] = controlHooks[0] control.Hooks[18] = controlHooks[1] + + control.Hooks[19] = controlHooks[2] controlMixinInters1 := controlMixin[1].Interceptors() controlMixinInters5 := controlMixin[5].Interceptors() controlMixinInters6 := controlMixin[6].Interceptors() diff --git a/internal/ent/historygenerated/controlhistory_update.go b/internal/ent/historygenerated/controlhistory_update.go index 0803ff45e4..85950ce30c 100644 --- a/internal/ent/historygenerated/controlhistory_update.go +++ b/internal/ent/historygenerated/controlhistory_update.go @@ -938,6 +938,26 @@ func (_u *ControlHistoryUpdate) ClearTrustCenterVisibility() *ControlHistoryUpda return _u } +// SetIsTrustCenterControl sets the "is_trust_center_control" field. +func (_u *ControlHistoryUpdate) SetIsTrustCenterControl(v bool) *ControlHistoryUpdate { + _u.mutation.SetIsTrustCenterControl(v) + return _u +} + +// SetNillableIsTrustCenterControl sets the "is_trust_center_control" field if the given value is not nil. +func (_u *ControlHistoryUpdate) SetNillableIsTrustCenterControl(v *bool) *ControlHistoryUpdate { + if v != nil { + _u.SetIsTrustCenterControl(*v) + } + return _u +} + +// ClearIsTrustCenterControl clears the value of the "is_trust_center_control" field. +func (_u *ControlHistoryUpdate) ClearIsTrustCenterControl() *ControlHistoryUpdate { + _u.mutation.ClearIsTrustCenterControl() + return _u +} + // Mutation returns the ControlHistoryMutation object of the builder. func (_u *ControlHistoryUpdate) Mutation() *ControlHistoryMutation { return _u.mutation @@ -1382,6 +1402,9 @@ func (_u *ControlHistoryUpdate) sqlSave(ctx context.Context) (_node int, err err if _u.mutation.TrustCenterVisibilityCleared() { _spec.ClearField(controlhistory.FieldTrustCenterVisibility, field.TypeEnum) } + if value, ok := _u.mutation.IsTrustCenterControl(); ok { + _spec.SetField(controlhistory.FieldIsTrustCenterControl, field.TypeBool, value) + } if _u.mutation.IsTrustCenterControlCleared() { _spec.ClearField(controlhistory.FieldIsTrustCenterControl, field.TypeBool) } @@ -2311,6 +2334,26 @@ func (_u *ControlHistoryUpdateOne) ClearTrustCenterVisibility() *ControlHistoryU return _u } +// SetIsTrustCenterControl sets the "is_trust_center_control" field. +func (_u *ControlHistoryUpdateOne) SetIsTrustCenterControl(v bool) *ControlHistoryUpdateOne { + _u.mutation.SetIsTrustCenterControl(v) + return _u +} + +// SetNillableIsTrustCenterControl sets the "is_trust_center_control" field if the given value is not nil. +func (_u *ControlHistoryUpdateOne) SetNillableIsTrustCenterControl(v *bool) *ControlHistoryUpdateOne { + if v != nil { + _u.SetIsTrustCenterControl(*v) + } + return _u +} + +// ClearIsTrustCenterControl clears the value of the "is_trust_center_control" field. +func (_u *ControlHistoryUpdateOne) ClearIsTrustCenterControl() *ControlHistoryUpdateOne { + _u.mutation.ClearIsTrustCenterControl() + return _u +} + // Mutation returns the ControlHistoryMutation object of the builder. func (_u *ControlHistoryUpdateOne) Mutation() *ControlHistoryMutation { return _u.mutation @@ -2785,6 +2828,9 @@ func (_u *ControlHistoryUpdateOne) sqlSave(ctx context.Context) (_node *ControlH if _u.mutation.TrustCenterVisibilityCleared() { _spec.ClearField(controlhistory.FieldTrustCenterVisibility, field.TypeEnum) } + if value, ok := _u.mutation.IsTrustCenterControl(); ok { + _spec.SetField(controlhistory.FieldIsTrustCenterControl, field.TypeBool, value) + } if _u.mutation.IsTrustCenterControlCleared() { _spec.ClearField(controlhistory.FieldIsTrustCenterControl, field.TypeBool) } diff --git a/internal/ent/hooks/control.go b/internal/ent/hooks/control.go index a2469a3e63..8260ed79d4 100644 --- a/internal/ent/hooks/control.go +++ b/internal/ent/hooks/control.go @@ -17,6 +17,57 @@ import ( "github.com/theopenlane/core/pkg/logx" ) +// HookControlTrustcenter runs on control mutations when adding making a trustcenter control +func HookControlTrustcenter() ent.Hook { + return hook.On(func(next ent.Mutator) ent.Mutator { + return hook.ControlFunc(func(ctx context.Context, m *generated.ControlMutation) (generated.Value, error) { + val, ok := m.IsTrustCenterControl() + if !ok || !val { + return next.Mutate(ctx, m) + } + + publicRepresentation, publicExists := m.PublicRepresentation() + standardID, standardExists := m.StandardID() + + switch m.Op() { + case ent.OpCreate: + if !publicExists || publicRepresentation == "" { + return nil, ErrTrustCenterControlNoPublicRepresentation + } + + if standardExists && standardID != "" { + return nil, ErrTrustCenterControlNoStandardRequired + } + + case ent.OpUpdateOne: + if !publicExists { + oldRepresentation, err := m.OldPublicRepresentation(ctx) + if err != nil { + return nil, err + } + + if oldRepresentation == "" { + return nil, ErrTrustCenterControlNoPublicRepresentation + } + } + + if !standardExists { + oldStandardID, err := m.OldStandardID(ctx) + if err != nil { + return nil, err + } + + if oldStandardID != "" { + return nil, ErrTrustCenterControlNoStandardRequired + } + } + } + + return next.Mutate(ctx, m) + }) + }, ent.OpCreate|ent.OpUpdate|ent.OpUpdateOne) +} + // HookControlReferenceFramework runs on control mutations to set the reference framework // based on the standard's short name func HookControlReferenceFramework() ent.Hook { diff --git a/internal/ent/hooks/errors.go b/internal/ent/hooks/errors.go index e5bcb0c346..7dcf267f7d 100644 --- a/internal/ent/hooks/errors.go +++ b/internal/ent/hooks/errors.go @@ -189,6 +189,10 @@ var ( ErrFailedToTriggerWorkflow = errors.New("failed to trigger workflow") // ErrMissingIDForTrustCenterNDARequest is returned when a mutation for trust center nda request is missing the ID field, which is required to determine the trust center and send the appropriate email ErrMissingIDForTrustCenterNDARequest = errors.New("missing ID for trust center NDA request mutation") + // ErrTrustCenterControlNoPublicRepresentation is returned when a control does not have a public representation yet when being linked to a trustcenter + ErrTrustCenterControlNoPublicRepresentation = errors.New("a trust center control requires a public representation") + // ErrTrustCenterControlNoStandardRequired is returned when a control is already linked to a standard and it is being connected to a trustcenter + ErrTrustCenterControlNoStandardRequired = errors.New("a trust center control must not be linked to a standard") ) // IsUniqueConstraintError reports if the error resulted from a DB uniqueness constraint violation. diff --git a/internal/ent/schema/control.go b/internal/ent/schema/control.go index 0bde1117a2..95c022857b 100644 --- a/internal/ent/schema/control.go +++ b/internal/ent/schema/control.go @@ -9,13 +9,14 @@ import ( "entgo.io/ent/schema/field" "entgo.io/ent/schema/index" "github.com/gertd/go-pluralize" - "github.com/theopenlane/core/common/enums" - "github.com/theopenlane/core/common/models" "github.com/theopenlane/entx" "github.com/theopenlane/entx/accessmap" "github.com/theopenlane/entx/oscalgen" "github.com/theopenlane/iam/entfga" + "github.com/theopenlane/core/common/enums" + "github.com/theopenlane/core/common/models" + "github.com/theopenlane/core/internal/ent/generated" "github.com/theopenlane/core/internal/ent/hooks" "github.com/theopenlane/core/internal/ent/interceptors" @@ -79,10 +80,6 @@ func (Control) Fields() []ent.Field { field.Bool("is_trust_center_control"). Default(false). Optional(). - Immutable(). - Annotations( - entgql.Skip(entgql.SkipMutationCreateInput, entgql.SkipMutationUpdateInput), - ). Comment("indicates the control is derived from the trust center standard, set by the system during control clone"), } @@ -225,6 +222,7 @@ func (Control) Hooks() []ent.Hook { return []ent.Hook{ hooks.HookControlReferenceFramework(), hooks.HookControlTrustCenterVisibility(), + hooks.HookControlTrustcenter(), } } diff --git a/internal/graphapi/checksum/.history_schema_checksum b/internal/graphapi/checksum/.history_schema_checksum index c28a002991..18e34586de 100644 --- a/internal/graphapi/checksum/.history_schema_checksum +++ b/internal/graphapi/checksum/.history_schema_checksum @@ -1 +1 @@ -56551cc51a4057cc66c71d8df667bc883601712d215771cf3c407403f16ec417 \ No newline at end of file +c35864d5a8f663ddb8fb142caa1d17899ff24b6e5a5db97f1e146d7b7508e5e1 \ No newline at end of file diff --git a/internal/graphapi/checksum/.schema_checksum b/internal/graphapi/checksum/.schema_checksum index 2a4455826e..3bc29b14fa 100644 --- a/internal/graphapi/checksum/.schema_checksum +++ b/internal/graphapi/checksum/.schema_checksum @@ -1 +1 @@ -5484f1f1567b3762c4d2d09f872c5ff0d04c720686c95c145879077d68b29cbf \ No newline at end of file +f404b0a42627d262dadb0acdf67cc43fdb23a6076f6bd59f1429c0b2e16f424a \ No newline at end of file diff --git a/internal/graphapi/clientschema/checksum/.schema_checksum b/internal/graphapi/clientschema/checksum/.schema_checksum index fb98ce74a7..c2598b76dd 100644 --- a/internal/graphapi/clientschema/checksum/.schema_checksum +++ b/internal/graphapi/clientschema/checksum/.schema_checksum @@ -1 +1 @@ -106152007288b8f81fecfc31255695f8d0c73908d053180e710a2c010e3de059 \ No newline at end of file +b25d7335d5761714ad4fe44cf0979c8a6021b320425d027ab355fc6104f4f197 \ No newline at end of file diff --git a/internal/graphapi/clientschema/schema.graphql b/internal/graphapi/clientschema/schema.graphql index 3ad6dd3adb..573f849039 100644 --- a/internal/graphapi/clientschema/schema.graphql +++ b/internal/graphapi/clientschema/schema.graphql @@ -11363,6 +11363,10 @@ input CreateControlInput { visibility of the control on the trust center, controls the publishing state for trust center display """ trustCenterVisibility: ControlTrustCenterControlVisibility + """ + indicates the control is derived from the trust center standard, set by the system during control clone + """ + isTrustCenterControl: Boolean evidenceIDs: [ID!] controlObjectiveIDs: [ID!] taskIDs: [ID!] @@ -83981,6 +83985,11 @@ input UpdateControlInput { """ trustCenterVisibility: ControlTrustCenterControlVisibility clearTrustCenterVisibility: Boolean + """ + indicates the control is derived from the trust center standard, set by the system during control clone + """ + isTrustCenterControl: Boolean + clearIsTrustCenterControl: Boolean addEvidenceIDs: [ID!] removeEvidenceIDs: [ID!] clearEvidence: Boolean diff --git a/internal/graphapi/control_test.go b/internal/graphapi/control_test.go index ab48f49de3..d10ab82380 100644 --- a/internal/graphapi/control_test.go +++ b/internal/graphapi/control_test.go @@ -17,6 +17,7 @@ import ( "github.com/theopenlane/core/common/enums" "github.com/theopenlane/core/common/models" "github.com/theopenlane/core/internal/ent/generated" + "github.com/theopenlane/core/internal/ent/hooks" "github.com/theopenlane/core/internal/graphapi/gqlerrors" "github.com/theopenlane/core/internal/graphapi/testclient" "github.com/theopenlane/core/internal/testutils" @@ -2958,6 +2959,7 @@ func TestQueryControlTrustCenterVisibility(t *testing.T) { SetTitle("Trust Center Public Control"). SetSource(enums.ControlSourceUserDefined). SetIsTrustCenterControl(true). + SetPublicRepresentation("p123"). SetOwnerID(testUser1.OrganizationID). Save(dbCtx) assert.NilError(t, err) @@ -2975,6 +2977,7 @@ func TestQueryControlTrustCenterVisibility(t *testing.T) { SetTitle("Trust Center Hidden Control"). SetSource(enums.ControlSourceUserDefined). SetIsTrustCenterControl(true). + SetPublicRepresentation("p1234"). SetOwnerID(testUser1.OrganizationID). Save(dbCtx) assert.NilError(t, err) @@ -3053,3 +3056,159 @@ func TestQueryControlTrustCenterVisibility(t *testing.T) { (&Cleanup[*generated.ControlDeleteOne]{client: suite.client.db.Control, IDs: []string{publicControl.ID, hiddenControl.ID, regularControl.ID}}).MustDelete(testUser1.UserCtx, t) (&Cleanup[*generated.TrustCenterDeleteOne]{client: suite.client.db.TrustCenter, ID: trustCenter.ID}).MustDelete(testUser1.UserCtx, t) } + +func TestMutationCreateControlTrustCenter(t *testing.T) { + publicStandard := (&StandardBuilder{client: suite.client, IsPublic: true}).MustNew(systemAdminUser.UserCtx, t) + + tt := []struct { + name string + request testclient.CreateControlInput + client *testclient.TestClient + ctx context.Context + expectedErr string + }{ + { + name: "fail, isTrustCenterControl is true but no public representation", + request: testclient.CreateControlInput{ + RefCode: "TC-1", + IsTrustCenterControl: lo.ToPtr(true), + }, + client: suite.client.api, + ctx: testUser1.UserCtx, + expectedErr: hooks.ErrTrustCenterControlNoPublicRepresentation.Error(), + }, + { + name: "fail, isTrustCenterControl is true with standard id but has public representation", + request: testclient.CreateControlInput{ + RefCode: "TC-2", + IsTrustCenterControl: lo.ToPtr(true), + PublicRepresentation: lo.ToPtr("This is a public representation"), + StandardID: &publicStandard.ID, + }, + client: suite.client.api, + ctx: testUser1.UserCtx, + expectedErr: hooks.ErrTrustCenterControlNoStandardRequired.Error(), + }, + { + name: "happy path, isTrustCenterControl is true with public representation but no standard id", + request: testclient.CreateControlInput{ + RefCode: "TC-3", + IsTrustCenterControl: lo.ToPtr(true), + PublicRepresentation: lo.ToPtr("This is a public representation"), + }, + client: suite.client.api, + ctx: testUser1.UserCtx, + }, + } + + controlIDsToDelete := []string{} + + for _, tc := range tt { + t.Run("Create "+tc.name, func(t *testing.T) { + resp, err := tc.client.CreateControl(tc.ctx, tc.request) + if tc.expectedErr != "" { + assert.ErrorContains(t, err, tc.expectedErr) + return + } + + assert.NilError(t, err) + assert.Check(t, resp != nil) + assert.Check(t, is.Equal(*tc.request.IsTrustCenterControl, *resp.CreateControl.Control.IsTrustCenterControl)) + assert.Check(t, is.Equal(*tc.request.PublicRepresentation, *resp.CreateControl.Control.PublicRepresentation)) + + controlIDsToDelete = append(controlIDsToDelete, resp.CreateControl.Control.ID) + }) + } + + (&Cleanup[*generated.ControlDeleteOne]{client: suite.client.db.Control, IDs: controlIDsToDelete}).MustDelete(testUser1.UserCtx, t) + (&Cleanup[*generated.StandardDeleteOne]{client: suite.client.db.Standard, ID: publicStandard.ID}).MustDelete(systemAdminUser.UserCtx, t) +} + +func TestMutationUpdateControlTrustCenterControlValidation(t *testing.T) { + standard := (&StandardBuilder{client: suite.client}).MustNew(testUser1.UserCtx, t) + + controlWithPublicRep := (&ControlBuilder{ + client: suite.client, + PublicRepresentation: "Original public representation", + }).MustNew(testUser1.UserCtx, t) + + controlWithStandardID := (&ControlBuilder{ + client: suite.client, + StandardID: standard.ID, + }).MustNew(testUser1.UserCtx, t) + + controlWithBoth := (&ControlBuilder{ + client: suite.client, + PublicRepresentation: "Another public representation", + StandardID: standard.ID, + }).MustNew(testUser1.UserCtx, t) + + testCases := []struct { + name string + request testclient.UpdateControlInput + controlID string + client *testclient.TestClient + ctx context.Context + expectedErr string + }{ + { + name: "fail, update to trust center control but control has no public representation", + request: testclient.UpdateControlInput{ + IsTrustCenterControl: lo.ToPtr(true), + }, + controlID: controlWithStandardID.ID, + client: suite.client.api, + ctx: testUser1.UserCtx, + expectedErr: hooks.ErrTrustCenterControlNoPublicRepresentation.Error(), + }, + { + name: "fail, update to trust center control but control has standard id", + request: testclient.UpdateControlInput{ + IsTrustCenterControl: lo.ToPtr(true), + PublicRepresentation: lo.ToPtr("New public representation"), + }, + controlID: controlWithStandardID.ID, + client: suite.client.api, + ctx: testUser1.UserCtx, + expectedErr: hooks.ErrTrustCenterControlNoStandardRequired.Error(), + }, + { + name: "fail, update to trust center control but control has both public rep and standard id", + request: testclient.UpdateControlInput{ + IsTrustCenterControl: lo.ToPtr(true), + }, + controlID: controlWithBoth.ID, + client: suite.client.api, + ctx: testUser1.UserCtx, + expectedErr: hooks.ErrTrustCenterControlNoStandardRequired.Error(), + }, + { + name: "happy path, update to trust center control with public rep and no standard", + request: testclient.UpdateControlInput{ + IsTrustCenterControl: lo.ToPtr(true), + }, + controlID: controlWithPublicRep.ID, + client: suite.client.api, + ctx: testUser1.UserCtx, + }, + } + + for _, tc := range testCases { + t.Run("Update "+tc.name, func(t *testing.T) { + resp, err := tc.client.UpdateControl(tc.ctx, tc.controlID, tc.request) + if tc.expectedErr != "" { + assert.ErrorContains(t, err, tc.expectedErr) + return + } + + assert.NilError(t, err) + assert.Check(t, resp != nil) + assert.Check(t, is.Equal(*tc.request.IsTrustCenterControl, *resp.UpdateControl.Control.IsTrustCenterControl)) + }) + } + + (&Cleanup[*generated.ControlDeleteOne]{client: suite.client.db.Control, ID: controlWithPublicRep.ID}).MustDelete(testUser1.UserCtx, t) + (&Cleanup[*generated.ControlDeleteOne]{client: suite.client.db.Control, ID: controlWithStandardID.ID}).MustDelete(testUser1.UserCtx, t) + (&Cleanup[*generated.ControlDeleteOne]{client: suite.client.db.Control, ID: controlWithBoth.ID}).MustDelete(testUser1.UserCtx, t) + (&Cleanup[*generated.StandardDeleteOne]{client: suite.client.db.Standard, ID: standard.ID}).MustDelete(testUser1.UserCtx, t) +} diff --git a/internal/graphapi/ent.resolvers.go b/internal/graphapi/ent.resolvers.go index 3c9943c87e..27b4b78110 100644 --- a/internal/graphapi/ent.resolvers.go +++ b/internal/graphapi/ent.resolvers.go @@ -3463,34 +3463,3 @@ type updateTFASettingInputResolver struct{ *Resolver } type updateTaskInputResolver struct{ *Resolver } type updateTrustCenterFAQInputResolver struct{ *Resolver } type updateTrustCenterInputResolver struct{ *Resolver } - -// !!! WARNING !!! -// The code below was going to be deleted when updating resolvers. It has been copied here so you have -// one last chance to move it out of harms way if you want. There are two reasons this happens: -// - When renaming or deleting a resolver the old code will be put in here. You can safely delete -// it when you're done. -// - You have helper methods in this file. Move them out to keep these resolver files clean. -/* - func (r *emailTemplateResolver) EmailBrandingID(ctx context.Context, obj *generated.EmailTemplate) (*string, error) { - panic(fmt.Errorf("not implemented: EmailBrandingID - emailBrandingID")) -} -func (r *emailTemplateResolver) EmailBranding(ctx context.Context, obj *generated.EmailTemplate) (*generated.EmailBranding, error) { - panic(fmt.Errorf("not implemented: EmailBranding - emailBranding")) -} -func (r *Resolver) EmailTemplate() gqlgenerated.EmailTemplateResolver { - return &emailTemplateResolver{r} -} -func (r *Resolver) CreateEmailTemplateInput() gqlgenerated.CreateEmailTemplateInputResolver { - return nil -} -func (r *Resolver) EmailTemplateWhereInput() gqlgenerated.EmailTemplateWhereInputResolver { - return nil -} -func (r *Resolver) UpdateEmailTemplateInput() gqlgenerated.UpdateEmailTemplateInputResolver { - return nil -} -type emailTemplateResolver struct{ *Resolver } -type createEmailTemplateInputResolver struct{ *Resolver } -type emailTemplateWhereInputResolver struct{ *Resolver } -type updateEmailTemplateInputResolver struct{ *Resolver } -*/ diff --git a/internal/graphapi/generated/ent.generated.go b/internal/graphapi/generated/ent.generated.go index bfaa35db45..22f85def83 100644 --- a/internal/graphapi/generated/ent.generated.go +++ b/internal/graphapi/generated/ent.generated.go @@ -249329,7 +249329,7 @@ func (ec *executionContext) unmarshalInputCreateControlInput(ctx context.Context asMap[k] = v } - fieldsInOrder := [...]string{"tags", "externalUUID", "title", "description", "descriptionJSON", "aliases", "referenceID", "auditorReferenceID", "status", "implementationStatus", "implementationDescription", "publicRepresentation", "source", "sourceName", "referenceFramework", "referenceFrameworkRevision", "category", "categoryID", "subcategory", "mappedCategories", "assessmentObjectives", "assessmentMethods", "controlQuestions", "implementationGuidance", "exampleEvidence", "references", "testingProcedures", "evidenceRequests", "internalNotes", "systemInternalID", "controlKindName", "environmentName", "scopeName", "workflowEligibleMarker", "refCode", "trustCenterVisibility", "evidenceIDs", "controlObjectiveIDs", "taskIDs", "narrativeIDs", "riskIDs", "actionPlanIDs", "procedureIDs", "internalPolicyIDs", "commentIDs", "discussionIDs", "controlOwnerID", "delegateID", "responsiblePartyID", "reviewIDs", "remediationIDs", "scanIDs", "ownerID", "blockedGroupIDs", "editorIDs", "controlKindID", "environmentID", "scopeID", "standardID", "programIDs", "platformIDs", "assetIDs", "entityIDs", "identityHolderIDs", "campaignIDs", "findingIDs", "controlImplementationIDs", "subcontrolIDs", "scheduledJobIDs", "workflowObjectRefIDs"} + fieldsInOrder := [...]string{"tags", "externalUUID", "title", "description", "descriptionJSON", "aliases", "referenceID", "auditorReferenceID", "status", "implementationStatus", "implementationDescription", "publicRepresentation", "source", "sourceName", "referenceFramework", "referenceFrameworkRevision", "category", "categoryID", "subcategory", "mappedCategories", "assessmentObjectives", "assessmentMethods", "controlQuestions", "implementationGuidance", "exampleEvidence", "references", "testingProcedures", "evidenceRequests", "internalNotes", "systemInternalID", "controlKindName", "environmentName", "scopeName", "workflowEligibleMarker", "refCode", "trustCenterVisibility", "isTrustCenterControl", "evidenceIDs", "controlObjectiveIDs", "taskIDs", "narrativeIDs", "riskIDs", "actionPlanIDs", "procedureIDs", "internalPolicyIDs", "commentIDs", "discussionIDs", "controlOwnerID", "delegateID", "responsiblePartyID", "reviewIDs", "remediationIDs", "scanIDs", "ownerID", "blockedGroupIDs", "editorIDs", "controlKindID", "environmentID", "scopeID", "standardID", "programIDs", "platformIDs", "assetIDs", "entityIDs", "identityHolderIDs", "campaignIDs", "findingIDs", "controlImplementationIDs", "subcontrolIDs", "scheduledJobIDs", "workflowObjectRefIDs"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -249820,6 +249820,13 @@ func (ec *executionContext) unmarshalInputCreateControlInput(ctx context.Context return it, err } it.TrustCenterVisibility = data + case "isTrustCenterControl": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("isTrustCenterControl")) + data, err := ec.unmarshalOBoolean2ᚖbool(ctx, v) + if err != nil { + return it, err + } + it.IsTrustCenterControl = data case "evidenceIDs": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("evidenceIDs")) data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) @@ -398162,7 +398169,7 @@ func (ec *executionContext) unmarshalInputUpdateControlInput(ctx context.Context asMap[k] = v } - fieldsInOrder := [...]string{"tags", "appendTags", "clearTags", "externalUUID", "clearExternalUUID", "title", "clearTitle", "description", "clearDescription", "descriptionJSON", "appendDescriptionJSON", "clearDescriptionJSON", "aliases", "appendAliases", "clearAliases", "referenceID", "clearReferenceID", "auditorReferenceID", "clearAuditorReferenceID", "status", "clearStatus", "implementationStatus", "clearImplementationStatus", "implementationDescription", "clearImplementationDescription", "publicRepresentation", "clearPublicRepresentation", "source", "clearSource", "sourceName", "clearSourceName", "referenceFrameworkRevision", "clearReferenceFrameworkRevision", "category", "clearCategory", "categoryID", "clearCategoryID", "subcategory", "clearSubcategory", "mappedCategories", "appendMappedCategories", "clearMappedCategories", "assessmentObjectives", "appendAssessmentObjectives", "clearAssessmentObjectives", "assessmentMethods", "appendAssessmentMethods", "clearAssessmentMethods", "controlQuestions", "appendControlQuestions", "clearControlQuestions", "implementationGuidance", "appendImplementationGuidance", "clearImplementationGuidance", "exampleEvidence", "appendExampleEvidence", "clearExampleEvidence", "references", "appendReferences", "clearReferences", "testingProcedures", "appendTestingProcedures", "clearTestingProcedures", "evidenceRequests", "appendEvidenceRequests", "clearEvidenceRequests", "internalNotes", "clearInternalNotes", "systemInternalID", "clearSystemInternalID", "controlKindName", "clearControlKindName", "environmentName", "clearEnvironmentName", "scopeName", "clearScopeName", "workflowEligibleMarker", "clearWorkflowEligibleMarker", "refCode", "trustCenterVisibility", "clearTrustCenterVisibility", "addEvidenceIDs", "removeEvidenceIDs", "clearEvidence", "addControlObjectiveIDs", "removeControlObjectiveIDs", "clearControlObjectives", "addTaskIDs", "removeTaskIDs", "clearTasks", "addNarrativeIDs", "removeNarrativeIDs", "clearNarratives", "addRiskIDs", "removeRiskIDs", "clearRisks", "addActionPlanIDs", "removeActionPlanIDs", "clearActionPlans", "addProcedureIDs", "removeProcedureIDs", "clearProcedures", "addInternalPolicyIDs", "removeInternalPolicyIDs", "clearInternalPolicies", "addCommentIDs", "removeCommentIDs", "clearComments", "addDiscussionIDs", "removeDiscussionIDs", "clearDiscussions", "controlOwnerID", "clearControlOwner", "delegateID", "clearDelegate", "responsiblePartyID", "clearResponsibleParty", "addReviewIDs", "removeReviewIDs", "clearReviews", "addRemediationIDs", "removeRemediationIDs", "clearRemediations", "addScanIDs", "removeScanIDs", "clearScans", "addBlockedGroupIDs", "removeBlockedGroupIDs", "clearBlockedGroups", "addEditorIDs", "removeEditorIDs", "clearEditors", "controlKindID", "clearControlKind", "environmentID", "clearEnvironment", "scopeID", "clearScope", "standardID", "clearStandard", "addProgramIDs", "removeProgramIDs", "clearPrograms", "addPlatformIDs", "removePlatformIDs", "clearPlatforms", "addAssetIDs", "removeAssetIDs", "clearAssets", "addEntityIDs", "removeEntityIDs", "clearEntities", "addIdentityHolderIDs", "removeIdentityHolderIDs", "clearIdentityHolders", "addCampaignIDs", "removeCampaignIDs", "clearCampaigns", "addFindingIDs", "removeFindingIDs", "clearFindings", "addControlImplementationIDs", "removeControlImplementationIDs", "clearControlImplementations", "addSubcontrolIDs", "removeSubcontrolIDs", "clearSubcontrols", "addScheduledJobIDs", "removeScheduledJobIDs", "clearScheduledJobs", "addWorkflowObjectRefIDs", "removeWorkflowObjectRefIDs", "clearWorkflowObjectRefs", "addDiscussion", "updateDiscussion", "deleteDiscussion", "addComment", "deleteComment"} + fieldsInOrder := [...]string{"tags", "appendTags", "clearTags", "externalUUID", "clearExternalUUID", "title", "clearTitle", "description", "clearDescription", "descriptionJSON", "appendDescriptionJSON", "clearDescriptionJSON", "aliases", "appendAliases", "clearAliases", "referenceID", "clearReferenceID", "auditorReferenceID", "clearAuditorReferenceID", "status", "clearStatus", "implementationStatus", "clearImplementationStatus", "implementationDescription", "clearImplementationDescription", "publicRepresentation", "clearPublicRepresentation", "source", "clearSource", "sourceName", "clearSourceName", "referenceFrameworkRevision", "clearReferenceFrameworkRevision", "category", "clearCategory", "categoryID", "clearCategoryID", "subcategory", "clearSubcategory", "mappedCategories", "appendMappedCategories", "clearMappedCategories", "assessmentObjectives", "appendAssessmentObjectives", "clearAssessmentObjectives", "assessmentMethods", "appendAssessmentMethods", "clearAssessmentMethods", "controlQuestions", "appendControlQuestions", "clearControlQuestions", "implementationGuidance", "appendImplementationGuidance", "clearImplementationGuidance", "exampleEvidence", "appendExampleEvidence", "clearExampleEvidence", "references", "appendReferences", "clearReferences", "testingProcedures", "appendTestingProcedures", "clearTestingProcedures", "evidenceRequests", "appendEvidenceRequests", "clearEvidenceRequests", "internalNotes", "clearInternalNotes", "systemInternalID", "clearSystemInternalID", "controlKindName", "clearControlKindName", "environmentName", "clearEnvironmentName", "scopeName", "clearScopeName", "workflowEligibleMarker", "clearWorkflowEligibleMarker", "refCode", "trustCenterVisibility", "clearTrustCenterVisibility", "isTrustCenterControl", "clearIsTrustCenterControl", "addEvidenceIDs", "removeEvidenceIDs", "clearEvidence", "addControlObjectiveIDs", "removeControlObjectiveIDs", "clearControlObjectives", "addTaskIDs", "removeTaskIDs", "clearTasks", "addNarrativeIDs", "removeNarrativeIDs", "clearNarratives", "addRiskIDs", "removeRiskIDs", "clearRisks", "addActionPlanIDs", "removeActionPlanIDs", "clearActionPlans", "addProcedureIDs", "removeProcedureIDs", "clearProcedures", "addInternalPolicyIDs", "removeInternalPolicyIDs", "clearInternalPolicies", "addCommentIDs", "removeCommentIDs", "clearComments", "addDiscussionIDs", "removeDiscussionIDs", "clearDiscussions", "controlOwnerID", "clearControlOwner", "delegateID", "clearDelegate", "responsiblePartyID", "clearResponsibleParty", "addReviewIDs", "removeReviewIDs", "clearReviews", "addRemediationIDs", "removeRemediationIDs", "clearRemediations", "addScanIDs", "removeScanIDs", "clearScans", "addBlockedGroupIDs", "removeBlockedGroupIDs", "clearBlockedGroups", "addEditorIDs", "removeEditorIDs", "clearEditors", "controlKindID", "clearControlKind", "environmentID", "clearEnvironment", "scopeID", "clearScope", "standardID", "clearStandard", "addProgramIDs", "removeProgramIDs", "clearPrograms", "addPlatformIDs", "removePlatformIDs", "clearPlatforms", "addAssetIDs", "removeAssetIDs", "clearAssets", "addEntityIDs", "removeEntityIDs", "clearEntities", "addIdentityHolderIDs", "removeIdentityHolderIDs", "clearIdentityHolders", "addCampaignIDs", "removeCampaignIDs", "clearCampaigns", "addFindingIDs", "removeFindingIDs", "clearFindings", "addControlImplementationIDs", "removeControlImplementationIDs", "clearControlImplementations", "addSubcontrolIDs", "removeSubcontrolIDs", "clearSubcontrols", "addScheduledJobIDs", "removeScheduledJobIDs", "clearScheduledJobs", "addWorkflowObjectRefIDs", "removeWorkflowObjectRefIDs", "clearWorkflowObjectRefs", "addDiscussion", "updateDiscussion", "deleteDiscussion", "addComment", "deleteComment"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -399083,6 +399090,20 @@ func (ec *executionContext) unmarshalInputUpdateControlInput(ctx context.Context return it, err } it.ClearTrustCenterVisibility = data + case "isTrustCenterControl": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("isTrustCenterControl")) + data, err := ec.unmarshalOBoolean2ᚖbool(ctx, v) + if err != nil { + return it, err + } + it.IsTrustCenterControl = data + case "clearIsTrustCenterControl": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("clearIsTrustCenterControl")) + data, err := ec.unmarshalOBoolean2bool(ctx, v) + if err != nil { + return it, err + } + it.ClearIsTrustCenterControl = data case "addEvidenceIDs": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("addEvidenceIDs")) data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) diff --git a/internal/graphapi/generated/root_.generated.go b/internal/graphapi/generated/root_.generated.go index 3a38c27d99..10bd54cf2c 100644 --- a/internal/graphapi/generated/root_.generated.go +++ b/internal/graphapi/generated/root_.generated.go @@ -65098,6 +65098,10 @@ input CreateControlInput { visibility of the control on the trust center, controls the publishing state for trust center display """ trustCenterVisibility: ControlTrustCenterControlVisibility + """ + indicates the control is derived from the trust center standard, set by the system during control clone + """ + isTrustCenterControl: Boolean evidenceIDs: [ID!] controlObjectiveIDs: [ID!] taskIDs: [ID!] @@ -125046,6 +125050,11 @@ input UpdateControlInput { """ trustCenterVisibility: ControlTrustCenterControlVisibility clearTrustCenterVisibility: Boolean + """ + indicates the control is derived from the trust center standard, set by the system during control clone + """ + isTrustCenterControl: Boolean + clearIsTrustCenterControl: Boolean addEvidenceIDs: [ID!] removeEvidenceIDs: [ID!] clearEvidence: Boolean diff --git a/internal/graphapi/historyschema/checksum/.history_schema_checksum b/internal/graphapi/historyschema/checksum/.history_schema_checksum index 91a3d90e4e..d786a8dab8 100644 --- a/internal/graphapi/historyschema/checksum/.history_schema_checksum +++ b/internal/graphapi/historyschema/checksum/.history_schema_checksum @@ -1 +1 @@ -4eb1045df5ef69da285494c7af10955329e07c70ba2cd9ca955dad9e5105520c \ No newline at end of file +a18db76017f77ef808093bf1e92e141cdb624126a762ee471b590376cbaa16b1 \ No newline at end of file diff --git a/internal/graphapi/models_test.go b/internal/graphapi/models_test.go index 00b81bbd4a..bcefca9122 100644 --- a/internal/graphapi/models_test.go +++ b/internal/graphapi/models_test.go @@ -274,6 +274,7 @@ type ControlBuilder struct { ControlOwnerID string ControlEditorGroupID string ControlImplementationID string + PublicRepresentation string // AllFields will set all direct fields on the control with random data AllFields bool Category string @@ -1369,6 +1370,10 @@ func (c *ControlBuilder) MustNew(ctx context.Context, t *testing.T) *ent.Control mutation.SetAliases(c.Aliases) } + if c.PublicRepresentation != "" { + mutation.SetPublicRepresentation(c.PublicRepresentation) + } + control, err := mutation. Save(ctx) requireNoError(t, err) diff --git a/internal/graphapi/query/emailtemplate.graphql b/internal/graphapi/query/emailtemplate.graphql index ecef2b92ae..8c00b5f066 100644 --- a/internal/graphapi/query/emailtemplate.graphql +++ b/internal/graphapi/query/emailtemplate.graphql @@ -1,366 +1,343 @@ -mutation CreateBulkCSVEmailTemplate($input: Upload!) { - createBulkCSVEmailTemplate(input: $input) { - emailTemplates { - active - bodyTemplate - createdAt - createdBy - defaults - description - format - id - integrationID - internalNotes - jsonconfig - key - locale - metadata - name - ownerID - preheaderTemplate - revision - subjectTemplate - systemInternalID - systemOwned - templateContext - textTemplate - uischema - updatedAt - updatedBy - version - workflowDefinitionID - workflowInstanceID - } - } +mutation CreateBulkCSVEmailTemplate ($input: Upload!) { + createBulkCSVEmailTemplate(input: $input) { + emailTemplates { + active + bodyTemplate + createdAt + createdBy + defaults + description + format + id + integrationID + internalNotes + jsonconfig + key + locale + metadata + name + ownerID + preheaderTemplate + revision + subjectTemplate + systemInternalID + systemOwned + templateContext + textTemplate + uischema + updatedAt + updatedBy + version + workflowDefinitionID + workflowInstanceID + } + } } - -mutation CreateBulkEmailTemplate($input: [CreateEmailTemplateInput!]) { - createBulkEmailTemplate(input: $input) { - emailTemplates { - active - bodyTemplate - createdAt - createdBy - defaults - description - format - id - integrationID - internalNotes - jsonconfig - key - locale - metadata - name - ownerID - preheaderTemplate - revision - subjectTemplate - systemInternalID - systemOwned - templateContext - textTemplate - uischema - updatedAt - updatedBy - version - workflowDefinitionID - workflowInstanceID - } - } +mutation CreateBulkEmailTemplate ($input: [CreateEmailTemplateInput!]) { + createBulkEmailTemplate(input: $input) { + emailTemplates { + active + bodyTemplate + createdAt + createdBy + defaults + description + format + id + integrationID + internalNotes + jsonconfig + key + locale + metadata + name + ownerID + preheaderTemplate + revision + subjectTemplate + systemInternalID + systemOwned + templateContext + textTemplate + uischema + updatedAt + updatedBy + version + workflowDefinitionID + workflowInstanceID + } + } } - -mutation CreateEmailTemplate($input: CreateEmailTemplateInput!) { - createEmailTemplate(input: $input) { - emailTemplate { - active - bodyTemplate - createdAt - createdBy - defaults - description - format - id - integrationID - internalNotes - jsonconfig - key - locale - metadata - name - ownerID - preheaderTemplate - revision - subjectTemplate - systemInternalID - systemOwned - templateContext - textTemplate - uischema - updatedAt - updatedBy - version - workflowDefinitionID - workflowInstanceID - } - } +mutation CreateEmailTemplate ($input: CreateEmailTemplateInput!) { + createEmailTemplate(input: $input) { + emailTemplate { + active + bodyTemplate + createdAt + createdBy + defaults + description + format + id + integrationID + internalNotes + jsonconfig + key + locale + metadata + name + ownerID + preheaderTemplate + revision + subjectTemplate + systemInternalID + systemOwned + templateContext + textTemplate + uischema + updatedAt + updatedBy + version + workflowDefinitionID + workflowInstanceID + } + } } - -mutation DeleteBulkEmailTemplate($ids: [ID!]!) { - deleteBulkEmailTemplate(ids: $ids) { - deletedIDs - } +mutation DeleteBulkEmailTemplate ($ids: [ID!]!) { + deleteBulkEmailTemplate(ids: $ids) { + deletedIDs + } } - -mutation DeleteEmailTemplate($deleteEmailTemplateId: ID!) { - deleteEmailTemplate(id: $deleteEmailTemplateId) { - deletedID - } +mutation DeleteEmailTemplate ($deleteEmailTemplateId: ID!) { + deleteEmailTemplate(id: $deleteEmailTemplateId) { + deletedID + } } - -query GetAllEmailTemplates($first: Int, $last: Int, $after: Cursor, $before: Cursor, $orderBy: [EmailTemplateOrder!]) { - emailTemplates( - first: $first - last: $last - after: $after - before: $before - orderBy: $orderBy - ) { - totalCount - pageInfo { - startCursor - endCursor - hasPreviousPage - hasNextPage - } - edges { - node { - active - bodyTemplate - createdAt - createdBy - defaults - description - format - id - integrationID - internalNotes - jsonconfig - key - locale - metadata - name - ownerID - preheaderTemplate - revision - subjectTemplate - systemInternalID - systemOwned - templateContext - textTemplate - uischema - updatedAt - updatedBy - version - workflowDefinitionID - workflowInstanceID - } - } - } +query GetAllEmailTemplates ($first: Int, $last: Int, $after: Cursor, $before: Cursor, $orderBy: [EmailTemplateOrder!]) { + emailTemplates(first: $first, last: $last, after: $after, before: $before, orderBy: $orderBy) { + totalCount + pageInfo { + startCursor + endCursor + hasPreviousPage + hasNextPage + } + edges { + node { + active + bodyTemplate + createdAt + createdBy + defaults + description + format + id + integrationID + internalNotes + jsonconfig + key + locale + metadata + name + ownerID + preheaderTemplate + revision + subjectTemplate + systemInternalID + systemOwned + templateContext + textTemplate + uischema + updatedAt + updatedBy + version + workflowDefinitionID + workflowInstanceID + } + } + } } - -query GetEmailTemplateByID($emailTemplateId: ID!) { - emailTemplate(id: $emailTemplateId) { - active - bodyTemplate - createdAt - createdBy - defaults - description - format - id - integrationID - internalNotes - jsonconfig - key - locale - metadata - name - ownerID - preheaderTemplate - revision - subjectTemplate - systemInternalID - systemOwned - templateContext - textTemplate - uischema - updatedAt - updatedBy - version - workflowDefinitionID - workflowInstanceID - } +query GetEmailTemplateByID ($emailTemplateId: ID!) { + emailTemplate(id: $emailTemplateId) { + active + bodyTemplate + createdAt + createdBy + defaults + description + format + id + integrationID + internalNotes + jsonconfig + key + locale + metadata + name + ownerID + preheaderTemplate + revision + subjectTemplate + systemInternalID + systemOwned + templateContext + textTemplate + uischema + updatedAt + updatedBy + version + workflowDefinitionID + workflowInstanceID + } } - -query GetEmailTemplates($first: Int, $last: Int, $after: Cursor, $before: Cursor, $orderBy: [EmailTemplateOrder!], $where: EmailTemplateWhereInput) { - emailTemplates( - first: $first - last: $last - after: $after - before: $before - orderBy: $orderBy - where: $where - ) { - totalCount - pageInfo { - startCursor - endCursor - hasPreviousPage - hasNextPage - } - edges { - node { - active - bodyTemplate - createdAt - createdBy - defaults - description - format - id - integrationID - internalNotes - jsonconfig - key - locale - metadata - name - ownerID - preheaderTemplate - revision - subjectTemplate - systemInternalID - systemOwned - templateContext - textTemplate - uischema - updatedAt - updatedBy - version - workflowDefinitionID - workflowInstanceID - } - } - } +query GetEmailTemplates ($first: Int, $last: Int, $after: Cursor, $before: Cursor, $orderBy: [EmailTemplateOrder!], $where: EmailTemplateWhereInput) { + emailTemplates(first: $first, last: $last, after: $after, before: $before, orderBy: $orderBy, where: $where) { + totalCount + pageInfo { + startCursor + endCursor + hasPreviousPage + hasNextPage + } + edges { + node { + active + bodyTemplate + createdAt + createdBy + defaults + description + format + id + integrationID + internalNotes + jsonconfig + key + locale + metadata + name + ownerID + preheaderTemplate + revision + subjectTemplate + systemInternalID + systemOwned + templateContext + textTemplate + uischema + updatedAt + updatedBy + version + workflowDefinitionID + workflowInstanceID + } + } + } } - -mutation UpdateBulkCSVEmailTemplate($input: Upload!) { - updateBulkCSVEmailTemplate(input: $input) { - emailTemplates { - active - bodyTemplate - createdAt - createdBy - defaults - description - format - id - integrationID - internalNotes - jsonconfig - key - locale - metadata - name - ownerID - preheaderTemplate - revision - subjectTemplate - systemInternalID - systemOwned - templateContext - textTemplate - uischema - updatedAt - updatedBy - version - workflowDefinitionID - workflowInstanceID - } - updatedIDs - } +mutation UpdateBulkCSVEmailTemplate ($input: Upload!) { + updateBulkCSVEmailTemplate(input: $input) { + emailTemplates { + active + bodyTemplate + createdAt + createdBy + defaults + description + format + id + integrationID + internalNotes + jsonconfig + key + locale + metadata + name + ownerID + preheaderTemplate + revision + subjectTemplate + systemInternalID + systemOwned + templateContext + textTemplate + uischema + updatedAt + updatedBy + version + workflowDefinitionID + workflowInstanceID + } + updatedIDs + } } - -mutation UpdateBulkEmailTemplate($ids: [ID!]!, $input: UpdateEmailTemplateInput!) { - updateBulkEmailTemplate(ids: $ids, input: $input) { - emailTemplates { - active - bodyTemplate - createdAt - createdBy - defaults - description - format - id - integrationID - internalNotes - jsonconfig - key - locale - metadata - name - ownerID - preheaderTemplate - revision - subjectTemplate - systemInternalID - systemOwned - templateContext - textTemplate - uischema - updatedAt - updatedBy - version - workflowDefinitionID - workflowInstanceID - } - updatedIDs - } +mutation UpdateBulkEmailTemplate ($ids: [ID!]!, $input: UpdateEmailTemplateInput!) { + updateBulkEmailTemplate(ids: $ids, input: $input) { + emailTemplates { + active + bodyTemplate + createdAt + createdBy + defaults + description + format + id + integrationID + internalNotes + jsonconfig + key + locale + metadata + name + ownerID + preheaderTemplate + revision + subjectTemplate + systemInternalID + systemOwned + templateContext + textTemplate + uischema + updatedAt + updatedBy + version + workflowDefinitionID + workflowInstanceID + } + updatedIDs + } } - -mutation UpdateEmailTemplate($updateEmailTemplateId: ID!, $input: UpdateEmailTemplateInput!) { - updateEmailTemplate(id: $updateEmailTemplateId, input: $input) { - emailTemplate { - active - bodyTemplate - createdAt - createdBy - defaults - description - format - id - integrationID - internalNotes - jsonconfig - key - locale - metadata - name - ownerID - preheaderTemplate - revision - subjectTemplate - systemInternalID - systemOwned - templateContext - textTemplate - uischema - updatedAt - updatedBy - version - workflowDefinitionID - workflowInstanceID - } - } +mutation UpdateEmailTemplate ($updateEmailTemplateId: ID!, $input: UpdateEmailTemplateInput!) { + updateEmailTemplate(id: $updateEmailTemplateId, input: $input) { + emailTemplate { + active + bodyTemplate + createdAt + createdBy + defaults + description + format + id + integrationID + internalNotes + jsonconfig + key + locale + metadata + name + ownerID + preheaderTemplate + revision + subjectTemplate + systemInternalID + systemOwned + templateContext + textTemplate + uischema + updatedAt + updatedBy + version + workflowDefinitionID + workflowInstanceID + } + } } diff --git a/internal/graphapi/schema/ent.graphql b/internal/graphapi/schema/ent.graphql index 282decebfa..dd655c0630 100644 --- a/internal/graphapi/schema/ent.graphql +++ b/internal/graphapi/schema/ent.graphql @@ -10399,6 +10399,10 @@ input CreateControlInput { visibility of the control on the trust center, controls the publishing state for trust center display """ trustCenterVisibility: ControlTrustCenterControlVisibility + """ + indicates the control is derived from the trust center standard, set by the system during control clone + """ + isTrustCenterControl: Boolean evidenceIDs: [ID!] controlObjectiveIDs: [ID!] taskIDs: [ID!] @@ -70347,6 +70351,11 @@ input UpdateControlInput { """ trustCenterVisibility: ControlTrustCenterControlVisibility clearTrustCenterVisibility: Boolean + """ + indicates the control is derived from the trust center standard, set by the system during control clone + """ + isTrustCenterControl: Boolean + clearIsTrustCenterControl: Boolean addEvidenceIDs: [ID!] removeEvidenceIDs: [ID!] clearEvidence: Boolean diff --git a/internal/graphapi/testclient/checksum/.client_checksum b/internal/graphapi/testclient/checksum/.client_checksum index 67027cd792..babb63263f 100644 --- a/internal/graphapi/testclient/checksum/.client_checksum +++ b/internal/graphapi/testclient/checksum/.client_checksum @@ -1 +1 @@ -ec5de04e383d0cf8ad87caae26294568eb657d369d1d343e282876bd36c2aaa1 \ No newline at end of file +8b659dc4348a53587af4926125c32b5cc3b0d3569f6a02b0ea6becdd82332708 \ No newline at end of file diff --git a/internal/graphapi/testclient/models.go b/internal/graphapi/testclient/models.go index 0ca6e6e8f1..48f2c6e5b6 100644 --- a/internal/graphapi/testclient/models.go +++ b/internal/graphapi/testclient/models.go @@ -6003,41 +6003,43 @@ type CreateControlInput struct { // the unique reference code for the control RefCode string `json:"refCode"` // visibility of the control on the trust center, controls the publishing state for trust center display - TrustCenterVisibility *enums.TrustCenterControlVisibility `json:"trustCenterVisibility,omitempty"` - EvidenceIDs []string `json:"evidenceIDs,omitempty"` - ControlObjectiveIDs []string `json:"controlObjectiveIDs,omitempty"` - TaskIDs []string `json:"taskIDs,omitempty"` - NarrativeIDs []string `json:"narrativeIDs,omitempty"` - RiskIDs []string `json:"riskIDs,omitempty"` - ActionPlanIDs []string `json:"actionPlanIDs,omitempty"` - ProcedureIDs []string `json:"procedureIDs,omitempty"` - InternalPolicyIDs []string `json:"internalPolicyIDs,omitempty"` - CommentIDs []string `json:"commentIDs,omitempty"` - DiscussionIDs []string `json:"discussionIDs,omitempty"` - ControlOwnerID *string `json:"controlOwnerID,omitempty"` - DelegateID *string `json:"delegateID,omitempty"` - ResponsiblePartyID *string `json:"responsiblePartyID,omitempty"` - ReviewIDs []string `json:"reviewIDs,omitempty"` - RemediationIDs []string `json:"remediationIDs,omitempty"` - ScanIDs []string `json:"scanIDs,omitempty"` - OwnerID *string `json:"ownerID,omitempty"` - BlockedGroupIDs []string `json:"blockedGroupIDs,omitempty"` - EditorIDs []string `json:"editorIDs,omitempty"` - ControlKindID *string `json:"controlKindID,omitempty"` - EnvironmentID *string `json:"environmentID,omitempty"` - ScopeID *string `json:"scopeID,omitempty"` - StandardID *string `json:"standardID,omitempty"` - ProgramIDs []string `json:"programIDs,omitempty"` - PlatformIDs []string `json:"platformIDs,omitempty"` - AssetIDs []string `json:"assetIDs,omitempty"` - EntityIDs []string `json:"entityIDs,omitempty"` - IdentityHolderIDs []string `json:"identityHolderIDs,omitempty"` - CampaignIDs []string `json:"campaignIDs,omitempty"` - FindingIDs []string `json:"findingIDs,omitempty"` - ControlImplementationIDs []string `json:"controlImplementationIDs,omitempty"` - SubcontrolIDs []string `json:"subcontrolIDs,omitempty"` - ScheduledJobIDs []string `json:"scheduledJobIDs,omitempty"` - WorkflowObjectRefIDs []string `json:"workflowObjectRefIDs,omitempty"` + TrustCenterVisibility *enums.TrustCenterControlVisibility `json:"trustCenterVisibility,omitempty"` + // indicates the control is derived from the trust center standard, set by the system during control clone + IsTrustCenterControl *bool `json:"isTrustCenterControl,omitempty"` + EvidenceIDs []string `json:"evidenceIDs,omitempty"` + ControlObjectiveIDs []string `json:"controlObjectiveIDs,omitempty"` + TaskIDs []string `json:"taskIDs,omitempty"` + NarrativeIDs []string `json:"narrativeIDs,omitempty"` + RiskIDs []string `json:"riskIDs,omitempty"` + ActionPlanIDs []string `json:"actionPlanIDs,omitempty"` + ProcedureIDs []string `json:"procedureIDs,omitempty"` + InternalPolicyIDs []string `json:"internalPolicyIDs,omitempty"` + CommentIDs []string `json:"commentIDs,omitempty"` + DiscussionIDs []string `json:"discussionIDs,omitempty"` + ControlOwnerID *string `json:"controlOwnerID,omitempty"` + DelegateID *string `json:"delegateID,omitempty"` + ResponsiblePartyID *string `json:"responsiblePartyID,omitempty"` + ReviewIDs []string `json:"reviewIDs,omitempty"` + RemediationIDs []string `json:"remediationIDs,omitempty"` + ScanIDs []string `json:"scanIDs,omitempty"` + OwnerID *string `json:"ownerID,omitempty"` + BlockedGroupIDs []string `json:"blockedGroupIDs,omitempty"` + EditorIDs []string `json:"editorIDs,omitempty"` + ControlKindID *string `json:"controlKindID,omitempty"` + EnvironmentID *string `json:"environmentID,omitempty"` + ScopeID *string `json:"scopeID,omitempty"` + StandardID *string `json:"standardID,omitempty"` + ProgramIDs []string `json:"programIDs,omitempty"` + PlatformIDs []string `json:"platformIDs,omitempty"` + AssetIDs []string `json:"assetIDs,omitempty"` + EntityIDs []string `json:"entityIDs,omitempty"` + IdentityHolderIDs []string `json:"identityHolderIDs,omitempty"` + CampaignIDs []string `json:"campaignIDs,omitempty"` + FindingIDs []string `json:"findingIDs,omitempty"` + ControlImplementationIDs []string `json:"controlImplementationIDs,omitempty"` + SubcontrolIDs []string `json:"subcontrolIDs,omitempty"` + ScheduledJobIDs []string `json:"scheduledJobIDs,omitempty"` + WorkflowObjectRefIDs []string `json:"workflowObjectRefIDs,omitempty"` } // CreateControlObjectiveInput is used for create ControlObjective object. @@ -38514,105 +38516,108 @@ type UpdateControlInput struct { // the unique reference code for the control RefCode *string `json:"refCode,omitempty"` // visibility of the control on the trust center, controls the publishing state for trust center display - TrustCenterVisibility *enums.TrustCenterControlVisibility `json:"trustCenterVisibility,omitempty"` - ClearTrustCenterVisibility *bool `json:"clearTrustCenterVisibility,omitempty"` - AddEvidenceIDs []string `json:"addEvidenceIDs,omitempty"` - RemoveEvidenceIDs []string `json:"removeEvidenceIDs,omitempty"` - ClearEvidence *bool `json:"clearEvidence,omitempty"` - AddControlObjectiveIDs []string `json:"addControlObjectiveIDs,omitempty"` - RemoveControlObjectiveIDs []string `json:"removeControlObjectiveIDs,omitempty"` - ClearControlObjectives *bool `json:"clearControlObjectives,omitempty"` - AddTaskIDs []string `json:"addTaskIDs,omitempty"` - RemoveTaskIDs []string `json:"removeTaskIDs,omitempty"` - ClearTasks *bool `json:"clearTasks,omitempty"` - AddNarrativeIDs []string `json:"addNarrativeIDs,omitempty"` - RemoveNarrativeIDs []string `json:"removeNarrativeIDs,omitempty"` - ClearNarratives *bool `json:"clearNarratives,omitempty"` - AddRiskIDs []string `json:"addRiskIDs,omitempty"` - RemoveRiskIDs []string `json:"removeRiskIDs,omitempty"` - ClearRisks *bool `json:"clearRisks,omitempty"` - AddActionPlanIDs []string `json:"addActionPlanIDs,omitempty"` - RemoveActionPlanIDs []string `json:"removeActionPlanIDs,omitempty"` - ClearActionPlans *bool `json:"clearActionPlans,omitempty"` - AddProcedureIDs []string `json:"addProcedureIDs,omitempty"` - RemoveProcedureIDs []string `json:"removeProcedureIDs,omitempty"` - ClearProcedures *bool `json:"clearProcedures,omitempty"` - AddInternalPolicyIDs []string `json:"addInternalPolicyIDs,omitempty"` - RemoveInternalPolicyIDs []string `json:"removeInternalPolicyIDs,omitempty"` - ClearInternalPolicies *bool `json:"clearInternalPolicies,omitempty"` - AddCommentIDs []string `json:"addCommentIDs,omitempty"` - RemoveCommentIDs []string `json:"removeCommentIDs,omitempty"` - ClearComments *bool `json:"clearComments,omitempty"` - AddDiscussionIDs []string `json:"addDiscussionIDs,omitempty"` - RemoveDiscussionIDs []string `json:"removeDiscussionIDs,omitempty"` - ClearDiscussions *bool `json:"clearDiscussions,omitempty"` - ControlOwnerID *string `json:"controlOwnerID,omitempty"` - ClearControlOwner *bool `json:"clearControlOwner,omitempty"` - DelegateID *string `json:"delegateID,omitempty"` - ClearDelegate *bool `json:"clearDelegate,omitempty"` - ResponsiblePartyID *string `json:"responsiblePartyID,omitempty"` - ClearResponsibleParty *bool `json:"clearResponsibleParty,omitempty"` - AddReviewIDs []string `json:"addReviewIDs,omitempty"` - RemoveReviewIDs []string `json:"removeReviewIDs,omitempty"` - ClearReviews *bool `json:"clearReviews,omitempty"` - AddRemediationIDs []string `json:"addRemediationIDs,omitempty"` - RemoveRemediationIDs []string `json:"removeRemediationIDs,omitempty"` - ClearRemediations *bool `json:"clearRemediations,omitempty"` - AddScanIDs []string `json:"addScanIDs,omitempty"` - RemoveScanIDs []string `json:"removeScanIDs,omitempty"` - ClearScans *bool `json:"clearScans,omitempty"` - AddBlockedGroupIDs []string `json:"addBlockedGroupIDs,omitempty"` - RemoveBlockedGroupIDs []string `json:"removeBlockedGroupIDs,omitempty"` - ClearBlockedGroups *bool `json:"clearBlockedGroups,omitempty"` - AddEditorIDs []string `json:"addEditorIDs,omitempty"` - RemoveEditorIDs []string `json:"removeEditorIDs,omitempty"` - ClearEditors *bool `json:"clearEditors,omitempty"` - ControlKindID *string `json:"controlKindID,omitempty"` - ClearControlKind *bool `json:"clearControlKind,omitempty"` - EnvironmentID *string `json:"environmentID,omitempty"` - ClearEnvironment *bool `json:"clearEnvironment,omitempty"` - ScopeID *string `json:"scopeID,omitempty"` - ClearScope *bool `json:"clearScope,omitempty"` - StandardID *string `json:"standardID,omitempty"` - ClearStandard *bool `json:"clearStandard,omitempty"` - AddProgramIDs []string `json:"addProgramIDs,omitempty"` - RemoveProgramIDs []string `json:"removeProgramIDs,omitempty"` - ClearPrograms *bool `json:"clearPrograms,omitempty"` - AddPlatformIDs []string `json:"addPlatformIDs,omitempty"` - RemovePlatformIDs []string `json:"removePlatformIDs,omitempty"` - ClearPlatforms *bool `json:"clearPlatforms,omitempty"` - AddAssetIDs []string `json:"addAssetIDs,omitempty"` - RemoveAssetIDs []string `json:"removeAssetIDs,omitempty"` - ClearAssets *bool `json:"clearAssets,omitempty"` - AddEntityIDs []string `json:"addEntityIDs,omitempty"` - RemoveEntityIDs []string `json:"removeEntityIDs,omitempty"` - ClearEntities *bool `json:"clearEntities,omitempty"` - AddIdentityHolderIDs []string `json:"addIdentityHolderIDs,omitempty"` - RemoveIdentityHolderIDs []string `json:"removeIdentityHolderIDs,omitempty"` - ClearIdentityHolders *bool `json:"clearIdentityHolders,omitempty"` - AddCampaignIDs []string `json:"addCampaignIDs,omitempty"` - RemoveCampaignIDs []string `json:"removeCampaignIDs,omitempty"` - ClearCampaigns *bool `json:"clearCampaigns,omitempty"` - AddFindingIDs []string `json:"addFindingIDs,omitempty"` - RemoveFindingIDs []string `json:"removeFindingIDs,omitempty"` - ClearFindings *bool `json:"clearFindings,omitempty"` - AddControlImplementationIDs []string `json:"addControlImplementationIDs,omitempty"` - RemoveControlImplementationIDs []string `json:"removeControlImplementationIDs,omitempty"` - ClearControlImplementations *bool `json:"clearControlImplementations,omitempty"` - AddSubcontrolIDs []string `json:"addSubcontrolIDs,omitempty"` - RemoveSubcontrolIDs []string `json:"removeSubcontrolIDs,omitempty"` - ClearSubcontrols *bool `json:"clearSubcontrols,omitempty"` - AddScheduledJobIDs []string `json:"addScheduledJobIDs,omitempty"` - RemoveScheduledJobIDs []string `json:"removeScheduledJobIDs,omitempty"` - ClearScheduledJobs *bool `json:"clearScheduledJobs,omitempty"` - AddWorkflowObjectRefIDs []string `json:"addWorkflowObjectRefIDs,omitempty"` - RemoveWorkflowObjectRefIDs []string `json:"removeWorkflowObjectRefIDs,omitempty"` - ClearWorkflowObjectRefs *bool `json:"clearWorkflowObjectRefs,omitempty"` - AddDiscussion *CreateDiscussionInput `json:"addDiscussion,omitempty"` - UpdateDiscussion *UpdateDiscussionsInput `json:"updateDiscussion,omitempty"` - DeleteDiscussion *string `json:"deleteDiscussion,omitempty"` - AddComment *CreateNoteInput `json:"addComment,omitempty"` - DeleteComment *string `json:"deleteComment,omitempty"` + TrustCenterVisibility *enums.TrustCenterControlVisibility `json:"trustCenterVisibility,omitempty"` + ClearTrustCenterVisibility *bool `json:"clearTrustCenterVisibility,omitempty"` + // indicates the control is derived from the trust center standard, set by the system during control clone + IsTrustCenterControl *bool `json:"isTrustCenterControl,omitempty"` + ClearIsTrustCenterControl *bool `json:"clearIsTrustCenterControl,omitempty"` + AddEvidenceIDs []string `json:"addEvidenceIDs,omitempty"` + RemoveEvidenceIDs []string `json:"removeEvidenceIDs,omitempty"` + ClearEvidence *bool `json:"clearEvidence,omitempty"` + AddControlObjectiveIDs []string `json:"addControlObjectiveIDs,omitempty"` + RemoveControlObjectiveIDs []string `json:"removeControlObjectiveIDs,omitempty"` + ClearControlObjectives *bool `json:"clearControlObjectives,omitempty"` + AddTaskIDs []string `json:"addTaskIDs,omitempty"` + RemoveTaskIDs []string `json:"removeTaskIDs,omitempty"` + ClearTasks *bool `json:"clearTasks,omitempty"` + AddNarrativeIDs []string `json:"addNarrativeIDs,omitempty"` + RemoveNarrativeIDs []string `json:"removeNarrativeIDs,omitempty"` + ClearNarratives *bool `json:"clearNarratives,omitempty"` + AddRiskIDs []string `json:"addRiskIDs,omitempty"` + RemoveRiskIDs []string `json:"removeRiskIDs,omitempty"` + ClearRisks *bool `json:"clearRisks,omitempty"` + AddActionPlanIDs []string `json:"addActionPlanIDs,omitempty"` + RemoveActionPlanIDs []string `json:"removeActionPlanIDs,omitempty"` + ClearActionPlans *bool `json:"clearActionPlans,omitempty"` + AddProcedureIDs []string `json:"addProcedureIDs,omitempty"` + RemoveProcedureIDs []string `json:"removeProcedureIDs,omitempty"` + ClearProcedures *bool `json:"clearProcedures,omitempty"` + AddInternalPolicyIDs []string `json:"addInternalPolicyIDs,omitempty"` + RemoveInternalPolicyIDs []string `json:"removeInternalPolicyIDs,omitempty"` + ClearInternalPolicies *bool `json:"clearInternalPolicies,omitempty"` + AddCommentIDs []string `json:"addCommentIDs,omitempty"` + RemoveCommentIDs []string `json:"removeCommentIDs,omitempty"` + ClearComments *bool `json:"clearComments,omitempty"` + AddDiscussionIDs []string `json:"addDiscussionIDs,omitempty"` + RemoveDiscussionIDs []string `json:"removeDiscussionIDs,omitempty"` + ClearDiscussions *bool `json:"clearDiscussions,omitempty"` + ControlOwnerID *string `json:"controlOwnerID,omitempty"` + ClearControlOwner *bool `json:"clearControlOwner,omitempty"` + DelegateID *string `json:"delegateID,omitempty"` + ClearDelegate *bool `json:"clearDelegate,omitempty"` + ResponsiblePartyID *string `json:"responsiblePartyID,omitempty"` + ClearResponsibleParty *bool `json:"clearResponsibleParty,omitempty"` + AddReviewIDs []string `json:"addReviewIDs,omitempty"` + RemoveReviewIDs []string `json:"removeReviewIDs,omitempty"` + ClearReviews *bool `json:"clearReviews,omitempty"` + AddRemediationIDs []string `json:"addRemediationIDs,omitempty"` + RemoveRemediationIDs []string `json:"removeRemediationIDs,omitempty"` + ClearRemediations *bool `json:"clearRemediations,omitempty"` + AddScanIDs []string `json:"addScanIDs,omitempty"` + RemoveScanIDs []string `json:"removeScanIDs,omitempty"` + ClearScans *bool `json:"clearScans,omitempty"` + AddBlockedGroupIDs []string `json:"addBlockedGroupIDs,omitempty"` + RemoveBlockedGroupIDs []string `json:"removeBlockedGroupIDs,omitempty"` + ClearBlockedGroups *bool `json:"clearBlockedGroups,omitempty"` + AddEditorIDs []string `json:"addEditorIDs,omitempty"` + RemoveEditorIDs []string `json:"removeEditorIDs,omitempty"` + ClearEditors *bool `json:"clearEditors,omitempty"` + ControlKindID *string `json:"controlKindID,omitempty"` + ClearControlKind *bool `json:"clearControlKind,omitempty"` + EnvironmentID *string `json:"environmentID,omitempty"` + ClearEnvironment *bool `json:"clearEnvironment,omitempty"` + ScopeID *string `json:"scopeID,omitempty"` + ClearScope *bool `json:"clearScope,omitempty"` + StandardID *string `json:"standardID,omitempty"` + ClearStandard *bool `json:"clearStandard,omitempty"` + AddProgramIDs []string `json:"addProgramIDs,omitempty"` + RemoveProgramIDs []string `json:"removeProgramIDs,omitempty"` + ClearPrograms *bool `json:"clearPrograms,omitempty"` + AddPlatformIDs []string `json:"addPlatformIDs,omitempty"` + RemovePlatformIDs []string `json:"removePlatformIDs,omitempty"` + ClearPlatforms *bool `json:"clearPlatforms,omitempty"` + AddAssetIDs []string `json:"addAssetIDs,omitempty"` + RemoveAssetIDs []string `json:"removeAssetIDs,omitempty"` + ClearAssets *bool `json:"clearAssets,omitempty"` + AddEntityIDs []string `json:"addEntityIDs,omitempty"` + RemoveEntityIDs []string `json:"removeEntityIDs,omitempty"` + ClearEntities *bool `json:"clearEntities,omitempty"` + AddIdentityHolderIDs []string `json:"addIdentityHolderIDs,omitempty"` + RemoveIdentityHolderIDs []string `json:"removeIdentityHolderIDs,omitempty"` + ClearIdentityHolders *bool `json:"clearIdentityHolders,omitempty"` + AddCampaignIDs []string `json:"addCampaignIDs,omitempty"` + RemoveCampaignIDs []string `json:"removeCampaignIDs,omitempty"` + ClearCampaigns *bool `json:"clearCampaigns,omitempty"` + AddFindingIDs []string `json:"addFindingIDs,omitempty"` + RemoveFindingIDs []string `json:"removeFindingIDs,omitempty"` + ClearFindings *bool `json:"clearFindings,omitempty"` + AddControlImplementationIDs []string `json:"addControlImplementationIDs,omitempty"` + RemoveControlImplementationIDs []string `json:"removeControlImplementationIDs,omitempty"` + ClearControlImplementations *bool `json:"clearControlImplementations,omitempty"` + AddSubcontrolIDs []string `json:"addSubcontrolIDs,omitempty"` + RemoveSubcontrolIDs []string `json:"removeSubcontrolIDs,omitempty"` + ClearSubcontrols *bool `json:"clearSubcontrols,omitempty"` + AddScheduledJobIDs []string `json:"addScheduledJobIDs,omitempty"` + RemoveScheduledJobIDs []string `json:"removeScheduledJobIDs,omitempty"` + ClearScheduledJobs *bool `json:"clearScheduledJobs,omitempty"` + AddWorkflowObjectRefIDs []string `json:"addWorkflowObjectRefIDs,omitempty"` + RemoveWorkflowObjectRefIDs []string `json:"removeWorkflowObjectRefIDs,omitempty"` + ClearWorkflowObjectRefs *bool `json:"clearWorkflowObjectRefs,omitempty"` + AddDiscussion *CreateDiscussionInput `json:"addDiscussion,omitempty"` + UpdateDiscussion *UpdateDiscussionsInput `json:"updateDiscussion,omitempty"` + DeleteDiscussion *string `json:"deleteDiscussion,omitempty"` + AddComment *CreateNoteInput `json:"addComment,omitempty"` + DeleteComment *string `json:"deleteComment,omitempty"` } // UpdateControlObjectiveInput is used for update ControlObjective object. diff --git a/internal/httpserve/handlers/csv/sample_control.csv b/internal/httpserve/handlers/csv/sample_control.csv index 61c827512d..86ab4a1912 100644 --- a/internal/httpserve/handlers/csv/sample_control.csv +++ b/internal/httpserve/handlers/csv/sample_control.csv @@ -1,2 +1,2 @@ -Tags,ExternalUuid,Title,Description,DescriptionJson,Aliases,ReferenceId,AuditorReferenceId,Status,ImplementationStatus,ImplementationDescription,PublicRepresentation,Source,SourceName,ReferenceFramework,ReferenceFrameworkRevision,Category,CategoryId,Subcategory,MappedCategories,AssessmentObjectives,AssessmentMethods,ControlQuestions,ImplementationGuidance,ExampleEvidence,References,TestingProcedures,EvidenceRequests,InternalNotes,SystemInternalId,ControlKindName,EnvironmentName,ScopeName,WorkflowEligibleMarker,RefCode,TrustCenterVisibility,EvidenceIDs,ControlObjectiveIDs,TaskIDs,NarrativeIDs,RiskIDs,ActionPlanIDs,ProcedureIDs,InternalPolicyIDs,CommentIDs,DiscussionIDs,ControlOwnerId,DelegateId,ResponsiblePartyId,ReviewIDs,RemediationIDs,ScanIDs,OwnerId,BlockedGroupIDs,EditorIDs,ControlKindId,EnvironmentId,ScopeId,StandardId,ProgramIDs,PlatformIDs,AssetIDs,EntityIDs,IdentityHolderIDs,CampaignIDs,FindingIDs,ControlImplementationIDs,SubcontrolIDs,ScheduledJobIDs,WorkflowObjectRefIDs,ControlDelegateGroupName,ControlOwnerGroupName,ResponsiblePartyEntityName -example_tags,example_externaluuid,example_title,example_description,example_descriptionjson,example_aliases,example_referenceid,example_auditorreferenceid,example_status,example_implementationstatus,example_implementationdescription,example_publicrepresentation,example_source,example_sourcename,example_referenceframework,example_referenceframeworkrevision,example_category,example_categoryid,example_subcategory,example_mappedcategories,example_assessmentobjectives,example_assessmentmethods,example_controlquestions,example_implementationguidance,example_exampleevidence,example_references,example_testingprocedures,example_evidencerequests,example_internalnotes,example_systeminternalid,example_controlkindname,example_environmentname,example_scopename,example_workfloweligiblemarker,example_refcode,example_trustcentervisibility,example_evidenceids,example_controlobjectiveids,example_taskids,example_narrativeids,example_riskids,example_actionplanids,example_procedureids,example_internalpolicyids,example_commentids,example_discussionids,example_controlownerid,example_delegateid,example_responsiblepartyid,example_reviewids,example_remediationids,example_scanids,example_ownerid,example_blockedgroupids,example_editorids,example_controlkindid,example_environmentid,example_scopeid,example_standardid,example_programids,example_platformids,example_assetids,example_entityids,example_identityholderids,example_campaignids,example_findingids,example_controlimplementationids,example_subcontrolids,example_scheduledjobids,example_workflowobjectrefids,example_controldelegategroupname,example_controlownergroupname,example_responsiblepartyentityname +Tags,ExternalUuid,Title,Description,DescriptionJson,Aliases,ReferenceId,AuditorReferenceId,Status,ImplementationStatus,ImplementationDescription,PublicRepresentation,Source,SourceName,ReferenceFramework,ReferenceFrameworkRevision,Category,CategoryId,Subcategory,MappedCategories,AssessmentObjectives,AssessmentMethods,ControlQuestions,ImplementationGuidance,ExampleEvidence,References,TestingProcedures,EvidenceRequests,InternalNotes,SystemInternalId,ControlKindName,EnvironmentName,ScopeName,WorkflowEligibleMarker,RefCode,TrustCenterVisibility,IsTrustCenterControl,EvidenceIDs,ControlObjectiveIDs,TaskIDs,NarrativeIDs,RiskIDs,ActionPlanIDs,ProcedureIDs,InternalPolicyIDs,CommentIDs,DiscussionIDs,ControlOwnerId,DelegateId,ResponsiblePartyId,ReviewIDs,RemediationIDs,ScanIDs,OwnerId,BlockedGroupIDs,EditorIDs,ControlKindId,EnvironmentId,ScopeId,StandardId,ProgramIDs,PlatformIDs,AssetIDs,EntityIDs,IdentityHolderIDs,CampaignIDs,FindingIDs,ControlImplementationIDs,SubcontrolIDs,ScheduledJobIDs,WorkflowObjectRefIDs,ControlDelegateGroupName,ControlOwnerGroupName,ResponsiblePartyEntityName +example_tags,example_externaluuid,example_title,example_description,example_descriptionjson,example_aliases,example_referenceid,example_auditorreferenceid,example_status,example_implementationstatus,example_implementationdescription,example_publicrepresentation,example_source,example_sourcename,example_referenceframework,example_referenceframeworkrevision,example_category,example_categoryid,example_subcategory,example_mappedcategories,example_assessmentobjectives,example_assessmentmethods,example_controlquestions,example_implementationguidance,example_exampleevidence,example_references,example_testingprocedures,example_evidencerequests,example_internalnotes,example_systeminternalid,example_controlkindname,example_environmentname,example_scopename,example_workfloweligiblemarker,example_refcode,example_trustcentervisibility,example_istrustcentercontrol,example_evidenceids,example_controlobjectiveids,example_taskids,example_narrativeids,example_riskids,example_actionplanids,example_procedureids,example_internalpolicyids,example_commentids,example_discussionids,example_controlownerid,example_delegateid,example_responsiblepartyid,example_reviewids,example_remediationids,example_scanids,example_ownerid,example_blockedgroupids,example_editorids,example_controlkindid,example_environmentid,example_scopeid,example_standardid,example_programids,example_platformids,example_assetids,example_entityids,example_identityholderids,example_campaignids,example_findingids,example_controlimplementationids,example_subcontrolids,example_scheduledjobids,example_workflowobjectrefids,example_controldelegategroupname,example_controlownergroupname,example_responsiblepartyentityname diff --git a/internal/httpserve/specs/openlane.openapi.json b/internal/httpserve/specs/openlane.openapi.json index 1aca10c9d9..cf06861dee 100644 --- a/internal/httpserve/specs/openlane.openapi.json +++ b/internal/httpserve/specs/openlane.openapi.json @@ -3832,7 +3832,7 @@ "examples": { "error": { "value": { - "error": "Get \"https://www.googleapis.com/oauth2/v2/userinfo?alt=json\u0026prettyPrint=false\": dial tcp: lookup www.googleapis.com: no such host", + "error": "googleapi: Error 401: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project., unauthorized", "error_code": "INVALID_INPUT", "success": false } diff --git a/internal/httpserve/specs/openlane.openapi.yaml b/internal/httpserve/specs/openlane.openapi.yaml index be6d59ca22..9d41aaa354 100644 --- a/internal/httpserve/specs/openlane.openapi.yaml +++ b/internal/httpserve/specs/openlane.openapi.yaml @@ -2750,7 +2750,7 @@ paths: examples: error: value: - error: 'Get "https://www.googleapis.com/oauth2/v2/userinfo?alt=json&prettyPrint=false": dial tcp: lookup www.googleapis.com: no such host' + error: 'googleapi: Error 401: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project., unauthorized' error_code: INVALID_INPUT success: false schema: