Rename control to mitigation

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-03-27 13:07:27 +01:00
parent be64c1c260
commit 483a620fe7
58 changed files with 4972 additions and 4200 deletions

View File

@@ -21,23 +21,23 @@ interface Node {
id: ID!
}
enum ControlState
@goModel(model: "github.com/getprobo/probo/pkg/coredata.ControlState") {
enum MitigationState
@goModel(model: "github.com/getprobo/probo/pkg/coredata.MitigationState") {
NOT_STARTED
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.ControlStateNotStarted"
value: "github.com/getprobo/probo/pkg/coredata.MitigationStateNotStarted"
)
IN_PROGRESS
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.ControlStateInProgress"
value: "github.com/getprobo/probo/pkg/coredata.MitigationStateInProgress"
)
NOT_APPLICABLE
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.ControlStateNotApplicable"
value: "github.com/getprobo/probo/pkg/coredata.MitigationStateNotApplicable"
)
IMPLEMENTED
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.ControlStateImplemented"
value: "github.com/getprobo/probo/pkg/coredata.MitigationStateImplemented"
)
}
@@ -75,19 +75,21 @@ enum PeopleKind
)
}
enum ControlImportance
@goModel(model: "github.com/getprobo/probo/pkg/coredata.ControlImportance") {
enum MitigationImportance
@goModel(
model: "github.com/getprobo/probo/pkg/coredata.MitigationImportance"
) {
MANDATORY
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.ControlImportanceMandatory"
value: "github.com/getprobo/probo/pkg/coredata.MitigationImportanceMandatory"
)
PREFERRED
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.ControlImportancePreferred"
value: "github.com/getprobo/probo/pkg/coredata.MitigationImportancePreferred"
)
ADVANCED
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.ControlImportanceAdvanced"
value: "github.com/getprobo/probo/pkg/coredata.MitigationImportanceAdvanced"
)
}
@@ -187,8 +189,10 @@ enum FrameworkOrderField
NAME
}
enum ControlOrderField
@goModel(model: "github.com/getprobo/probo/pkg/coredata.ControlOrderField") {
enum MitigationOrderField
@goModel(
model: "github.com/getprobo/probo/pkg/coredata.MitigationOrderField"
) {
NAME
}
@@ -231,12 +235,12 @@ input FrameworkOrder
field: FrameworkOrderField!
}
input ControlOrder
input MitigationOrder
@goModel(
model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.ControlOrderBy"
model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.MitigationOrderBy"
) {
direction: OrderDirection!
field: ControlOrderField!
field: MitigationOrderField!
}
input TaskOrder
@@ -327,36 +331,36 @@ type Framework implements Node {
name: String!
description: String!
controls(
mitigations(
first: Int
after: CursorKey
last: Int
before: CursorKey
orderBy: ControlOrder
): ControlConnection! @goField(forceResolver: true)
orderBy: MitigationOrder
): MitigationConnection! @goField(forceResolver: true)
createdAt: Datetime!
updatedAt: Datetime!
}
type ControlConnection {
edges: [ControlEdge!]!
type MitigationConnection {
edges: [MitigationEdge!]!
pageInfo: PageInfo!
}
type ControlEdge {
type MitigationEdge {
cursor: CursorKey!
node: Control!
node: Mitigation!
}
type Control implements Node {
type Mitigation implements Node {
id: ID!
version: Int!
category: String!
name: String!
description: String!
state: ControlState!
importance: ControlImportance!
state: MitigationState!
importance: MitigationImportance!
tasks(
first: Int
@@ -503,8 +507,8 @@ type Mutation {
updateFramework(input: UpdateFrameworkInput!): UpdateFrameworkPayload!
importFramework(input: ImportFrameworkInput!): ImportFrameworkPayload!
createControl(input: CreateControlInput!): CreateControlPayload!
updateControl(input: UpdateControlInput!): UpdateControlPayload!
createMitigation(input: CreateMitigationInput!): CreateMitigationPayload!
updateMitigation(input: UpdateMitigationInput!): UpdateMitigationPayload!
uploadEvidence(input: UploadEvidenceInput!): UploadEvidencePayload!
deleteEvidence(input: DeleteEvidenceInput!): DeleteEvidencePayload!
@@ -639,7 +643,7 @@ type DeleteOrganizationPayload {
}
input CreateTaskInput {
controlId: ID!
mitigationId: ID!
name: String!
description: String!
timeEstimate: Duration
@@ -675,16 +679,16 @@ type CreateFrameworkPayload {
frameworkEdge: FrameworkEdge!
}
input CreateControlInput {
input CreateMitigationInput {
frameworkId: ID!
name: String!
description: String!
category: String!
importance: ControlImportance!
importance: MitigationImportance!
}
type CreateControlPayload {
controlEdge: ControlEdge!
type CreateMitigationPayload {
mitigationEdge: MitigationEdge!
}
type UpdateFrameworkPayload {
@@ -699,18 +703,18 @@ type UpdatePeoplePayload {
people: People!
}
input UpdateControlInput {
input UpdateMitigationInput {
id: ID!
expectedVersion: Int!
name: String
description: String
category: String
state: ControlState
importance: ControlImportance
state: MitigationState
importance: MitigationImportance
}
type UpdateControlPayload {
control: Control!
type UpdateMitigationPayload {
mitigation: Mitigation!
}
input UploadEvidenceInput {

File diff suppressed because it is too large Load Diff

View File

@@ -20,31 +20,31 @@ import (
)
type (
ControlOrderBy OrderBy[coredata.ControlOrderField]
MitigationOrderBy OrderBy[coredata.MitigationOrderField]
)
func NewControlConnection(p *page.Page[*coredata.Control, coredata.ControlOrderField]) *ControlConnection {
var edges = make([]*ControlEdge, len(p.Data))
func NewMitigationConnection(p *page.Page[*coredata.Mitigation, coredata.MitigationOrderField]) *MitigationConnection {
var edges = make([]*MitigationEdge, len(p.Data))
for i := range edges {
edges[i] = NewControlEdge(p.Data[i], p.Cursor.OrderBy.Field)
edges[i] = NewMitigationEdge(p.Data[i], p.Cursor.OrderBy.Field)
}
return &ControlConnection{
return &MitigationConnection{
Edges: edges,
PageInfo: NewPageInfo(p),
}
}
func NewControlEdge(c *coredata.Control, orderBy coredata.ControlOrderField) *ControlEdge {
return &ControlEdge{
func NewMitigationEdge(c *coredata.Mitigation, orderBy coredata.MitigationOrderField) *MitigationEdge {
return &MitigationEdge{
Cursor: c.CursorKey(orderBy),
Node: NewControl(c),
Node: NewMitigation(c),
}
}
func NewControl(c *coredata.Control) *Control {
return &Control{
func NewMitigation(c *coredata.Mitigation) *Mitigation {
return &Mitigation{
ID: c.ID,
Version: c.Version,
Category: c.Category,

View File

@@ -36,44 +36,6 @@ type ConfirmEmailPayload struct {
Success bool `json:"success"`
}
type Control struct {
ID gid.GID `json:"id"`
Version int `json:"version"`
Category string `json:"category"`
Name string `json:"name"`
Description string `json:"description"`
State coredata.ControlState `json:"state"`
Importance coredata.ControlImportance `json:"importance"`
Tasks *TaskConnection `json:"tasks"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
func (Control) IsNode() {}
func (this Control) GetID() gid.GID { return this.ID }
type ControlConnection struct {
Edges []*ControlEdge `json:"edges"`
PageInfo *PageInfo `json:"pageInfo"`
}
type ControlEdge struct {
Cursor page.CursorKey `json:"cursor"`
Node *Control `json:"node"`
}
type CreateControlInput struct {
FrameworkID gid.GID `json:"frameworkId"`
Name string `json:"name"`
Description string `json:"description"`
Category string `json:"category"`
Importance coredata.ControlImportance `json:"importance"`
}
type CreateControlPayload struct {
ControlEdge *ControlEdge `json:"controlEdge"`
}
type CreateFrameworkInput struct {
OrganizationID gid.GID `json:"organizationId"`
Name string `json:"name"`
@@ -84,6 +46,18 @@ type CreateFrameworkPayload struct {
FrameworkEdge *FrameworkEdge `json:"frameworkEdge"`
}
type CreateMitigationInput struct {
FrameworkID gid.GID `json:"frameworkId"`
Name string `json:"name"`
Description string `json:"description"`
Category string `json:"category"`
Importance coredata.MitigationImportance `json:"importance"`
}
type CreateMitigationPayload struct {
MitigationEdge *MitigationEdge `json:"mitigationEdge"`
}
type CreateOrganizationInput struct {
Name string `json:"name"`
}
@@ -118,7 +92,7 @@ type CreatePolicyPayload struct {
}
type CreateTaskInput struct {
ControlID gid.GID `json:"controlId"`
MitigationID gid.GID `json:"mitigationId"`
Name string `json:"name"`
Description string `json:"description"`
TimeEstimate *time.Duration `json:"timeEstimate,omitempty"`
@@ -222,13 +196,13 @@ type EvidenceEdge struct {
}
type Framework struct {
ID gid.GID `json:"id"`
Version int `json:"version"`
Name string `json:"name"`
Description string `json:"description"`
Controls *ControlConnection `json:"controls"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
ID gid.GID `json:"id"`
Version int `json:"version"`
Name string `json:"name"`
Description string `json:"description"`
Mitigations *MitigationConnection `json:"mitigations"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
func (Framework) IsNode() {}
@@ -263,6 +237,32 @@ type InviteUserPayload struct {
Success bool `json:"success"`
}
type Mitigation struct {
ID gid.GID `json:"id"`
Version int `json:"version"`
Category string `json:"category"`
Name string `json:"name"`
Description string `json:"description"`
State coredata.MitigationState `json:"state"`
Importance coredata.MitigationImportance `json:"importance"`
Tasks *TaskConnection `json:"tasks"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
func (Mitigation) IsNode() {}
func (this Mitigation) GetID() gid.GID { return this.ID }
type MitigationConnection struct {
Edges []*MitigationEdge `json:"edges"`
PageInfo *PageInfo `json:"pageInfo"`
}
type MitigationEdge struct {
Cursor page.CursorKey `json:"cursor"`
Node *Mitigation `json:"node"`
}
type Mutation struct {
}
@@ -404,20 +404,6 @@ type UnassignTaskPayload struct {
Task *Task `json:"task"`
}
type UpdateControlInput struct {
ID gid.GID `json:"id"`
ExpectedVersion int `json:"expectedVersion"`
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
Category *string `json:"category,omitempty"`
State *coredata.ControlState `json:"state,omitempty"`
Importance *coredata.ControlImportance `json:"importance,omitempty"`
}
type UpdateControlPayload struct {
Control *Control `json:"control"`
}
type UpdateFrameworkInput struct {
ID gid.GID `json:"id"`
ExpectedVersion int `json:"expectedVersion"`
@@ -429,6 +415,20 @@ type UpdateFrameworkPayload struct {
Framework *Framework `json:"framework"`
}
type UpdateMitigationInput struct {
ID gid.GID `json:"id"`
ExpectedVersion int `json:"expectedVersion"`
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
Category *string `json:"category,omitempty"`
State *coredata.MitigationState `json:"state,omitempty"`
Importance *coredata.MitigationImportance `json:"importance,omitempty"`
}
type UpdateMitigationPayload struct {
Mitigation *Mitigation `json:"mitigation"`
}
type UpdateOrganizationInput struct {
OrganizationID gid.GID `json:"organizationId"`
Name *string `json:"name,omitempty"`

View File

@@ -19,31 +19,6 @@ import (
"github.com/vektah/gqlparser/v2/gqlerror"
)
// Tasks is the resolver for the tasks field.
func (r *controlResolver) Tasks(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TaskOrderBy) (*types.TaskConnection, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, obj.ID.TenantID())
pageOrderBy := page.OrderBy[coredata.TaskOrderField]{
Field: coredata.TaskOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if orderBy != nil {
pageOrderBy = page.OrderBy[coredata.TaskOrderField]{
Field: orderBy.Field,
Direction: orderBy.Direction,
}
}
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
page, err := svc.Tasks.ListForControlID(ctx, obj.ID, cursor)
if err != nil {
return nil, fmt.Errorf("cannot list control tasks: %w", err)
}
return types.NewTaskConnection(page), nil
}
// FileURL is the resolver for the fileUrl field.
func (r *evidenceResolver) FileURL(ctx context.Context, obj *types.Evidence) (*string, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, obj.ID.TenantID())
@@ -61,16 +36,40 @@ func (r *evidenceResolver) FileURL(ctx context.Context, obj *types.Evidence) (*s
return &result, nil
}
// Controls is the resolver for the controls field.
func (r *frameworkResolver) Controls(ctx context.Context, obj *types.Framework, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy) (*types.ControlConnection, error) {
// Mitigations is the resolver for the mitigations field.
func (r *frameworkResolver) Mitigations(ctx context.Context, obj *types.Framework, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MitigationOrderBy) (*types.MitigationConnection, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, obj.ID.TenantID())
pageOrderBy := page.OrderBy[coredata.ControlOrderField]{
Field: coredata.ControlOrderFieldCreatedAt,
pageOrderBy := page.OrderBy[coredata.MitigationOrderField]{
Field: coredata.MitigationOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if orderBy != nil {
pageOrderBy = page.OrderBy[coredata.ControlOrderField]{
pageOrderBy = page.OrderBy[coredata.MitigationOrderField]{
Field: orderBy.Field,
Direction: orderBy.Direction,
}
}
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
page, err := svc.Mitigations.ListForFrameworkID(ctx, obj.ID, cursor)
if err != nil {
return nil, fmt.Errorf("cannot list framework mitigations: %w", err)
}
return types.NewMitigationConnection(page), nil
}
// Tasks is the resolver for the tasks field.
func (r *mitigationResolver) Tasks(ctx context.Context, obj *types.Mitigation, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TaskOrderBy) (*types.TaskConnection, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, obj.ID.TenantID())
pageOrderBy := page.OrderBy[coredata.TaskOrderField]{
Field: coredata.TaskOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if orderBy != nil {
pageOrderBy = page.OrderBy[coredata.TaskOrderField]{
Field: orderBy.Field,
Direction: orderBy.Direction,
}
@@ -78,12 +77,12 @@ func (r *frameworkResolver) Controls(ctx context.Context, obj *types.Framework,
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
page, err := svc.Controls.ListForFrameworkID(ctx, obj.ID, cursor)
page, err := svc.Tasks.ListForMitigationID(ctx, obj.ID, cursor)
if err != nil {
return nil, fmt.Errorf("cannot list framework controls: %w", err)
return nil, fmt.Errorf("cannot list mitigation tasks: %w", err)
}
return types.NewControlConnection(page), nil
return types.NewTaskConnection(page), nil
}
// CreateVendor is the resolver for the createVendor field.
@@ -260,10 +259,10 @@ func (r *mutationResolver) DeleteOrganization(ctx context.Context, input types.D
// CreateTask is the resolver for the createTask field.
func (r *mutationResolver) CreateTask(ctx context.Context, input types.CreateTaskInput) (*types.CreateTaskPayload, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, input.ControlID.TenantID())
svc := r.GetTenantServiceIfAuthorized(ctx, input.MitigationID.TenantID())
task, err := svc.Tasks.Create(ctx, probo.CreateTaskRequest{
ControlID: input.ControlID,
MitigationID: input.MitigationID,
Name: input.Name,
Description: input.Description,
TimeEstimate: input.TimeEstimate,
@@ -282,7 +281,7 @@ func (r *mutationResolver) UpdateTask(ctx context.Context, input types.UpdateTas
svc := r.GetTenantServiceIfAuthorized(ctx, input.TaskID.TenantID())
task, err := svc.Tasks.Update(ctx, probo.UpdateTaskRequest{
ID: input.TaskID,
TaskID: input.TaskID,
ExpectedVersion: input.ExpectedVersion,
Name: input.Name,
Description: input.Description,
@@ -396,11 +395,11 @@ func (r *mutationResolver) ImportFramework(ctx context.Context, input types.Impo
}, nil
}
// CreateControl is the resolver for the createControl field.
func (r *mutationResolver) CreateControl(ctx context.Context, input types.CreateControlInput) (*types.CreateControlPayload, error) {
// CreateMitigation is the resolver for the createMitigation field.
func (r *mutationResolver) CreateMitigation(ctx context.Context, input types.CreateMitigationInput) (*types.CreateMitigationPayload, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, input.FrameworkID.TenantID())
control, err := svc.Controls.Create(ctx, probo.CreateControlRequest{
mitigation, err := svc.Mitigations.Create(ctx, probo.CreateMitigationRequest{
FrameworkID: input.FrameworkID,
Name: input.Name,
Description: input.Description,
@@ -408,33 +407,33 @@ func (r *mutationResolver) CreateControl(ctx context.Context, input types.Create
Importance: input.Importance,
})
if err != nil {
return nil, fmt.Errorf("cannot create control: %w", err)
panic(fmt.Errorf("cannot create mitigation: %w", err))
}
return &types.CreateControlPayload{
ControlEdge: types.NewControlEdge(control, coredata.ControlOrderFieldCreatedAt),
return &types.CreateMitigationPayload{
MitigationEdge: types.NewMitigationEdge(mitigation, coredata.MitigationOrderFieldCreatedAt),
}, nil
}
// UpdateControl is the resolver for the updateControl field.
func (r *mutationResolver) UpdateControl(ctx context.Context, input types.UpdateControlInput) (*types.UpdateControlPayload, error) {
// UpdateMitigation is the resolver for the updateMitigation field.
func (r *mutationResolver) UpdateMitigation(ctx context.Context, input types.UpdateMitigationInput) (*types.UpdateMitigationPayload, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, input.ID.TenantID())
control, err := svc.Controls.Update(ctx, probo.UpdateControlRequest{
mitigation, err := svc.Mitigations.Update(ctx, probo.UpdateMitigationRequest{
ID: input.ID,
ExpectedVersion: input.ExpectedVersion,
Name: input.Name,
Description: input.Description,
Category: input.Category,
State: input.State,
Importance: input.Importance,
State: input.State,
})
if err != nil {
return nil, fmt.Errorf("cannot update control: %w", err)
panic(fmt.Errorf("cannot update mitigation: %w", err))
}
return &types.UpdateControlPayload{
Control: types.NewControl(control),
return &types.UpdateMitigationPayload{
Mitigation: types.NewMitigation(mitigation),
}, nil
}
@@ -785,13 +784,13 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
}
return types.NewFramework(framework), nil
case coredata.ControlEntityType:
control, err := svc.Controls.Get(ctx, id)
case coredata.MitigationEntityType:
mitigation, err := svc.Mitigations.Get(ctx, id)
if err != nil {
return nil, err
}
return types.NewControl(control), nil
return types.NewMitigation(mitigation), nil
case coredata.TaskEntityType:
task, err := svc.Tasks.Get(ctx, id)
if err != nil {
@@ -838,11 +837,11 @@ func (r *taskResolver) AssignedTo(ctx context.Context, obj *types.Task) (*types.
return nil, fmt.Errorf("cannot get task: %w", err)
}
if task.AssignedTo == nil {
if task.AssignedToID == nil {
return nil, nil
}
people, err := svc.Peoples.Get(ctx, *task.AssignedTo)
people, err := svc.Peoples.Get(ctx, *task.AssignedToID)
if err != nil {
return nil, fmt.Errorf("cannot get assigned to: %w", err)
}
@@ -899,15 +898,15 @@ func (r *viewerResolver) Organizations(ctx context.Context, obj *types.Viewer, f
}, nil
}
// Control returns schema.ControlResolver implementation.
func (r *Resolver) Control() schema.ControlResolver { return &controlResolver{r} }
// Evidence returns schema.EvidenceResolver implementation.
func (r *Resolver) Evidence() schema.EvidenceResolver { return &evidenceResolver{r} }
// Framework returns schema.FrameworkResolver implementation.
func (r *Resolver) Framework() schema.FrameworkResolver { return &frameworkResolver{r} }
// Mitigation returns schema.MitigationResolver implementation.
func (r *Resolver) Mitigation() schema.MitigationResolver { return &mitigationResolver{r} }
// Mutation returns schema.MutationResolver implementation.
func (r *Resolver) Mutation() schema.MutationResolver { return &mutationResolver{r} }
@@ -926,9 +925,9 @@ func (r *Resolver) Task() schema.TaskResolver { return &taskResolver{r} }
// Viewer returns schema.ViewerResolver implementation.
func (r *Resolver) Viewer() schema.ViewerResolver { return &viewerResolver{r} }
type controlResolver struct{ *Resolver }
type evidenceResolver struct{ *Resolver }
type frameworkResolver struct{ *Resolver }
type mitigationResolver struct{ *Resolver }
type mutationResolver struct{ *Resolver }
type organizationResolver struct{ *Resolver }
type policyResolver struct{ *Resolver }