First step of mitigation migration

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-03-27 23:34:35 +01:00
parent 449bd620da
commit 7321862ba9
62 changed files with 4025 additions and 2141 deletions

View File

@@ -155,6 +155,14 @@ type Organization implements Node {
orderBy: PolicyOrder
): PolicyConnection! @goField(forceResolver: true)
mitigations(
first: Int
after: CursorKey
last: Int
before: CursorKey
orderBy: MitigationOrder
): MitigationConnection! @goField(forceResolver: true)
createdAt: Datetime!
updatedAt: Datetime!
}
@@ -186,7 +194,18 @@ enum FrameworkOrderField
@goModel(
model: "github.com/getprobo/probo/pkg/coredata.FrameworkOrderField"
) {
NAME
CREATED_AT
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.FrameworkOrderFieldCreatedAt"
)
}
enum ControlOrderField
@goModel(model: "github.com/getprobo/probo/pkg/coredata.ControlOrderField") {
CREATED_AT
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.ControlOrderFieldCreatedAt"
)
}
enum MitigationOrderField
@@ -235,6 +254,14 @@ input FrameworkOrder
field: FrameworkOrderField!
}
input ControlOrder
@goModel(
model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.ControlOrderBy"
) {
direction: OrderDirection!
field: ControlOrderField!
}
input MitigationOrder
@goModel(
model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.MitigationOrderBy"
@@ -285,7 +312,6 @@ type People implements Node {
kind: PeopleKind!
createdAt: Datetime!
updatedAt: Datetime!
version: Int!
}
type VendorConnection {
@@ -311,7 +337,6 @@ type Vendor implements Node {
privacyPolicyUrl: String
createdAt: Datetime!
updatedAt: Datetime!
version: Int!
}
type FrameworkConnection {
@@ -326,23 +351,40 @@ type FrameworkEdge {
type Framework implements Node {
id: ID!
version: Int!
name: String!
description: String!
mitigations(
controls(
first: Int
after: CursorKey
last: Int
before: CursorKey
orderBy: MitigationOrder
): MitigationConnection! @goField(forceResolver: true)
orderBy: ControlOrder
): ControlConnection! @goField(forceResolver: true)
createdAt: Datetime!
updatedAt: Datetime!
}
type ControlConnection {
edges: [ControlEdge!]!
pageInfo: PageInfo!
}
type ControlEdge {
cursor: CursorKey!
node: Control!
}
type Control implements Node {
id: ID!
referenceId: String!
name: String!
description: String!
createdAt: Datetime!
updatedAt: Datetime!
}
type MitigationConnection {
edges: [MitigationEdge!]!
pageInfo: PageInfo!
@@ -355,7 +397,6 @@ type MitigationEdge {
type Mitigation implements Node {
id: ID!
version: Int!
category: String!
name: String!
description: String!
@@ -386,7 +427,6 @@ type TaskEdge {
type Task implements Node {
id: ID!
version: Int!
name: String!
description: String!
state: TaskState!
@@ -506,6 +546,7 @@ type Mutation {
createFramework(input: CreateFrameworkInput!): CreateFrameworkPayload!
updateFramework(input: UpdateFrameworkInput!): UpdateFrameworkPayload!
importFramework(input: ImportFrameworkInput!): ImportFrameworkPayload!
deleteFramework(input: DeleteFrameworkInput!): DeleteFrameworkPayload!
createMitigation(input: CreateMitigationInput!): CreateMitigationPayload!
updateMitigation(input: UpdateMitigationInput!): UpdateMitigationPayload!
@@ -553,7 +594,6 @@ input CreatePeopleInput {
input UpdatePeopleInput {
id: ID!
expectedVersion: Int!
fullName: String
primaryEmailAddress: String
additionalEmailAddresses: [String!]
@@ -588,7 +628,6 @@ enum RiskTier
input UpdateVendorInput {
id: ID!
expectedVersion: Int!
name: String
description: String
serviceStartAt: Datetime
@@ -662,6 +701,14 @@ type DeleteTaskPayload {
deletedTaskId: ID!
}
input DeleteFrameworkInput {
frameworkId: ID!
}
type DeleteFrameworkPayload {
deletedFrameworkId: ID!
}
input CreateFrameworkInput {
organizationId: ID!
name: String!
@@ -670,7 +717,6 @@ input CreateFrameworkInput {
input UpdateFrameworkInput {
id: ID!
expectedVersion: Int!
name: String
description: String
}
@@ -680,7 +726,7 @@ type CreateFrameworkPayload {
}
input CreateMitigationInput {
frameworkId: ID!
organizationId: ID!
name: String!
description: String!
category: String!
@@ -705,7 +751,6 @@ type UpdatePeoplePayload {
input UpdateMitigationInput {
id: ID!
expectedVersion: Int!
name: String
description: String
category: String
@@ -757,7 +802,6 @@ input CreatePolicyInput {
input UpdatePolicyInput {
id: ID!
expectedVersion: Int!
name: String
content: String
status: PolicyStatus
@@ -783,7 +827,6 @@ type DeletePolicyPayload {
type Policy implements Node {
id: ID!
version: Int!
name: String!
status: PolicyStatus!
content: String!
@@ -805,7 +848,6 @@ type PolicyEdge {
input UpdateTaskInput {
taskId: ID!
expectedVersion: Int!
name: String
description: String
state: TaskState

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,55 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package types
import (
"github.com/getprobo/probo/pkg/coredata"
"github.com/getprobo/probo/pkg/page"
)
type (
ControlOrderBy OrderBy[coredata.ControlOrderField]
)
func NewControlConnection(p *page.Page[*coredata.Control, coredata.ControlOrderField]) *ControlConnection {
var edges = make([]*ControlEdge, len(p.Data))
for i := range edges {
edges[i] = NewControlEdge(p.Data[i], p.Cursor.OrderBy.Field)
}
return &ControlConnection{
Edges: edges,
PageInfo: NewPageInfo(p),
}
}
func NewControlEdge(c *coredata.Control, orderBy coredata.ControlOrderField) *ControlEdge {
return &ControlEdge{
Cursor: c.CursorKey(orderBy),
Node: NewControl(c),
}
}
func NewControl(c *coredata.Control) *Control {
return &Control{
ID: c.ID,
ReferenceID: c.ReferenceID,
Name: c.Name,
Description: c.Description,
CreatedAt: c.CreatedAt,
UpdatedAt: c.UpdatedAt,
}
}

View File

@@ -46,7 +46,6 @@ func NewFrameworkEdge(f *coredata.Framework, orderBy coredata.FrameworkOrderFiel
func NewFramework(f *coredata.Framework) *Framework {
return &Framework{
ID: f.ID,
Version: f.Version,
Name: f.Name,
Description: f.Description,
CreatedAt: f.CreatedAt,

View File

@@ -46,7 +46,6 @@ func NewMitigationEdge(c *coredata.Mitigation, orderBy coredata.MitigationOrderF
func NewMitigation(c *coredata.Mitigation) *Mitigation {
return &Mitigation{
ID: c.ID,
Version: c.Version,
Category: c.Category,
Name: c.Name,
Description: c.Description,

View File

@@ -52,6 +52,5 @@ func NewPeople(p *coredata.People) *People {
Kind: p.Kind,
CreatedAt: p.CreatedAt,
UpdatedAt: p.UpdatedAt,
Version: p.Version,
}
}

View File

@@ -45,7 +45,6 @@ func NewPolicyEdge(policy *coredata.Policy, orderBy coredata.PolicyOrderField) *
func NewPolicy(policy *coredata.Policy) *Policy {
return &Policy{
ID: policy.ID,
Version: policy.Version,
Name: policy.Name,
Content: policy.Content,
CreatedAt: policy.CreatedAt,

View File

@@ -52,6 +52,5 @@ func NewTask(t *coredata.Task) *Task {
TimeEstimate: t.TimeEstimate,
CreatedAt: t.CreatedAt,
UpdatedAt: t.UpdatedAt,
Version: t.Version,
}
}

View File

@@ -36,6 +36,28 @@ type ConfirmEmailPayload struct {
Success bool `json:"success"`
}
type Control struct {
ID gid.GID `json:"id"`
ReferenceID string `json:"referenceId"`
Name string `json:"name"`
Description string `json:"description"`
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 CreateFrameworkInput struct {
OrganizationID gid.GID `json:"organizationId"`
Name string `json:"name"`
@@ -47,11 +69,11 @@ type CreateFrameworkPayload struct {
}
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"`
OrganizationID gid.GID `json:"organizationId"`
Name string `json:"name"`
Description string `json:"description"`
Category string `json:"category"`
Importance coredata.MitigationImportance `json:"importance"`
}
type CreateMitigationPayload struct {
@@ -128,6 +150,14 @@ type DeleteEvidencePayload struct {
DeletedEvidenceID gid.GID `json:"deletedEvidenceId"`
}
type DeleteFrameworkInput struct {
FrameworkID gid.GID `json:"frameworkId"`
}
type DeleteFrameworkPayload struct {
DeletedFrameworkID gid.GID `json:"deletedFrameworkId"`
}
type DeleteOrganizationInput struct {
OrganizationID gid.GID `json:"organizationId"`
}
@@ -196,13 +226,12 @@ type EvidenceEdge struct {
}
type Framework struct {
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"`
ID gid.GID `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Controls *ControlConnection `json:"controls"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
func (Framework) IsNode() {}
@@ -239,7 +268,6 @@ type InviteUserPayload struct {
type Mitigation struct {
ID gid.GID `json:"id"`
Version int `json:"version"`
Category string `json:"category"`
Name string `json:"name"`
Description string `json:"description"`
@@ -267,16 +295,17 @@ type Mutation struct {
}
type Organization struct {
ID gid.GID `json:"id"`
Name string `json:"name"`
LogoURL *string `json:"logoUrl,omitempty"`
Users *UserConnection `json:"users"`
Frameworks *FrameworkConnection `json:"frameworks"`
Vendors *VendorConnection `json:"vendors"`
Peoples *PeopleConnection `json:"peoples"`
Policies *PolicyConnection `json:"policies"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
ID gid.GID `json:"id"`
Name string `json:"name"`
LogoURL *string `json:"logoUrl,omitempty"`
Users *UserConnection `json:"users"`
Frameworks *FrameworkConnection `json:"frameworks"`
Vendors *VendorConnection `json:"vendors"`
Peoples *PeopleConnection `json:"peoples"`
Policies *PolicyConnection `json:"policies"`
Mitigations *MitigationConnection `json:"mitigations"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
func (Organization) IsNode() {}
@@ -312,7 +341,6 @@ type People struct {
Kind coredata.PeopleKind `json:"kind"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Version int `json:"version"`
}
func (People) IsNode() {}
@@ -330,7 +358,6 @@ type PeopleEdge struct {
type Policy struct {
ID gid.GID `json:"id"`
Version int `json:"version"`
Name string `json:"name"`
Status coredata.PolicyStatus `json:"status"`
Content string `json:"content"`
@@ -372,7 +399,6 @@ type Session struct {
type Task struct {
ID gid.GID `json:"id"`
Version int `json:"version"`
Name string `json:"name"`
Description string `json:"description"`
State coredata.TaskState `json:"state"`
@@ -405,10 +431,9 @@ type UnassignTaskPayload struct {
}
type UpdateFrameworkInput struct {
ID gid.GID `json:"id"`
ExpectedVersion int `json:"expectedVersion"`
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
ID gid.GID `json:"id"`
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
}
type UpdateFrameworkPayload struct {
@@ -416,13 +441,12 @@ type UpdateFrameworkPayload struct {
}
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"`
ID gid.GID `json:"id"`
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 {
@@ -441,7 +465,6 @@ type UpdateOrganizationPayload struct {
type UpdatePeopleInput struct {
ID gid.GID `json:"id"`
ExpectedVersion int `json:"expectedVersion"`
FullName *string `json:"fullName,omitempty"`
PrimaryEmailAddress *string `json:"primaryEmailAddress,omitempty"`
AdditionalEmailAddresses []string `json:"additionalEmailAddresses,omitempty"`
@@ -453,13 +476,12 @@ type UpdatePeoplePayload struct {
}
type UpdatePolicyInput struct {
ID gid.GID `json:"id"`
ExpectedVersion int `json:"expectedVersion"`
Name *string `json:"name,omitempty"`
Content *string `json:"content,omitempty"`
Status *coredata.PolicyStatus `json:"status,omitempty"`
ReviewDate *time.Time `json:"reviewDate,omitempty"`
OwnerID *gid.GID `json:"ownerId,omitempty"`
ID gid.GID `json:"id"`
Name *string `json:"name,omitempty"`
Content *string `json:"content,omitempty"`
Status *coredata.PolicyStatus `json:"status,omitempty"`
ReviewDate *time.Time `json:"reviewDate,omitempty"`
OwnerID *gid.GID `json:"ownerId,omitempty"`
}
type UpdatePolicyPayload struct {
@@ -467,12 +489,11 @@ type UpdatePolicyPayload struct {
}
type UpdateTaskInput struct {
TaskID gid.GID `json:"taskId"`
ExpectedVersion int `json:"expectedVersion"`
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
State *coredata.TaskState `json:"state,omitempty"`
TimeEstimate *time.Duration `json:"timeEstimate,omitempty"`
TaskID gid.GID `json:"taskId"`
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
State *coredata.TaskState `json:"state,omitempty"`
TimeEstimate *time.Duration `json:"timeEstimate,omitempty"`
}
type UpdateTaskPayload struct {
@@ -481,7 +502,6 @@ type UpdateTaskPayload struct {
type UpdateVendorInput struct {
ID gid.GID `json:"id"`
ExpectedVersion int `json:"expectedVersion"`
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
ServiceStartAt *time.Time `json:"serviceStartAt,omitempty"`
@@ -544,7 +564,6 @@ type Vendor struct {
PrivacyPolicyURL *string `json:"privacyPolicyUrl,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Version int `json:"version"`
}
func (Vendor) IsNode() {}

View File

@@ -57,6 +57,5 @@ func NewVendor(v *coredata.Vendor) *Vendor {
StatusPageURL: v.StatusPageURL,
TermsOfServiceURL: v.TermsOfServiceURL,
PrivacyPolicyURL: v.PrivacyPolicyURL,
Version: v.Version,
}
}

View File

@@ -36,28 +36,29 @@ func (r *evidenceResolver) FileURL(ctx context.Context, obj *types.Evidence) (*s
return &result, nil
}
// 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) {
// 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) {
svc := r.GetTenantServiceIfAuthorized(ctx, obj.ID.TenantID())
pageOrderBy := page.OrderBy[coredata.MitigationOrderField]{
Field: coredata.MitigationOrderFieldCreatedAt,
pageOrderBy := page.OrderBy[coredata.ControlOrderField]{
Field: coredata.ControlOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if orderBy != nil {
pageOrderBy = page.OrderBy[coredata.MitigationOrderField]{
pageOrderBy = page.OrderBy[coredata.ControlOrderField]{
Field: orderBy.Field,
Direction: orderBy.Direction,
}
}
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
page, err := svc.Mitigations.ListForFrameworkID(ctx, obj.ID, cursor)
page, err := svc.Controls.ListForFrameworkID(ctx, obj.ID, cursor)
if err != nil {
return nil, fmt.Errorf("cannot list framework mitigations: %w", err)
return nil, fmt.Errorf("cannot list controls: %w", err)
}
return types.NewMitigationConnection(page), nil
return types.NewControlConnection(page), nil
}
// Tasks is the resolver for the tasks field.
@@ -115,7 +116,6 @@ func (r *mutationResolver) UpdateVendor(ctx context.Context, input types.UpdateV
vendor, err := svc.Vendors.Update(ctx, probo.UpdateVendorRequest{
ID: input.ID,
ExpectedVersion: input.ExpectedVersion,
Name: input.Name,
Description: input.Description,
ServiceStartAt: input.ServiceStartAt,
@@ -176,7 +176,6 @@ func (r *mutationResolver) UpdatePeople(ctx context.Context, input types.UpdateP
people, err := svc.Peoples.Update(ctx, probo.UpdatePeopleRequest{
ID: input.ID,
ExpectedVersion: input.ExpectedVersion,
FullName: input.FullName,
PrimaryEmailAddress: input.PrimaryEmailAddress,
AdditionalEmailAddresses: &input.AdditionalEmailAddresses,
@@ -281,12 +280,11 @@ 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{
TaskID: input.TaskID,
ExpectedVersion: input.ExpectedVersion,
Name: input.Name,
Description: input.Description,
State: input.State,
TimeEstimate: input.TimeEstimate,
TaskID: input.TaskID,
Name: input.Name,
Description: input.Description,
State: input.State,
TimeEstimate: input.TimeEstimate,
})
if err != nil {
return nil, fmt.Errorf("cannot update task: %w", err)
@@ -346,7 +344,6 @@ func (r *mutationResolver) CreateFramework(ctx context.Context, input types.Crea
framework, err := svc.Frameworks.Create(ctx, probo.CreateFrameworkRequest{
OrganizationID: input.OrganizationID,
Name: input.Name,
Description: input.Description,
})
if err != nil {
return nil, fmt.Errorf("cannot create framework: %w", err)
@@ -362,10 +359,9 @@ func (r *mutationResolver) UpdateFramework(ctx context.Context, input types.Upda
svc := r.GetTenantServiceIfAuthorized(ctx, input.ID.TenantID())
framework, err := svc.Frameworks.Update(ctx, probo.UpdateFrameworkRequest{
ID: input.ID,
ExpectedVersion: input.ExpectedVersion,
Name: input.Name,
Description: input.Description,
ID: input.ID,
Name: input.Name,
Description: input.Description,
})
if err != nil {
return nil, fmt.Errorf("cannot update framework: %w", err)
@@ -376,12 +372,26 @@ func (r *mutationResolver) UpdateFramework(ctx context.Context, input types.Upda
}, nil
}
// DeleteFramework is the resolver for the deleteFramework field.
func (r *mutationResolver) DeleteFramework(ctx context.Context, input types.DeleteFrameworkInput) (*types.DeleteFrameworkPayload, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, input.FrameworkID.TenantID())
err := svc.Frameworks.Delete(ctx, input.FrameworkID)
if err != nil {
return nil, fmt.Errorf("cannot delete framework: %w", err)
}
return &types.DeleteFrameworkPayload{
DeletedFrameworkID: input.FrameworkID,
}, nil
}
// ImportFramework is the resolver for the importFramework field.
func (r *mutationResolver) ImportFramework(ctx context.Context, input types.ImportFrameworkInput) (*types.ImportFrameworkPayload, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, input.OrganizationID.TenantID())
req := probo.ImportFrameworkRequest{}
if err := json.NewDecoder(input.File.File).Decode(&req.Data); err != nil {
if err := json.NewDecoder(input.File.File).Decode(&req.Framework); err != nil {
return nil, fmt.Errorf("cannot decode framework: %w", err)
}
@@ -395,16 +405,16 @@ func (r *mutationResolver) ImportFramework(ctx context.Context, input types.Impo
}, nil
}
// CreateMitigation is the resolver for the createMitigation field.
// // 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())
svc := r.GetTenantServiceIfAuthorized(ctx, input.OrganizationID.TenantID())
mitigation, err := svc.Mitigations.Create(ctx, probo.CreateMitigationRequest{
FrameworkID: input.FrameworkID,
Name: input.Name,
Description: input.Description,
Category: input.Category,
Importance: input.Importance,
OrganizationID: input.OrganizationID,
Name: input.Name,
Description: input.Description,
Category: input.Category,
Importance: input.Importance,
})
if err != nil {
panic(fmt.Errorf("cannot create mitigation: %w", err))
@@ -420,13 +430,12 @@ func (r *mutationResolver) UpdateMitigation(ctx context.Context, input types.Upd
svc := r.GetTenantServiceIfAuthorized(ctx, input.ID.TenantID())
mitigation, err := svc.Mitigations.Update(ctx, probo.UpdateMitigationRequest{
ID: input.ID,
ExpectedVersion: input.ExpectedVersion,
Name: input.Name,
Description: input.Description,
Category: input.Category,
Importance: input.Importance,
State: input.State,
ID: input.ID,
Name: input.Name,
Description: input.Description,
Category: input.Category,
Importance: input.Importance,
State: input.State,
})
if err != nil {
panic(fmt.Errorf("cannot update mitigation: %w", err))
@@ -515,13 +524,12 @@ func (r *mutationResolver) UpdatePolicy(ctx context.Context, input types.UpdateP
svc := r.GetTenantServiceIfAuthorized(ctx, input.ID.TenantID())
policy, err := svc.Policies.Update(ctx, probo.UpdatePolicyRequest{
ID: input.ID,
ExpectedVersion: input.ExpectedVersion,
Name: input.Name,
Content: input.Content,
Status: input.Status,
ReviewDate: input.ReviewDate,
OwnerID: input.OwnerID,
ID: input.ID,
Name: input.Name,
Content: input.Content,
Status: input.Status,
ReviewDate: input.ReviewDate,
OwnerID: input.OwnerID,
})
if err != nil {
return nil, fmt.Errorf("cannot update policy: %w", err)
@@ -733,6 +741,31 @@ func (r *organizationResolver) Policies(ctx context.Context, obj *types.Organiza
return types.NewPolicyConnection(page), nil
}
// Mitigations is the resolver for the mitigations field.
func (r *organizationResolver) Mitigations(ctx context.Context, obj *types.Organization, 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.MitigationOrderField]{
Field: coredata.MitigationOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if orderBy != nil {
pageOrderBy = page.OrderBy[coredata.MitigationOrderField]{
Field: orderBy.Field,
Direction: orderBy.Direction,
}
}
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
page, err := svc.Mitigations.ListForOrganizationID(ctx, obj.ID, cursor)
if err != nil {
return nil, fmt.Errorf("cannot list organization mitigations: %w", err)
}
return types.NewMitigationConnection(page), nil
}
// Owner is the resolver for the owner field.
func (r *policyResolver) Owner(ctx context.Context, obj *types.Policy) (*types.People, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, obj.ID.TenantID())