package console_v1 // This file will be automatically regenerated based on the schema, any resolver // implementations // will be copied through when generating and any unknown code will be moved to the end. // Code generated by github.com/99designs/gqlgen version v0.17.86 import ( "context" "encoding/base64" "encoding/json" "errors" "fmt" "time" pgx "github.com/jackc/pgx/v5" "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/gid" "go.probo.inc/probo/pkg/iam" "go.probo.inc/probo/pkg/page" "go.probo.inc/probo/pkg/probo" "go.probo.inc/probo/pkg/server/api/authn" "go.probo.inc/probo/pkg/server/api/console/v1/schema" "go.probo.inc/probo/pkg/server/api/console/v1/types" "go.probo.inc/probo/pkg/server/gqlutils" "go.probo.inc/probo/pkg/server/gqlutils/types/cursor" ) // StateOfApplicability is the resolver for the stateOfApplicability field. func (r *applicabilityStatementResolver) StateOfApplicability(ctx context.Context, obj *types.ApplicabilityStatement) (*types.StateOfApplicability, error) { if err := r.authorize(ctx, obj.StateOfApplicability.ID, probo.ActionStateOfApplicabilityGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.StateOfApplicability.ID.TenantID()) soa, err := prb.StatesOfApplicability.Get(ctx, obj.StateOfApplicability.ID) if err != nil { panic(fmt.Errorf("cannot get state of applicability: %w", err)) } return types.NewStateOfApplicability(soa), nil } // Control is the resolver for the control field. func (r *applicabilityStatementResolver) Control(ctx context.Context, obj *types.ApplicabilityStatement) (*types.Control, error) { if err := r.authorize(ctx, obj.ID, probo.ActionControlGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) control, err := prb.Controls.Get(ctx, obj.Control.ID) if err != nil { panic(fmt.Errorf("cannot get control: %w", err)) } return types.NewControl(control), nil } // Permission is the resolver for the permission field. func (r *applicabilityStatementResolver) Permission(ctx context.Context, obj *types.ApplicabilityStatement, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *applicabilityStatementConnectionResolver) TotalCount(ctx context.Context, obj *types.ApplicabilityStatementConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionApplicabilityStatementList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *stateOfApplicabilityResolver: count, err := prb.StatesOfApplicability.CountApplicabilityStatements(ctx, obj.ParentID) if err != nil { panic(fmt.Errorf("cannot count applicability statements: %w", err)) } return count, nil } panic(fmt.Errorf("not implemented: TotalCount for parent type %T", obj.Resolver)) } // Owner is the resolver for the owner field. func (r *assetResolver) Owner(ctx context.Context, obj *types.Asset) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } owner, err := r.iam.OrganizationService.GetProfile(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get owner: %w", err)) } return types.NewProfile(owner), nil } // Vendors is the resolver for the vendors field. func (r *assetResolver) Vendors(ctx context.Context, obj *types.Asset, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) (*types.VendorConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.VendorOrderField]{ Field: coredata.VendorOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.VendorOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Vendors.ListForAssetID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list asset vendors: %w", err)) } return types.NewVendorConnection(page, r, obj.ID), nil } // Organization is the resolver for the organization field. func (r *assetResolver) Organization(ctx context.Context, obj *types.Asset) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) asset, err := prb.Assets.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot load audit: %w", err)) } org, err := prb.Organizations.Get(ctx, asset.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(org), nil } // Permission is the resolver for the permission field. func (r *assetResolver) Permission(ctx context.Context, obj *types.Asset, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *assetConnectionResolver) TotalCount(ctx context.Context, obj *types.AssetConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionAssetList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: assetFilter := coredata.NewAssetFilter(nil) if obj.Filter != nil { assetFilter = coredata.NewAssetFilter(&obj.Filter.SnapshotID) } count, err := prb.Assets.CountForOrganizationID(ctx, obj.ParentID, assetFilter) if err != nil { panic(fmt.Errorf("cannot count assets: %w", err)) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Organization is the resolver for the organization field. func (r *auditResolver) Organization(ctx context.Context, obj *types.Audit) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load organization: %w", err)) } return types.NewOrganization(organization), nil } // Framework is the resolver for the framework field. func (r *auditResolver) Framework(ctx context.Context, obj *types.Audit) (*types.Framework, error) { if err := r.authorize(ctx, obj.ID, probo.ActionFrameworkGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) framework, err := prb.Frameworks.Get(ctx, obj.Framework.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load framework: %w", err)) } return types.NewFramework(framework), nil } // Report is the resolver for the report field. func (r *auditResolver) Report(ctx context.Context, obj *types.Audit) (*types.Report, error) { if err := r.authorize(ctx, obj.ID, probo.ActionReportGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) if obj.Report == nil { return nil, nil } report, err := prb.Reports.Get(ctx, obj.Report.ID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot load report: %w", err)) } return types.NewReport(report), nil } // ReportURL is the resolver for the reportUrl field. func (r *auditResolver) ReportURL(ctx context.Context, obj *types.Audit) (*string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionReportGetReportUrl); err != nil { return nil, err } if obj.Report == nil { return nil, nil } prb := r.ProboService(ctx, obj.ID.TenantID()) url, err := prb.Audits.GenerateReportURL(ctx, obj.ID, 15*time.Minute) if err != nil { panic(fmt.Errorf("cannot generate report URL: %w", err)) } return url, nil } // Controls is the resolver for the controls field. func (r *auditResolver) Controls(ctx context.Context, obj *types.Audit, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ControlOrderField]{ Field: coredata.ControlOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ControlOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var controlFilter = coredata.NewControlFilter(nil) if filter != nil { controlFilter = coredata.NewControlFilter(filter.Query) } page, err := prb.Controls.ListForAuditID(ctx, obj.ID, cursor, controlFilter) if err != nil { panic(fmt.Errorf("cannot list audit controls: %w", err)) } return types.NewControlConnection(page, r, obj.ID, controlFilter), nil } // Permission is the resolver for the permission field. func (r *auditResolver) Permission(ctx context.Context, obj *types.Audit, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *auditConnectionResolver) TotalCount(ctx context.Context, obj *types.AuditConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionAuditList); err != nil { return 0, err } // TODO missing switch case prb := r.ProboService(ctx, obj.ParentID.TenantID()) count, err := prb.Audits.CountForOrganizationID(ctx, obj.ParentID) if err != nil { panic(fmt.Errorf("cannot count audits: %w", err)) } return count, nil } // Organization is the resolver for the organization field. func (r *continualImprovementResolver) Organization(ctx context.Context, obj *types.ContinualImprovement) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get continual improvement organization: %w", err)) } return types.NewOrganization(organization), nil } // Owner is the resolver for the owner field. func (r *continualImprovementResolver) Owner(ctx context.Context, obj *types.ContinualImprovement) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } owner, err := r.iam.OrganizationService.GetProfile(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get continual improvement owner: %w", err)) } return types.NewProfile(owner), nil } // Permission is the resolver for the permission field. func (r *continualImprovementResolver) Permission(ctx context.Context, obj *types.ContinualImprovement, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *continualImprovementConnectionResolver) TotalCount(ctx context.Context, obj *types.ContinualImprovementConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionContinualImprovementList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: continualImprovementFilter := coredata.NewContinualImprovementFilter(nil) if obj.Filter != nil { continualImprovementFilter = coredata.NewContinualImprovementFilter(&obj.Filter.SnapshotID) } count, err := prb.ContinualImprovements.CountByOrganizationID(ctx, obj.ParentID, continualImprovementFilter) if err != nil { panic(fmt.Errorf("cannot count continual improvements: %w", err)) } return count, nil } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Organization is the resolver for the organization field. func (r *controlResolver) Organization(ctx context.Context, obj *types.Control) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // Regulatory is the resolver for the regulatory field. func (r *controlResolver) Regulatory(ctx context.Context, obj *types.Control) (bool, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) hasRegulatory, err := prb.Controls.HasRegulatoryObligation(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot check regulatory obligation: %w", err)) } return hasRegulatory, nil } // Contractual is the resolver for the contractual field. func (r *controlResolver) Contractual(ctx context.Context, obj *types.Control) (bool, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) hasContractual, err := prb.Controls.HasContractualObligation(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot check contractual obligation: %w", err)) } return hasContractual, nil } // RiskAssessment is the resolver for the riskAssessment field. func (r *controlResolver) RiskAssessment(ctx context.Context, obj *types.Control) (bool, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) hasRisk, err := prb.Controls.HasRiskAssessment(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot check risk assessment: %w", err)) } return hasRisk, nil } // Framework is the resolver for the framework field. func (r *controlResolver) Framework(ctx context.Context, obj *types.Control) (*types.Framework, error) { if err := r.authorize(ctx, obj.ID, probo.ActionFrameworkGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) framework, err := prb.Frameworks.Get(ctx, obj.Framework.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get framework: %w", err)) } return types.NewFramework(framework), nil } // Measures is the resolver for the measures field. func (r *controlResolver) Measures(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) (*types.MeasureConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionMeasureList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.MeasureOrderField]{ Field: coredata.MeasureOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.MeasureOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var measureFilter = coredata.NewMeasureFilter(nil, nil) if filter != nil { measureFilter = coredata.NewMeasureFilter(filter.Query, filter.State) } page, err := prb.Measures.ListForControlID(ctx, obj.ID, cursor, measureFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list measures: %w", err)) } return types.NewMeasureConnection(page, r, obj.ID, measureFilter), nil } // Documents is the resolver for the documents field. func (r *controlResolver) Documents(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) (*types.DocumentConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDocumentList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{ Field: coredata.DocumentOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var documentFilter = coredata.NewDocumentFilter(nil) if filter != nil { documentFilter = coredata.NewDocumentFilter(filter.Query) } page, err := prb.Documents.ListForControlID(ctx, obj.ID, cursor, documentFilter) if err != nil { panic(fmt.Errorf("cannot list documents: %w", err)) } return types.NewDocumentConnection(page, r, obj.ID, documentFilter), nil } // Audits is the resolver for the audits field. func (r *controlResolver) Audits(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AuditOrderBy) (*types.AuditConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionAuditList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.AuditOrderField]{ Field: coredata.AuditOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.AuditOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Audits.ListForControlID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list control audits: %w", err)) } return types.NewAuditConnection(page, r, obj.ID), nil } // Obligations is the resolver for the obligations field. func (r *controlResolver) Obligations(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ObligationOrderBy, filter *types.ObligationFilter) (*types.ObligationConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionObligationList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ObligationOrderField]{ Field: coredata.ObligationOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ObligationOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var snapshotID **gid.GID if filter != nil { snapshotID = &filter.SnapshotID } obligationFilter := coredata.NewObligationFilter(snapshotID) page, err := prb.Obligations.ListForControlID(ctx, obj.ID, cursor, obligationFilter) if err != nil { panic(fmt.Errorf("cannot list control obligations: %w", err)) } return types.NewObligationConnection(page, r, obj.ID, filter), nil } // Snapshots is the resolver for the snapshots field. func (r *controlResolver) Snapshots(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SnapshotOrderBy) (*types.SnapshotConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionSnapshotList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.SnapshotOrderField]{ Field: coredata.SnapshotOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.SnapshotOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Snapshots.ListForControlID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list control snapshots: %w", err)) } return types.NewSnapshotConnection(page, r, obj.ID), nil } // Permission is the resolver for the permission field. func (r *controlResolver) Permission(ctx context.Context, obj *types.Control, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *controlConnectionResolver) TotalCount(ctx context.Context, obj *types.ControlConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionControlList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Controls.CountForOrganizationID(ctx, obj.ParentID, obj.Filters) if err != nil { panic(fmt.Errorf("cannot count controls: %w", err)) } return count, nil case *frameworkResolver: count, err := prb.Controls.CountForFrameworkID(ctx, obj.ParentID, obj.Filters) if err != nil { panic(fmt.Errorf("cannot count controls: %w", err)) } return count, nil case *documentResolver: count, err := prb.Controls.CountForDocumentID(ctx, obj.ParentID, obj.Filters) if err != nil { panic(fmt.Errorf("cannot count controls: %w", err)) } return count, nil case *measureResolver: count, err := prb.Controls.CountForMeasureID(ctx, obj.ParentID, obj.Filters) if err != nil { panic(fmt.Errorf("cannot count controls: %w", err)) } return count, nil case *riskResolver: count, err := prb.Controls.CountForRiskID(ctx, obj.ParentID, obj.Filters) if err != nil { panic(fmt.Errorf("cannot count controls: %w", err)) } return count, nil case *stateOfApplicabilityResolver: count, err := prb.Controls.CountForStateOfApplicabilityID(ctx, obj.ParentID, obj.Filters) if err != nil { panic(fmt.Errorf("cannot count controls: %w", err)) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Permission is the resolver for the permission field. func (r *customDomainResolver) Permission(ctx context.Context, obj *types.CustomDomain, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // ProcessingActivity is the resolver for the processingActivity field. func (r *dataProtectionImpactAssessmentResolver) ProcessingActivity(ctx context.Context, obj *types.DataProtectionImpactAssessment) (*types.ProcessingActivity, error) { if err := r.authorize(ctx, obj.ID, probo.ActionProcessingActivityList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) dpia, err := prb.DataProtectionImpactAssessments.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get processing activity dpia: %w", err)) } processingActivity, err := prb.ProcessingActivities.Get(ctx, dpia.ProcessingActivityID) if err != nil { panic(fmt.Errorf("cannot get processing activity: %w", err)) } return types.NewProcessingActivity(processingActivity), nil } // Organization is the resolver for the organization field. func (r *dataProtectionImpactAssessmentResolver) Organization(ctx context.Context, obj *types.DataProtectionImpactAssessment) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) dpia, err := prb.DataProtectionImpactAssessments.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get processing activity dpia: %w", err)) } organization, err := prb.Organizations.Get(ctx, dpia.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // Permission is the resolver for the permission field. func (r *dataProtectionImpactAssessmentResolver) Permission(ctx context.Context, obj *types.DataProtectionImpactAssessment, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *dataProtectionImpactAssessmentConnectionResolver) TotalCount(ctx context.Context, obj *types.DataProtectionImpactAssessmentConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionDataProtectionImpactAssessmentList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.DataProtectionImpactAssessments.CountForOrganizationID(ctx, obj.ParentID, obj.Filter) if err != nil { panic(fmt.Errorf("cannot count organization data protection impact assessments: %w", err)) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Owner is the resolver for the owner field. func (r *datumResolver) Owner(ctx context.Context, obj *types.Datum) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } owner, err := r.iam.OrganizationService.GetProfile(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } return nil, fmt.Errorf("cannot get owner: %w", err) } return types.NewProfile(owner), nil } // Vendors is the resolver for the vendors field. func (r *datumResolver) Vendors(ctx context.Context, obj *types.Datum, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) (*types.VendorConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.VendorOrderField]{ Field: coredata.VendorOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.VendorOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Data.ListVendors(ctx, obj.ID, cursor) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list data vendors: %w", err)) } return types.NewVendorConnection(page, r, obj.ID), nil } // Organization is the resolver for the organization field. func (r *datumResolver) Organization(ctx context.Context, obj *types.Datum) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) org, err := prb.Organizations.Get(ctx, obj.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(org), nil } // Permission is the resolver for the permission field. func (r *datumResolver) Permission(ctx context.Context, obj *types.Datum, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *datumConnectionResolver) TotalCount(ctx context.Context, obj *types.DatumConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionDatumList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: datumFilter := coredata.NewDatumFilter(nil) if obj.Filter != nil { datumFilter = coredata.NewDatumFilter(&obj.Filter.SnapshotID) } count, err := prb.Data.CountForOrganizationID(ctx, obj.ParentID, datumFilter) if err != nil { panic(fmt.Errorf("cannot count data: %w", err)) } return count, nil } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Owner is the resolver for the owner field. func (r *documentResolver) Owner(ctx context.Context, obj *types.Document) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } owner, err := r.iam.OrganizationService.GetProfile(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get owner: %w", err)) } return types.NewProfile(owner), nil } // Organization is the resolver for the organization field. func (r *documentResolver) Organization(ctx context.Context, obj *types.Document) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // Versions is the resolver for the versions field. func (r *documentResolver) Versions(ctx context.Context, obj *types.Document, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionOrderBy, filter *types.DocumentVersionFilter) (*types.DocumentVersionConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDocumentVersionList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DocumentVersionOrderField]{ Field: coredata.DocumentVersionOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DocumentVersionOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) versionFilter := coredata.NewDocumentVersionFilter() page, err := prb.Documents.ListVersions(ctx, obj.ID, cursor, versionFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list document versions: %w", err)) } return types.NewDocumentVersionConnection(page, r, obj.ID), nil } // Controls is the resolver for the controls field. func (r *documentResolver) Controls(ctx context.Context, obj *types.Document, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ControlOrderField]{ Field: coredata.ControlOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ControlOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var controlFilter = coredata.NewControlFilter(nil) if filter != nil { controlFilter = coredata.NewControlFilter(filter.Query) } page, err := prb.Controls.ListForDocumentID(ctx, obj.ID, cursor, controlFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list document controls: %w", err)) } return types.NewControlConnection(page, r, obj.ID, controlFilter), nil } // Permission is the resolver for the permission field. func (r *documentResolver) Permission(ctx context.Context, obj *types.Document, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *documentConnectionResolver) TotalCount(ctx context.Context, obj *types.DocumentConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionDocumentList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *controlResolver: count, err := prb.Documents.CountForControlID(ctx, obj.ParentID, obj.Filters) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count controls: %w", err)) } return count, nil case *organizationResolver: count, err := prb.Documents.CountForOrganizationID(ctx, obj.ParentID, obj.Filters) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count documents: %w", err)) } return count, nil case *riskResolver: count, err := prb.Documents.CountForRiskID(ctx, obj.ParentID, obj.Filters) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count risks: %w", err)) } return count, nil } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Document is the resolver for the document field. func (r *documentVersionResolver) Document(ctx context.Context, obj *types.DocumentVersion) (*types.Document, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDocumentGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) document, err := prb.Documents.Get(ctx, obj.Document.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get document: %w", err)) } return types.NewDocument(document), nil } // Owner is the resolver for the owner field. func (r *documentVersionResolver) Owner(ctx context.Context, obj *types.DocumentVersion) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } owner, err := r.iam.OrganizationService.GetProfile(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get owner: %w", err)) } return types.NewProfile(owner), nil } // Signatures is the resolver for the signatures field. func (r *documentVersionResolver) Signatures(ctx context.Context, obj *types.DocumentVersion, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionSignatureOrder, filter *types.DocumentVersionSignatureFilter) (*types.DocumentVersionSignatureConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDocumentVersionSignatureList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DocumentVersionSignatureOrderField]{ Field: coredata.DocumentVersionSignatureOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DocumentVersionSignatureOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } var signatureStates []coredata.DocumentVersionSignatureState var activeContract *bool if filter != nil { if filter.States != nil { signatureStates = filter.States } if filter.ActiveContract != nil { activeContract = filter.ActiveContract } } signatureFilter := coredata.NewDocumentVersionSignatureFilter(signatureStates, activeContract) cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Documents.ListSignatures(ctx, obj.ID, cursor, signatureFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list document version signatures: %w", err)) } return types.NewDocumentVersionSignatureConnection(page, r, obj.ID, signatureFilter), nil } // Signed is the resolver for the signed field. func (r *documentVersionResolver) Signed(ctx context.Context, obj *types.DocumentVersion) (bool, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDocumentVersionGet); err != nil { return false, err } identity := authn.IdentityFromContext(ctx) prb := r.ProboService(ctx, obj.ID.TenantID()) signed, err := prb.Documents.IsVersionSignedByUserEmail(ctx, obj.ID, identity.EmailAddress) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot check if document version is signed: %w", err)) } return signed, nil } // Permission is the resolver for the permission field. func (r *documentVersionResolver) Permission(ctx context.Context, obj *types.DocumentVersion, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *documentVersionConnectionResolver) TotalCount(ctx context.Context, obj *types.DocumentVersionConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionDocumentVersionList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *documentResolver: filter := &coredata.DocumentVersionFilter{} if obj.Filters != nil { filter = obj.Filters } count, err := prb.Documents.CountVersionsForDocumentID(ctx, obj.ParentID, filter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count document versions: %w", err)) } return count, nil } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // DocumentVersion is the resolver for the documentVersion field. func (r *documentVersionSignatureResolver) DocumentVersion(ctx context.Context, obj *types.DocumentVersionSignature) (*types.DocumentVersion, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDocumentVersionGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) documentVersion, err := prb.Documents.GetVersion(ctx, obj.DocumentVersion.ID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get document version: %w", err)) } return types.NewDocumentVersion(documentVersion), nil } // SignedBy is the resolver for the signedBy field. func (r *documentVersionSignatureResolver) SignedBy(ctx context.Context, obj *types.DocumentVersionSignature) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } signatory, err := r.iam.OrganizationService.GetProfile(ctx, obj.SignedBy.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get people: %w", err)) } return types.NewProfile(signatory), nil } // Permission is the resolver for the permission field. func (r *documentVersionSignatureResolver) Permission(ctx context.Context, obj *types.DocumentVersionSignature, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *documentVersionSignatureConnectionResolver) TotalCount(ctx context.Context, obj *types.DocumentVersionSignatureConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionDocumentVersionSignatureList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *documentVersionResolver: filter := &coredata.DocumentVersionSignatureFilter{} if obj.Filters != nil { filter = obj.Filters } count, err := prb.Documents.CountSignaturesForVersionID(ctx, obj.ParentID, filter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count signatures: %w", err)) } return count, nil } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // File is the resolver for the file field. func (r *evidenceResolver) File(ctx context.Context, obj *types.Evidence) (*types.File, error) { if err := r.authorize(ctx, obj.ID, probo.ActionFileGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) if obj.File == nil { return nil, nil } file, err := prb.Files.Get(ctx, obj.File.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load evidence file: %w", err)) } return types.NewFile(file), nil } // Task is the resolver for the task field. func (r *evidenceResolver) Task(ctx context.Context, obj *types.Evidence) (*types.Task, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTaskGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) if obj.Task == nil { panic(fmt.Errorf("evidence is not associated with a task")) } task, err := prb.Tasks.Get(ctx, obj.Task.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot load task: %w", err)) } return types.NewTask(task), nil } // Measure is the resolver for the measure field. func (r *evidenceResolver) Measure(ctx context.Context, obj *types.Evidence) (*types.Measure, error) { if err := r.authorize(ctx, obj.ID, probo.ActionMeasureGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) measure, err := prb.Measures.Get(ctx, obj.Measure.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot load measure: %w", err)) } return types.NewMeasure(measure), nil } // Permission is the resolver for the permission field. func (r *evidenceResolver) Permission(ctx context.Context, obj *types.Evidence, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *evidenceConnectionResolver) TotalCount(ctx context.Context, obj *types.EvidenceConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionEvidenceList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *measureResolver: count, err := prb.Evidences.CountForMeasureID(ctx, obj.ParentID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count measure evidence: %w", err)) } return count, nil case *taskResolver: count, err := prb.Evidences.CountForTaskID(ctx, obj.ParentID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count task evidence: %w", err)) } return count, nil } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // DownloadURL is the resolver for the downloadUrl field. func (r *fileResolver) DownloadURL(ctx context.Context, obj *types.File) (string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionFileDownloadUrl); err != nil { return "", err } prb := r.ProboService(ctx, obj.ID.TenantID()) downloadUrl, err := prb.Files.GenerateFileTempURL(ctx, obj.ID, 60*time.Second) if err != nil { // TODO no panic use gqlutils.InternalError return "", fmt.Errorf("cannot generate download url: %w", err) } // TODO no panic use gqlutils.InternalError return downloadUrl, nil } // Organization is the resolver for the organization field. func (r *frameworkResolver) Organization(ctx context.Context, obj *types.Framework) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot load organization: %w", err)) } return types.NewOrganization(organization), 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, filter *types.ControlFilter) (*types.ControlConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ControlOrderField]{ Field: coredata.ControlOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ControlOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var controlFilter = coredata.NewControlFilter(nil) if filter != nil { controlFilter = coredata.NewControlFilter(filter.Query) } page, err := prb.Controls.ListForFrameworkID(ctx, obj.ID, cursor, controlFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list controls: %w", err)) } return types.NewControlConnection(page, r, obj.ID, controlFilter), nil } // LightLogoURL is the resolver for the lightLogoURL field. func (r *frameworkResolver) LightLogoURL(ctx context.Context, obj *types.Framework) (*string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionFrameworkGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) return prb.Frameworks.GenerateLightLogoURL(ctx, obj.ID, 1*time.Hour) } // DarkLogoURL is the resolver for the darkLogoURL field. func (r *frameworkResolver) DarkLogoURL(ctx context.Context, obj *types.Framework) (*string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionFrameworkGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) return prb.Frameworks.GenerateDarkLogoURL(ctx, obj.ID, 1*time.Hour) } // Permission is the resolver for the permission field. func (r *frameworkResolver) Permission(ctx context.Context, obj *types.Framework, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *frameworkConnectionResolver) TotalCount(ctx context.Context, obj *types.FrameworkConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionFrameworkList); err != nil { return 0, err } switch obj.Resolver.(type) { case *organizationResolver: prb := r.ProboService(ctx, obj.ParentID.TenantID()) count, err := prb.Frameworks.CountForOrganizationID(ctx, obj.ParentID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count frameworks: %w", err)) } return count, nil } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Evidences is the resolver for the evidences field. func (r *measureResolver) Evidences(ctx context.Context, obj *types.Measure, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.EvidenceOrderBy) (*types.EvidenceConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionEvidenceList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.EvidenceOrderField]{ Field: coredata.EvidenceOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.EvidenceOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Evidences.ListForMeasureID(ctx, obj.ID, cursor) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list measure evidences: %w", err)) } return types.NewEvidenceConnection(page, r, obj.ID), nil } // Tasks is the resolver for the tasks field. func (r *measureResolver) Tasks(ctx context.Context, obj *types.Measure, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TaskOrderBy) (*types.TaskConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTaskList); err != nil { return nil, err } prb := r.ProboService(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 := prb.Tasks.ListForMeasureID(ctx, obj.ID, cursor) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list measure tasks: %w", err)) } return types.NewTaskConnection(page, r, obj.ID), nil } // Risks is the resolver for the risks field. func (r *measureResolver) Risks(ctx context.Context, obj *types.Measure, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.RiskOrderBy, filter *types.RiskFilter) (*types.RiskConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionRiskList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.RiskOrderField]{ Field: coredata.RiskOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.RiskOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var riskFilter = coredata.NewRiskFilter(nil, nil) if filter != nil { riskFilter = coredata.NewRiskFilter(filter.Query, &filter.SnapshotID) } page, err := prb.Risks.ListForMeasureID(ctx, obj.ID, cursor, riskFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list measure risks: %w", err)) } return types.NewRiskConnection(page, r, obj.ID, riskFilter), nil } // Controls is the resolver for the controls field. func (r *measureResolver) Controls(ctx context.Context, obj *types.Measure, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ControlOrderField]{ Field: coredata.ControlOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ControlOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var controlFilter = coredata.NewControlFilter(nil) if filter != nil { controlFilter = coredata.NewControlFilter(filter.Query) } page, err := prb.Controls.ListForMeasureID(ctx, obj.ID, cursor, controlFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list measure controls: %w", err)) } return types.NewControlConnection(page, r, obj.ID, controlFilter), nil } // Permission is the resolver for the permission field. func (r *measureResolver) Permission(ctx context.Context, obj *types.Measure, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *measureConnectionResolver) TotalCount(ctx context.Context, obj *types.MeasureConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionMeasureList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Measures.CountForOrganizationID(ctx, obj.ParentID, obj.Filters) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count measures: %w", err)) } return count, nil case *controlResolver: count, err := prb.Measures.CountForControlID(ctx, obj.ParentID, obj.Filters) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count measures: %w", err)) } return count, nil case *riskResolver: count, err := prb.Measures.CountForRiskID(ctx, obj.ParentID, obj.Filters) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count measures: %w", err)) } return count, nil } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Attendees is the resolver for the attendees field. func (r *meetingResolver) Attendees(ctx context.Context, obj *types.Meeting) ([]*types.Profile, error) { // TODO bug must be paginated if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) attendees, err := prb.Meetings.GetAttendees(ctx, obj.ID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot load meeting attendees: %w", err)) } if len(attendees) == 0 { return []*types.Profile{}, nil } people := make([]*types.Profile, len(attendees)) for i, attendee := range attendees { people[i] = types.NewProfile(attendee) } return people, nil } // Organization is the resolver for the organization field. func (r *meetingResolver) Organization(ctx context.Context, obj *types.Meeting) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot load organization: %w", err)) } return types.NewOrganization(organization), nil } // Permission is the resolver for the permission field. func (r *meetingResolver) Permission(ctx context.Context, obj *types.Meeting, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *meetingConnectionResolver) TotalCount(ctx context.Context, obj *types.MeetingConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionMeetingList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Meetings.CountForOrganizationID(ctx, obj.ParentID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count meetings: %w", err)) } return count, nil } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // UpdateOrganizationContext is the resolver for the updateOrganizationContext field. func (r *mutationResolver) UpdateOrganizationContext(ctx context.Context, input types.UpdateOrganizationContextInput) (*types.UpdateOrganizationContextPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionOrganizationContextUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) req := probo.UpdateOrganizationContextRequest{ OrganizationID: input.OrganizationID, Summary: gqlutils.UnwrapOmittable(input.Summary), } organizationContext, err := prb.Organizations.UpdateContext(ctx, req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update organization context: %w", err)) } return &types.UpdateOrganizationContextPayload{ Context: types.NewOrganizationContext(organizationContext), }, nil } // UpdateTrustCenter is the resolver for the updateTrustCenter field. func (r *mutationResolver) UpdateTrustCenter(ctx context.Context, input types.UpdateTrustCenterInput) (*types.UpdateTrustCenterPayload, error) { if err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.TrustCenterID.TenantID()) trustCenter, file, err := prb.TrustCenters.Update( ctx, &probo.UpdateTrustCenterRequest{ ID: input.TrustCenterID, Active: input.Active, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update trust center: %w", err)) } return &types.UpdateTrustCenterPayload{ TrustCenter: types.NewTrustCenter(trustCenter, file), }, nil } // UploadTrustCenterNda is the resolver for the uploadTrustCenterNDA field. func (r *mutationResolver) UploadTrustCenterNda(ctx context.Context, input types.UploadTrustCenterNDAInput) (*types.UploadTrustCenterNDAPayload, error) { if err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterNonDisclosureAgreementUpload); err != nil { return nil, err } prb := r.ProboService(ctx, input.TrustCenterID.TenantID()) trustCenter, file, err := prb.TrustCenters.UploadNDA( ctx, &probo.UploadTrustCenterNDARequest{ TrustCenterID: input.TrustCenterID, File: input.File.File, FileName: input.FileName, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot upload trust center NDA: %w", err)) } return &types.UploadTrustCenterNDAPayload{ TrustCenter: types.NewTrustCenter(trustCenter, file), }, nil } // DeleteTrustCenterNda is the resolver for the deleteTrustCenterNDA field. func (r *mutationResolver) DeleteTrustCenterNda(ctx context.Context, input types.DeleteTrustCenterNDAInput) (*types.DeleteTrustCenterNDAPayload, error) { if err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterNonDisclosureAgreementDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.TrustCenterID.TenantID()) trustCenter, file, err := prb.TrustCenters.DeleteNDA(ctx, input.TrustCenterID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete trust center NDA: %w", err)) } return &types.DeleteTrustCenterNDAPayload{ TrustCenter: types.NewTrustCenter(trustCenter, file), }, nil } // UpdateTrustCenterBrand is the resolver for the updateTrustCenterBrand field. func (r *mutationResolver) UpdateTrustCenterBrand(ctx context.Context, input types.UpdateTrustCenterBrandInput) (*types.UpdateTrustCenterBrandPayload, error) { if err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.TrustCenterID.TenantID()) req := &probo.UpdateTrustCenterBrandRequest{ TrustCenterID: input.TrustCenterID, } if input.LogoFile.IsSet() { logoFile := input.LogoFile.Value() if logoFile == nil { var nilFile *probo.FileUpload req.LogoFile = &nilFile } else { fileUpload := &probo.FileUpload{ Content: logoFile.File, Filename: logoFile.Filename, Size: logoFile.Size, ContentType: logoFile.ContentType, } req.LogoFile = &fileUpload } } if input.DarkLogoFile.IsSet() { darkLogoFile := input.DarkLogoFile.Value() if darkLogoFile == nil { var nilFile *probo.FileUpload req.DarkLogoFile = &nilFile } else { fileUpload := &probo.FileUpload{ Content: darkLogoFile.File, Filename: darkLogoFile.Filename, Size: darkLogoFile.Size, ContentType: darkLogoFile.ContentType, } req.DarkLogoFile = &fileUpload } } trustCenter, file, err := prb.TrustCenters.UpdateTrustCenterBrand(ctx, req) if err != nil { r.logger.ErrorCtx(ctx, "cannot update trust center brand", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.UpdateTrustCenterBrandPayload{ TrustCenter: types.NewTrustCenter(trustCenter, file), }, nil } // CreateTrustCenterAccess is the resolver for the createTrustCenterAccess field. func (r *mutationResolver) CreateTrustCenterAccess(ctx context.Context, input types.CreateTrustCenterAccessInput) (*types.CreateTrustCenterAccessPayload, error) { if err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterAccessCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.TrustCenterID.TenantID()) // TODO: should not create an access nor identity, but send a compliance page invitation identity, err := r.iam.AuthService.LoadOrCreateIdentity( ctx, &iam.LoadOrCreateIdentityRequest{ Email: input.Email, FullName: input.Name, }, ) if err != nil { r.logger.ErrorCtx(ctx, "cannot load or create identity", log.Error(err)) return nil, gqlutils.Internal(ctx) } access, err := prb.TrustCenterAccesses.Create( ctx, &probo.CreateTrustCenterAccessRequest{ TrustCenterID: input.TrustCenterID, Email: identity.EmailAddress, FullName: identity.FullName, }, ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } r.logger.ErrorCtx(ctx, "cannot create trust center access", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.CreateTrustCenterAccessPayload{ TrustCenterAccessEdge: types.NewTrustCenterAccessEdge(access, coredata.TrustCenterAccessOrderFieldCreatedAt), }, nil } // UpdateTrustCenterAccess is the resolver for the updateTrustCenterAccess field. func (r *mutationResolver) UpdateTrustCenterAccess(ctx context.Context, input types.UpdateTrustCenterAccessInput) (*types.UpdateTrustCenterAccessPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterAccessUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) var documentAccesses []probo.UpdateTrustCenterDocumentAccessRequest var reportAccesses []probo.UpdateTrustCenterDocumentAccessRequest var fileAccesses []probo.UpdateTrustCenterDocumentAccessRequest for _, documentAccess := range input.Documents { documentAccesses = append(documentAccesses, probo.UpdateTrustCenterDocumentAccessRequest{ ID: documentAccess.ID, Status: documentAccess.Status, }) } for _, reportAccess := range input.Reports { reportAccesses = append(reportAccesses, probo.UpdateTrustCenterDocumentAccessRequest{ ID: reportAccess.ID, Status: reportAccess.Status, }) } for _, fileAccess := range input.TrustCenterFiles { fileAccesses = append(fileAccesses, probo.UpdateTrustCenterDocumentAccessRequest{ ID: fileAccess.ID, Status: fileAccess.Status, }) } access, err := prb.TrustCenterAccesses.Update( ctx, &probo.UpdateTrustCenterAccessRequest{ ID: input.ID, Name: input.Name, State: input.State, DocumentAccesses: documentAccesses, ReportAccesses: reportAccesses, TrustCenterFileAccesses: fileAccesses, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update trust center access: %w", err)) } return &types.UpdateTrustCenterAccessPayload{ TrustCenterAccess: types.NewTrustCenterAccess(access), }, nil } // DeleteTrustCenterAccess is the resolver for the deleteTrustCenterAccess field. func (r *mutationResolver) DeleteTrustCenterAccess(ctx context.Context, input types.DeleteTrustCenterAccessInput) (*types.DeleteTrustCenterAccessPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterAccessDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) err := prb.TrustCenterAccesses.Delete(ctx, input.ID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete trust center access: %w", err)) } return &types.DeleteTrustCenterAccessPayload{ DeletedTrustCenterAccessID: input.ID, }, nil } // CreateTrustCenterReference is the resolver for the createTrustCenterReference field. func (r *mutationResolver) CreateTrustCenterReference(ctx context.Context, input types.CreateTrustCenterReferenceInput) (*types.CreateTrustCenterReferencePayload, error) { if err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterReferenceCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.TrustCenterID.TenantID()) reference, err := prb.TrustCenterReferences.Create( ctx, &probo.CreateTrustCenterReferenceRequest{ TrustCenterID: input.TrustCenterID, Name: input.Name, Description: input.Description, WebsiteURL: input.WebsiteURL, LogoFile: probo.File{ Content: input.LogoFile.File, Filename: input.LogoFile.Filename, Size: input.LogoFile.Size, ContentType: input.LogoFile.ContentType, }, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create trust center reference: %w", err)) } return &types.CreateTrustCenterReferencePayload{ TrustCenterReferenceEdge: types.NewTrustCenterReferenceEdge(reference, coredata.TrustCenterReferenceOrderFieldRank), }, nil } // UpdateTrustCenterReference is the resolver for the updateTrustCenterReference field. func (r *mutationResolver) UpdateTrustCenterReference(ctx context.Context, input types.UpdateTrustCenterReferenceInput) (*types.UpdateTrustCenterReferencePayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterReferenceUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) req := &probo.UpdateTrustCenterReferenceRequest{ ID: input.ID, Name: input.Name, Description: gqlutils.UnwrapOmittable(input.Description), WebsiteURL: input.WebsiteURL, Rank: input.Rank, } if input.LogoFile != nil { req.LogoFile = &probo.File{ Content: input.LogoFile.File, Filename: input.LogoFile.Filename, Size: input.LogoFile.Size, ContentType: input.LogoFile.ContentType, } } reference, err := prb.TrustCenterReferences.Update(ctx, req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update trust center reference: %w", err)) } return &types.UpdateTrustCenterReferencePayload{ TrustCenterReference: types.NewTrustCenterReference(reference), }, nil } // DeleteTrustCenterReference is the resolver for the deleteTrustCenterReference field. func (r *mutationResolver) DeleteTrustCenterReference(ctx context.Context, input types.DeleteTrustCenterReferenceInput) (*types.DeleteTrustCenterReferencePayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterReferenceDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) err := prb.TrustCenterReferences.Delete(ctx, input.ID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete trust center reference: %w", err)) } return &types.DeleteTrustCenterReferencePayload{ DeletedTrustCenterReferenceID: input.ID, }, nil } // CreateTrustCenterFile is the resolver for the createTrustCenterFile field. func (r *mutationResolver) CreateTrustCenterFile(ctx context.Context, input types.CreateTrustCenterFileInput) (*types.CreateTrustCenterFilePayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionTrustCenterFileCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) file, err := prb.TrustCenterFiles.Create( ctx, &probo.CreateTrustCenterFileRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Category: input.Category, File: probo.File{ Content: input.File.File, Filename: input.File.Filename, Size: input.File.Size, ContentType: input.File.ContentType, }, TrustCenterVisibility: input.TrustCenterVisibility, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create trust center file: %w", err)) } return &types.CreateTrustCenterFilePayload{ TrustCenterFileEdge: types.NewTrustCenterFileEdge(file, coredata.TrustCenterFileOrderFieldCreatedAt), }, nil } // UpdateTrustCenterFile is the resolver for the updateTrustCenterFile field. func (r *mutationResolver) UpdateTrustCenterFile(ctx context.Context, input types.UpdateTrustCenterFileInput) (*types.UpdateTrustCenterFilePayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterFileUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) file, err := prb.TrustCenterFiles.Update( ctx, &probo.UpdateTrustCenterFileRequest{ ID: input.ID, Name: input.Name, Category: input.Category, TrustCenterVisibility: input.TrustCenterVisibility, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update trust center file: %w", err)) } return &types.UpdateTrustCenterFilePayload{ TrustCenterFile: types.NewTrustCenterFile(file), }, nil } // GetTrustCenterFile is the resolver for the getTrustCenterFile field. func (r *mutationResolver) GetTrustCenterFile(ctx context.Context, input types.GetTrustCenterFileInput) (*types.GetTrustCenterFilePayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterFileGet); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) file, err := prb.TrustCenterFiles.Get(ctx, input.ID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get trust center file: %w", err)) } return &types.GetTrustCenterFilePayload{ TrustCenterFile: types.NewTrustCenterFile(file), }, nil } // DeleteTrustCenterFile is the resolver for the deleteTrustCenterFile field. func (r *mutationResolver) DeleteTrustCenterFile(ctx context.Context, input types.DeleteTrustCenterFileInput) (*types.DeleteTrustCenterFilePayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterFileDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) err := prb.TrustCenterFiles.Delete(ctx, input.ID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete trust center file: %w", err)) } return &types.DeleteTrustCenterFilePayload{ DeletedTrustCenterFileID: input.ID, }, nil } // CreateVendor is the resolver for the createVendor field. func (r *mutationResolver) CreateVendor(ctx context.Context, input types.CreateVendorInput) (*types.CreateVendorPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionVendorCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) vendor, err := prb.Vendors.Create( ctx, probo.CreateVendorRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Description: input.Description, StatusPageURL: input.StatusPageURL, TermsOfServiceURL: input.TermsOfServiceURL, PrivacyPolicyURL: input.PrivacyPolicyURL, ServiceLevelAgreementURL: input.ServiceLevelAgreementURL, LegalName: input.LegalName, HeadquarterAddress: input.HeadquarterAddress, WebsiteURL: input.WebsiteURL, Category: input.Category, DataProcessingAgreementURL: input.DataProcessingAgreementURL, BusinessAssociateAgreementURL: input.BusinessAssociateAgreementURL, SubprocessorsListURL: input.SubprocessorsListURL, Certifications: input.Certifications, SecurityPageURL: input.SecurityPageURL, TrustPageURL: input.TrustPageURL, BusinessOwnerID: input.BusinessOwnerID, SecurityOwnerID: input.SecurityOwnerID, Countries: input.Countries, }, ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError return nil, fmt.Errorf("cannot create vendor: %w", err) } return &types.CreateVendorPayload{ VendorEdge: types.NewVendorEdge(vendor, coredata.VendorOrderFieldName), }, nil } // UpdateVendor is the resolver for the updateVendor field. func (r *mutationResolver) UpdateVendor(ctx context.Context, input types.UpdateVendorInput) (*types.UpdateVendorPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionVendorUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) vendor, err := prb.Vendors.Update( ctx, probo.UpdateVendorRequest{ ID: input.ID, Name: input.Name, Description: gqlutils.UnwrapOmittable(input.Description), StatusPageURL: gqlutils.UnwrapOmittable(input.StatusPageURL), TermsOfServiceURL: gqlutils.UnwrapOmittable(input.TermsOfServiceURL), PrivacyPolicyURL: gqlutils.UnwrapOmittable(input.PrivacyPolicyURL), ServiceLevelAgreementURL: gqlutils.UnwrapOmittable(input.ServiceLevelAgreementURL), DataProcessingAgreementURL: gqlutils.UnwrapOmittable(input.DataProcessingAgreementURL), BusinessAssociateAgreementURL: gqlutils.UnwrapOmittable(input.BusinessAssociateAgreementURL), SubprocessorsListURL: gqlutils.UnwrapOmittable(input.SubprocessorsListURL), SecurityPageURL: gqlutils.UnwrapOmittable(input.SecurityPageURL), TrustPageURL: gqlutils.UnwrapOmittable(input.TrustPageURL), HeadquarterAddress: gqlutils.UnwrapOmittable(input.HeadquarterAddress), LegalName: gqlutils.UnwrapOmittable(input.LegalName), WebsiteURL: gqlutils.UnwrapOmittable(input.WebsiteURL), Category: input.Category, Certifications: input.Certifications, BusinessOwnerID: gqlutils.UnwrapOmittable(input.BusinessOwnerID), SecurityOwnerID: gqlutils.UnwrapOmittable(input.SecurityOwnerID), ShowOnTrustCenter: input.ShowOnTrustCenter, Countries: input.Countries, }, ) if err != nil { // TODO no panic use gqlutils.InternalError return nil, fmt.Errorf("cannot update vendor: %w", err) } return &types.UpdateVendorPayload{ Vendor: types.NewVendor(vendor), }, nil } // DeleteVendor is the resolver for the deleteVendor field. func (r *mutationResolver) DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (*types.DeleteVendorPayload, error) { if err := r.authorize(ctx, input.VendorID, probo.ActionVendorDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.VendorID.TenantID()) err := prb.Vendors.Delete(ctx, input.VendorID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete vendor: %w", err)) } return &types.DeleteVendorPayload{ DeletedVendorID: input.VendorID, }, nil } // CreateVendorContact is the resolver for the createVendorContact field. func (r *mutationResolver) CreateVendorContact(ctx context.Context, input types.CreateVendorContactInput) (*types.CreateVendorContactPayload, error) { if err := r.authorize(ctx, input.VendorID, probo.ActionVendorContactCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.VendorID.TenantID()) req := probo.CreateVendorContactRequest{ VendorID: input.VendorID, FullName: input.FullName, Email: input.Email, Phone: input.Phone, Role: input.Role, } vendorContact, err := prb.VendorContacts.Create(ctx, req) if err != nil { // TODO no panic use gqlutils.InternalError return nil, fmt.Errorf("cannot create vendor contact: %w", err) } return &types.CreateVendorContactPayload{ VendorContactEdge: types.NewVendorContactEdge(vendorContact, coredata.VendorContactOrderFieldCreatedAt), }, nil } // UpdateVendorContact is the resolver for the updateVendorContact field. func (r *mutationResolver) UpdateVendorContact(ctx context.Context, input types.UpdateVendorContactInput) (*types.UpdateVendorContactPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionVendorContactUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) req := probo.UpdateVendorContactRequest{ ID: input.ID, FullName: gqlutils.UnwrapOmittable(input.FullName), Email: gqlutils.UnwrapOmittable(input.Email), Phone: gqlutils.UnwrapOmittable(input.Phone), Role: gqlutils.UnwrapOmittable(input.Role), } vendorContact, err := prb.VendorContacts.Update(ctx, req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update vendor contact: %w", err)) } return &types.UpdateVendorContactPayload{ VendorContact: types.NewVendorContact(vendorContact), }, nil } // DeleteVendorContact is the resolver for the deleteVendorContact field. func (r *mutationResolver) DeleteVendorContact(ctx context.Context, input types.DeleteVendorContactInput) (*types.DeleteVendorContactPayload, error) { if err := r.authorize(ctx, input.VendorContactID, probo.ActionVendorContactDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.VendorContactID.TenantID()) err := prb.VendorContacts.Delete(ctx, input.VendorContactID) if err != nil { // TODO no panic use gqlutils.InternalError return nil, fmt.Errorf("cannot delete vendor contact: %w", err) } return &types.DeleteVendorContactPayload{ DeletedVendorContactID: input.VendorContactID, }, nil } // CreateVendorService is the resolver for the createVendorService field. func (r *mutationResolver) CreateVendorService(ctx context.Context, input types.CreateVendorServiceInput) (*types.CreateVendorServicePayload, error) { if err := r.authorize(ctx, input.VendorID, probo.ActionVendorServiceCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.VendorID.TenantID()) req := probo.CreateVendorServiceRequest{ VendorID: input.VendorID, Name: input.Name, Description: input.Description, } vendorService, err := prb.VendorServices.Create(ctx, req) if err != nil { // TODO no panic use gqlutils.InternalError return nil, fmt.Errorf("cannot create vendor service: %w", err) } return &types.CreateVendorServicePayload{ VendorServiceEdge: types.NewVendorServiceEdge(vendorService, coredata.VendorServiceOrderFieldCreatedAt), }, nil } // UpdateVendorService is the resolver for the updateVendorService field. func (r *mutationResolver) UpdateVendorService(ctx context.Context, input types.UpdateVendorServiceInput) (*types.UpdateVendorServicePayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionVendorServiceUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) req := probo.UpdateVendorServiceRequest{ ID: input.ID, Name: input.Name, Description: gqlutils.UnwrapOmittable(input.Description), } vendorService, err := prb.VendorServices.Update(ctx, req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update vendor service: %w", err)) } return &types.UpdateVendorServicePayload{ VendorService: types.NewVendorService(vendorService), }, nil } // DeleteVendorService is the resolver for the deleteVendorService field. func (r *mutationResolver) DeleteVendorService(ctx context.Context, input types.DeleteVendorServiceInput) (*types.DeleteVendorServicePayload, error) { if err := r.authorize(ctx, input.VendorServiceID, probo.ActionVendorServiceDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.VendorServiceID.TenantID()) err := prb.VendorServices.Delete(ctx, input.VendorServiceID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete vendor service: %w", err)) } return &types.DeleteVendorServicePayload{ DeletedVendorServiceID: input.VendorServiceID, }, nil } // CreateFramework is the resolver for the createFramework field. func (r *mutationResolver) CreateFramework(ctx context.Context, input types.CreateFrameworkInput) (*types.CreateFrameworkPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionFrameworkCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) framework, err := prb.Frameworks.Create( ctx, probo.CreateFrameworkRequest{ OrganizationID: input.OrganizationID, Name: input.Name, }, ) if err != nil { // TODO no panic use gqlutils.InternalError return nil, fmt.Errorf("cannot create framework: %w", err) } return &types.CreateFrameworkPayload{ FrameworkEdge: types.NewFrameworkEdge(framework, coredata.FrameworkOrderFieldCreatedAt), }, nil } // UpdateFramework is the resolver for the updateFramework field. func (r *mutationResolver) UpdateFramework(ctx context.Context, input types.UpdateFrameworkInput) (*types.UpdateFrameworkPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionFrameworkUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) framework, err := prb.Frameworks.Update( ctx, probo.UpdateFrameworkRequest{ ID: input.ID, Name: input.Name, Description: gqlutils.UnwrapOmittable(input.Description), }, ) if err != nil { // TODO no panic use gqlutils.InternalError return nil, fmt.Errorf("cannot update framework: %w", err) } return &types.UpdateFrameworkPayload{ Framework: types.NewFramework(framework), }, nil } // ImportFramework is the resolver for the importFramework field. func (r *mutationResolver) ImportFramework(ctx context.Context, input types.ImportFrameworkInput) (*types.ImportFrameworkPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionFrameworkImport); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) req := probo.ImportFrameworkRequest{} if err := json.NewDecoder(input.File.File).Decode(&req.Framework); err != nil { panic(fmt.Errorf("cannot decode framework: %w", err)) } framework, err := prb.Frameworks.Import(ctx, input.OrganizationID, req) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot import framework: %w", err)) } return &types.ImportFrameworkPayload{ FrameworkEdge: types.NewFrameworkEdge(framework, coredata.FrameworkOrderFieldCreatedAt), }, nil } // DeleteFramework is the resolver for the deleteFramework field. func (r *mutationResolver) DeleteFramework(ctx context.Context, input types.DeleteFrameworkInput) (*types.DeleteFrameworkPayload, error) { if err := r.authorize(ctx, input.FrameworkID, probo.ActionFrameworkDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.FrameworkID.TenantID()) err := prb.Frameworks.Delete(ctx, input.FrameworkID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete framework: %w", err)) } return &types.DeleteFrameworkPayload{ DeletedFrameworkID: input.FrameworkID, }, nil } // GenerateFrameworkStateOfApplicability is the resolver for the generateFrameworkStateOfApplicability field. func (r *mutationResolver) GenerateFrameworkStateOfApplicability(ctx context.Context, input types.GenerateFrameworkStateOfApplicabilityInput) (*types.GenerateFrameworkStateOfApplicabilityPayload, error) { if err := r.authorize(ctx, input.FrameworkID, probo.ActionFrameworkStateOfApplicabilityGenerate); err != nil { return nil, err } prb := r.ProboService(ctx, input.FrameworkID.TenantID()) soa, err := prb.Frameworks.StateOfApplicability(ctx, input.FrameworkID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot generate framework SOA: %w", err)) } return &types.GenerateFrameworkStateOfApplicabilityPayload{ Data: fmt.Sprintf( "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,%s", base64.StdEncoding.EncodeToString(soa), ), }, nil } // ExportFramework is the resolver for the exportFramework field. func (r *mutationResolver) ExportFramework(ctx context.Context, input types.ExportFrameworkInput) (*types.ExportFrameworkPayload, error) { if err := r.authorize(ctx, input.FrameworkID, probo.ActionFrameworkExport); err != nil { return nil, err } prb := r.ProboService(ctx, input.FrameworkID.TenantID()) identity := authn.IdentityFromContext(ctx) exportJob, exportErr := prb.Frameworks.RequestExport( ctx, input.FrameworkID, identity.EmailAddress, identity.FullName, ) if exportErr != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot export framework: %w", exportErr)) } return &types.ExportFrameworkPayload{ ExportJobID: exportJob.ID, }, nil } // CreateControl is the resolver for the createControl field. func (r *mutationResolver) CreateControl(ctx context.Context, input types.CreateControlInput) (*types.CreateControlPayload, error) { if err := r.authorize(ctx, input.FrameworkID, probo.ActionControlCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.FrameworkID.TenantID()) control, err := prb.Controls.Create( ctx, probo.CreateControlRequest{ FrameworkID: input.FrameworkID, Name: input.Name, Description: input.Description, SectionTitle: input.SectionTitle, Status: &input.Status, ExclusionJustification: input.ExclusionJustification, BestPractice: input.BestPractice, }, ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create control: %w", err)) } return &types.CreateControlPayload{ ControlEdge: types.NewControlEdge(control, coredata.ControlOrderFieldCreatedAt), }, nil } // UpdateControl is the resolver for the updateControl field. func (r *mutationResolver) UpdateControl(ctx context.Context, input types.UpdateControlInput) (*types.UpdateControlPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionControlUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) control, err := prb.Controls.Update( ctx, probo.UpdateControlRequest{ ID: input.ID, Name: input.Name, Description: gqlutils.UnwrapOmittable(input.Description), SectionTitle: input.SectionTitle, Status: input.Status, ExclusionJustification: input.ExclusionJustification, BestPractice: input.BestPractice, }, ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update control: %w", err)) } return &types.UpdateControlPayload{ Control: types.NewControl(control), }, nil } // DeleteControl is the resolver for the deleteControl field. func (r *mutationResolver) DeleteControl(ctx context.Context, input types.DeleteControlInput) (*types.DeleteControlPayload, error) { if err := r.authorize(ctx, input.ControlID, probo.ActionControlDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.ControlID.TenantID()) err := prb.Controls.Delete(ctx, input.ControlID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete control: %w", err)) } return &types.DeleteControlPayload{ DeletedControlID: input.ControlID, }, nil } // // CreateMeasure is the resolver for the createMeasure field. func (r *mutationResolver) CreateMeasure(ctx context.Context, input types.CreateMeasureInput) (*types.CreateMeasurePayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionMeasureCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) measure, err := prb.Measures.Create( ctx, probo.CreateMeasureRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Description: input.Description, Category: input.Category, }, ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } panic(fmt.Errorf("cannot create measure: %w", err)) } return &types.CreateMeasurePayload{ MeasureEdge: types.NewMeasureEdge(measure, coredata.MeasureOrderFieldCreatedAt), }, nil } // UpdateMeasure is the resolver for the updateMeasure field. func (r *mutationResolver) UpdateMeasure(ctx context.Context, input types.UpdateMeasureInput) (*types.UpdateMeasurePayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionMeasureUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) measure, err := prb.Measures.Update( ctx, probo.UpdateMeasureRequest{ ID: input.ID, Name: input.Name, Description: gqlutils.UnwrapOmittable(input.Description), Category: input.Category, State: input.State, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update measure: %w", err)) } return &types.UpdateMeasurePayload{ Measure: types.NewMeasure(measure), }, nil } // ImportMeasure is the resolver for the importMeasure field. func (r *mutationResolver) ImportMeasure(ctx context.Context, input types.ImportMeasureInput) (*types.ImportMeasurePayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionMeasureImport); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) var req probo.ImportMeasureRequest if err := json.NewDecoder(input.File.File).Decode(&req.Measures); err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot unmarshal measure: %w", err)) } measures, err := prb.Measures.Import(ctx, input.OrganizationID, req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot import measure: %w", err)) } measureEdges := make([]*types.MeasureEdge, len(measures.Data)) for i, measure := range measures.Data { measureEdges[i] = types.NewMeasureEdge(measure, coredata.MeasureOrderFieldCreatedAt) } return &types.ImportMeasurePayload{ MeasureEdges: measureEdges, }, nil } // DeleteMeasure is the resolver for the deleteMeasure field. func (r *mutationResolver) DeleteMeasure(ctx context.Context, input types.DeleteMeasureInput) (*types.DeleteMeasurePayload, error) { if err := r.authorize(ctx, input.MeasureID, probo.ActionMeasureDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.MeasureID.TenantID()) err := prb.Measures.Delete(ctx, input.MeasureID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete measure: %w", err)) } return &types.DeleteMeasurePayload{ DeletedMeasureID: input.MeasureID, }, nil } // CreateControlMeasureMapping is the resolver for the createControlMeasureMapping field. func (r *mutationResolver) CreateControlMeasureMapping(ctx context.Context, input types.CreateControlMeasureMappingInput) (*types.CreateControlMeasureMappingPayload, error) { if err := r.authorize(ctx, input.ControlID, probo.ActionControlMeasureMappingCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.MeasureID.TenantID()) control, measure, err := prb.Controls.CreateMeasureMapping(ctx, input.ControlID, input.MeasureID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create control measure mapping: %w", err)) } return &types.CreateControlMeasureMappingPayload{ ControlEdge: types.NewControlEdge(control, coredata.ControlOrderFieldCreatedAt), MeasureEdge: types.NewMeasureEdge(measure, coredata.MeasureOrderFieldCreatedAt), }, nil } // CreateControlDocumentMapping is the resolver for the createControlDocumentMapping field. func (r *mutationResolver) CreateControlDocumentMapping(ctx context.Context, input types.CreateControlDocumentMappingInput) (*types.CreateControlDocumentMappingPayload, error) { if err := r.authorize(ctx, input.ControlID, probo.ActionControlDocumentMappingCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.DocumentID.TenantID()) control, document, err := prb.Controls.CreateDocumentMapping(ctx, input.ControlID, input.DocumentID) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create control document mapping: %w", err)) } return &types.CreateControlDocumentMappingPayload{ ControlEdge: types.NewControlEdge(control, coredata.ControlOrderFieldCreatedAt), DocumentEdge: types.NewDocumentEdge(document, coredata.DocumentOrderFieldTitle), }, nil } // DeleteControlMeasureMapping is the resolver for the deleteControlMeasureMapping field. func (r *mutationResolver) DeleteControlMeasureMapping(ctx context.Context, input types.DeleteControlMeasureMappingInput) (*types.DeleteControlMeasureMappingPayload, error) { if err := r.authorize(ctx, input.ControlID, probo.ActionControlMeasureMappingDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.MeasureID.TenantID()) control, measure, err := prb.Controls.DeleteMeasureMapping(ctx, input.ControlID, input.MeasureID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete control measure mapping: %w", err)) } return &types.DeleteControlMeasureMappingPayload{ DeletedControlID: control.ID, DeletedMeasureID: measure.ID, }, nil } // DeleteControlDocumentMapping is the resolver for the deleteControlDocumentMapping field. func (r *mutationResolver) DeleteControlDocumentMapping(ctx context.Context, input types.DeleteControlDocumentMappingInput) (*types.DeleteControlDocumentMappingPayload, error) { if err := r.authorize(ctx, input.ControlID, probo.ActionControlDocumentMappingDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.DocumentID.TenantID()) control, document, err := prb.Controls.DeleteDocumentMapping(ctx, input.ControlID, input.DocumentID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete control document mapping: %w", err)) } return &types.DeleteControlDocumentMappingPayload{ DeletedControlID: control.ID, DeletedDocumentID: document.ID, }, nil } // CreateApplicabilityStatement is the resolver for the createApplicabilityStatement field. func (r *mutationResolver) CreateApplicabilityStatement(ctx context.Context, input types.CreateApplicabilityStatementInput) (*types.CreateApplicabilityStatementPayload, error) { if err := r.authorize(ctx, input.ControlID, probo.ActionApplicabilityStatementCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.StateOfApplicabilityID.TenantID()) applicabilityStatement, err := prb.StatesOfApplicability.CreateApplicabilityStatement(ctx, input.StateOfApplicabilityID, input.ControlID, input.Applicability, input.Justification) if err != nil { panic(fmt.Errorf("cannot create applicability statement: %w", err)) } return &types.CreateApplicabilityStatementPayload{ ApplicabilityStatementEdge: types.NewApplicabilityStatementEdge(applicabilityStatement, coredata.ApplicabilityStatementOrderFieldCreatedAt), }, nil } // UpdateApplicabilityStatement is the resolver for the updateApplicabilityStatement field. func (r *mutationResolver) UpdateApplicabilityStatement(ctx context.Context, input types.UpdateApplicabilityStatementInput) (*types.UpdateApplicabilityStatementPayload, error) { if err := r.authorize(ctx, input.ApplicabilityStatementID, probo.ActionApplicabilityStatementUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ApplicabilityStatementID.TenantID()) applicabilityStatement, err := prb.StatesOfApplicability.UpdateApplicabilityStatement(ctx, input.ApplicabilityStatementID, input.Applicability, input.Justification) if err != nil { panic(fmt.Errorf("cannot update applicability statement: %w", err)) } return &types.UpdateApplicabilityStatementPayload{ ApplicabilityStatement: types.NewApplicabilityStatement(applicabilityStatement), }, nil } // DeleteApplicabilityStatement is the resolver for the deleteApplicabilityStatement field. func (r *mutationResolver) DeleteApplicabilityStatement(ctx context.Context, input types.DeleteApplicabilityStatementInput) (*types.DeleteApplicabilityStatementPayload, error) { if err := r.authorize(ctx, input.ApplicabilityStatementID, probo.ActionApplicabilityStatementDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.ApplicabilityStatementID.TenantID()) err := prb.StatesOfApplicability.DeleteApplicabilityStatement(ctx, input.ApplicabilityStatementID) if err != nil { panic(fmt.Errorf("cannot delete applicability statement: %w", err)) } return &types.DeleteApplicabilityStatementPayload{ DeletedApplicabilityStatementID: input.ApplicabilityStatementID, }, nil } // CreateControlAuditMapping is the resolver for the createControlAuditMapping field. func (r *mutationResolver) CreateControlAuditMapping(ctx context.Context, input types.CreateControlAuditMappingInput) (*types.CreateControlAuditMappingPayload, error) { if err := r.authorize(ctx, input.ControlID, probo.ActionControlAuditMappingCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.AuditID.TenantID()) control, audit, err := prb.Controls.CreateAuditMapping(ctx, input.ControlID, input.AuditID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create control audit mapping: %w", err)) } return &types.CreateControlAuditMappingPayload{ ControlEdge: types.NewControlEdge(control, coredata.ControlOrderFieldCreatedAt), AuditEdge: types.NewAuditEdge(audit, coredata.AuditOrderFieldCreatedAt), }, nil } // DeleteControlAuditMapping is the resolver for the deleteControlAuditMapping field. func (r *mutationResolver) DeleteControlAuditMapping(ctx context.Context, input types.DeleteControlAuditMappingInput) (*types.DeleteControlAuditMappingPayload, error) { if err := r.authorize(ctx, input.ControlID, probo.ActionControlAuditMappingDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.AuditID.TenantID()) control, audit, err := prb.Controls.DeleteAuditMapping(ctx, input.ControlID, input.AuditID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete control audit mapping: %w", err)) } return &types.DeleteControlAuditMappingPayload{ DeletedControlID: control.ID, DeletedAuditID: audit.ID, }, nil } // CreateControlObligationMapping is the resolver for the createControlObligationMapping field. func (r *mutationResolver) CreateControlObligationMapping(ctx context.Context, input types.CreateControlObligationMappingInput) (*types.CreateControlObligationMappingPayload, error) { if err := r.authorize(ctx, input.ControlID, probo.ActionControlObligationMappingCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ObligationID.TenantID()) control, obligation, err := prb.Controls.CreateObligationMapping(ctx, input.ControlID, input.ObligationID) if err != nil { panic(fmt.Errorf("cannot create control obligation mapping: %w", err)) } return &types.CreateControlObligationMappingPayload{ ControlEdge: types.NewControlEdge(control, coredata.ControlOrderFieldCreatedAt), ObligationEdge: types.NewObligationEdge(obligation, coredata.ObligationOrderFieldCreatedAt), }, nil } // DeleteControlObligationMapping is the resolver for the deleteControlObligationMapping field. func (r *mutationResolver) DeleteControlObligationMapping(ctx context.Context, input types.DeleteControlObligationMappingInput) (*types.DeleteControlObligationMappingPayload, error) { if err := r.authorize(ctx, input.ControlID, probo.ActionControlObligationMappingDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.ObligationID.TenantID()) control, obligation, err := prb.Controls.DeleteObligationMapping(ctx, input.ControlID, input.ObligationID) if err != nil { panic(fmt.Errorf("cannot delete control obligation mapping: %w", err)) } return &types.DeleteControlObligationMappingPayload{ DeletedControlID: control.ID, DeletedObligationID: obligation.ID, }, nil } // CreateControlSnapshotMapping is the resolver for the createControlSnapshotMapping field. func (r *mutationResolver) CreateControlSnapshotMapping(ctx context.Context, input types.CreateControlSnapshotMappingInput) (*types.CreateControlSnapshotMappingPayload, error) { if err := r.authorize(ctx, input.ControlID, probo.ActionControlSnapshotMappingCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.SnapshotID.TenantID()) control, snapshot, err := prb.Controls.CreateSnapshotMapping(ctx, input.ControlID, input.SnapshotID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create control snapshot mapping: %w", err)) } return &types.CreateControlSnapshotMappingPayload{ ControlEdge: types.NewControlEdge(control, coredata.ControlOrderFieldCreatedAt), SnapshotEdge: types.NewSnapshotEdge(snapshot, coredata.SnapshotOrderFieldCreatedAt), }, nil } // DeleteControlSnapshotMapping is the resolver for the deleteControlSnapshotMapping field. func (r *mutationResolver) DeleteControlSnapshotMapping(ctx context.Context, input types.DeleteControlSnapshotMappingInput) (*types.DeleteControlSnapshotMappingPayload, error) { if err := r.authorize(ctx, input.ControlID, probo.ActionControlSnapshotMappingDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.SnapshotID.TenantID()) control, snapshot, err := prb.Controls.DeleteSnapshotMapping(ctx, input.ControlID, input.SnapshotID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete control snapshot mapping: %w", err)) } return &types.DeleteControlSnapshotMappingPayload{ DeletedControlID: control.ID, DeletedSnapshotID: snapshot.ID, }, nil } // CreateTask is the resolver for the createTask field. func (r *mutationResolver) CreateTask(ctx context.Context, input types.CreateTaskInput) (*types.CreateTaskPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionTaskCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) task, err := prb.Tasks.Create( ctx, probo.CreateTaskRequest{ MeasureID: input.MeasureID, OrganizationID: input.OrganizationID, Name: input.Name, Description: input.Description, TimeEstimate: input.TimeEstimate, AssignedToID: input.AssignedToID, Deadline: input.Deadline, }, ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create task: %w", err)) } return &types.CreateTaskPayload{ TaskEdge: types.NewTaskEdge(task, coredata.TaskOrderFieldCreatedAt), }, nil } // UpdateTask is the resolver for the updateTask field. func (r *mutationResolver) UpdateTask(ctx context.Context, input types.UpdateTaskInput) (*types.UpdateTaskPayload, error) { if err := r.authorize(ctx, input.TaskID, probo.ActionTaskUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.TaskID.TenantID()) task, err := prb.Tasks.Update( ctx, probo.UpdateTaskRequest{ TaskID: input.TaskID, Name: input.Name, Description: gqlutils.UnwrapOmittable(input.Description), State: input.State, TimeEstimate: gqlutils.UnwrapOmittable(input.TimeEstimate), Deadline: gqlutils.UnwrapOmittable(input.Deadline), AssignedToID: gqlutils.UnwrapOmittable(input.AssignedToID), MeasureID: gqlutils.UnwrapOmittable(input.MeasureID), }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update task: %w", err)) } return &types.UpdateTaskPayload{ Task: types.NewTask(task), }, nil } // DeleteTask is the resolver for the deleteTask field. func (r *mutationResolver) DeleteTask(ctx context.Context, input types.DeleteTaskInput) (*types.DeleteTaskPayload, error) { if err := r.authorize(ctx, input.TaskID, probo.ActionTaskDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.TaskID.TenantID()) err := prb.Tasks.Delete(ctx, input.TaskID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete task: %w", err)) } return &types.DeleteTaskPayload{ DeletedTaskID: input.TaskID, }, nil } // CreateRisk is the resolver for the createRisk field. func (r *mutationResolver) CreateRisk(ctx context.Context, input types.CreateRiskInput) (*types.CreateRiskPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionRiskCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) risk, err := prb.Risks.Create( ctx, probo.CreateRiskRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Description: input.Description, Category: input.Category, Treatment: input.Treatment, OwnerID: input.OwnerID, InherentLikelihood: input.InherentLikelihood, InherentImpact: input.InherentImpact, ResidualLikelihood: input.ResidualLikelihood, ResidualImpact: input.ResidualImpact, Note: input.Note, }, ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create risk: %w", err)) } return &types.CreateRiskPayload{ RiskEdge: types.NewRiskEdge(risk, coredata.RiskOrderFieldCreatedAt), }, nil } // UpdateRisk is the resolver for the updateRisk field. func (r *mutationResolver) UpdateRisk(ctx context.Context, input types.UpdateRiskInput) (*types.UpdateRiskPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionRiskUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) risk, err := prb.Risks.Update( ctx, probo.UpdateRiskRequest{ ID: input.ID, Name: input.Name, Description: gqlutils.UnwrapOmittable(input.Description), Category: input.Category, Treatment: input.Treatment, OwnerID: gqlutils.UnwrapOmittable(input.OwnerID), InherentLikelihood: input.InherentLikelihood, InherentImpact: input.InherentImpact, ResidualLikelihood: input.ResidualLikelihood, ResidualImpact: input.ResidualImpact, Note: input.Note, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update risk: %w", err)) } return &types.UpdateRiskPayload{ Risk: types.NewRisk(risk), }, nil } // DeleteRisk is the resolver for the deleteRisk field. func (r *mutationResolver) DeleteRisk(ctx context.Context, input types.DeleteRiskInput) (*types.DeleteRiskPayload, error) { if err := r.authorize(ctx, input.RiskID, probo.ActionRiskDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.RiskID.TenantID()) err := prb.Risks.Delete(ctx, input.RiskID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete risk: %w", err)) } return &types.DeleteRiskPayload{ DeletedRiskID: input.RiskID, }, nil } // CreateRiskMeasureMapping is the resolver for the createRiskMeasureMapping field. func (r *mutationResolver) CreateRiskMeasureMapping(ctx context.Context, input types.CreateRiskMeasureMappingInput) (*types.CreateRiskMeasureMappingPayload, error) { if err := r.authorize(ctx, input.RiskID, probo.ActionRiskMeasureMappingCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.RiskID.TenantID()) risk, measure, err := prb.Risks.CreateMeasureMapping(ctx, input.RiskID, input.MeasureID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create risk measure mapping: %w", err)) } return &types.CreateRiskMeasureMappingPayload{ RiskEdge: types.NewRiskEdge(risk, coredata.RiskOrderFieldCreatedAt), MeasureEdge: types.NewMeasureEdge(measure, coredata.MeasureOrderFieldCreatedAt), }, nil } // DeleteRiskMeasureMapping is the resolver for the deleteRiskMeasureMapping field. func (r *mutationResolver) DeleteRiskMeasureMapping(ctx context.Context, input types.DeleteRiskMeasureMappingInput) (*types.DeleteRiskMeasureMappingPayload, error) { if err := r.authorize(ctx, input.RiskID, probo.ActionRiskMeasureMappingDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.RiskID.TenantID()) risk, measure, err := prb.Risks.DeleteMeasureMapping(ctx, input.RiskID, input.MeasureID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete risk measure mapping: %w", err)) } return &types.DeleteRiskMeasureMappingPayload{ DeletedRiskID: risk.ID, DeletedMeasureID: measure.ID, }, nil } // CreateRiskDocumentMapping is the resolver for the createRiskDocumentMapping field. func (r *mutationResolver) CreateRiskDocumentMapping(ctx context.Context, input types.CreateRiskDocumentMappingInput) (*types.CreateRiskDocumentMappingPayload, error) { if err := r.authorize(ctx, input.RiskID, probo.ActionRiskDocumentMappingCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.RiskID.TenantID()) risk, document, err := prb.Risks.CreateDocumentMapping(ctx, input.RiskID, input.DocumentID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create risk document mapping: %w", err)) } return &types.CreateRiskDocumentMappingPayload{ RiskEdge: types.NewRiskEdge(risk, coredata.RiskOrderFieldCreatedAt), DocumentEdge: types.NewDocumentEdge(document, coredata.DocumentOrderFieldTitle), }, nil } // DeleteRiskDocumentMapping is the resolver for the deleteRiskDocumentMapping field. func (r *mutationResolver) DeleteRiskDocumentMapping(ctx context.Context, input types.DeleteRiskDocumentMappingInput) (*types.DeleteRiskDocumentMappingPayload, error) { if err := r.authorize(ctx, input.RiskID, probo.ActionRiskDocumentMappingDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.RiskID.TenantID()) risk, document, err := prb.Risks.DeleteDocumentMapping(ctx, input.RiskID, input.DocumentID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete risk document mapping: %w", err)) } return &types.DeleteRiskDocumentMappingPayload{ DeletedRiskID: risk.ID, DeletedDocumentID: document.ID, }, nil } // CreateRiskObligationMapping is the resolver for the createRiskObligationMapping field. func (r *mutationResolver) CreateRiskObligationMapping(ctx context.Context, input types.CreateRiskObligationMappingInput) (*types.CreateRiskObligationMappingPayload, error) { if err := r.authorize(ctx, input.RiskID, probo.ActionRiskObligationMappingCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.RiskID.TenantID()) risk, obligation, err := prb.Risks.CreateObligationMapping(ctx, input.RiskID, input.ObligationID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create risk obligation mapping: %w", err)) } return &types.CreateRiskObligationMappingPayload{ RiskEdge: types.NewRiskEdge(risk, coredata.RiskOrderFieldCreatedAt), ObligationEdge: types.NewObligationEdge(obligation, coredata.ObligationOrderFieldCreatedAt), }, nil } // DeleteRiskObligationMapping is the resolver for the deleteRiskObligationMapping field. func (r *mutationResolver) DeleteRiskObligationMapping(ctx context.Context, input types.DeleteRiskObligationMappingInput) (*types.DeleteRiskObligationMappingPayload, error) { if err := r.authorize(ctx, input.RiskID, probo.ActionRiskObligationMappingDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.RiskID.TenantID()) risk, obligation, err := prb.Risks.DeleteObligationMapping(ctx, input.RiskID, input.ObligationID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete risk obligation mapping: %w", err)) } return &types.DeleteRiskObligationMappingPayload{ DeletedRiskID: risk.ID, DeletedObligationID: obligation.ID, }, nil } // DeleteEvidence is the resolver for the deleteEvidence field. func (r *mutationResolver) DeleteEvidence(ctx context.Context, input types.DeleteEvidenceInput) (*types.DeleteEvidencePayload, error) { if err := r.authorize(ctx, input.EvidenceID, probo.ActionEvidenceDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.EvidenceID.TenantID()) err := prb.Evidences.Delete(ctx, input.EvidenceID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete evidence: %w", err)) } return &types.DeleteEvidencePayload{ DeletedEvidenceID: input.EvidenceID, }, nil } // UploadMeasureEvidence is the resolver for the uploadMeasureEvidence field. func (r *mutationResolver) UploadMeasureEvidence(ctx context.Context, input types.UploadMeasureEvidenceInput) (*types.UploadMeasureEvidencePayload, error) { if err := r.authorize(ctx, input.MeasureID, probo.ActionMeasureEvidenceUpload); err != nil { return nil, err } prb := r.ProboService(ctx, input.MeasureID.TenantID()) evidence, err := prb.Evidences.UploadMeasureEvidence( ctx, probo.UploadMeasureEvidenceRequest{ MeasureID: input.MeasureID, File: probo.FileUpload{ Content: input.File.File, Filename: input.File.Filename, Size: input.File.Size, ContentType: input.File.ContentType, }, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot upload measure evidence: %w", err)) } return &types.UploadMeasureEvidencePayload{ EvidenceEdge: types.NewEvidenceEdge(evidence, coredata.EvidenceOrderFieldCreatedAt), }, nil } // UploadVendorComplianceReport is the resolver for the uploadVendorComplianceReport field. func (r *mutationResolver) UploadVendorComplianceReport(ctx context.Context, input types.UploadVendorComplianceReportInput) (*types.UploadVendorComplianceReportPayload, error) { if err := r.authorize(ctx, input.VendorID, probo.ActionVendorComplianceReportUpload); err != nil { return nil, err } prb := r.ProboService(ctx, input.VendorID.TenantID()) vendorComplianceReport, err := prb.VendorComplianceReports.Upload( ctx, input.VendorID, &probo.VendorComplianceReportCreateRequest{ File: probo.FileUpload{Filename: input.File.Filename, Size: input.File.Size, Content: input.File.File, ContentType: input.File.ContentType}, ReportDate: input.ReportDate, ValidUntil: input.ValidUntil, ReportName: input.ReportName, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot upload vendor compliance report: %w", err)) } return &types.UploadVendorComplianceReportPayload{ VendorComplianceReportEdge: types.NewVendorComplianceReportEdge(vendorComplianceReport, coredata.VendorComplianceReportOrderFieldCreatedAt), }, nil } // DeleteVendorComplianceReport is the resolver for the deleteVendorComplianceReport field. func (r *mutationResolver) DeleteVendorComplianceReport(ctx context.Context, input types.DeleteVendorComplianceReportInput) (*types.DeleteVendorComplianceReportPayload, error) { if err := r.authorize(ctx, input.ReportID, probo.ActionVendorComplianceReportDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.ReportID.TenantID()) err := prb.VendorComplianceReports.Delete(ctx, input.ReportID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete vendor compliance report: %w", err)) } return &types.DeleteVendorComplianceReportPayload{ DeletedVendorComplianceReportID: input.ReportID, }, nil } // UploadVendorBusinessAssociateAgreement is the resolver for the uploadVendorBusinessAssociateAgreement field. func (r *mutationResolver) UploadVendorBusinessAssociateAgreement(ctx context.Context, input types.UploadVendorBusinessAssociateAgreementInput) (*types.UploadVendorBusinessAssociateAgreementPayload, error) { if err := r.authorize(ctx, input.VendorID, probo.ActionVendorBusinessAssociateAgreementUpload); err != nil { return nil, err } prb := r.ProboService(ctx, input.VendorID.TenantID()) vendorBusinessAssociateAgreement, file, err := prb.VendorBusinessAssociateAgreements.Upload( ctx, input.VendorID, &probo.VendorBusinessAssociateAgreementCreateRequest{ File: input.File.File, ValidFrom: input.ValidFrom, ValidUntil: input.ValidUntil, FileName: input.FileName, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot upload vendor business associate agreement: %w", err)) } return &types.UploadVendorBusinessAssociateAgreementPayload{ VendorBusinessAssociateAgreement: types.NewVendorBusinessAssociateAgreement(vendorBusinessAssociateAgreement, file), }, nil } // UpdateVendorBusinessAssociateAgreement is the resolver for the updateVendorBusinessAssociateAgreement field. func (r *mutationResolver) UpdateVendorBusinessAssociateAgreement(ctx context.Context, input types.UpdateVendorBusinessAssociateAgreementInput) (*types.UpdateVendorBusinessAssociateAgreementPayload, error) { if err := r.authorize(ctx, input.VendorID, probo.ActionVendorBusinessAssociateAgreementUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.VendorID.TenantID()) vendorBusinessAssociateAgreement, file, err := prb.VendorBusinessAssociateAgreements.Update( ctx, input.VendorID, &probo.VendorBusinessAssociateAgreementUpdateRequest{ ValidFrom: gqlutils.UnwrapOmittable(input.ValidFrom), ValidUntil: gqlutils.UnwrapOmittable(input.ValidUntil), }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update vendor business associate agreement: %w", err)) } return &types.UpdateVendorBusinessAssociateAgreementPayload{ VendorBusinessAssociateAgreement: types.NewVendorBusinessAssociateAgreement(vendorBusinessAssociateAgreement, file), }, nil } // DeleteVendorBusinessAssociateAgreement is the resolver for the deleteVendorBusinessAssociateAgreement field. func (r *mutationResolver) DeleteVendorBusinessAssociateAgreement(ctx context.Context, input types.DeleteVendorBusinessAssociateAgreementInput) (*types.DeleteVendorBusinessAssociateAgreementPayload, error) { if err := r.authorize(ctx, input.VendorID, probo.ActionVendorBusinessAssociateAgreementDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.VendorID.TenantID()) err := prb.VendorBusinessAssociateAgreements.DeleteByVendorID(ctx, input.VendorID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete vendor business associate agreement: %w", err)) } return &types.DeleteVendorBusinessAssociateAgreementPayload{ DeletedVendorID: input.VendorID, }, nil } // UploadVendorDataPrivacyAgreement is the resolver for the uploadVendorDataPrivacyAgreement field. func (r *mutationResolver) UploadVendorDataPrivacyAgreement(ctx context.Context, input types.UploadVendorDataPrivacyAgreementInput) (*types.UploadVendorDataPrivacyAgreementPayload, error) { if err := r.authorize(ctx, input.VendorID, probo.ActionVendorDataPrivacyAgreementUpload); err != nil { return nil, err } prb := r.ProboService(ctx, input.VendorID.TenantID()) vendorDataPrivacyAgreement, file, err := prb.VendorDataPrivacyAgreements.Upload( ctx, input.VendorID, &probo.VendorDataPrivacyAgreementCreateRequest{ File: input.File.File, ValidFrom: input.ValidFrom, ValidUntil: input.ValidUntil, FileName: input.FileName, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot upload vendor data privacy agreement: %w", err)) } return &types.UploadVendorDataPrivacyAgreementPayload{ VendorDataPrivacyAgreement: types.NewVendorDataPrivacyAgreement(vendorDataPrivacyAgreement, file), }, nil } // UpdateVendorDataPrivacyAgreement is the resolver for the updateVendorDataPrivacyAgreement field. func (r *mutationResolver) UpdateVendorDataPrivacyAgreement(ctx context.Context, input types.UpdateVendorDataPrivacyAgreementInput) (*types.UpdateVendorDataPrivacyAgreementPayload, error) { if err := r.authorize(ctx, input.VendorID, probo.ActionVendorDataPrivacyAgreementUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.VendorID.TenantID()) vendorDataPrivacyAgreement, file, err := prb.VendorDataPrivacyAgreements.Update( ctx, input.VendorID, &probo.VendorDataPrivacyAgreementUpdateRequest{ ValidFrom: gqlutils.UnwrapOmittable(input.ValidFrom), ValidUntil: gqlutils.UnwrapOmittable(input.ValidUntil), }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update vendor data privacy agreement: %w", err)) } return &types.UpdateVendorDataPrivacyAgreementPayload{ VendorDataPrivacyAgreement: types.NewVendorDataPrivacyAgreement(vendorDataPrivacyAgreement, file), }, nil } // DeleteVendorDataPrivacyAgreement is the resolver for the deleteVendorDataPrivacyAgreement field. func (r *mutationResolver) DeleteVendorDataPrivacyAgreement(ctx context.Context, input types.DeleteVendorDataPrivacyAgreementInput) (*types.DeleteVendorDataPrivacyAgreementPayload, error) { if err := r.authorize(ctx, input.VendorID, probo.ActionVendorDataPrivacyAgreementDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.VendorID.TenantID()) err := prb.VendorDataPrivacyAgreements.DeleteByVendorID(ctx, input.VendorID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete vendor data privacy agreement: %w", err)) } return &types.DeleteVendorDataPrivacyAgreementPayload{ DeletedVendorID: input.VendorID, }, nil } // CreateDocument is the resolver for the createDocument field. func (r *mutationResolver) CreateDocument(ctx context.Context, input types.CreateDocumentInput) (*types.CreateDocumentPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionDocumentCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) document, documentVersion, err := prb.Documents.Create( ctx, probo.CreateDocumentRequest{ OrganizationID: input.OrganizationID, DocumentType: input.DocumentType, Title: input.Title, OwnerID: input.OwnerID, Content: input.Content, Classification: input.Classification, TrustCenterVisibility: input.TrustCenterVisibility, }, ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create document: %w", err)) } return &types.CreateDocumentPayload{ DocumentEdge: types.NewDocumentEdge(document, coredata.DocumentOrderFieldTitle), DocumentVersionEdge: types.NewDocumentVersionEdge(documentVersion, coredata.DocumentVersionOrderFieldCreatedAt), }, nil } // UpdateDocument is the resolver for the updateDocument field. func (r *mutationResolver) UpdateDocument(ctx context.Context, input types.UpdateDocumentInput) (*types.UpdateDocumentPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionDocumentUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) document, err := prb.Documents.Update( ctx, probo.UpdateDocumentRequest{ DocumentID: input.ID, Title: input.Title, OwnerID: input.OwnerID, Classification: input.Classification, DocumentType: input.DocumentType, TrustCenterVisibility: input.TrustCenterVisibility, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update document: %w", err)) } return &types.UpdateDocumentPayload{ Document: types.NewDocument(document), }, nil } // DeleteDocument is the resolver for the deleteDocument field. func (r *mutationResolver) DeleteDocument(ctx context.Context, input types.DeleteDocumentInput) (*types.DeleteDocumentPayload, error) { if err := r.authorize(ctx, input.DocumentID, probo.ActionDocumentDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.DocumentID.TenantID()) err := prb.Documents.SoftDelete(ctx, input.DocumentID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot soft delete document: %w", err)) } return &types.DeleteDocumentPayload{ DeletedDocumentID: input.DocumentID, }, nil } // CreateMeeting is the resolver for the createMeeting field. func (r *mutationResolver) CreateMeeting(ctx context.Context, input types.CreateMeetingInput) (*types.CreateMeetingPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionMeetingCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) meeting, err := prb.Meetings.Create( ctx, probo.CreateMeetingRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Date: input.Date, AttendeeIDs: input.AttendeeIds, Minutes: input.Minutes, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create meeting: %w", err)) } return &types.CreateMeetingPayload{ MeetingEdge: types.NewMeetingEdge(meeting, coredata.MeetingOrderFieldCreatedAt), }, nil } // UpdateMeeting is the resolver for the updateMeeting field. func (r *mutationResolver) UpdateMeeting(ctx context.Context, input types.UpdateMeetingInput) (*types.UpdateMeetingPayload, error) { if err := r.authorize(ctx, input.MeetingID, probo.ActionMeetingUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.MeetingID.TenantID()) var attendeeIDs []gid.GID if input.AttendeeIds != nil { attendeeIDs = input.AttendeeIds } meeting, err := prb.Meetings.Update( ctx, probo.UpdateMeetingRequest{ MeetingID: input.MeetingID, Name: input.Name, Date: input.Date, AttendeeIDs: attendeeIDs, Minutes: gqlutils.UnwrapOmittable(input.Minutes), }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update meeting: %w", err)) } return &types.UpdateMeetingPayload{ Meeting: types.NewMeeting(meeting), }, nil } // DeleteMeeting is the resolver for the deleteMeeting field. func (r *mutationResolver) DeleteMeeting(ctx context.Context, input types.DeleteMeetingInput) (*types.DeleteMeetingPayload, error) { if err := r.authorize(ctx, input.MeetingID, probo.ActionMeetingDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.MeetingID.TenantID()) err := prb.Meetings.Delete(ctx, input.MeetingID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete meeting: %w", err)) } return &types.DeleteMeetingPayload{ DeletedMeetingID: input.MeetingID, }, nil } // CreateStateOfApplicability is the resolver for the createStateOfApplicability field. func (r *mutationResolver) CreateStateOfApplicability(ctx context.Context, input types.CreateStateOfApplicabilityInput) (*types.CreateStateOfApplicabilityPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionStateOfApplicabilityCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) stateOfApplicability, err := prb.StatesOfApplicability.Create( ctx, probo.CreateStateOfApplicabilityRequest{ OrganizationID: input.OrganizationID, Name: input.Name, OwnerID: input.OwnerID, }, ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } panic(fmt.Errorf("cannot create state_of_applicability: %w", err)) } return &types.CreateStateOfApplicabilityPayload{ StateOfApplicabilityEdge: types.NewStateOfApplicabilityEdge(stateOfApplicability, coredata.StateOfApplicabilityOrderFieldCreatedAt), }, nil } // UpdateStateOfApplicability is the resolver for the updateStateOfApplicability field. func (r *mutationResolver) UpdateStateOfApplicability(ctx context.Context, input types.UpdateStateOfApplicabilityInput) (*types.UpdateStateOfApplicabilityPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionStateOfApplicabilityUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) var name *string if input.Name != nil { name = input.Name } stateOfApplicability, err := prb.StatesOfApplicability.Update( ctx, probo.UpdateStateOfApplicabilityRequest{ StateOfApplicabilityID: input.ID, Name: name, OwnerID: input.OwnerID, }, ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } panic(fmt.Errorf("cannot update state_of_applicability: %w", err)) } return &types.UpdateStateOfApplicabilityPayload{ StateOfApplicability: types.NewStateOfApplicability(stateOfApplicability), }, nil } // DeleteStateOfApplicability is the resolver for the deleteStateOfApplicability field. func (r *mutationResolver) DeleteStateOfApplicability(ctx context.Context, input types.DeleteStateOfApplicabilityInput) (*types.DeleteStateOfApplicabilityPayload, error) { if err := r.authorize(ctx, input.StateOfApplicabilityID, probo.ActionStateOfApplicabilityDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.StateOfApplicabilityID.TenantID()) err := prb.StatesOfApplicability.Delete(ctx, input.StateOfApplicabilityID) if err != nil { panic(fmt.Errorf("cannot delete state_of_applicability: %w", err)) } return &types.DeleteStateOfApplicabilityPayload{ DeletedStateOfApplicabilityID: input.StateOfApplicabilityID, }, nil } // ExportStateOfApplicabilityPDF is the resolver for the exportStateOfApplicabilityPDF field. func (r *mutationResolver) ExportStateOfApplicabilityPDF(ctx context.Context, input types.ExportStateOfApplicabilityPDFInput) (*types.ExportStateOfApplicabilityPDFPayload, error) { if err := r.authorize(ctx, input.StateOfApplicabilityID, probo.ActionStateOfApplicabilityExport); err != nil { return nil, err } prb := r.ProboService(ctx, input.StateOfApplicabilityID.TenantID()) pdfData, err := prb.StatesOfApplicability.ExportPDF(ctx, input.StateOfApplicabilityID) if err != nil { panic(fmt.Errorf("cannot export state of applicability PDF: %w", err)) } base64Data := base64.StdEncoding.EncodeToString(pdfData) dataURI := fmt.Sprintf("data:application/pdf;base64,%s", base64Data) return &types.ExportStateOfApplicabilityPDFPayload{ Data: dataURI, }, nil } // PublishDocumentVersion is the resolver for the publishDocumentVersion field. func (r *mutationResolver) PublishDocumentVersion(ctx context.Context, input types.PublishDocumentVersionInput) (*types.PublishDocumentVersionPayload, error) { if err := r.authorize(ctx, input.DocumentID, probo.ActionDocumentVersionPublish); err != nil { return nil, err } prb := r.ProboService(ctx, input.DocumentID.TenantID()) identity := authn.IdentityFromContext(ctx) document, documentVersion, err := prb.Documents.PublishVersion(ctx, input.DocumentID, identity.ID, input.Changelog) if err != nil { var errNoChanges *probo.ErrDocumentVersionNoChanges if errors.As(err, &errNoChanges) { return nil, gqlutils.Invalid(ctx, errNoChanges) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot publish document version: %w", err)) } return &types.PublishDocumentVersionPayload{ DocumentVersion: types.NewDocumentVersion(documentVersion), Document: types.NewDocument(document), }, nil } // BulkPublishDocumentVersions is the resolver for the bulkPublishDocumentVersions field. func (r *mutationResolver) BulkPublishDocumentVersions(ctx context.Context, input types.BulkPublishDocumentVersionsInput) (*types.BulkPublishDocumentVersionsPayload, error) { if len(input.DocumentIds) == 0 { return &types.BulkPublishDocumentVersionsPayload{ DocumentVersionEdges: []*types.DocumentVersionEdge{}, DocumentEdges: []*types.DocumentEdge{}, }, nil } for _, documentID := range input.DocumentIds { if err := r.authorize(ctx, documentID, probo.ActionDocumentVersionPublish); err != nil { return nil, err } } prb := r.ProboService(ctx, input.DocumentIds[0].TenantID()) identity := authn.IdentityFromContext(ctx) documentVersions, documents, err := prb.Documents.BulkPublishVersions( ctx, probo.BulkPublishVersionsRequest{ DocumentIDs: input.DocumentIds, PublishedBy: identity.ID, Changelog: input.Changelog, }, ) if err != nil { var errNoChanges *probo.ErrDocumentVersionNoChanges if errors.As(err, &errNoChanges) { return nil, gqlutils.Invalid(ctx, errNoChanges) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot bulk publish document versions: %w", err)) } return &types.BulkPublishDocumentVersionsPayload{ DocumentVersionEdges: types.NewDocumentVersionEdges(documentVersions, coredata.DocumentVersionOrderFieldCreatedAt), DocumentEdges: types.NewDocumentEdges(documents, coredata.DocumentOrderFieldTitle), }, nil } // BulkDeleteDocuments is the resolver for the bulkDeleteDocuments field. func (r *mutationResolver) BulkDeleteDocuments(ctx context.Context, input types.BulkDeleteDocumentsInput) (*types.BulkDeleteDocumentsPayload, error) { if len(input.DocumentIds) == 0 { return &types.BulkDeleteDocumentsPayload{ DeletedDocumentIds: []gid.GID{}, }, nil } for _, documentID := range input.DocumentIds { if err := r.authorize(ctx, documentID, probo.ActionDocumentDelete); err != nil { return nil, err } } prb := r.ProboService(ctx, input.DocumentIds[0].TenantID()) err := prb.Documents.BulkSoftDelete(ctx, input.DocumentIds) if err != nil { panic(fmt.Errorf("cannot bulk delete documents: %w", err)) } return &types.BulkDeleteDocumentsPayload{ DeletedDocumentIds: input.DocumentIds, }, nil } // BulkExportDocuments is the resolver for the bulkExportDocuments field. func (r *mutationResolver) BulkExportDocuments(ctx context.Context, input types.BulkExportDocumentsInput) (*types.BulkExportDocumentsPayload, error) { if len(input.DocumentIds) == 0 { panic(fmt.Errorf("no document ids provided")) } // TODO have a way to batch authorize for resources for _, documentID := range input.DocumentIds { if err := r.authorize(ctx, documentID, probo.ActionDocumentVersionExport); err != nil { return nil, err } } prb := r.ProboService(ctx, input.DocumentIds[0].TenantID()) identity := authn.IdentityFromContext(ctx) options := probo.ExportPDFOptions{ WithWatermark: input.WithWatermark, WithSignatures: input.WithSignatures, WatermarkEmail: input.WatermarkEmail, } documentExport, exportErr := prb.Documents.RequestExport(ctx, input.DocumentIds, identity.EmailAddress, identity.FullName, options) if exportErr != nil { panic(fmt.Errorf("cannot request document export: %w", exportErr)) } return &types.BulkExportDocumentsPayload{ ExportJobID: documentExport.ID, }, nil } // GenerateDocumentChangelog is the resolver for the generateDocumentChangelog field. func (r *mutationResolver) GenerateDocumentChangelog(ctx context.Context, input types.GenerateDocumentChangelogInput) (*types.GenerateDocumentChangelogPayload, error) { if err := r.authorize(ctx, input.DocumentID, probo.ActionDocumentChangelogGenerate); err != nil { return nil, err } prb := r.ProboService(ctx, input.DocumentID.TenantID()) changelog, err := prb.Documents.GenerateChangelog(ctx, input.DocumentID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot generate document changelog: %w", err)) } return &types.GenerateDocumentChangelogPayload{ Changelog: *changelog, }, nil } // CreateDraftDocumentVersion is the resolver for the createDraftDocumentVersion field. func (r *mutationResolver) CreateDraftDocumentVersion(ctx context.Context, input types.CreateDraftDocumentVersionInput) (*types.CreateDraftDocumentVersionPayload, error) { if err := r.authorize(ctx, input.DocumentID, probo.ActionDocumentDraftVersionCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.DocumentID.TenantID()) documentVersion, err := prb.Documents.CreateDraft(ctx, input.DocumentID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create draft document version: %w", err)) } return &types.CreateDraftDocumentVersionPayload{ DocumentVersionEdge: types.NewDocumentVersionEdge(documentVersion, coredata.DocumentVersionOrderFieldCreatedAt), }, nil } // DeleteDraftDocumentVersion is the resolver for the deleteDraftDocumentVersion field. func (r *mutationResolver) DeleteDraftDocumentVersion(ctx context.Context, input types.DeleteDraftDocumentVersionInput) (*types.DeleteDraftDocumentVersionPayload, error) { if err := r.authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionDeleteDraft); err != nil { return nil, err } prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) err := prb.Documents.DeleteDraft(ctx, input.DocumentVersionID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete draft document version: %w", err)) } return &types.DeleteDraftDocumentVersionPayload{ DeletedDocumentVersionID: input.DocumentVersionID, }, nil } // UpdateDocumentVersion is the resolver for the updateDocumentVersion field. func (r *mutationResolver) UpdateDocumentVersion(ctx context.Context, input types.UpdateDocumentVersionInput) (*types.UpdateDocumentVersionPayload, error) { if err := r.authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) documentVersion, err := prb.Documents.UpdateVersion( ctx, probo.UpdateDocumentVersionRequest{ ID: input.DocumentVersionID, Content: input.Content, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update document version: %w", err)) } return &types.UpdateDocumentVersionPayload{ DocumentVersion: types.NewDocumentVersion(documentVersion), }, nil } // RequestSignature is the resolver for the requestSignature field. func (r *mutationResolver) RequestSignature(ctx context.Context, input types.RequestSignatureInput) (*types.RequestSignaturePayload, error) { if err := r.authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionSignatureRequest); err != nil { return nil, err } prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) documentVersionSignature, err := prb.Documents.RequestSignature( ctx, probo.RequestSignatureRequest{ DocumentVersionID: input.DocumentVersionID, Signatory: input.SignatoryID, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot request signature: %w", err)) } return &types.RequestSignaturePayload{ DocumentVersionSignatureEdge: types.NewDocumentVersionSignatureEdge(documentVersionSignature, coredata.DocumentVersionSignatureOrderFieldCreatedAt), }, nil } // BulkRequestSignatures is the resolver for the bulkRequestSignatures field. func (r *mutationResolver) BulkRequestSignatures(ctx context.Context, input types.BulkRequestSignaturesInput) (*types.BulkRequestSignaturesPayload, error) { if len(input.DocumentIds) == 0 { return &types.BulkRequestSignaturesPayload{ DocumentVersionSignatureEdges: []*types.DocumentVersionSignatureEdge{}, }, nil } for _, documentID := range input.DocumentIds { if err := r.authorize(ctx, documentID, probo.ActionDocumentVersionSignatureRequest); err != nil { return nil, err } } prb := r.ProboService(ctx, input.DocumentIds[0].TenantID()) documentVersionSignatures, err := prb.Documents.BulkRequestSignatures( ctx, probo.BulkRequestSignaturesRequest{ DocumentIDs: input.DocumentIds, SignatoryIDs: input.SignatoryIds, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot bulk request signatures: %w", err)) } return &types.BulkRequestSignaturesPayload{ DocumentVersionSignatureEdges: types.NewDocumentVersionSignatureEdges(documentVersionSignatures, coredata.DocumentVersionSignatureOrderFieldCreatedAt), }, nil } // SendSigningNotifications is the resolver for the sendSigningNotifications field. func (r *mutationResolver) SendSigningNotifications(ctx context.Context, input types.SendSigningNotificationsInput) (*types.SendSigningNotificationsPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionDocumentSendSigningNotifications); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) err := prb.Documents.SendSigningNotifications(ctx, input.OrganizationID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot send signing notifications: %w", err)) } return &types.SendSigningNotificationsPayload{ Success: true, }, nil } // CancelSignatureRequest is the resolver for the cancelSignatureRequest field. func (r *mutationResolver) CancelSignatureRequest(ctx context.Context, input types.CancelSignatureRequestInput) (*types.CancelSignatureRequestPayload, error) { if err := r.authorize(ctx, input.DocumentVersionSignatureID, probo.ActionDocumentVersionCancelSignature); err != nil { return nil, err } prb := r.ProboService(ctx, input.DocumentVersionSignatureID.TenantID()) err := prb.Documents.CancelSignatureRequest(ctx, input.DocumentVersionSignatureID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot cancel signature request: %w", err)) } return &types.CancelSignatureRequestPayload{ DeletedDocumentVersionSignatureID: input.DocumentVersionSignatureID, }, nil } // SignDocument is the resolver for the signDocument field. func (r *mutationResolver) SignDocument(ctx context.Context, input types.SignDocumentInput) (*types.SignDocumentPayload, error) { if err := r.authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionSign); err != nil { return nil, err } identity := authn.IdentityFromContext(ctx) prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) documentVersionSignature, err := prb.Documents.SignDocumentVersionByIdentity(ctx, input.DocumentVersionID, identity.ID) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot sign document: %w", err)) } return &types.SignDocumentPayload{ DocumentVersionSignature: types.NewDocumentVersionSignature(documentVersionSignature), }, nil } // ExportDocumentVersionPDF is the resolver for the exportDocumentVersionPDF field. func (r *mutationResolver) ExportDocumentVersionPDF(ctx context.Context, input types.ExportDocumentVersionPDFInput) (*types.ExportDocumentVersionPDFPayload, error) { if err := r.authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionExportPDF); err != nil { return nil, err } prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) options := probo.ExportPDFOptions{ WithSignatures: input.WithSignatures, WithWatermark: input.WithWatermark, WatermarkEmail: input.WatermarkEmail, } pdf, err := prb.Documents.ExportPDF(ctx, input.DocumentVersionID, options) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot export document version PDF: %w", err)) } return &types.ExportDocumentVersionPDFPayload{ Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)), }, nil } // ExportSignableVersionDocumentPDF is the resolver for the exportSignableVersionDocumentPDF field. func (r *mutationResolver) ExportSignableVersionDocumentPDF(ctx context.Context, input types.ExportSignableDocumentVersionPDFInput) (*types.ExportSignableDocumentVersionPDFPayload, error) { if err := r.authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionExportSignable); err != nil { return nil, err } prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) documentVersion, err := prb.Documents.GetVersion(ctx, input.DocumentVersionID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get document version: %w", err)) } identity := authn.IdentityFromContext(ctx) documentFilter := coredata.NewDocumentFilter(nil).WithUserEmail(&identity.EmailAddress) _, err = prb.Documents.GetWithFilter(ctx, documentVersion.DocumentID, documentFilter) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get signable document: %w", err)) } options := probo.ExportPDFOptions{ WithSignatures: false, WithWatermark: true, WatermarkEmail: &identity.EmailAddress, } pdf, err := prb.Documents.ExportPDF(ctx, input.DocumentVersionID, options) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot export signable document PDF: %w", err)) } return &types.ExportSignableDocumentVersionPDFPayload{ Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)), }, nil } // ExportProcessingActivitiesPDF is the resolver for the exportProcessingActivitiesPDF field. func (r *mutationResolver) ExportProcessingActivitiesPDF(ctx context.Context, input types.ExportProcessingActivitiesPDFInput) (*types.ExportProcessingActivitiesPDFPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionProcessingActivityExport); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) var snapshotIDPtr *gid.GID if input.Filter != nil { snapshotIDPtr = input.Filter.SnapshotID } processingActivityFilter := coredata.NewProcessingActivityFilter(&snapshotIDPtr) pdf, err := prb.ProcessingActivities.ExportPDF(ctx, input.OrganizationID, processingActivityFilter) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot export processing activities PDF: %w", err)) } return &types.ExportProcessingActivitiesPDFPayload{ Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)), }, nil } // ExportDataProtectionImpactAssessmentsPDF is the resolver for the exportDataProtectionImpactAssessmentsPDF field. func (r *mutationResolver) ExportDataProtectionImpactAssessmentsPDF(ctx context.Context, input types.ExportDataProtectionImpactAssessmentsPDFInput) (*types.ExportDataProtectionImpactAssessmentsPDFPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionDataProtectionImpactAssessmentExport); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) var snapshotIDPtr *gid.GID if input.Filter != nil { snapshotIDPtr = input.Filter.SnapshotID } dpiaFilter := coredata.NewDataProtectionImpactAssessmentFilter(&snapshotIDPtr) pdf, err := prb.DataProtectionImpactAssessments.ExportPDF(ctx, input.OrganizationID, dpiaFilter) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot export data protection impact assessments PDF: %w", err)) } return &types.ExportDataProtectionImpactAssessmentsPDFPayload{ Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)), }, nil } // ExportTransferImpactAssessmentsPDF is the resolver for the exportTransferImpactAssessmentsPDF field. func (r *mutationResolver) ExportTransferImpactAssessmentsPDF(ctx context.Context, input types.ExportTransferImpactAssessmentsPDFInput) (*types.ExportTransferImpactAssessmentsPDFPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionTransferImpactAssessmentExport); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) var snapshotIDPtr *gid.GID if input.Filter != nil { snapshotIDPtr = input.Filter.SnapshotID } tiaFilter := coredata.NewTransferImpactAssessmentFilter(&snapshotIDPtr) pdf, err := prb.TransferImpactAssessments.ExportPDF(ctx, input.OrganizationID, tiaFilter) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot export transfer impact assessments PDF: %w", err)) } return &types.ExportTransferImpactAssessmentsPDFPayload{ Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)), }, nil } // CreateVendorRiskAssessment is the resolver for the createVendorRiskAssessment field. func (r *mutationResolver) CreateVendorRiskAssessment(ctx context.Context, input types.CreateVendorRiskAssessmentInput) (*types.CreateVendorRiskAssessmentPayload, error) { if err := r.authorize(ctx, input.VendorID, probo.ActionVendorRiskAssessmentCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.VendorID.TenantID()) vendorRiskAssessment, err := prb.Vendors.CreateRiskAssessment( ctx, probo.CreateVendorRiskAssessmentRequest{ VendorID: input.VendorID, ExpiresAt: input.ExpiresAt, DataSensitivity: input.DataSensitivity, BusinessImpact: input.BusinessImpact, Notes: input.Notes, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create vendor risk assessment: %w", err)) } return &types.CreateVendorRiskAssessmentPayload{ VendorRiskAssessmentEdge: types.NewVendorRiskAssessmentEdge(vendorRiskAssessment, coredata.VendorRiskAssessmentOrderFieldCreatedAt), }, nil } // AssessVendor is the resolver for the assessVendor field. func (r *mutationResolver) AssessVendor(ctx context.Context, input types.AssessVendorInput) (*types.AssessVendorPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionVendorAssess); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) vendor, err := prb.Vendors.Assess( ctx, probo.AssessVendorRequest{ ID: input.ID, WebsiteURL: input.WebsiteURL, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot assess vendor: %w", err)) } return &types.AssessVendorPayload{ Vendor: types.NewVendor(vendor), }, nil } // CreateAsset is the resolver for the createAsset field. func (r *mutationResolver) CreateAsset(ctx context.Context, input types.CreateAssetInput) (*types.CreateAssetPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionAssetCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) asset, err := prb.Assets.Create( ctx, probo.CreateAssetRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Amount: input.Amount, OwnerID: input.OwnerID, AssetType: input.AssetType, DataTypesStored: input.DataTypesStored, VendorIDs: input.VendorIds, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create asset: %w", err)) } return &types.CreateAssetPayload{ AssetEdge: types.NewAssetEdge(asset, coredata.AssetOrderFieldCreatedAt), }, nil } // UpdateAsset is the resolver for the updateAsset field. func (r *mutationResolver) UpdateAsset(ctx context.Context, input types.UpdateAssetInput) (*types.UpdateAssetPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionAssetUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) asset, err := prb.Assets.Update( ctx, probo.UpdateAssetRequest{ ID: input.ID, Name: input.Name, Amount: input.Amount, OwnerID: input.OwnerID, AssetType: input.AssetType, DataTypesStored: input.DataTypesStored, VendorIDs: input.VendorIds, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update asset: %w", err)) } return &types.UpdateAssetPayload{ Asset: types.NewAsset(asset), }, nil } // DeleteAsset is the resolver for the deleteAsset field. func (r *mutationResolver) DeleteAsset(ctx context.Context, input types.DeleteAssetInput) (*types.DeleteAssetPayload, error) { if err := r.authorize(ctx, input.AssetID, probo.ActionAssetDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.AssetID.TenantID()) err := prb.Assets.Delete(ctx, input.AssetID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete asset: %w", err)) } return &types.DeleteAssetPayload{ DeletedAssetID: input.AssetID, }, nil } // CreateDatum is the resolver for the createDatum field. func (r *mutationResolver) CreateDatum(ctx context.Context, input types.CreateDatumInput) (*types.CreateDatumPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionDatumCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) data, err := prb.Data.Create( ctx, probo.CreateDatumRequest{ OrganizationID: input.OrganizationID, Name: input.Name, DataClassification: input.DataClassification, OwnerID: input.OwnerID, VendorIDs: input.VendorIds, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create datum: %w", err)) } return &types.CreateDatumPayload{ DatumEdge: types.NewDatumEdge(data, coredata.DatumOrderFieldCreatedAt), }, nil } // UpdateDatum is the resolver for the updateDatum field. func (r *mutationResolver) UpdateDatum(ctx context.Context, input types.UpdateDatumInput) (*types.UpdateDatumPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionDatumUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) datum, err := prb.Data.Update( ctx, probo.UpdateDatumRequest{ ID: input.ID, Name: input.Name, DataClassification: input.DataClassification, OwnerID: input.OwnerID, VendorIDs: input.VendorIds, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update datum: %w", err)) } return &types.UpdateDatumPayload{ Datum: types.NewDatum(datum), }, nil } // DeleteDatum is the resolver for the deleteDatum field. func (r *mutationResolver) DeleteDatum(ctx context.Context, input types.DeleteDatumInput) (*types.DeleteDatumPayload, error) { if err := r.authorize(ctx, input.DatumID, probo.ActionDatumDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.DatumID.TenantID()) if err := prb.Data.Delete(ctx, input.DatumID); err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete datum: %w", err)) } return &types.DeleteDatumPayload{ DeletedDatumID: input.DatumID, }, nil } // CreateAudit is the resolver for the createAudit field. func (r *mutationResolver) CreateAudit(ctx context.Context, input types.CreateAuditInput) (*types.CreateAuditPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionAuditCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) req := probo.CreateAuditRequest{ OrganizationID: input.OrganizationID, FrameworkID: input.FrameworkID, Name: input.Name, ValidFrom: input.ValidFrom, ValidUntil: input.ValidUntil, State: input.State, TrustCenterVisibility: input.TrustCenterVisibility, } audit, err := prb.Audits.Create(ctx, &req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create audit: %w", err)) } return &types.CreateAuditPayload{ AuditEdge: types.NewAuditEdge(audit, coredata.AuditOrderFieldCreatedAt), }, nil } // UpdateAudit is the resolver for the updateAudit field. func (r *mutationResolver) UpdateAudit(ctx context.Context, input types.UpdateAuditInput) (*types.UpdateAuditPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionAuditUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) req := probo.UpdateAuditRequest{ ID: input.ID, Name: gqlutils.UnwrapOmittable(input.Name), ValidFrom: input.ValidFrom, ValidUntil: input.ValidUntil, State: input.State, TrustCenterVisibility: input.TrustCenterVisibility, } audit, err := prb.Audits.Update(ctx, &req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update audit: %w", err)) } return &types.UpdateAuditPayload{ Audit: types.NewAudit(audit), }, nil } // DeleteAudit is the resolver for the deleteAudit field. func (r *mutationResolver) DeleteAudit(ctx context.Context, input types.DeleteAuditInput) (*types.DeleteAuditPayload, error) { if err := r.authorize(ctx, input.AuditID, probo.ActionAuditDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.AuditID.TenantID()) err := prb.Audits.Delete(ctx, input.AuditID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete audit: %w", err)) } return &types.DeleteAuditPayload{ DeletedAuditID: input.AuditID, }, nil } // UploadAuditReport is the resolver for the uploadAuditReport field. func (r *mutationResolver) UploadAuditReport(ctx context.Context, input types.UploadAuditReportInput) (*types.UploadAuditReportPayload, error) { if err := r.authorize(ctx, input.AuditID, probo.ActionAuditReportUpload); err != nil { return nil, err } prb := r.ProboService(ctx, input.AuditID.TenantID()) req := probo.UploadAuditReportRequest{ AuditID: input.AuditID, File: probo.File{ Content: input.File.File, Filename: input.File.Filename, Size: input.File.Size, ContentType: input.File.ContentType, }, } audit, err := prb.Audits.UploadReport(ctx, req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot upload audit report: %w", err)) } return &types.UploadAuditReportPayload{ Audit: types.NewAudit(audit), }, nil } // DeleteAuditReport is the resolver for the deleteAuditReport field. func (r *mutationResolver) DeleteAuditReport(ctx context.Context, input types.DeleteAuditReportInput) (*types.DeleteAuditReportPayload, error) { if err := r.authorize(ctx, input.AuditID, probo.ActionAuditReportDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.AuditID.TenantID()) audit, err := prb.Audits.DeleteReport(ctx, input.AuditID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete audit report: %w", err)) } return &types.DeleteAuditReportPayload{ Audit: types.NewAudit(audit), }, nil } // CreateNonconformity is the resolver for the createNonconformity field. func (r *mutationResolver) CreateNonconformity(ctx context.Context, input types.CreateNonconformityInput) (*types.CreateNonconformityPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionNonconformityCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) req := probo.CreateNonconformityRequest{ OrganizationID: input.OrganizationID, ReferenceID: input.ReferenceID, Description: input.Description, AuditID: input.AuditID, DateIdentified: input.DateIdentified, RootCause: input.RootCause, CorrectiveAction: input.CorrectiveAction, OwnerID: input.OwnerID, DueDate: input.DueDate, Status: &input.Status, EffectivenessCheck: input.EffectivenessCheck, } nonconformity, err := prb.Nonconformities.Create(ctx, &req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create nonconformity: %w", err)) } return &types.CreateNonconformityPayload{ NonconformityEdge: types.NewNonconformityEdge(nonconformity, coredata.NonconformityOrderFieldCreatedAt), }, nil } // UpdateNonconformity is the resolver for the updateNonconformity field. func (r *mutationResolver) UpdateNonconformity(ctx context.Context, input types.UpdateNonconformityInput) (*types.UpdateNonconformityPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionNonconformityUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) req := probo.UpdateNonconformityRequest{ ID: input.ID, ReferenceID: input.ReferenceID, Description: gqlutils.UnwrapOmittable(input.Description), DateIdentified: gqlutils.UnwrapOmittable(input.DateIdentified), RootCause: input.RootCause, CorrectiveAction: gqlutils.UnwrapOmittable(input.CorrectiveAction), OwnerID: input.OwnerID, AuditID: gqlutils.UnwrapOmittable(input.AuditID), DueDate: gqlutils.UnwrapOmittable(input.DueDate), Status: input.Status, EffectivenessCheck: gqlutils.UnwrapOmittable(input.EffectivenessCheck), } nonconformity, err := prb.Nonconformities.Update(ctx, &req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update nonconformity: %w", err)) } return &types.UpdateNonconformityPayload{ Nonconformity: types.NewNonconformity(nonconformity), }, nil } // DeleteNonconformity is the resolver for the deleteNonconformity field. func (r *mutationResolver) DeleteNonconformity(ctx context.Context, input types.DeleteNonconformityInput) (*types.DeleteNonconformityPayload, error) { if err := r.authorize(ctx, input.NonconformityID, probo.ActionNonconformityDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.NonconformityID.TenantID()) err := prb.Nonconformities.Delete(ctx, input.NonconformityID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete nonconformity: %w", err)) } return &types.DeleteNonconformityPayload{ DeletedNonconformityID: input.NonconformityID, }, nil } // CreateObligation is the resolver for the createObligation field. func (r *mutationResolver) CreateObligation(ctx context.Context, input types.CreateObligationInput) (*types.CreateObligationPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionObligationCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) req := probo.CreateObligationRequest{ OrganizationID: input.OrganizationID, Area: input.Area, Source: input.Source, Requirement: input.Requirement, ActionsToBeImplemented: input.ActionsToBeImplemented, Regulator: input.Regulator, OwnerID: input.OwnerID, LastReviewDate: input.LastReviewDate, DueDate: input.DueDate, Status: input.Status, Type: input.Type, } obligation, err := prb.Obligations.Create(ctx, &req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create obligation: %w", err)) } return &types.CreateObligationPayload{ ObligationEdge: types.NewObligationEdge(obligation, coredata.ObligationOrderFieldCreatedAt), }, nil } // UpdateObligation is the resolver for the updateObligation field. func (r *mutationResolver) UpdateObligation(ctx context.Context, input types.UpdateObligationInput) (*types.UpdateObligationPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionObligationUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) req := probo.UpdateObligationRequest{ ID: input.ID, Area: gqlutils.UnwrapOmittable(input.Area), Source: gqlutils.UnwrapOmittable(input.Source), Requirement: gqlutils.UnwrapOmittable(input.Requirement), ActionsToBeImplemented: gqlutils.UnwrapOmittable(input.ActionsToBeImplemented), Regulator: gqlutils.UnwrapOmittable(input.Regulator), OwnerID: input.OwnerID, LastReviewDate: gqlutils.UnwrapOmittable(input.LastReviewDate), DueDate: gqlutils.UnwrapOmittable(input.DueDate), Status: input.Status, Type: input.Type, } obligation, err := prb.Obligations.Update(ctx, &req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update obligation: %w", err)) } return &types.UpdateObligationPayload{ Obligation: types.NewObligation(obligation), }, nil } // DeleteObligation is the resolver for the deleteObligation field. func (r *mutationResolver) DeleteObligation(ctx context.Context, input types.DeleteObligationInput) (*types.DeleteObligationPayload, error) { if err := r.authorize(ctx, input.ObligationID, probo.ActionObligationDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.ObligationID.TenantID()) err := prb.Obligations.Delete(ctx, input.ObligationID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete obligation: %w", err)) } return &types.DeleteObligationPayload{ DeletedObligationID: input.ObligationID, }, nil } // CreateContinualImprovement is the resolver for the createContinualImprovement field. func (r *mutationResolver) CreateContinualImprovement(ctx context.Context, input types.CreateContinualImprovementInput) (*types.CreateContinualImprovementPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionContinualImprovementCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) req := probo.CreateContinualImprovementRequest{ OrganizationID: input.OrganizationID, ReferenceID: input.ReferenceID, Description: input.Description, Source: input.Source, OwnerID: input.OwnerID, TargetDate: input.TargetDate, Status: &input.Status, Priority: &input.Priority, } continualImprovement, err := prb.ContinualImprovements.Create(ctx, &req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create continual improvement: %w", err)) } return &types.CreateContinualImprovementPayload{ ContinualImprovementEdge: types.NewContinualImprovementEdge(continualImprovement, coredata.ContinualImprovementOrderFieldCreatedAt), }, nil } // UpdateContinualImprovement is the resolver for the updateContinualImprovement field. func (r *mutationResolver) UpdateContinualImprovement(ctx context.Context, input types.UpdateContinualImprovementInput) (*types.UpdateContinualImprovementPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionContinualImprovementUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) req := probo.UpdateContinualImprovementRequest{ ID: input.ID, ReferenceID: input.ReferenceID, Description: gqlutils.UnwrapOmittable(input.Description), Source: gqlutils.UnwrapOmittable(input.Source), OwnerID: input.OwnerID, TargetDate: gqlutils.UnwrapOmittable(input.TargetDate), Status: input.Status, Priority: input.Priority, } continualImprovement, err := prb.ContinualImprovements.Update(ctx, &req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update continual improvement: %w", err)) } return &types.UpdateContinualImprovementPayload{ ContinualImprovement: types.NewContinualImprovement(continualImprovement), }, nil } // DeleteContinualImprovement is the resolver for the deleteContinualImprovement field. func (r *mutationResolver) DeleteContinualImprovement(ctx context.Context, input types.DeleteContinualImprovementInput) (*types.DeleteContinualImprovementPayload, error) { if err := r.authorize(ctx, input.ContinualImprovementID, probo.ActionContinualImprovementDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.ContinualImprovementID.TenantID()) err := prb.ContinualImprovements.Delete(ctx, input.ContinualImprovementID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete continual improvement: %w", err)) } return &types.DeleteContinualImprovementPayload{ DeletedContinualImprovementID: input.ContinualImprovementID, }, nil } // CreateRightsRequest is the resolver for the createRightsRequest field. func (r *mutationResolver) CreateRightsRequest(ctx context.Context, input types.CreateRightsRequestInput) (*types.CreateRightsRequestPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionRightsRequestCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) req := probo.CreateRightsRequestRequest{ OrganizationID: input.OrganizationID, RequestType: &input.RequestType, RequestState: &input.RequestState, DataSubject: input.DataSubject, Contact: input.Contact, Details: input.Details, Deadline: input.Deadline, ActionTaken: input.ActionTaken, } rightsRequest, err := prb.RightsRequests.Create(ctx, &req) if err != nil { panic(fmt.Errorf("cannot create rights request: %w", err)) } return &types.CreateRightsRequestPayload{ RightsRequestEdge: types.NewRightsRequestEdge(rightsRequest, coredata.RightsRequestOrderFieldCreatedAt), }, nil } // UpdateRightsRequest is the resolver for the updateRightsRequest field. func (r *mutationResolver) UpdateRightsRequest(ctx context.Context, input types.UpdateRightsRequestInput) (*types.UpdateRightsRequestPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionRightsRequestUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) req := probo.UpdateRightsRequestRequest{ ID: input.ID, RequestType: input.RequestType, RequestState: input.RequestState, DataSubject: gqlutils.UnwrapOmittable(input.DataSubject), Contact: gqlutils.UnwrapOmittable(input.Contact), Details: gqlutils.UnwrapOmittable(input.Details), Deadline: gqlutils.UnwrapOmittable(input.Deadline), ActionTaken: gqlutils.UnwrapOmittable(input.ActionTaken), } rightsRequest, err := prb.RightsRequests.Update(ctx, &req) if err != nil { panic(fmt.Errorf("cannot update rights request: %w", err)) } return &types.UpdateRightsRequestPayload{ RightsRequest: types.NewRightsRequest(rightsRequest), }, nil } // DeleteRightsRequest is the resolver for the deleteRightsRequest field. func (r *mutationResolver) DeleteRightsRequest(ctx context.Context, input types.DeleteRightsRequestInput) (*types.DeleteRightsRequestPayload, error) { if err := r.authorize(ctx, input.RightsRequestID, probo.ActionRightsRequestDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.RightsRequestID.TenantID()) err := prb.RightsRequests.Delete(ctx, input.RightsRequestID) if err != nil { panic(fmt.Errorf("cannot delete rights request: %w", err)) } return &types.DeleteRightsRequestPayload{ DeletedRightsRequestID: input.RightsRequestID, }, nil } // CreateProcessingActivity is the resolver for the createProcessingActivity field. func (r *mutationResolver) CreateProcessingActivity(ctx context.Context, input types.CreateProcessingActivityInput) (*types.CreateProcessingActivityPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionProcessingActivityCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) req := probo.CreateProcessingActivityRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Purpose: input.Purpose, DataSubjectCategory: input.DataSubjectCategory, PersonalDataCategory: input.PersonalDataCategory, SpecialOrCriminalData: input.SpecialOrCriminalData, LawfulBasis: input.LawfulBasis, Recipients: input.Recipients, Location: input.Location, InternationalTransfers: input.InternationalTransfers, TransferSafeguard: input.TransferSafeguards, RetentionPeriod: input.RetentionPeriod, SecurityMeasures: input.SecurityMeasures, DataProtectionImpactAssessmentNeeded: input.DataProtectionImpactAssessmentNeeded, TransferImpactAssessmentNeeded: input.TransferImpactAssessmentNeeded, LastReviewDate: input.LastReviewDate, NextReviewDate: input.NextReviewDate, Role: input.Role, DataProtectionOfficerID: input.DataProtectionOfficerID, VendorIDs: input.VendorIds, } activity, err := prb.ProcessingActivities.Create(ctx, &req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create processing activity: %w", err)) } return &types.CreateProcessingActivityPayload{ ProcessingActivityEdge: types.NewProcessingActivityEdge(activity, coredata.ProcessingActivityOrderFieldCreatedAt), }, nil } // UpdateProcessingActivity is the resolver for the updateProcessingActivity field. func (r *mutationResolver) UpdateProcessingActivity(ctx context.Context, input types.UpdateProcessingActivityInput) (*types.UpdateProcessingActivityPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionProcessingActivityUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) req := probo.UpdateProcessingActivityRequest{ ID: input.ID, Name: input.Name, Purpose: gqlutils.UnwrapOmittable(input.Purpose), DataSubjectCategory: gqlutils.UnwrapOmittable(input.DataSubjectCategory), PersonalDataCategory: gqlutils.UnwrapOmittable(input.PersonalDataCategory), SpecialOrCriminalData: input.SpecialOrCriminalData, LawfulBasis: input.LawfulBasis, Recipients: gqlutils.UnwrapOmittable(input.Recipients), Location: gqlutils.UnwrapOmittable(input.Location), InternationalTransfers: input.InternationalTransfers, TransferSafeguard: gqlutils.UnwrapOmittable(input.TransferSafeguards), RetentionPeriod: gqlutils.UnwrapOmittable(input.RetentionPeriod), SecurityMeasures: gqlutils.UnwrapOmittable(input.SecurityMeasures), DataProtectionImpactAssessmentNeeded: input.DataProtectionImpactAssessmentNeeded, TransferImpactAssessmentNeeded: input.TransferImpactAssessmentNeeded, LastReviewDate: gqlutils.UnwrapOmittable(input.LastReviewDate), NextReviewDate: gqlutils.UnwrapOmittable(input.NextReviewDate), Role: input.Role, DataProtectionOfficerID: gqlutils.UnwrapOmittable(input.DataProtectionOfficerID), VendorIDs: &input.VendorIds, } activity, err := prb.ProcessingActivities.Update(ctx, &req) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot update processing activity: %w", err)) } return &types.UpdateProcessingActivityPayload{ ProcessingActivity: types.NewProcessingActivity(activity), }, nil } // DeleteProcessingActivity is the resolver for the deleteProcessingActivity field. func (r *mutationResolver) DeleteProcessingActivity(ctx context.Context, input types.DeleteProcessingActivityInput) (*types.DeleteProcessingActivityPayload, error) { if err := r.authorize(ctx, input.ProcessingActivityID, probo.ActionProcessingActivityDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.ProcessingActivityID.TenantID()) err := prb.ProcessingActivities.Delete(ctx, input.ProcessingActivityID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete processing activity: %w", err)) } return &types.DeleteProcessingActivityPayload{ DeletedProcessingActivityID: input.ProcessingActivityID, }, nil } // CreateDataProtectionImpactAssessment is the resolver for the createDataProtectionImpactAssessment field. func (r *mutationResolver) CreateDataProtectionImpactAssessment(ctx context.Context, input types.CreateDataProtectionImpactAssessmentInput) (*types.CreateDataProtectionImpactAssessmentPayload, error) { if err := r.authorize(ctx, input.ProcessingActivityID, probo.ActionDataProtectionImpactAssessmentCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ProcessingActivityID.TenantID()) req := probo.CreateDataProtectionImpactAssessmentRequest{ ProcessingActivityID: input.ProcessingActivityID, Description: input.Description, NecessityAndProportionality: input.NecessityAndProportionality, PotentialRisk: input.PotentialRisk, Mitigations: input.Mitigations, ResidualRisk: input.ResidualRisk, } dpia, err := prb.DataProtectionImpactAssessments.Create(ctx, &req) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } r.logger.ErrorCtx(ctx, "cannot create data protection impact assessment", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.CreateDataProtectionImpactAssessmentPayload{ DataProtectionImpactAssessment: types.NewDataProtectionImpactAssessment(dpia), }, nil } // UpdateDataProtectionImpactAssessment is the resolver for the updateDataProtectionImpactAssessment field. func (r *mutationResolver) UpdateDataProtectionImpactAssessment(ctx context.Context, input types.UpdateDataProtectionImpactAssessmentInput) (*types.UpdateDataProtectionImpactAssessmentPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionDataProtectionImpactAssessmentUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) req := probo.UpdateDataProtectionImpactAssessmentRequest{ ID: input.ID, Description: gqlutils.UnwrapOmittable(input.Description), NecessityAndProportionality: gqlutils.UnwrapOmittable(input.NecessityAndProportionality), PotentialRisk: gqlutils.UnwrapOmittable(input.PotentialRisk), Mitigations: gqlutils.UnwrapOmittable(input.Mitigations), ResidualRisk: input.ResidualRisk, } dpia, err := prb.DataProtectionImpactAssessments.Update(ctx, &req) if err != nil { panic(fmt.Errorf("cannot update data protection impact assessment: %w", err)) } return &types.UpdateDataProtectionImpactAssessmentPayload{ DataProtectionImpactAssessment: types.NewDataProtectionImpactAssessment(dpia), }, nil } // DeleteDataProtectionImpactAssessment is the resolver for the deleteDataProtectionImpactAssessment field. func (r *mutationResolver) DeleteDataProtectionImpactAssessment(ctx context.Context, input types.DeleteDataProtectionImpactAssessmentInput) (*types.DeleteDataProtectionImpactAssessmentPayload, error) { if err := r.authorize(ctx, input.DataProtectionImpactAssessmentID, probo.ActionDataProtectionImpactAssessmentDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.DataProtectionImpactAssessmentID.TenantID()) err := prb.DataProtectionImpactAssessments.Delete(ctx, input.DataProtectionImpactAssessmentID) if err != nil { panic(fmt.Errorf("cannot delete data protection impact assessment: %w", err)) } return &types.DeleteDataProtectionImpactAssessmentPayload{ DeletedDataProtectionImpactAssessmentID: input.DataProtectionImpactAssessmentID, }, nil } // CreateTransferImpactAssessment is the resolver for the createTransferImpactAssessment field. func (r *mutationResolver) CreateTransferImpactAssessment(ctx context.Context, input types.CreateTransferImpactAssessmentInput) (*types.CreateTransferImpactAssessmentPayload, error) { if err := r.authorize(ctx, input.ProcessingActivityID, probo.ActionTransferImpactAssessmentCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ProcessingActivityID.TenantID()) req := probo.CreateTransferImpactAssessmentRequest{ ProcessingActivityID: input.ProcessingActivityID, DataSubjects: input.DataSubjects, LegalMechanism: input.LegalMechanism, Transfer: input.Transfer, LocalLawRisk: input.LocalLawRisk, SupplementaryMeasures: input.SupplementaryMeasures, } tia, err := prb.TransferImpactAssessments.Create(ctx, &req) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { return nil, gqlutils.Conflict(ctx, err) } r.logger.ErrorCtx(ctx, "cannot create transfer impact assessment", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.CreateTransferImpactAssessmentPayload{ TransferImpactAssessment: types.NewTransferImpactAssessment(tia), }, nil } // UpdateTransferImpactAssessment is the resolver for the updateTransferImpactAssessment field. func (r *mutationResolver) UpdateTransferImpactAssessment(ctx context.Context, input types.UpdateTransferImpactAssessmentInput) (*types.UpdateTransferImpactAssessmentPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionTransferImpactAssessmentUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) req := probo.UpdateTransferImpactAssessmentRequest{ ID: input.ID, DataSubjects: gqlutils.UnwrapOmittable(input.DataSubjects), LegalMechanism: gqlutils.UnwrapOmittable(input.LegalMechanism), Transfer: gqlutils.UnwrapOmittable(input.Transfer), LocalLawRisk: gqlutils.UnwrapOmittable(input.LocalLawRisk), SupplementaryMeasures: gqlutils.UnwrapOmittable(input.SupplementaryMeasures), } tia, err := prb.TransferImpactAssessments.Update(ctx, &req) if err != nil { panic(fmt.Errorf("cannot update transfer impact assessment: %w", err)) } return &types.UpdateTransferImpactAssessmentPayload{ TransferImpactAssessment: types.NewTransferImpactAssessment(tia), }, nil } // DeleteTransferImpactAssessment is the resolver for the deleteTransferImpactAssessment field. func (r *mutationResolver) DeleteTransferImpactAssessment(ctx context.Context, input types.DeleteTransferImpactAssessmentInput) (*types.DeleteTransferImpactAssessmentPayload, error) { if err := r.authorize(ctx, input.TransferImpactAssessmentID, probo.ActionTransferImpactAssessmentDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.TransferImpactAssessmentID.TenantID()) err := prb.TransferImpactAssessments.Delete(ctx, input.TransferImpactAssessmentID) if err != nil { panic(fmt.Errorf("cannot delete transfer impact assessment: %w", err)) } return &types.DeleteTransferImpactAssessmentPayload{ DeletedTransferImpactAssessmentID: input.TransferImpactAssessmentID, }, nil } // CreateSnapshot is the resolver for the createSnapshot field. func (r *mutationResolver) CreateSnapshot(ctx context.Context, input types.CreateSnapshotInput) (*types.CreateSnapshotPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionSnapshotCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) snapshot, err := prb.Snapshots.Create( ctx, &probo.CreateSnapshotRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Description: input.Description, Type: input.Type, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create snapshot: %w", err)) } return &types.CreateSnapshotPayload{ SnapshotEdge: types.NewSnapshotEdge(snapshot, coredata.SnapshotOrderFieldCreatedAt), }, nil } // DeleteSnapshot is the resolver for the deleteSnapshot field. func (r *mutationResolver) DeleteSnapshot(ctx context.Context, input types.DeleteSnapshotInput) (*types.DeleteSnapshotPayload, error) { if err := r.authorize(ctx, input.SnapshotID, probo.ActionSnapshotDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.SnapshotID.TenantID()) err := prb.Snapshots.Delete(ctx, input.SnapshotID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete snapshot: %w", err)) } return &types.DeleteSnapshotPayload{ DeletedSnapshotID: input.SnapshotID, }, nil } // CreateCustomDomain is the resolver for the createCustomDomain field. func (r *mutationResolver) CreateCustomDomain(ctx context.Context, input types.CreateCustomDomainInput) (*types.CreateCustomDomainPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionCustomDomainCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) domain, err := prb.CustomDomains.CreateCustomDomain( ctx, probo.CreateCustomDomainRequest{ OrganizationID: input.OrganizationID, Domain: input.Domain, }, ) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot create custom domain: %w", err)) } return &types.CreateCustomDomainPayload{ CustomDomain: types.NewCustomDomain(domain, r.customDomainCname), }, nil } // DeleteCustomDomain is the resolver for the deleteCustomDomain field. func (r *mutationResolver) DeleteCustomDomain(ctx context.Context, input types.DeleteCustomDomainInput) (*types.DeleteCustomDomainPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionCustomDomainDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) // TODO Drop this wierd logic // Get the current custom domain ID before deleting domain, err := prb.CustomDomains.GetOrganizationCustomDomain(ctx, input.OrganizationID) if err != nil { panic(fmt.Errorf("cannot get custom domain: %w", err)) } if domain == nil { return nil, fmt.Errorf("organization has no custom domain") } deletedDomainID := domain.ID if err := prb.CustomDomains.DeleteCustomDomain(ctx, input.OrganizationID); err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot delete custom domain: %w", err)) } return &types.DeleteCustomDomainPayload{ DeletedCustomDomainID: deletedDomainID, }, nil } // Organization is the resolver for the organization field. func (r *nonconformityResolver) Organization(ctx context.Context, obj *types.Nonconformity) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get nonconformity organization: %w", err)) } return types.NewOrganization(organization), nil } // Audit is the resolver for the audit field. func (r *nonconformityResolver) Audit(ctx context.Context, obj *types.Nonconformity) (*types.Audit, error) { if err := r.authorize(ctx, obj.ID, probo.ActionAuditGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) if obj.Audit == nil { return nil, nil } audit, err := prb.Audits.Get(ctx, obj.Audit.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get nonconformity audit: %w", err)) } return types.NewAudit(audit), nil } // Owner is the resolver for the owner field. func (r *nonconformityResolver) Owner(ctx context.Context, obj *types.Nonconformity) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } owner, err := r.iam.OrganizationService.GetProfile(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get nonconformity owner: %w", err)) } return types.NewProfile(owner), nil } // Permission is the resolver for the permission field. func (r *nonconformityResolver) Permission(ctx context.Context, obj *types.Nonconformity, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *nonconformityConnectionResolver) TotalCount(ctx context.Context, obj *types.NonconformityConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionNonconformityList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: nonconformityFilter := coredata.NewNonconformityFilter(nil) if obj.Filter != nil { nonconformityFilter = coredata.NewNonconformityFilter(&obj.Filter.SnapshotID) } count, err := prb.Nonconformities.CountForOrganizationID(ctx, obj.ParentID, nonconformityFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count nonconformities: %w", err)) } return count, nil } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Organization is the resolver for the organization field. func (r *obligationResolver) Organization(ctx context.Context, obj *types.Obligation) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get obligation organization: %w", err)) } return types.NewOrganization(organization), nil } // Owner is the resolver for the owner field. func (r *obligationResolver) Owner(ctx context.Context, obj *types.Obligation) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } owner, err := r.iam.OrganizationService.GetProfile(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get obligation owner: %w", err)) } return types.NewProfile(owner), nil } // Permission is the resolver for the permission field. func (r *obligationResolver) Permission(ctx context.Context, obj *types.Obligation, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *obligationConnectionResolver) TotalCount(ctx context.Context, obj *types.ObligationConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionObligationList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: obligationFilter := coredata.NewObligationFilter(nil) if obj.Filter != nil { obligationFilter = coredata.NewObligationFilter(&obj.Filter.SnapshotID) } count, err := prb.Obligations.CountForOrganizationID(ctx, obj.ParentID, obligationFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count obligations: %w", err)) } return count, nil case *riskResolver: obligationFilter := coredata.NewObligationFilter(nil) if obj.Filter != nil { obligationFilter = coredata.NewObligationFilter(&obj.Filter.SnapshotID) } count, err := prb.Obligations.CountForRiskID(ctx, obj.ParentID, obligationFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count risk obligations: %w", err)) } return count, nil } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // LogoURL is the resolver for the logoUrl field. func (r *organizationResolver) LogoURL(ctx context.Context, obj *types.Organization) (*string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGetLogoUrl); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) logoURL, err := prb.Organizations.GenerateLogoURL(ctx, obj.ID, 1*time.Hour) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot generate logo url: %w", err)) } return logoURL, nil } // HorizontalLogoURL is the resolver for the horizontalLogoUrl field. func (r *organizationResolver) HorizontalLogoURL(ctx context.Context, obj *types.Organization) (*string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGetHorizontalLogoUrl); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) horizontalLogoURL, err := prb.Organizations.GenerateHorizontalLogoURL(ctx, obj.ID, 1*time.Hour) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot generate horizontal logo url: %w", err)) } return horizontalLogoURL, nil } // Context is the resolver for the context field. func (r *organizationResolver) Context(ctx context.Context, obj *types.Organization) (*types.OrganizationContext, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationContextGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) orgContext, err := prb.Organizations.GetContextSummary(ctx, obj.ID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot load organization context: %w", err)) } return types.NewOrganizationContext(orgContext), nil } // Profiles is the resolver for the profiles field. func (r *organizationResolver) Profiles(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProfileOrderBy, filter *types.ProfileFilter) (*types.ProfileConnection, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileList); err != nil { return nil, err } if gqlutils.OnlyTotalCountSelected(ctx) { return &types.ProfileConnection{ Resolver: r, ParentID: obj.ID, }, nil } filters := coredata.NewMembershipProfileFilter(nil) if filter != nil { filters = coredata.NewMembershipProfileFilter(filter.ExcludeContractEnded) } pageOrderBy := page.OrderBy[coredata.MembershipProfileOrderField]{ Field: coredata.MembershipProfileOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy.Field = coredata.MembershipProfileOrderField(orderBy.Field) pageOrderBy.Direction = page.OrderDirection(orderBy.Direction) } cursor := cursor.NewCursor(first, after, last, before, pageOrderBy) page, err := r.iam.OrganizationService.ListProfiles(ctx, obj.ID, cursor, filters) if err != nil { r.logger.ErrorCtx(ctx, "cannot list profiles", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewProfileConnection(page, r, obj.ID, filters), nil } // SlackConnections is the resolver for the slackConnections field. func (r *organizationResolver) SlackConnections(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.SlackConnectionConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionSlackConnectionList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) slackProvider := coredata.ConnectorProviderSlack filter := coredata.NewConnectorProviderFilter(&slackProvider) pageOrderBy := page.OrderBy[coredata.ConnectorOrderField]{ Field: coredata.ConnectorOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Connectors.ListForOrganizationID(ctx, obj.ID, cursor, filter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization slack connections: %w", err)) } return types.NewSlackConnectionConnection(page), nil } // Frameworks is the resolver for the frameworks field. func (r *organizationResolver) Frameworks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.FrameworkOrderBy) (*types.FrameworkConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionFrameworkList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.FrameworkOrderField]{ Field: coredata.FrameworkOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.FrameworkOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Frameworks.ListForOrganizationID(ctx, obj.ID, cursor) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization frameworks: %w", err)) } return types.NewFrameworkConnection(page, r, obj.ID), nil } // Controls is the resolver for the controls field. func (r *organizationResolver) Controls(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ControlOrderField]{ Field: coredata.ControlOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ControlOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var controlFilter = coredata.NewControlFilter(nil) if filter != nil { controlFilter = coredata.NewControlFilter(filter.Query) } page, err := prb.Controls.ListForOrganizationID(ctx, obj.ID, cursor, controlFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list controls: %w", err)) } return types.NewControlConnection(page, r, obj.ID, controlFilter), nil } // Vendors is the resolver for the vendors field. func (r *organizationResolver) Vendors(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy, filter *types.VendorFilter) (*types.VendorConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.VendorOrderField]{ Field: coredata.VendorOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.VendorOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var vendorFilter = coredata.NewVendorFilter(nil, nil) if filter != nil { vendorFilter = coredata.NewVendorFilter(&filter.SnapshotID, nil) } page, err := prb.Vendors.ListForOrganizationID(ctx, obj.ID, cursor, vendorFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization vendors: %w", err)) } return types.NewVendorConnection(page, r, obj.ID), nil } // Documents is the resolver for the documents field. func (r *organizationResolver) Documents(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) (*types.DocumentConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDocumentList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{ Field: coredata.DocumentOrderFieldTitle, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var documentFilter = coredata.NewDocumentFilter(nil) if filter != nil { documentFilter = coredata.NewDocumentFilter(filter.Query) } page, err := prb.Documents.ListByOrganizationID(ctx, obj.ID, cursor, documentFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization documents: %w", err)) } return types.NewDocumentConnection(page, r, obj.ID, documentFilter), nil } // Meetings is the resolver for the meetings field. func (r *organizationResolver) Meetings(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeetingOrderBy) (*types.MeetingConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionMeetingList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.MeetingOrderField]{ Field: coredata.MeetingOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.MeetingOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Meetings.ListForOrganizationID(ctx, obj.ID, cursor) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization meetings: %w", err)) } return types.NewMeetingConnection(page, r, obj.ID), nil } // StatesOfApplicability is the resolver for the statesOfApplicability field. func (r *organizationResolver) StatesOfApplicability(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.StateOfApplicabilityOrderBy, filter *types.StateOfApplicabilityFilter) (*types.StateOfApplicabilityConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionStateOfApplicabilityList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.StateOfApplicabilityOrderField]{ Field: coredata.StateOfApplicabilityOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.StateOfApplicabilityOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var stateOfApplicabilityFilter = coredata.NewStateOfApplicabilityFilter(nil) if filter != nil { stateOfApplicabilityFilter = coredata.NewStateOfApplicabilityFilter(&filter.SnapshotID) } page, err := prb.StatesOfApplicability.ListForOrganizationID(ctx, obj.ID, cursor, stateOfApplicabilityFilter) if err != nil { panic(fmt.Errorf("cannot list organization states_of_applicability: %w", err)) } return types.NewStateOfApplicabilityConnection(page, r, obj.ID, stateOfApplicabilityFilter), nil } // Measures is the resolver for the measures field. func (r *organizationResolver) Measures(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) (*types.MeasureConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionMeasureList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.MeasureOrderField]{ Field: coredata.MeasureOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.MeasureOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var measureFilter = coredata.NewMeasureFilter(nil, nil) if filter != nil { measureFilter = coredata.NewMeasureFilter(filter.Query, filter.State) } page, err := prb.Measures.ListForOrganizationID(ctx, obj.ID, cursor, measureFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization measures: %w", err)) } return types.NewMeasureConnection(page, r, obj.ID, measureFilter), nil } // Risks is the resolver for the risks field. func (r *organizationResolver) Risks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.RiskOrderBy, filter *types.RiskFilter) (*types.RiskConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionRiskList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.RiskOrderField]{ Field: coredata.RiskOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.RiskOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var riskFilter = coredata.NewRiskFilter(nil, nil) if filter != nil { riskFilter = coredata.NewRiskFilter(filter.Query, &filter.SnapshotID) } page, err := prb.Risks.ListForOrganizationID(ctx, obj.ID, cursor, riskFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization risks: %w", err)) } return types.NewRiskConnection(page, r, obj.ID, riskFilter), nil } // Tasks is the resolver for the tasks field. func (r *organizationResolver) Tasks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TaskOrderBy) (*types.TaskConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTaskList); err != nil { return nil, err } prb := r.ProboService(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 := prb.Tasks.ListForOrganizationID(ctx, obj.ID, cursor) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization tasks: %w", err)) } return types.NewTaskConnection(page, r, obj.ID), nil } // Assets is the resolver for the assets field. func (r *organizationResolver) Assets(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AssetOrderBy, filter *types.AssetFilter) (*types.AssetConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionAssetList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.AssetOrderField]{ Field: coredata.AssetOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.AssetOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) assetFilter := coredata.NewAssetFilter(nil) if filter != nil { assetFilter = coredata.NewAssetFilter(&filter.SnapshotID) } page, err := prb.Assets.ListForOrganizationID(ctx, obj.ID, cursor, assetFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization assets: %w", err)) } return types.NewAssetConnection(page, r, obj.ID, filter), nil } // Assets is the resolver for the assets field. func (r *organizationResolver) Data(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DatumOrderBy, filter *types.DatumFilter) (*types.DatumConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDatumList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DatumOrderField]{ Field: coredata.DatumOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DatumOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) datumFilter := coredata.NewDatumFilter(nil) if filter != nil { datumFilter = coredata.NewDatumFilter(&filter.SnapshotID) } page, err := prb.Data.ListForOrganizationID(ctx, obj.ID, cursor, datumFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization data: %w", err)) } return types.NewDataConnection(page, r, obj.ID, filter), nil } // Audits is the resolver for the audits field. func (r *organizationResolver) Audits(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AuditOrderBy) (*types.AuditConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionAuditList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.AuditOrderField]{ Field: coredata.AuditOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.AuditOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Audits.ListForOrganizationID(ctx, obj.ID, cursor) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization audits: %w", err)) } return types.NewAuditConnection(page, r, obj.ID), nil } // Nonconformities is the resolver for the nonconformities field. func (r *organizationResolver) Nonconformities(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.NonconformityOrderBy, filter *types.NonconformityFilter) (*types.NonconformityConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionNonconformityList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.NonconformityOrderField]{ Field: coredata.NonconformityOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.NonconformityOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) nonconformityFilter := coredata.NewNonconformityFilter(nil) if filter != nil { nonconformityFilter = coredata.NewNonconformityFilter(&filter.SnapshotID) } page, err := prb.Nonconformities.ListForOrganizationID(ctx, obj.ID, cursor, nonconformityFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization nonconformities: %w", err)) } return types.NewNonconformityConnection(page, r, obj.ID, filter), nil } // Obligations is the resolver for the obligations field. func (r *organizationResolver) Obligations(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ObligationOrderBy, filter *types.ObligationFilter) (*types.ObligationConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionObligationList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ObligationOrderField]{ Field: coredata.ObligationOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ObligationOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) obligationFilter := coredata.NewObligationFilter(nil) if filter != nil { obligationFilter = coredata.NewObligationFilter(&filter.SnapshotID) } page, err := prb.Obligations.ListForOrganizationID(ctx, obj.ID, cursor, obligationFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization obligations: %w", err)) } return types.NewObligationConnection(page, r, obj.ID, filter), nil } // ContinualImprovements is the resolver for the continualImprovements field. func (r *organizationResolver) ContinualImprovements(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ContinualImprovementOrderBy, filter *types.ContinualImprovementFilter) (*types.ContinualImprovementConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionContinualImprovementList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ContinualImprovementOrderField]{ Field: coredata.ContinualImprovementOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ContinualImprovementOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) continualImprovementFilter := coredata.NewContinualImprovementFilter(nil) if filter != nil { continualImprovementFilter = coredata.NewContinualImprovementFilter(&filter.SnapshotID) } page, err := prb.ContinualImprovements.ListForOrganizationID(ctx, obj.ID, cursor, continualImprovementFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization continual improvements: %w", err)) } return types.NewContinualImprovementConnection(page, r, obj.ID, filter), nil } // RightsRequests is the resolver for the rightsRequests field. func (r *organizationResolver) RightsRequests(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.RightsRequestOrderBy) (*types.RightsRequestConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionRightsRequestList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.RightsRequestOrderField]{ Field: coredata.RightsRequestOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.RightsRequestOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.RightsRequests.ListForOrganizationID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list organization rights requests: %w", err)) } return types.NewRightsRequestConnection(page, r, obj.ID), nil } // ProcessingActivities is the resolver for the processingActivities field. func (r *organizationResolver) ProcessingActivities(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProcessingActivityOrderBy, filter *types.ProcessingActivityFilter) (*types.ProcessingActivityConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionProcessingActivityList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ProcessingActivityOrderField]{ Field: coredata.ProcessingActivityOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ProcessingActivityOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) processingActivityFilter := coredata.NewProcessingActivityFilter(nil) if filter != nil { processingActivityFilter = coredata.NewProcessingActivityFilter(&filter.SnapshotID) } page, err := prb.ProcessingActivities.ListForOrganizationID(ctx, obj.ID, cursor, processingActivityFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization processing activities: %w", err)) } return types.NewProcessingActivityConnection(page, r, obj.ID, filter), nil } // DataProtectionImpactAssessments is the resolver for the dataProtectionImpactAssessments field. func (r *organizationResolver) DataProtectionImpactAssessments(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DataProtectionImpactAssessmentOrderBy, filter *types.DataProtectionImpactAssessmentFilter) (*types.DataProtectionImpactAssessmentConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDataProtectionImpactAssessmentList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DataProtectionImpactAssessmentOrderField]{ Field: coredata.DataProtectionImpactAssessmentOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DataProtectionImpactAssessmentOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) dpiaFilter := coredata.NewDataProtectionImpactAssessmentFilter(nil) if filter != nil { dpiaFilter = coredata.NewDataProtectionImpactAssessmentFilter(&filter.SnapshotID) } page, err := prb.DataProtectionImpactAssessments.ListForOrganizationID(ctx, obj.ID, cursor, dpiaFilter) if err != nil { panic(fmt.Errorf("cannot list organization data protection impact assessments: %w", err)) } return types.NewDataProtectionImpactAssessmentConnection(page, r, obj.ID, dpiaFilter), nil } // TransferImpactAssessments is the resolver for the transferImpactAssessments field. func (r *organizationResolver) TransferImpactAssessments(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TransferImpactAssessmentOrderBy, filter *types.TransferImpactAssessmentFilter) (*types.TransferImpactAssessmentConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTransferImpactAssessmentList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.TransferImpactAssessmentOrderField]{ Field: coredata.TransferImpactAssessmentOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.TransferImpactAssessmentOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) tiaFilter := coredata.NewTransferImpactAssessmentFilter(nil) if filter != nil { tiaFilter = coredata.NewTransferImpactAssessmentFilter(&filter.SnapshotID) } page, err := prb.TransferImpactAssessments.ListForOrganizationID(ctx, obj.ID, cursor, tiaFilter) if err != nil { panic(fmt.Errorf("cannot list organization transfer impact assessments: %w", err)) } return types.NewTransferImpactAssessmentConnection(page, r, obj.ID, tiaFilter), nil } // Snapshots is the resolver for the snapshots field. func (r *organizationResolver) Snapshots(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SnapshotOrderBy) (*types.SnapshotConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionSnapshotList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.SnapshotOrderField]{ Field: coredata.SnapshotOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.SnapshotOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Snapshots.ListForOrganizationID(ctx, obj.ID, cursor) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization snapshots: %w", err)) } return types.NewSnapshotConnection(page, r, obj.ID), nil } // TrustCenterFiles is the resolver for the trustCenterFiles field. func (r *organizationResolver) TrustCenterFiles(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterFileOrderField]) (*types.TrustCenterFileConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterFileList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.TrustCenterFileOrderField]{ Field: coredata.TrustCenterFileOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.TrustCenterFileOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) pageResult, err := prb.TrustCenterFiles.ListForOrganizationID(ctx, obj.ID, cursor, &coredata.TrustCenterFileFilter{}) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list organization trust center files: %w", err)) } return types.NewTrustCenterFileConnection(pageResult, obj.ID), nil } // TrustCenter is the resolver for the trustCenter field. func (r *organizationResolver) TrustCenter(ctx context.Context, obj *types.Organization) (*types.TrustCenter, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) trustCenter, file, err := prb.TrustCenters.GetByOrganizationID(ctx, obj.ID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get trust center: %w", err)) } return types.NewTrustCenter(trustCenter, file), nil } // CustomDomain is the resolver for the customDomain field. func (r *organizationResolver) CustomDomain(ctx context.Context, obj *types.Organization) (*types.CustomDomain, error) { if err := r.authorize(ctx, obj.ID, probo.ActionCustomDomainGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) domain, err := prb.CustomDomains.GetOrganizationCustomDomain(ctx, obj.ID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get custom domain: %w", err)) } if domain == nil { return nil, nil } return types.NewCustomDomain(domain, r.customDomainCname), nil } // Permission is the resolver for the permission field. func (r *organizationResolver) Permission(ctx context.Context, obj *types.Organization, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // Organization is the resolver for the organization field. func (r *processingActivityResolver) Organization(ctx context.Context, obj *types.ProcessingActivity) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // DataProtectionOfficer is the resolver for the dataProtectionOfficer field. func (r *processingActivityResolver) DataProtectionOfficer(ctx context.Context, obj *types.ProcessingActivity) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } if obj.DataProtectionOfficer == nil { return nil, nil } dpo, err := r.iam.OrganizationService.GetProfile(ctx, obj.DataProtectionOfficer.ID) if err != nil { panic(fmt.Errorf("cannot get data protection officer: %w", err)) } return types.NewProfile(dpo), nil } // Vendors is the resolver for the vendors field. func (r *processingActivityResolver) Vendors(ctx context.Context, obj *types.ProcessingActivity, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) (*types.VendorConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.VendorOrderField]{ Field: coredata.VendorOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.VendorOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Vendors.ListForProcessingActivityID(ctx, obj.ID, cursor) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list processing activity vendors: %w", err)) } return types.NewVendorConnection(page, r, obj.ID), nil } // DataProtectionImpactAssessment is the resolver for the dataProtectionImpactAssessment field. func (r *processingActivityResolver) DataProtectionImpactAssessment(ctx context.Context, obj *types.ProcessingActivity) (*types.DataProtectionImpactAssessment, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDataProtectionImpactAssessmentGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) dpia, err := prb.DataProtectionImpactAssessments.GetByProcessingActivityID(ctx, obj.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, nil } panic(fmt.Errorf("cannot get processing activity dpia: %w", err)) } return types.NewDataProtectionImpactAssessment(dpia), nil } // TransferImpactAssessment is the resolver for the transferImpactAssessment field. func (r *processingActivityResolver) TransferImpactAssessment(ctx context.Context, obj *types.ProcessingActivity) (*types.TransferImpactAssessment, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTransferImpactAssessmentGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) tia, err := prb.TransferImpactAssessments.GetByProcessingActivityID(ctx, obj.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, nil } panic(fmt.Errorf("cannot get processing activity tia: %w", err)) } return types.NewTransferImpactAssessment(tia), nil } // Permission is the resolver for the permission field. func (r *processingActivityResolver) Permission(ctx context.Context, obj *types.ProcessingActivity, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *processingActivityConnectionResolver) TotalCount(ctx context.Context, obj *types.ProcessingActivityConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionProcessingActivityList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: processingActivityFilter := coredata.NewProcessingActivityFilter(nil) if obj.Filter != nil { processingActivityFilter = coredata.NewProcessingActivityFilter(&obj.Filter.SnapshotID) } count, err := prb.ProcessingActivities.CountForOrganizationID(ctx, obj.ParentID, processingActivityFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count organization processing activities: %w", err)) } return count, nil } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Permission is the resolver for the permission field. func (r *profileResolver) Permission(ctx context.Context, obj *types.Profile, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *profileConnectionResolver) TotalCount(ctx context.Context, obj *types.ProfileConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, iam.ActionMembershipProfileList); err != nil { return 0, err } switch obj.Resolver.(type) { case *stateOfApplicabilityResolver: count, err := r.iam.OrganizationService.CountProfiles(ctx, obj.ParentID, obj.Filters) if err != nil { panic(fmt.Errorf("cannot count profiles: %w", err)) } return count, nil } panic(fmt.Errorf("not implemented: TotalCount for parent type %T", obj.Resolver)) } // Node is the resolver for the node field. func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error) { var ( loadNode func(ctx context.Context, id gid.GID) (types.Node, error) action string prb = r.ProboService(ctx, id.TenantID()) ) switch id.EntityType() { case coredata.OrganizationEntityType: action = iam.ActionOrganizationGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { organization, err := prb.Organizations.Get(ctx, id) if err != nil { return nil, err } return types.NewOrganization(organization), nil } case coredata.VendorEntityType: action = probo.ActionVendorGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { vendor, err := prb.Vendors.Get(ctx, id) if err != nil { return nil, err } return types.NewVendor(vendor), nil } case coredata.FrameworkEntityType: action = probo.ActionFrameworkGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { framework, err := prb.Frameworks.Get(ctx, id) if err != nil { return nil, err } return types.NewFramework(framework), nil } case coredata.MeasureEntityType: action = probo.ActionMeasureGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { measure, err := prb.Measures.Get(ctx, id) if err != nil { return nil, err } return types.NewMeasure(measure), nil } case coredata.TaskEntityType: action = probo.ActionTaskGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { task, err := prb.Tasks.Get(ctx, id) if err != nil { return nil, err } return types.NewTask(task), nil } case coredata.EvidenceEntityType: action = probo.ActionEvidenceList loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { evidence, err := prb.Evidences.Get(ctx, id) if err != nil { return nil, err } return types.NewEvidence(evidence), nil } case coredata.DocumentEntityType: action = probo.ActionDocumentGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { document, err := prb.Documents.Get(ctx, id) if err != nil { return nil, err } return types.NewDocument(document), nil } case coredata.ControlEntityType: action = probo.ActionControlList loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { control, err := prb.Controls.Get(ctx, id) if err != nil { return nil, err } return types.NewControl(control), nil } case coredata.RiskEntityType: action = probo.ActionRiskGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { risk, err := prb.Risks.Get(ctx, id) if err != nil { return nil, err } return types.NewRisk(risk), nil } case coredata.VendorComplianceReportEntityType: action = probo.ActionVendorComplianceReportGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { vendorComplianceReport, err := prb.VendorComplianceReports.Get(ctx, id) if err != nil { return nil, err } return types.NewVendorComplianceReport(vendorComplianceReport), nil } case coredata.VendorContactEntityType: action = probo.ActionVendorContactGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { vendorContact, err := prb.VendorContacts.Get(ctx, id) if err != nil { return nil, err } return types.NewVendorContact(vendorContact), nil } case coredata.VendorServiceEntityType: action = probo.ActionVendorServiceGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { vendorService, err := prb.VendorServices.Get(ctx, id) if err != nil { return nil, err } return types.NewVendorService(vendorService), nil } case coredata.DocumentVersionEntityType: action = probo.ActionDocumentVersionList loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { documentVersion, err := prb.Documents.GetVersion(ctx, id) if err != nil { return nil, err } return types.NewDocumentVersion(documentVersion), nil } case coredata.DocumentVersionSignatureEntityType: action = probo.ActionDocumentVersionSignatureList loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { documentVersionSignature, err := prb.Documents.GetVersionSignature(ctx, id) if err != nil { return nil, err } return types.NewDocumentVersionSignature(documentVersionSignature), nil } case coredata.AssetEntityType: action = probo.ActionAssetList loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { asset, err := prb.Assets.Get(ctx, id) if err != nil { return nil, err } return types.NewAsset(asset), nil } case coredata.DatumEntityType: action = probo.ActionDatumList loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { datum, err := prb.Data.Get(ctx, id) if err != nil { return nil, err } return types.NewDatum(datum), nil } case coredata.AuditEntityType: action = probo.ActionAuditList loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { audit, err := prb.Audits.Get(ctx, id) if err != nil { return nil, err } return types.NewAudit(audit), nil } case coredata.NonconformityEntityType: action = probo.ActionNonconformityList loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { nonconformity, err := prb.Nonconformities.Get(ctx, id) if err != nil { return nil, err } return types.NewNonconformity(nonconformity), nil } case coredata.ObligationEntityType: action = probo.ActionObligationList loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { obligation, err := prb.Obligations.Get(ctx, id) if err != nil { return nil, err } return types.NewObligation(obligation), nil } case coredata.ContinualImprovementEntityType: action = probo.ActionContinualImprovementList loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { continualImprovement, err := prb.ContinualImprovements.Get(ctx, id) if err != nil { return nil, err } return types.NewContinualImprovement(continualImprovement), nil } case coredata.ReportEntityType: action = probo.ActionReportGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { report, err := prb.Reports.Get(ctx, id) if err != nil { return nil, err } return types.NewReport(report), nil } case coredata.ProcessingActivityEntityType: action = probo.ActionProcessingActivityList loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { processingActivity, err := prb.ProcessingActivities.Get(ctx, id) if err != nil { return nil, err } return types.NewProcessingActivity(processingActivity), nil } case coredata.DataProtectionImpactAssessmentEntityType: // TODO: add action // action = probo.ActionDataProtectionImpactAssessmentGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { dpia, err := prb.DataProtectionImpactAssessments.Get(ctx, id) if err != nil { return nil, err } return types.NewDataProtectionImpactAssessment(dpia), nil } case coredata.TransferImpactAssessmentEntityType: // TODO: add action //action = probo.ActionTransferImpactAssessmentGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { tia, err := prb.TransferImpactAssessments.Get(ctx, id) if err != nil { return nil, err } return types.NewTransferImpactAssessment(tia), nil } case coredata.SnapshotEntityType: action = probo.ActionSnapshotList loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { snapshot, err := prb.Snapshots.Get(ctx, id) if err != nil { return nil, err } return types.NewSnapshot(snapshot), nil } case coredata.TrustCenterEntityType: action = probo.ActionTrustCenterGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { trustCenter, file, err := prb.TrustCenters.Get(ctx, id) if err != nil { return nil, err } return types.NewTrustCenter(trustCenter, file), nil } case coredata.TrustCenterAccessEntityType: action = probo.ActionTrustCenterAccessGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { trustCenterAccess, err := prb.TrustCenterAccesses.Get(ctx, id) if err != nil { return nil, err } return types.NewTrustCenterAccess(trustCenterAccess), nil } case coredata.MeetingEntityType: action = probo.ActionMeetingGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { meeting, err := prb.Meetings.Get(ctx, id) if err != nil { return nil, err } return types.NewMeeting(meeting), nil } case coredata.RightsRequestEntityType: action = probo.ActionRightsRequestGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { rightsRequest, err := prb.RightsRequests.Get(ctx, id) if err != nil { return nil, err } return types.NewRightsRequest(rightsRequest), nil } case coredata.StateOfApplicabilityEntityType: action = probo.ActionStateOfApplicabilityGet loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) { stateOfApplicability, err := prb.StatesOfApplicability.Get(ctx, id) if err != nil { return nil, err } return types.NewStateOfApplicability(stateOfApplicability), nil } default: } if err := r.authorize(ctx, id, action); err != nil { return nil, err } node, err := loadNode(ctx, id) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load node: %w", err)) } return node, nil } // Viewer is the resolver for the viewer field. func (r *queryResolver) Viewer(ctx context.Context) (*types.Viewer, error) { identity := authn.IdentityFromContext(ctx) session := authn.SessionFromContext(ctx) apiKey := authn.APIKeyFromContext(ctx) var viewerID gid.GID if session != nil { viewerID = session.ID } else if apiKey != nil { viewerID = apiKey.ID } else { viewerID = identity.ID } return &types.Viewer{ID: viewerID}, nil } // DownloadURL is the resolver for the downloadUrl field. func (r *reportResolver) DownloadURL(ctx context.Context, obj *types.Report) (*string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionReportDownloadUrlGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) url, err := prb.Reports.GenerateDownloadURL(ctx, obj.ID, 15*time.Minute) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot generate download URL: %w", err)) } return url, nil } // Audit is the resolver for the audit field. func (r *reportResolver) Audit(ctx context.Context, obj *types.Report) (*types.Audit, error) { if err := r.authorize(ctx, obj.ID, probo.ActionAuditGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) audit, err := prb.Audits.GetByReportID(ctx, obj.ID) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot load audit for report: %w", err)) } return types.NewAudit(audit), nil } // Permission is the resolver for the permission field. func (r *reportResolver) Permission(ctx context.Context, obj *types.Report, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // Organization is the resolver for the organization field. func (r *rightsRequestResolver) Organization(ctx context.Context, obj *types.RightsRequest) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, iam.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) rightsRequest, err := prb.RightsRequests.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get rights request: %w", err)) } organization, err := prb.Organizations.Get(ctx, rightsRequest.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // Permission is the resolver for the permission field. func (r *rightsRequestResolver) Permission(ctx context.Context, obj *types.RightsRequest, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *rightsRequestConnectionResolver) TotalCount(ctx context.Context, obj *types.RightsRequestConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionRightsRequestList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.RightsRequests.CountByOrganizationID(ctx, obj.ParentID) if err != nil { panic(fmt.Errorf("cannot count rights requests: %w", err)) } return count, nil default: panic(fmt.Errorf("unsupported resolver type for RightsRequestConnection: %T", obj.Resolver)) } } // Owner is the resolver for the owner field. func (r *riskResolver) Owner(ctx context.Context, obj *types.Risk) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } if obj.Owner == nil { return nil, nil } owner, err := r.iam.OrganizationService.GetProfile(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get owner: %w", err)) } return types.NewProfile(owner), nil } // Organization is the resolver for the organization field. func (r *riskResolver) Organization(ctx context.Context, obj *types.Risk) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // Measures is the resolver for the measures field. func (r *riskResolver) Measures(ctx context.Context, obj *types.Risk, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) (*types.MeasureConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionMeasureList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.MeasureOrderField]{ Field: coredata.MeasureOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.MeasureOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var measureFilter = coredata.NewMeasureFilter(nil, nil) if filter != nil { measureFilter = coredata.NewMeasureFilter(filter.Query, filter.State) } page, err := prb.Measures.ListForRiskID(ctx, obj.ID, cursor, measureFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list risk measures: %w", err)) } return types.NewMeasureConnection(page, r, obj.ID, measureFilter), nil } // Documents is the resolver for the documents field. func (r *riskResolver) Documents(ctx context.Context, obj *types.Risk, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) (*types.DocumentConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDocumentList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{ Field: coredata.DocumentOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var documentFilter = coredata.NewDocumentFilter(nil) if filter != nil { documentFilter = coredata.NewDocumentFilter(filter.Query) } page, err := prb.Documents.ListForRiskID(ctx, obj.ID, cursor, documentFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list risk documents: %w", err)) } return types.NewDocumentConnection(page, r, obj.ID, documentFilter), nil } // Controls is the resolver for the controls field. func (r *riskResolver) Controls(ctx context.Context, obj *types.Risk, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ControlOrderField]{ Field: coredata.ControlOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ControlOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var filters = coredata.NewControlFilter(nil) if filter != nil { filters = coredata.NewControlFilter(filter.Query) } page, err := prb.Controls.ListForRiskID(ctx, obj.ID, cursor, filters) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list risk controls: %w", err)) } return types.NewControlConnection(page, r, obj.ID, filters), nil } // Obligations is the resolver for the obligations field. func (r *riskResolver) Obligations(ctx context.Context, obj *types.Risk, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ObligationOrderBy, filter *types.ObligationFilter) (*types.ObligationConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionObligationList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ObligationOrderField]{ Field: coredata.ObligationOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ObligationOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var obligationFilter = coredata.NewObligationFilter(nil) if filter != nil { obligationFilter = coredata.NewObligationFilter(&filter.SnapshotID) } page, err := prb.Obligations.ListForRiskID(ctx, obj.ID, cursor, obligationFilter) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot list risk obligations: %w", err)) } return types.NewObligationConnection(page, r, obj.ID, filter), nil } // Permission is the resolver for the permission field. func (r *riskResolver) Permission(ctx context.Context, obj *types.Risk, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *riskConnectionResolver) TotalCount(ctx context.Context, obj *types.RiskConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionRiskList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *measureResolver: count, err := prb.Risks.CountForMeasureID(ctx, obj.ParentID, obj.Filters) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count risks: %w", err)) } return count, nil case *organizationResolver: count, err := prb.Risks.CountForOrganizationID(ctx, obj.ParentID, obj.Filters) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot count risks: %w", err)) } return count, nil } // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Signed is the resolver for the signed field. func (r *signableDocumentResolver) Signed(ctx context.Context, obj *types.SignableDocument) (bool, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDocumentGet); err != nil { return false, err } identity := authn.IdentityFromContext(ctx) prb := r.ProboService(ctx, obj.ID.TenantID()) signed, err := prb.Documents.IsSigned(ctx, obj.ID, identity.EmailAddress) if err != nil { panic(fmt.Errorf("cannot check if document is signed: %w", err)) } return signed, nil } // Versions is the resolver for the versions field. func (r *signableDocumentResolver) Versions(ctx context.Context, obj *types.SignableDocument, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionOrderBy, filter *types.DocumentVersionFilter) (*types.DocumentVersionConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDocumentVersionList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DocumentVersionOrderField]{ Field: coredata.DocumentVersionOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DocumentVersionOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) user := authn.IdentityFromContext(ctx) versionFilter := coredata.NewDocumentVersionFilter().WithUserEmail(&user.EmailAddress) page, err := prb.Documents.ListVersions(ctx, obj.ID, cursor, versionFilter) if err != nil { panic(fmt.Errorf("cannot list signable document versions: %w", err)) } return types.NewDocumentVersionConnection(page, r, obj.ID), nil } // Organization is the resolver for the organization field. func (r *snapshotResolver) Organization(ctx context.Context, obj *types.Snapshot) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) snapshot, err := prb.Snapshots.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get snapshot: %w", err)) } organization, err := prb.Organizations.Get(ctx, snapshot.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // Controls is the resolver for the controls field. func (r *snapshotResolver) Controls(ctx context.Context, obj *types.Snapshot, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ControlOrderField]{ Field: coredata.ControlOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ControlOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var controlFilter = coredata.NewControlFilter(nil) if filter != nil { controlFilter = coredata.NewControlFilter(filter.Query) } page, err := prb.Controls.ListForSnapshotID(ctx, obj.ID, cursor, controlFilter) if err != nil { panic(fmt.Errorf("cannot list snapshot controls: %w", err)) } return types.NewControlConnection(page, r, obj.ID, controlFilter), nil } // Permission is the resolver for the permission field. func (r *snapshotResolver) Permission(ctx context.Context, obj *types.Snapshot, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *snapshotConnectionResolver) TotalCount(ctx context.Context, obj *types.SnapshotConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionSnapshotList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Snapshots.CountForOrganizationID(ctx, obj.ParentID) if err != nil { panic(fmt.Errorf("cannot count snapshots: %w", err)) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Organization is the resolver for the organization field. func (r *stateOfApplicabilityResolver) Organization(ctx context.Context, obj *types.StateOfApplicability) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load organization: %w", err)) } return types.NewOrganization(organization), nil } // Owner is the resolver for the owner field. func (r *stateOfApplicabilityResolver) Owner(ctx context.Context, obj *types.StateOfApplicability) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } owner, err := r.iam.OrganizationService.GetProfile(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load owner: %w", err)) } return types.NewProfile(owner), nil } // ApplicabilityStatements is the resolver for the applicabilityStatements field. func (r *stateOfApplicabilityResolver) ApplicabilityStatements(ctx context.Context, obj *types.StateOfApplicability, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ApplicabilityStatementOrderBy) (*types.ApplicabilityStatementConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionApplicabilityStatementList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ApplicabilityStatementOrderField]{ Field: coredata.ApplicabilityStatementOrderFieldCreatedAt, Direction: page.OrderDirectionAsc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ApplicabilityStatementOrderField]{ Field: coredata.ApplicabilityStatementOrderField(orderBy.Field), Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) p, err := prb.StatesOfApplicability.ListApplicabilityStatements(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list applicability statements: %w", err)) } return types.NewApplicabilityStatementConnection(p, r, obj.ID), nil } // Permission is the resolver for the permission field. func (r *stateOfApplicabilityResolver) Permission(ctx context.Context, obj *types.StateOfApplicability, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *stateOfApplicabilityConnectionResolver) TotalCount(ctx context.Context, obj *types.StateOfApplicabilityConnection) (int, error) { prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.StatesOfApplicability.CountForOrganizationID(ctx, obj.ParentID, obj.Filters) if err != nil { panic(fmt.Errorf("cannot count states_of_applicability: %w", err)) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // AssignedTo is the resolver for the assignedTo field. func (r *taskResolver) AssignedTo(ctx context.Context, obj *types.Task) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } if obj.AssignedTo == nil { return nil, nil } assignee, err := r.iam.OrganizationService.GetProfile(ctx, obj.AssignedTo.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get assigned to: %w", err)) } return types.NewProfile(assignee), nil } // Organization is the resolver for the organization field. func (r *taskResolver) Organization(ctx context.Context, obj *types.Task) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // Measure is the resolver for the measure field. func (r *taskResolver) Measure(ctx context.Context, obj *types.Task) (*types.Measure, error) { if err := r.authorize(ctx, obj.ID, probo.ActionMeasureGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) if obj.Measure == nil { return nil, nil } measure, err := prb.Measures.Get(ctx, obj.Measure.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get measure: %w", err)) } return types.NewMeasure(measure), nil } // Evidences is the resolver for the evidences field. func (r *taskResolver) Evidences(ctx context.Context, obj *types.Task, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.EvidenceOrderBy) (*types.EvidenceConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionEvidenceList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.EvidenceOrderField]{ Field: coredata.EvidenceOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.EvidenceOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Evidences.ListForTaskID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list task evidences: %w", err)) } return types.NewEvidenceConnection(page, r, obj.ID), nil } // Permission is the resolver for the permission field. func (r *taskResolver) Permission(ctx context.Context, obj *types.Task, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *taskConnectionResolver) TotalCount(ctx context.Context, obj *types.TaskConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionTaskList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *measureResolver: count, err := prb.Tasks.CountForMeasureID(ctx, obj.ParentID) if err != nil { panic(fmt.Errorf("cannot count tasks: %w", err)) } return count, nil case *organizationResolver: count, err := prb.Tasks.CountForOrganizationID(ctx, obj.ParentID) if err != nil { panic(fmt.Errorf("cannot count tasks: %w", err)) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // ProcessingActivity is the resolver for the processingActivity field. func (r *transferImpactAssessmentResolver) ProcessingActivity(ctx context.Context, obj *types.TransferImpactAssessment) (*types.ProcessingActivity, error) { if err := r.authorize(ctx, obj.ID, probo.ActionProcessingActivityGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) processingActivity, err := prb.ProcessingActivities.Get(ctx, obj.ProcessingActivity.ID) if err != nil { panic(fmt.Errorf("cannot get processing activity: %w", err)) } return types.NewProcessingActivity(processingActivity), nil } // Organization is the resolver for the organization field. func (r *transferImpactAssessmentResolver) Organization(ctx context.Context, obj *types.TransferImpactAssessment) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // Permission is the resolver for the permission field. func (r *transferImpactAssessmentResolver) Permission(ctx context.Context, obj *types.TransferImpactAssessment, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *transferImpactAssessmentConnectionResolver) TotalCount(ctx context.Context, obj *types.TransferImpactAssessmentConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionTransferImpactAssessmentList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.TransferImpactAssessments.CountForOrganizationID(ctx, obj.ParentID, obj.Filter) if err != nil { panic(fmt.Errorf("cannot count organization transfer impact assessments: %w", err)) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // LogoFileURL is the resolver for the logoFileUrl field. func (r *trustCenterResolver) LogoFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) logoURL, err := prb.TrustCenters.GenerateLogoURL(ctx, obj.ID, 1*time.Hour) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot generate logo url: %w", err)) } return logoURL, nil } // DarkLogoFileURL is the resolver for the darkLogoFileUrl field. func (r *trustCenterResolver) DarkLogoFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) logoURL, err := prb.TrustCenters.GenerateDarkLogoURL(ctx, obj.ID, 1*time.Hour) if err != nil { // TODO no panic use gqlutils.InternalError panic(fmt.Errorf("cannot generate logo url: %w", err)) } return logoURL, nil } // NdaFileURL is the resolver for the ndaFileUrl field. func (r *trustCenterResolver) NdaFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) { hasPermission, err := r.Resolver.Permission(ctx, obj, probo.ActionTrustCenterGetNda) if err != nil { panic(fmt.Errorf("cannot authorize: %w", err)) } if !hasPermission { return nil, nil } prb := r.ProboService(ctx, obj.ID.TenantID()) fileURL, err := prb.TrustCenters.GenerateNDAFileURL(ctx, obj.ID, 15*time.Minute) if err != nil { panic(fmt.Errorf("cannot generate NDA file URL: %w", err)) } return fileURL, nil } // Organization is the resolver for the organization field. func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) trustCenter, _, err := prb.TrustCenters.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get trust center: %w", err)) } organization, err := prb.Organizations.Get(ctx, trustCenter.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // Accesses is the resolver for the accesses field. func (r *trustCenterResolver) Accesses(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterAccessOrderField]) (*types.TrustCenterAccessConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterAccessList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.TrustCenterAccessOrderField]{ Field: coredata.TrustCenterAccessOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.TrustCenterAccessOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) result, err := prb.TrustCenterAccesses.ListForTrustCenterID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list trust center accesses: %w", err)) } return types.NewTrustCenterAccessConnection(result), nil } // References is the resolver for the references field. func (r *trustCenterResolver) References(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterReferenceOrderField]) (*types.TrustCenterReferenceConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterReferenceList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.TrustCenterReferenceOrderField]{ Field: coredata.TrustCenterReferenceOrderFieldRank, Direction: page.OrderDirectionAsc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.TrustCenterReferenceOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) result, err := prb.TrustCenterReferences.ListForTrustCenterID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list trust center references: %w", err)) } return types.NewTrustCenterReferenceConnection(result, obj.ID), nil } // Permission is the resolver for the permission field. func (r *trustCenterResolver) Permission(ctx context.Context, obj *types.TrustCenter, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // PendingRequestCount is the resolver for the pendingRequestCount field. func (r *trustCenterAccessResolver) PendingRequestCount(ctx context.Context, obj *types.TrustCenterAccess) (int, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterAccessGet); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ID.TenantID()) count, err := prb.TrustCenterAccesses.CountPendingRequestDocumentAccesses(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot count pending request document accesses: %w", err)) } return count, nil } // ActiveCount is the resolver for the activeCount field. func (r *trustCenterAccessResolver) ActiveCount(ctx context.Context, obj *types.TrustCenterAccess) (int, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterAccessGet); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ID.TenantID()) count, err := prb.TrustCenterAccesses.CountActiveDocumentAccesses(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot count active document accesses: %w", err)) } return count, nil } // AvailableDocumentAccesses is the resolver for the availableDocumentAccesses field. func (r *trustCenterAccessResolver) AvailableDocumentAccesses(ctx context.Context, obj *types.TrustCenterAccess, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterDocumentAccessOrderField]) (*types.TrustCenterDocumentAccessConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterAccessGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.TrustCenterDocumentAccessOrderField]{ Field: coredata.TrustCenterDocumentAccessOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.TrustCenterDocumentAccessOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) result, err := prb.TrustCenterAccesses.ListAvailableDocumentAccesses(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list trust center document accesses: %w", err)) } return types.NewTrustCenterDocumentAccessConnection(result, obj, obj.ID), nil } // Permission is the resolver for the permission field. func (r *trustCenterAccessResolver) Permission(ctx context.Context, obj *types.TrustCenterAccess, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // Document is the resolver for the document field. func (r *trustCenterDocumentAccessResolver) Document(ctx context.Context, obj *types.TrustCenterDocumentAccess) (*types.Document, error) { if err := r.authorize(ctx, obj.ID, probo.ActionDocumentGet); err != nil { return nil, err } if obj.DocumentID == nil { return nil, nil } prb := r.ProboService(ctx, obj.TrustCenterAccessID.TenantID()) document, err := prb.Documents.Get(ctx, *obj.DocumentID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load document: %w", err)) } return types.NewDocument(document), nil } // Report is the resolver for the report field. func (r *trustCenterDocumentAccessResolver) Report(ctx context.Context, obj *types.TrustCenterDocumentAccess) (*types.Report, error) { if err := r.authorize(ctx, obj.TrustCenterAccessID, probo.ActionReportGet); err != nil { return nil, err } if obj.ReportID == nil { return nil, nil } prb := r.ProboService(ctx, obj.TrustCenterAccessID.TenantID()) report, err := prb.Reports.Get(ctx, *obj.ReportID) if err != nil { panic(fmt.Errorf("cannot load report: %w", err)) } return types.NewReport(report), nil } // TrustCenterFile is the resolver for the trustCenterFile field. func (r *trustCenterDocumentAccessResolver) TrustCenterFile(ctx context.Context, obj *types.TrustCenterDocumentAccess) (*types.TrustCenterFile, error) { if err := r.authorize(ctx, obj.TrustCenterAccessID, probo.ActionTrustCenterFileGet); err != nil { return nil, err } if obj.TrustCenterFileID == nil { return nil, nil } prb := r.ProboService(ctx, obj.TrustCenterAccessID.TenantID()) trustCenterFile, err := prb.TrustCenterFiles.Get(ctx, *obj.TrustCenterFileID) if err != nil { panic(fmt.Errorf("cannot load trust center file: %w", err)) } return types.NewTrustCenterFile(trustCenterFile), nil } // TotalCount is the resolver for the totalCount field. func (r *trustCenterDocumentAccessConnectionResolver) TotalCount(ctx context.Context, obj *types.TrustCenterDocumentAccessConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionTrustCenterDocumentAccessList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) count, err := prb.TrustCenterAccesses.CountDocumentAccesses(ctx, obj.ParentID) if err != nil { panic(fmt.Errorf("cannot count trust center document accesses: %w", err)) } return count, nil } // FileURL is the resolver for the fileUrl field. func (r *trustCenterFileResolver) FileURL(ctx context.Context, obj *types.TrustCenterFile) (string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterFileGetFileUrl); err != nil { return "", err } prb := r.ProboService(ctx, obj.ID.TenantID()) fileURL, err := prb.TrustCenterFiles.GenerateFileURL(ctx, obj.ID, 1*time.Hour) if err != nil { panic(fmt.Errorf("cannot generate file URL: %w", err)) } return fileURL, nil } // Organization is the resolver for the organization field. func (r *trustCenterFileResolver) Organization(ctx context.Context, obj *types.TrustCenterFile) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) trustCenterFile, err := prb.TrustCenterFiles.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get trust center file: %w", err)) } organization, err := prb.Organizations.Get(ctx, trustCenterFile.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // Permission is the resolver for the permission field. func (r *trustCenterFileResolver) Permission(ctx context.Context, obj *types.TrustCenterFile, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *trustCenterFileConnectionResolver) TotalCount(ctx context.Context, obj *types.TrustCenterFileConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionTrustCenterFileList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) count, err := prb.TrustCenterFiles.CountForOrganizationID(ctx, obj.ParentID) if err != nil { panic(fmt.Errorf("cannot count trust center files: %w", err)) } return count, nil } // LogoURL is the resolver for the logoUrl field. func (r *trustCenterReferenceResolver) LogoURL(ctx context.Context, obj *types.TrustCenterReference) (string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterReferenceGetLogoUrl); err != nil { return "", err } prb := r.ProboService(ctx, obj.ID.TenantID()) fileURL, err := prb.TrustCenterReferences.GenerateLogoURL(ctx, obj.ID, 1*time.Hour) if err != nil { panic(fmt.Errorf("cannot generate logo URL: %w", err)) } return fileURL, nil } // Permission is the resolver for the permission field. func (r *trustCenterReferenceResolver) Permission(ctx context.Context, obj *types.TrustCenterReference, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *trustCenterReferenceConnectionResolver) TotalCount(ctx context.Context, obj *types.TrustCenterReferenceConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionTrustCenterReferenceList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) count, err := prb.TrustCenterReferences.CountForTrustCenterID(ctx, obj.ParentID) if err != nil { panic(fmt.Errorf("cannot count trust center references: %w", err)) } return count, nil } // Organization is the resolver for the organization field. func (r *vendorResolver) Organization(ctx context.Context, obj *types.Vendor) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // ComplianceReports is the resolver for the complianceReports field. func (r *vendorResolver) ComplianceReports(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorComplianceReportOrderBy) (*types.VendorComplianceReportConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorComplianceReportList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.VendorComplianceReportOrderField]{ Field: coredata.VendorComplianceReportOrderFieldReportDate, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.VendorComplianceReportOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.VendorComplianceReports.ListForVendorID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list vendor compliance reports: %w", err)) } return types.NewVendorComplianceReportConnection(page), nil } // BusinessAssociateAgreement is the resolver for the businessAssociateAgreement field. func (r *vendorResolver) BusinessAssociateAgreement(ctx context.Context, obj *types.Vendor) (*types.VendorBusinessAssociateAgreement, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorBusinessAssociateAgreementGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) vendorBusinessAssociateAgreement, file, err := prb.VendorBusinessAssociateAgreements.GetByVendorID(ctx, obj.ID) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return nil, nil } panic(fmt.Errorf("cannot get vendor business associate agreement: %w", err)) } return types.NewVendorBusinessAssociateAgreement(vendorBusinessAssociateAgreement, file), nil } // DataPrivacyAgreement is the resolver for the dataPrivacyAgreement field. func (r *vendorResolver) DataPrivacyAgreement(ctx context.Context, obj *types.Vendor) (*types.VendorDataPrivacyAgreement, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorDataPrivacyAgreementGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) vendorDataPrivacyAgreement, file, err := prb.VendorDataPrivacyAgreements.GetByVendorID(ctx, obj.ID) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return nil, nil } panic(fmt.Errorf("cannot get vendor data privacy agreement: %w", err)) } return types.NewVendorDataPrivacyAgreement(vendorDataPrivacyAgreement, file), nil } // Contacts is the resolver for the contacts field. func (r *vendorResolver) Contacts(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorContactOrderBy) (*types.VendorContactConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorContactList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.VendorContactOrderField]{ Field: coredata.VendorContactOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.VendorContactOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.VendorContacts.List(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list vendor contacts: %w", err)) } return types.NewVendorContactConnection(page), nil } // Services is the resolver for the services field. func (r *vendorResolver) Services(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorServiceOrderBy) (*types.VendorServiceConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorServiceList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.VendorServiceOrderField]{ Field: coredata.VendorServiceOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.VendorServiceOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.VendorServices.List(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list vendor services: %w", err)) } return types.NewVendorServiceConnection(page), nil } // RiskAssessments is the resolver for the riskAssessments field. func (r *vendorResolver) RiskAssessments(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorRiskAssessmentOrder) (*types.VendorRiskAssessmentConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorRiskAssessmentList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.VendorRiskAssessmentOrderField]{ Field: coredata.VendorRiskAssessmentOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.VendorRiskAssessmentOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Vendors.ListRiskAssessments(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list vendor risk assessments: %w", err)) } return types.NewVendorRiskAssessmentConnection(page), nil } // BusinessOwner is the resolver for the businessOwner field. func (r *vendorResolver) BusinessOwner(ctx context.Context, obj *types.Vendor) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } if obj.BusinessOwner == nil { return nil, nil } businessOwner, err := r.iam.OrganizationService.GetProfile(ctx, obj.BusinessOwner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get business owner: %w", err)) } return types.NewProfile(businessOwner), nil } // SecurityOwner is the resolver for the securityOwner field. func (r *vendorResolver) SecurityOwner(ctx context.Context, obj *types.Vendor) (*types.Profile, error) { if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } if obj.SecurityOwner == nil { return nil, nil } securityOwner, err := r.iam.OrganizationService.GetProfile(ctx, obj.SecurityOwner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get security owner: %w", err)) } return types.NewProfile(securityOwner), nil } // Permission is the resolver for the permission field. func (r *vendorResolver) Permission(ctx context.Context, obj *types.Vendor, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // Vendor is the resolver for the vendor field. func (r *vendorBusinessAssociateAgreementResolver) Vendor(ctx context.Context, obj *types.VendorBusinessAssociateAgreement) (*types.Vendor, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } return nil, fmt.Errorf("cannot get vendor: %w", err) } return types.NewVendor(vendor), nil } // FileURL is the resolver for the fileUrl field. func (r *vendorBusinessAssociateAgreementResolver) FileURL(ctx context.Context, obj *types.VendorBusinessAssociateAgreement) (string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionFileDownloadUrl); err != nil { return "", err } prb := r.ProboService(ctx, obj.ID.TenantID()) fileURL, err := prb.VendorBusinessAssociateAgreements.GenerateFileURL(ctx, obj.ID, 1*time.Hour) if err != nil { panic(fmt.Errorf("cannot generate file URL: %w", err)) } return fileURL, nil } // Permission is the resolver for the permission field. func (r *vendorBusinessAssociateAgreementResolver) Permission(ctx context.Context, obj *types.VendorBusinessAssociateAgreement, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // Vendor is the resolver for the vendor field. func (r *vendorComplianceReportResolver) Vendor(ctx context.Context, obj *types.VendorComplianceReport) (*types.Vendor, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get vendor: %w", err)) } return types.NewVendor(vendor), nil } // File is the resolver for the file field. func (r *vendorComplianceReportResolver) File(ctx context.Context, obj *types.VendorComplianceReport) (*types.File, error) { if err := r.authorize(ctx, obj.ID, probo.ActionFileGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) evidence, err := prb.VendorComplianceReports.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot load evidence: %w", err)) } if evidence.ReportFileId == nil { return nil, nil } file, err := prb.Files.Get(ctx, *evidence.ReportFileId) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load evidence file: %w", err)) } return types.NewFile(file), nil } // Permission is the resolver for the permission field. func (r *vendorComplianceReportResolver) Permission(ctx context.Context, obj *types.VendorComplianceReport, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *vendorConnectionResolver) TotalCount(ctx context.Context, obj *types.VendorConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionVendorList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Vendors.CountForOrganizationID(ctx, obj.ParentID) if err != nil { panic(fmt.Errorf("cannot count vendors: %w", err)) } return count, nil case *assetResolver: count, err := prb.Vendors.CountForAssetID(ctx, obj.ParentID) if err != nil { panic(fmt.Errorf("cannot count vendors: %w", err)) } return count, nil case *datumResolver: count, err := prb.Vendors.CountForDatumID(ctx, obj.ParentID) if err != nil { panic(fmt.Errorf("cannot count vendors: %w", err)) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Vendor is the resolver for the vendor field. func (r *vendorContactResolver) Vendor(ctx context.Context, obj *types.VendorContact) (*types.Vendor, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) // Get the vendor contact to access the VendorID vendorContact, err := prb.VendorContacts.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get vendor contact: %w", err)) } vendor, err := prb.Vendors.Get(ctx, vendorContact.VendorID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get vendor: %w", err)) } return types.NewVendor(vendor), nil } // Permission is the resolver for the permission field. func (r *vendorContactResolver) Permission(ctx context.Context, obj *types.VendorContact, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // Vendor is the resolver for the vendor field. func (r *vendorDataPrivacyAgreementResolver) Vendor(ctx context.Context, obj *types.VendorDataPrivacyAgreement) (*types.Vendor, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get vendor: %w", err)) } return types.NewVendor(vendor), nil } // FileURL is the resolver for the fileUrl field. func (r *vendorDataPrivacyAgreementResolver) FileURL(ctx context.Context, obj *types.VendorDataPrivacyAgreement) (string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionFileDownloadUrl); err != nil { return "", err } prb := r.ProboService(ctx, obj.ID.TenantID()) fileURL, err := prb.VendorDataPrivacyAgreements.GenerateFileURL(ctx, obj.ID, 1*time.Hour) if err != nil { panic(fmt.Errorf("cannot generate file URL: %w", err)) } return fileURL, nil } // Permission is the resolver for the permission field. func (r *vendorDataPrivacyAgreementResolver) Permission(ctx context.Context, obj *types.VendorDataPrivacyAgreement, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // Vendor is the resolver for the vendor field. func (r *vendorRiskAssessmentResolver) Vendor(ctx context.Context, obj *types.VendorRiskAssessment) (*types.Vendor, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.GetByRiskAssessmentID(ctx, obj.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get vendor: %w", err)) } return types.NewVendor(vendor), nil } // Permission is the resolver for the permission field. func (r *vendorRiskAssessmentResolver) Permission(ctx context.Context, obj *types.VendorRiskAssessment, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // Vendor is the resolver for the vendor field. func (r *vendorServiceResolver) Vendor(ctx context.Context, obj *types.VendorService) (*types.Vendor, error) { if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.Vendor.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get vendor: %w", err)) } return types.NewVendor(vendor), nil } // Permission is the resolver for the permission field. func (r *vendorServiceResolver) Permission(ctx context.Context, obj *types.VendorService, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // SignableDocuments is the resolver for the signableDocuments field. func (r *viewerResolver) SignableDocuments(ctx context.Context, obj *types.Viewer, organizationID gid.GID, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy) (*types.SignableDocumentConnection, error) { if err := r.authorize(ctx, organizationID, probo.ActionDocumentList); err != nil { return nil, err } prb := r.ProboService(ctx, organizationID.TenantID()) pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{ Field: coredata.DocumentOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) identity := authn.IdentityFromContext(ctx) documentFilter := coredata.NewDocumentFilter(nil).WithUserEmail(&identity.EmailAddress) documentsPage, err := prb.Documents.ListByOrganizationID(ctx, organizationID, cursor, documentFilter) if err != nil { panic(fmt.Errorf("cannot list organization signable documents: %w", err)) } signableDocuments := make([]*types.SignableDocument, len(documentsPage.Data)) for i, doc := range documentsPage.Data { signableDocuments[i] = &types.SignableDocument{ ID: doc.ID, Title: doc.Title, DocumentType: doc.DocumentType, Classification: doc.Classification, CreatedAt: doc.CreatedAt, UpdatedAt: doc.UpdatedAt, } } page := page.NewPage(signableDocuments, documentsPage.Cursor) return types.NewSignableDocumentConnection(page), nil } // SignableDocument is the resolver for the signableDocument field. func (r *viewerResolver) SignableDocument(ctx context.Context, obj *types.Viewer, id gid.GID) (*types.SignableDocument, error) { if err := r.authorize(ctx, id, probo.ActionDocumentGet); err != nil { return nil, err } prb := r.ProboService(ctx, id.TenantID()) identity := authn.IdentityFromContext(ctx) documentFilter := coredata.NewDocumentFilter(nil).WithUserEmail(&identity.EmailAddress) document, err := prb.Documents.GetWithFilter(ctx, id, documentFilter) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get signable document: %w", err)) } return &types.SignableDocument{ ID: document.ID, Title: document.Title, DocumentType: document.DocumentType, Classification: document.Classification, CreatedAt: document.CreatedAt, UpdatedAt: document.UpdatedAt, }, nil } // ApplicabilityStatement returns schema.ApplicabilityStatementResolver implementation. func (r *Resolver) ApplicabilityStatement() schema.ApplicabilityStatementResolver { return &applicabilityStatementResolver{r} } // ApplicabilityStatementConnection returns schema.ApplicabilityStatementConnectionResolver implementation. func (r *Resolver) ApplicabilityStatementConnection() schema.ApplicabilityStatementConnectionResolver { return &applicabilityStatementConnectionResolver{r} } // Asset returns schema.AssetResolver implementation. func (r *Resolver) Asset() schema.AssetResolver { return &assetResolver{r} } // AssetConnection returns schema.AssetConnectionResolver implementation. func (r *Resolver) AssetConnection() schema.AssetConnectionResolver { return &assetConnectionResolver{r} } // Audit returns schema.AuditResolver implementation. func (r *Resolver) Audit() schema.AuditResolver { return &auditResolver{r} } // AuditConnection returns schema.AuditConnectionResolver implementation. func (r *Resolver) AuditConnection() schema.AuditConnectionResolver { return &auditConnectionResolver{r} } // ContinualImprovement returns schema.ContinualImprovementResolver implementation. func (r *Resolver) ContinualImprovement() schema.ContinualImprovementResolver { return &continualImprovementResolver{r} } // ContinualImprovementConnection returns schema.ContinualImprovementConnectionResolver implementation. func (r *Resolver) ContinualImprovementConnection() schema.ContinualImprovementConnectionResolver { return &continualImprovementConnectionResolver{r} } // Control returns schema.ControlResolver implementation. func (r *Resolver) Control() schema.ControlResolver { return &controlResolver{r} } // ControlConnection returns schema.ControlConnectionResolver implementation. func (r *Resolver) ControlConnection() schema.ControlConnectionResolver { return &controlConnectionResolver{r} } // CustomDomain returns schema.CustomDomainResolver implementation. func (r *Resolver) CustomDomain() schema.CustomDomainResolver { return &customDomainResolver{r} } // DataProtectionImpactAssessment returns schema.DataProtectionImpactAssessmentResolver implementation. func (r *Resolver) DataProtectionImpactAssessment() schema.DataProtectionImpactAssessmentResolver { return &dataProtectionImpactAssessmentResolver{r} } // DataProtectionImpactAssessmentConnection returns schema.DataProtectionImpactAssessmentConnectionResolver implementation. func (r *Resolver) DataProtectionImpactAssessmentConnection() schema.DataProtectionImpactAssessmentConnectionResolver { return &dataProtectionImpactAssessmentConnectionResolver{r} } // Datum returns schema.DatumResolver implementation. func (r *Resolver) Datum() schema.DatumResolver { return &datumResolver{r} } // DatumConnection returns schema.DatumConnectionResolver implementation. func (r *Resolver) DatumConnection() schema.DatumConnectionResolver { return &datumConnectionResolver{r} } // Document returns schema.DocumentResolver implementation. func (r *Resolver) Document() schema.DocumentResolver { return &documentResolver{r} } // DocumentConnection returns schema.DocumentConnectionResolver implementation. func (r *Resolver) DocumentConnection() schema.DocumentConnectionResolver { return &documentConnectionResolver{r} } // DocumentVersion returns schema.DocumentVersionResolver implementation. func (r *Resolver) DocumentVersion() schema.DocumentVersionResolver { return &documentVersionResolver{r} } // DocumentVersionConnection returns schema.DocumentVersionConnectionResolver implementation. func (r *Resolver) DocumentVersionConnection() schema.DocumentVersionConnectionResolver { return &documentVersionConnectionResolver{r} } // DocumentVersionSignature returns schema.DocumentVersionSignatureResolver implementation. func (r *Resolver) DocumentVersionSignature() schema.DocumentVersionSignatureResolver { return &documentVersionSignatureResolver{r} } // DocumentVersionSignatureConnection returns schema.DocumentVersionSignatureConnectionResolver implementation. func (r *Resolver) DocumentVersionSignatureConnection() schema.DocumentVersionSignatureConnectionResolver { return &documentVersionSignatureConnectionResolver{r} } // Evidence returns schema.EvidenceResolver implementation. func (r *Resolver) Evidence() schema.EvidenceResolver { return &evidenceResolver{r} } // EvidenceConnection returns schema.EvidenceConnectionResolver implementation. func (r *Resolver) EvidenceConnection() schema.EvidenceConnectionResolver { return &evidenceConnectionResolver{r} } // File returns schema.FileResolver implementation. func (r *Resolver) File() schema.FileResolver { return &fileResolver{r} } // Framework returns schema.FrameworkResolver implementation. func (r *Resolver) Framework() schema.FrameworkResolver { return &frameworkResolver{r} } // FrameworkConnection returns schema.FrameworkConnectionResolver implementation. func (r *Resolver) FrameworkConnection() schema.FrameworkConnectionResolver { return &frameworkConnectionResolver{r} } // Measure returns schema.MeasureResolver implementation. func (r *Resolver) Measure() schema.MeasureResolver { return &measureResolver{r} } // MeasureConnection returns schema.MeasureConnectionResolver implementation. func (r *Resolver) MeasureConnection() schema.MeasureConnectionResolver { return &measureConnectionResolver{r} } // Meeting returns schema.MeetingResolver implementation. func (r *Resolver) Meeting() schema.MeetingResolver { return &meetingResolver{r} } // MeetingConnection returns schema.MeetingConnectionResolver implementation. func (r *Resolver) MeetingConnection() schema.MeetingConnectionResolver { return &meetingConnectionResolver{r} } // Mutation returns schema.MutationResolver implementation. func (r *Resolver) Mutation() schema.MutationResolver { return &mutationResolver{r} } // Nonconformity returns schema.NonconformityResolver implementation. func (r *Resolver) Nonconformity() schema.NonconformityResolver { return &nonconformityResolver{r} } // NonconformityConnection returns schema.NonconformityConnectionResolver implementation. func (r *Resolver) NonconformityConnection() schema.NonconformityConnectionResolver { return &nonconformityConnectionResolver{r} } // Obligation returns schema.ObligationResolver implementation. func (r *Resolver) Obligation() schema.ObligationResolver { return &obligationResolver{r} } // ObligationConnection returns schema.ObligationConnectionResolver implementation. func (r *Resolver) ObligationConnection() schema.ObligationConnectionResolver { return &obligationConnectionResolver{r} } // Organization returns schema.OrganizationResolver implementation. func (r *Resolver) Organization() schema.OrganizationResolver { return &organizationResolver{r} } // ProcessingActivity returns schema.ProcessingActivityResolver implementation. func (r *Resolver) ProcessingActivity() schema.ProcessingActivityResolver { return &processingActivityResolver{r} } // ProcessingActivityConnection returns schema.ProcessingActivityConnectionResolver implementation. func (r *Resolver) ProcessingActivityConnection() schema.ProcessingActivityConnectionResolver { return &processingActivityConnectionResolver{r} } // Profile returns schema.ProfileResolver implementation. func (r *Resolver) Profile() schema.ProfileResolver { return &profileResolver{r} } // ProfileConnection returns schema.ProfileConnectionResolver implementation. func (r *Resolver) ProfileConnection() schema.ProfileConnectionResolver { return &profileConnectionResolver{r} } // Query returns schema.QueryResolver implementation. func (r *Resolver) Query() schema.QueryResolver { return &queryResolver{r} } // Report returns schema.ReportResolver implementation. func (r *Resolver) Report() schema.ReportResolver { return &reportResolver{r} } // RightsRequest returns schema.RightsRequestResolver implementation. func (r *Resolver) RightsRequest() schema.RightsRequestResolver { return &rightsRequestResolver{r} } // RightsRequestConnection returns schema.RightsRequestConnectionResolver implementation. func (r *Resolver) RightsRequestConnection() schema.RightsRequestConnectionResolver { return &rightsRequestConnectionResolver{r} } // Risk returns schema.RiskResolver implementation. func (r *Resolver) Risk() schema.RiskResolver { return &riskResolver{r} } // RiskConnection returns schema.RiskConnectionResolver implementation. func (r *Resolver) RiskConnection() schema.RiskConnectionResolver { return &riskConnectionResolver{r} } // SignableDocument returns schema.SignableDocumentResolver implementation. func (r *Resolver) SignableDocument() schema.SignableDocumentResolver { return &signableDocumentResolver{r} } // Snapshot returns schema.SnapshotResolver implementation. func (r *Resolver) Snapshot() schema.SnapshotResolver { return &snapshotResolver{r} } // SnapshotConnection returns schema.SnapshotConnectionResolver implementation. func (r *Resolver) SnapshotConnection() schema.SnapshotConnectionResolver { return &snapshotConnectionResolver{r} } // StateOfApplicability returns schema.StateOfApplicabilityResolver implementation. func (r *Resolver) StateOfApplicability() schema.StateOfApplicabilityResolver { return &stateOfApplicabilityResolver{r} } // StateOfApplicabilityConnection returns schema.StateOfApplicabilityConnectionResolver implementation. func (r *Resolver) StateOfApplicabilityConnection() schema.StateOfApplicabilityConnectionResolver { return &stateOfApplicabilityConnectionResolver{r} } // Task returns schema.TaskResolver implementation. func (r *Resolver) Task() schema.TaskResolver { return &taskResolver{r} } // TaskConnection returns schema.TaskConnectionResolver implementation. func (r *Resolver) TaskConnection() schema.TaskConnectionResolver { return &taskConnectionResolver{r} } // TransferImpactAssessment returns schema.TransferImpactAssessmentResolver implementation. func (r *Resolver) TransferImpactAssessment() schema.TransferImpactAssessmentResolver { return &transferImpactAssessmentResolver{r} } // TransferImpactAssessmentConnection returns schema.TransferImpactAssessmentConnectionResolver implementation. func (r *Resolver) TransferImpactAssessmentConnection() schema.TransferImpactAssessmentConnectionResolver { return &transferImpactAssessmentConnectionResolver{r} } // TrustCenter returns schema.TrustCenterResolver implementation. func (r *Resolver) TrustCenter() schema.TrustCenterResolver { return &trustCenterResolver{r} } // TrustCenterAccess returns schema.TrustCenterAccessResolver implementation. func (r *Resolver) TrustCenterAccess() schema.TrustCenterAccessResolver { return &trustCenterAccessResolver{r} } // TrustCenterDocumentAccess returns schema.TrustCenterDocumentAccessResolver implementation. func (r *Resolver) TrustCenterDocumentAccess() schema.TrustCenterDocumentAccessResolver { return &trustCenterDocumentAccessResolver{r} } // TrustCenterDocumentAccessConnection returns schema.TrustCenterDocumentAccessConnectionResolver implementation. func (r *Resolver) TrustCenterDocumentAccessConnection() schema.TrustCenterDocumentAccessConnectionResolver { return &trustCenterDocumentAccessConnectionResolver{r} } // TrustCenterFile returns schema.TrustCenterFileResolver implementation. func (r *Resolver) TrustCenterFile() schema.TrustCenterFileResolver { return &trustCenterFileResolver{r} } // TrustCenterFileConnection returns schema.TrustCenterFileConnectionResolver implementation. func (r *Resolver) TrustCenterFileConnection() schema.TrustCenterFileConnectionResolver { return &trustCenterFileConnectionResolver{r} } // TrustCenterReference returns schema.TrustCenterReferenceResolver implementation. func (r *Resolver) TrustCenterReference() schema.TrustCenterReferenceResolver { return &trustCenterReferenceResolver{r} } // TrustCenterReferenceConnection returns schema.TrustCenterReferenceConnectionResolver implementation. func (r *Resolver) TrustCenterReferenceConnection() schema.TrustCenterReferenceConnectionResolver { return &trustCenterReferenceConnectionResolver{r} } // Vendor returns schema.VendorResolver implementation. func (r *Resolver) Vendor() schema.VendorResolver { return &vendorResolver{r} } // VendorBusinessAssociateAgreement returns schema.VendorBusinessAssociateAgreementResolver implementation. func (r *Resolver) VendorBusinessAssociateAgreement() schema.VendorBusinessAssociateAgreementResolver { return &vendorBusinessAssociateAgreementResolver{r} } // VendorComplianceReport returns schema.VendorComplianceReportResolver implementation. func (r *Resolver) VendorComplianceReport() schema.VendorComplianceReportResolver { return &vendorComplianceReportResolver{r} } // VendorConnection returns schema.VendorConnectionResolver implementation. func (r *Resolver) VendorConnection() schema.VendorConnectionResolver { return &vendorConnectionResolver{r} } // VendorContact returns schema.VendorContactResolver implementation. func (r *Resolver) VendorContact() schema.VendorContactResolver { return &vendorContactResolver{r} } // VendorDataPrivacyAgreement returns schema.VendorDataPrivacyAgreementResolver implementation. func (r *Resolver) VendorDataPrivacyAgreement() schema.VendorDataPrivacyAgreementResolver { return &vendorDataPrivacyAgreementResolver{r} } // VendorRiskAssessment returns schema.VendorRiskAssessmentResolver implementation. func (r *Resolver) VendorRiskAssessment() schema.VendorRiskAssessmentResolver { return &vendorRiskAssessmentResolver{r} } // VendorService returns schema.VendorServiceResolver implementation. func (r *Resolver) VendorService() schema.VendorServiceResolver { return &vendorServiceResolver{r} } // Viewer returns schema.ViewerResolver implementation. func (r *Resolver) Viewer() schema.ViewerResolver { return &viewerResolver{r} } type applicabilityStatementResolver struct{ *Resolver } type applicabilityStatementConnectionResolver struct{ *Resolver } type assetResolver struct{ *Resolver } type assetConnectionResolver struct{ *Resolver } type auditResolver struct{ *Resolver } type auditConnectionResolver struct{ *Resolver } type continualImprovementResolver struct{ *Resolver } type continualImprovementConnectionResolver struct{ *Resolver } type controlResolver struct{ *Resolver } type controlConnectionResolver struct{ *Resolver } type customDomainResolver struct{ *Resolver } type dataProtectionImpactAssessmentResolver struct{ *Resolver } type dataProtectionImpactAssessmentConnectionResolver struct{ *Resolver } type datumResolver struct{ *Resolver } type datumConnectionResolver struct{ *Resolver } type documentResolver struct{ *Resolver } type documentConnectionResolver struct{ *Resolver } type documentVersionResolver struct{ *Resolver } type documentVersionConnectionResolver struct{ *Resolver } type documentVersionSignatureResolver struct{ *Resolver } type documentVersionSignatureConnectionResolver struct{ *Resolver } type evidenceResolver struct{ *Resolver } type evidenceConnectionResolver struct{ *Resolver } type fileResolver struct{ *Resolver } type frameworkResolver struct{ *Resolver } type frameworkConnectionResolver struct{ *Resolver } type measureResolver struct{ *Resolver } type measureConnectionResolver struct{ *Resolver } type meetingResolver struct{ *Resolver } type meetingConnectionResolver struct{ *Resolver } type mutationResolver struct{ *Resolver } type nonconformityResolver struct{ *Resolver } type nonconformityConnectionResolver struct{ *Resolver } type obligationResolver struct{ *Resolver } type obligationConnectionResolver struct{ *Resolver } type organizationResolver struct{ *Resolver } type processingActivityResolver struct{ *Resolver } type processingActivityConnectionResolver struct{ *Resolver } type profileResolver struct{ *Resolver } type profileConnectionResolver struct{ *Resolver } type queryResolver struct{ *Resolver } type reportResolver struct{ *Resolver } type rightsRequestResolver struct{ *Resolver } type rightsRequestConnectionResolver struct{ *Resolver } type riskResolver struct{ *Resolver } type riskConnectionResolver struct{ *Resolver } type signableDocumentResolver struct{ *Resolver } type snapshotResolver struct{ *Resolver } type snapshotConnectionResolver struct{ *Resolver } type stateOfApplicabilityResolver struct{ *Resolver } type stateOfApplicabilityConnectionResolver struct{ *Resolver } type taskResolver struct{ *Resolver } type taskConnectionResolver struct{ *Resolver } type transferImpactAssessmentResolver struct{ *Resolver } type transferImpactAssessmentConnectionResolver struct{ *Resolver } type trustCenterResolver struct{ *Resolver } type trustCenterAccessResolver struct{ *Resolver } type trustCenterDocumentAccessResolver struct{ *Resolver } type trustCenterDocumentAccessConnectionResolver struct{ *Resolver } type trustCenterFileResolver struct{ *Resolver } type trustCenterFileConnectionResolver struct{ *Resolver } type trustCenterReferenceResolver struct{ *Resolver } type trustCenterReferenceConnectionResolver struct{ *Resolver } type vendorResolver struct{ *Resolver } type vendorBusinessAssociateAgreementResolver struct{ *Resolver } type vendorComplianceReportResolver struct{ *Resolver } type vendorConnectionResolver struct{ *Resolver } type vendorContactResolver struct{ *Resolver } type vendorDataPrivacyAgreementResolver struct{ *Resolver } type vendorRiskAssessmentResolver struct{ *Resolver } type vendorServiceResolver struct{ *Resolver } type viewerResolver struct{ *Resolver }