Trust GraphQL and MCP still exposed presigned URL strings for trust-center logos while console and connect already serve stable File.downloadUrl paths. Phase 1 migrates the seven public logo fields on trust GraphQL and the trust-center file references on MCP to the shared File type; trust GraphQL NDA stays on fileUrl for a follow-up. Trust resolvers load public files through filemanager and map them with types.NewFile. The trust app Relay queries and components now read logo.downloadUrl. MCP specification, resolvers, and helpers are updated in sync, including NDA on MCP where callers already have file access. filemanager is split into focused files and its URL surface is narrowed to GenerateFileURL(file) for stable app URLs and GeneratePresignedURL for S3 redirects. GetPublicFile remains the DB entry point when only a file ID is known. Add trust and MCP e2e coverage for public logo download URLs. Signed-off-by: Ludovic Vielle <ludovic@probo.com>
7059 lines
260 KiB
Go
7059 lines
260 KiB
Go
package mcp_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 mcpgen. DO NOT EDIT.
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/modelcontextprotocol/go-sdk/mcp"
|
|
"go.gearno.de/kit/log"
|
|
"go.probo.inc/probo/pkg/accessreview"
|
|
"go.probo.inc/probo/pkg/cookiebanner"
|
|
"go.probo.inc/probo/pkg/coredata"
|
|
"go.probo.inc/probo/pkg/gid"
|
|
"go.probo.inc/probo/pkg/iam"
|
|
"go.probo.inc/probo/pkg/mail"
|
|
"go.probo.inc/probo/pkg/page"
|
|
"go.probo.inc/probo/pkg/probo"
|
|
"go.probo.inc/probo/pkg/riskmanagement"
|
|
"go.probo.inc/probo/pkg/server/api/authn"
|
|
"go.probo.inc/probo/pkg/server/api/mcp/v1/types"
|
|
"go.probo.inc/probo/pkg/thirdparty"
|
|
"go.probo.inc/probo/pkg/validator"
|
|
)
|
|
|
|
// ListOrganizationsTool handles the listOrganizations tool
|
|
// List all organizations the user has access to
|
|
func (r *Resolver) ListOrganizationsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListOrganizationsInput) (*mcp.CallToolResult, types.ListOrganizationsOutput, error) {
|
|
user := authn.IdentityFromContext(ctx)
|
|
|
|
organizations, err := r.iamSvc.AccountService.ListOrganizations(ctx, user.ID)
|
|
if err != nil {
|
|
return nil, types.ListOrganizationsOutput{}, fmt.Errorf("failed to list organizations: %w", err)
|
|
}
|
|
|
|
result := types.ListOrganizationsOutput{
|
|
Organizations: make([]*types.Organization, 0, len(organizations)),
|
|
}
|
|
|
|
for _, org := range organizations {
|
|
result.Organizations = append(result.Organizations, types.NewOrganization(org))
|
|
}
|
|
|
|
return nil, result, nil
|
|
}
|
|
|
|
// ListThirdPartiesTool handles the listThirdParties tool
|
|
// List all thirdParties for the organization
|
|
func (r *Resolver) ListThirdPartiesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListThirdPartiesInput) (*mcp.CallToolResult, types.ListThirdPartiesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionThirdPartyList)
|
|
if err != nil {
|
|
return nil, types.ListThirdPartiesOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ThirdPartyOrderField]{
|
|
Field: coredata.ThirdPartyOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ThirdPartyOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
thirdPartyFilter := coredata.NewThirdPartyFilter(nil, input.Level, nil)
|
|
|
|
page, err := prb.ThirdParties.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor, thirdPartyFilter)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization thirdParties: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListThirdPartiesOutput(page), nil
|
|
}
|
|
|
|
// AddThirdPartyTool handles the addThirdParty tool
|
|
// Add a new thirdParty to the organization
|
|
func (r *Resolver) AddThirdPartyTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddThirdPartyInput) (*mcp.CallToolResult, types.AddThirdPartyOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionThirdPartyCreate)
|
|
if err != nil {
|
|
return nil, types.AddThirdPartyOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
var category *coredata.ThirdPartyCategory
|
|
|
|
if input.Category != nil {
|
|
cat := coredata.ThirdPartyCategory(*input.Category)
|
|
category = &cat
|
|
}
|
|
|
|
var countries coredata.CountryCodes
|
|
if len(input.Countries) > 0 {
|
|
countries = make(coredata.CountryCodes, len(input.Countries))
|
|
for i, c := range input.Countries {
|
|
countries[i] = coredata.CountryCode(c)
|
|
}
|
|
}
|
|
|
|
thirdParty, err := svc.ThirdParties.Create(
|
|
ctx, scope,
|
|
probo.CreateThirdPartyRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Name: input.Name,
|
|
Description: input.Description,
|
|
Category: category,
|
|
HeadquarterAddress: input.HeadquarterAddress,
|
|
LegalName: input.LegalName,
|
|
WebsiteURL: input.WebsiteURL,
|
|
PrivacyPolicyURL: input.PrivacyPolicyURL,
|
|
ServiceLevelAgreementURL: input.ServiceLevelAgreementURL,
|
|
DataProcessingAgreementURL: input.DataProcessingAgreementURL,
|
|
BusinessAssociateAgreementURL: input.BusinessAssociateAgreementURL,
|
|
SubprocessorsListURL: input.SubprocessorsListURL,
|
|
Certifications: input.Certifications,
|
|
Countries: countries,
|
|
BusinessOwnerID: input.BusinessOwnerID,
|
|
SecurityOwnerID: input.SecurityOwnerID,
|
|
StatusPageURL: input.StatusPageURL,
|
|
TermsOfServiceURL: input.TermsOfServiceURL,
|
|
SecurityPageURL: input.SecurityPageURL,
|
|
TrustPageURL: input.TrustPageURL,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddThirdPartyOutput{}, fmt.Errorf("failed to create thirdParty: %w", err)
|
|
}
|
|
|
|
return nil, types.NewAddThirdPartyOutput(thirdParty), nil
|
|
}
|
|
|
|
// UpdateThirdPartyTool handles the updateThirdParty tool
|
|
// Update an existing thirdParty
|
|
func (r *Resolver) UpdateThirdPartyTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateThirdPartyInput) (*mcp.CallToolResult, types.UpdateThirdPartyOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionThirdPartyUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateThirdPartyOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
var description **string
|
|
if input.Description != nil {
|
|
description = &input.Description
|
|
}
|
|
|
|
var headquarterAddress **string
|
|
if input.HeadquarterAddress != nil {
|
|
headquarterAddress = &input.HeadquarterAddress
|
|
}
|
|
|
|
var legalName **string
|
|
if input.LegalName != nil {
|
|
legalName = &input.LegalName
|
|
}
|
|
|
|
var websiteURL **string
|
|
if input.WebsiteURL != nil {
|
|
websiteURL = &input.WebsiteURL
|
|
}
|
|
|
|
var privacyPolicyURL **string
|
|
if input.PrivacyPolicyURL != nil {
|
|
privacyPolicyURL = &input.PrivacyPolicyURL
|
|
}
|
|
|
|
var serviceLevelAgreementURL **string
|
|
if input.ServiceLevelAgreementURL != nil {
|
|
serviceLevelAgreementURL = &input.ServiceLevelAgreementURL
|
|
}
|
|
|
|
var dataProcessingAgreementURL **string
|
|
if input.DataProcessingAgreementURL != nil {
|
|
dataProcessingAgreementURL = &input.DataProcessingAgreementURL
|
|
}
|
|
|
|
var businessAssociateAgreementURL **string
|
|
if input.BusinessAssociateAgreementURL != nil {
|
|
businessAssociateAgreementURL = &input.BusinessAssociateAgreementURL
|
|
}
|
|
|
|
var subprocessorsListURL **string
|
|
if input.SubprocessorsListURL != nil {
|
|
subprocessorsListURL = &input.SubprocessorsListURL
|
|
}
|
|
|
|
var statusPageURL **string
|
|
if input.StatusPageURL != nil {
|
|
statusPageURL = &input.StatusPageURL
|
|
}
|
|
|
|
var termsOfServiceURL **string
|
|
if input.TermsOfServiceURL != nil {
|
|
termsOfServiceURL = &input.TermsOfServiceURL
|
|
}
|
|
|
|
var securityPageURL **string
|
|
if input.SecurityPageURL != nil {
|
|
securityPageURL = &input.SecurityPageURL
|
|
}
|
|
|
|
var trustPageURL **string
|
|
if input.TrustPageURL != nil {
|
|
trustPageURL = &input.TrustPageURL
|
|
}
|
|
|
|
var businessOwnerID **gid.GID
|
|
if input.BusinessOwnerID != nil {
|
|
businessOwnerID = &input.BusinessOwnerID
|
|
}
|
|
|
|
var securityOwnerID **gid.GID
|
|
if input.SecurityOwnerID != nil {
|
|
securityOwnerID = &input.SecurityOwnerID
|
|
}
|
|
|
|
var category *coredata.ThirdPartyCategory
|
|
|
|
if input.Category != nil {
|
|
cat := coredata.ThirdPartyCategory(*input.Category)
|
|
category = &cat
|
|
}
|
|
|
|
var countries coredata.CountryCodes
|
|
if len(input.Countries) > 0 {
|
|
countries = make(coredata.CountryCodes, len(input.Countries))
|
|
for i, c := range input.Countries {
|
|
countries[i] = coredata.CountryCode(c)
|
|
}
|
|
}
|
|
|
|
thirdParty, err := svc.ThirdParties.Update(
|
|
ctx, scope,
|
|
probo.UpdateThirdPartyRequest{
|
|
ID: input.ID,
|
|
Name: input.Name,
|
|
Description: description,
|
|
Category: category,
|
|
HeadquarterAddress: headquarterAddress,
|
|
LegalName: legalName,
|
|
WebsiteURL: websiteURL,
|
|
PrivacyPolicyURL: privacyPolicyURL,
|
|
ServiceLevelAgreementURL: serviceLevelAgreementURL,
|
|
DataProcessingAgreementURL: dataProcessingAgreementURL,
|
|
BusinessAssociateAgreementURL: businessAssociateAgreementURL,
|
|
SubprocessorsListURL: subprocessorsListURL,
|
|
Certifications: input.Certifications,
|
|
Countries: countries,
|
|
BusinessOwnerID: businessOwnerID,
|
|
SecurityOwnerID: securityOwnerID,
|
|
StatusPageURL: statusPageURL,
|
|
TermsOfServiceURL: termsOfServiceURL,
|
|
SecurityPageURL: securityPageURL,
|
|
TrustPageURL: trustPageURL,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateThirdPartyOutput{}, fmt.Errorf("failed to update thirdParty: %w", err)
|
|
}
|
|
|
|
return nil, types.NewUpdateThirdPartyOutput(thirdParty), nil
|
|
}
|
|
|
|
func (r *Resolver) ListRisksTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListRisksInput) (*mcp.CallToolResult, types.ListRisksOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionRiskList)
|
|
if err != nil {
|
|
return nil, types.ListRisksOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.RiskOrderField]{
|
|
Field: coredata.RiskOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.RiskOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
riskFilter := coredata.NewRiskFilter(nil)
|
|
if input.Filter != nil {
|
|
riskFilter = coredata.NewRiskFilter(input.Filter.Query)
|
|
}
|
|
|
|
page, err := prb.Risks.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor, riskFilter)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization risks: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListRisksOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetRiskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetRiskInput) (*mcp.CallToolResult, types.GetRiskOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskGet)
|
|
if err != nil {
|
|
return nil, types.GetRiskOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
risk, err := prb.Risks.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetRiskOutput{}, fmt.Errorf("failed to get risk: %w", err)
|
|
}
|
|
|
|
return nil, types.GetRiskOutput{
|
|
Risk: types.NewRisk(risk),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddRiskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddRiskInput) (*mcp.CallToolResult, types.AddRiskOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionRiskCreate)
|
|
if err != nil {
|
|
return nil, types.AddRiskOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
risk, err := svc.Risks.Create(
|
|
ctx, scope,
|
|
probo.CreateRiskRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Name: input.Name,
|
|
Description: input.Description,
|
|
Category: input.Category,
|
|
Treatment: input.Treatment,
|
|
InherentLikelihood: input.InherentLikelihood,
|
|
InherentImpact: input.InherentImpact,
|
|
ResidualLikelihood: input.ResidualLikelihood,
|
|
ResidualImpact: input.ResidualImpact,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddRiskOutput{}, fmt.Errorf("failed to create risk: %w", err)
|
|
}
|
|
|
|
return nil, types.AddRiskOutput{
|
|
Risk: types.NewRisk(risk),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateRiskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateRiskInput) (*mcp.CallToolResult, types.UpdateRiskOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateRiskOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
risk, err := svc.Risks.Update(
|
|
ctx, scope,
|
|
probo.UpdateRiskRequest{
|
|
ID: input.ID,
|
|
Name: input.Name,
|
|
Description: UnwrapOmittable(input.Description),
|
|
Category: input.Category,
|
|
Treatment: input.Treatment,
|
|
OwnerID: UnwrapOmittable(input.OwnerID),
|
|
InherentLikelihood: input.InherentLikelihood,
|
|
InherentImpact: input.InherentImpact,
|
|
ResidualLikelihood: input.ResidualLikelihood,
|
|
ResidualImpact: input.ResidualImpact,
|
|
Note: input.Note,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateRiskOutput{}, fmt.Errorf("failed to update risk: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateRiskOutput{
|
|
Risk: types.NewRisk(risk),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListMeasuresTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListMeasuresInput) (*mcp.CallToolResult, types.ListMeasuresOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionMeasureList)
|
|
if err != nil {
|
|
return nil, types.ListMeasuresOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.MeasureOrderField]{
|
|
Field: coredata.MeasureOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.MeasureOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
var measureFilter = coredata.NewMeasureFilter(nil, nil, nil)
|
|
if input.Filter != nil {
|
|
measureFilter = coredata.NewMeasureFilter(input.Filter.Query, input.Filter.State, input.Filter.Category)
|
|
}
|
|
|
|
page, err := prb.Measures.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor, measureFilter)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization measures: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListMeasuresOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetMeasureTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetMeasureInput) (*mcp.CallToolResult, types.GetMeasureOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionMeasureGet)
|
|
if err != nil {
|
|
return nil, types.GetMeasureOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
measure, err := prb.Measures.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetMeasureOutput{}, fmt.Errorf("failed to get measure: %w", err)
|
|
}
|
|
|
|
return nil, types.GetMeasureOutput{
|
|
Measure: types.NewMeasure(measure),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddMeasureTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddMeasureInput) (*mcp.CallToolResult, types.AddMeasureOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionMeasureCreate)
|
|
if err != nil {
|
|
return nil, types.AddMeasureOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
measure, err := svc.Measures.Create(
|
|
ctx, scope,
|
|
probo.CreateMeasureRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Name: input.Name,
|
|
Description: input.Description,
|
|
Category: input.Category,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddMeasureOutput{}, fmt.Errorf("failed to create measure: %w", err)
|
|
}
|
|
|
|
return nil, types.AddMeasureOutput{
|
|
Measure: types.NewMeasure(measure),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateMeasureTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateMeasureInput) (*mcp.CallToolResult, types.UpdateMeasureOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionMeasureUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateMeasureOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
measure, err := svc.Measures.Update(
|
|
ctx, scope,
|
|
probo.UpdateMeasureRequest{
|
|
ID: input.ID,
|
|
Name: input.Name,
|
|
Description: UnwrapOmittable(input.Description),
|
|
Category: input.Category,
|
|
State: input.State,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateMeasureOutput{}, fmt.Errorf("failed to update measure: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateMeasureOutput{
|
|
Measure: types.NewMeasure(measure),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListFrameworksTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListFrameworksInput) (*mcp.CallToolResult, types.ListFrameworksOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionFrameworkList)
|
|
if err != nil {
|
|
return nil, types.ListFrameworksOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.FrameworkOrderField]{
|
|
Field: coredata.FrameworkOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.FrameworkOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
page, err := prb.Frameworks.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization frameworks: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListFrameworksOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetFrameworkTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetFrameworkInput) (*mcp.CallToolResult, types.GetFrameworkOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionFrameworkGet)
|
|
if err != nil {
|
|
return nil, types.GetFrameworkOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
framework, err := prb.Frameworks.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetFrameworkOutput{}, fmt.Errorf("failed to get framework: %w", err)
|
|
}
|
|
|
|
return nil, types.GetFrameworkOutput{
|
|
Framework: types.NewFramework(framework),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddFrameworkTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddFrameworkInput) (*mcp.CallToolResult, types.AddFrameworkOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionFrameworkCreate)
|
|
if err != nil {
|
|
return nil, types.AddFrameworkOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
framework, err := svc.Frameworks.Create(
|
|
ctx, scope,
|
|
probo.CreateFrameworkRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Name: input.Name,
|
|
Description: input.Description,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddFrameworkOutput{}, fmt.Errorf("failed to create framework: %w", err)
|
|
}
|
|
|
|
return nil, types.AddFrameworkOutput{
|
|
Framework: types.NewFramework(framework),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateFrameworkTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateFrameworkInput) (*mcp.CallToolResult, types.UpdateFrameworkOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionFrameworkUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateFrameworkOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
framework, err := svc.Frameworks.Update(
|
|
ctx, scope,
|
|
probo.UpdateFrameworkRequest{
|
|
ID: input.ID,
|
|
Name: input.Name,
|
|
Description: UnwrapOmittable(input.Description),
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateFrameworkOutput{}, fmt.Errorf("failed to update framework: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateFrameworkOutput{
|
|
Framework: types.NewFramework(framework),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListAssetsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListAssetsInput) (*mcp.CallToolResult, types.ListAssetsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionAssetList)
|
|
if err != nil {
|
|
return nil, types.ListAssetsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.AssetOrderField]{
|
|
Field: coredata.AssetOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.AssetOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
page, err := prb.Assets.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization assets: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListAssetsOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetAssetTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetAssetInput) (*mcp.CallToolResult, types.GetAssetOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionAssetGet)
|
|
if err != nil {
|
|
return nil, types.GetAssetOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
asset, err := prb.Assets.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetAssetOutput{}, fmt.Errorf("failed to get asset: %w", err)
|
|
}
|
|
|
|
return nil, types.GetAssetOutput{
|
|
Asset: types.NewAsset(asset),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddAssetTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddAssetInput) (*mcp.CallToolResult, types.AddAssetOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionAssetCreate)
|
|
if err != nil {
|
|
return nil, types.AddAssetOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
asset, err := svc.Assets.Create(
|
|
ctx, scope,
|
|
probo.CreateAssetRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Name: input.Name,
|
|
Amount: input.Amount,
|
|
OwnerID: input.OwnerID,
|
|
AssetType: input.AssetType,
|
|
DataTypesStored: input.DataTypesStored,
|
|
ThirdPartyIDs: input.ThirdPartyIds,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddAssetOutput{}, fmt.Errorf("failed to create asset: %w", err)
|
|
}
|
|
|
|
return nil, types.AddAssetOutput{
|
|
Asset: types.NewAsset(asset),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateAssetTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateAssetInput) (*mcp.CallToolResult, types.UpdateAssetOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionAssetUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateAssetOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
asset, err := svc.Assets.Update(
|
|
ctx, scope,
|
|
probo.UpdateAssetRequest{
|
|
ID: input.ID,
|
|
Name: input.Name,
|
|
Amount: input.Amount,
|
|
OwnerID: input.OwnerID,
|
|
AssetType: input.AssetType,
|
|
DataTypesStored: input.DataTypesStored,
|
|
ThirdPartyIDs: input.ThirdPartyIds,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateAssetOutput{}, fmt.Errorf("failed to update asset: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateAssetOutput{
|
|
Asset: types.NewAsset(asset),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListDataTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListDataInput) (*mcp.CallToolResult, types.ListDataOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionDatumList)
|
|
if err != nil {
|
|
return nil, types.ListDataOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.DatumOrderField]{
|
|
Field: coredata.DatumOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.DatumOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
page, err := prb.Data.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization data: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListDataOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetDatumTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetDatumInput) (*mcp.CallToolResult, types.GetDatumOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDatumGet)
|
|
if err != nil {
|
|
return nil, types.GetDatumOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
datum, err := prb.Data.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetDatumOutput{}, fmt.Errorf("failed to get datum: %w", err)
|
|
}
|
|
|
|
return nil, types.GetDatumOutput{
|
|
Datum: types.NewDatum(datum),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddDatumTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddDatumInput) (*mcp.CallToolResult, types.AddDatumOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionDatumCreate)
|
|
if err != nil {
|
|
return nil, types.AddDatumOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
datum, err := svc.Data.Create(
|
|
ctx, scope,
|
|
probo.CreateDatumRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Name: input.Name,
|
|
DataClassification: input.DataClassification,
|
|
OwnerID: input.OwnerID,
|
|
ThirdPartyIDs: input.ThirdPartyIds,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddDatumOutput{}, fmt.Errorf("failed to create datum: %w", err)
|
|
}
|
|
|
|
return nil, types.AddDatumOutput{
|
|
Datum: types.NewDatum(datum),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateDatumTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateDatumInput) (*mcp.CallToolResult, types.UpdateDatumOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDatumUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateDatumOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
datum, err := svc.Data.Update(
|
|
ctx, scope,
|
|
probo.UpdateDatumRequest{
|
|
ID: input.ID,
|
|
Name: input.Name,
|
|
DataClassification: input.DataClassification,
|
|
OwnerID: input.OwnerID,
|
|
ThirdPartyIDs: input.ThirdPartyIds,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateDatumOutput{}, fmt.Errorf("failed to update datum: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateDatumOutput{
|
|
Datum: types.NewDatum(datum),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListFindingsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListFindingsInput) (*mcp.CallToolResult, types.ListFindingsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionFindingList)
|
|
if err != nil {
|
|
return nil, types.ListFindingsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.FindingOrderField]{
|
|
Field: coredata.FindingOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.FindingOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
findingFilter := coredata.NewFindingFilter(nil, nil, nil, nil)
|
|
if input.Filter != nil {
|
|
findingFilter = coredata.NewFindingFilter(
|
|
input.Filter.Kind,
|
|
input.Filter.Status,
|
|
input.Filter.Priority,
|
|
input.Filter.OwnerID,
|
|
)
|
|
}
|
|
|
|
page, err := prb.Findings.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor, findingFilter)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization findings: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListFindingsOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetFindingTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetFindingInput) (*mcp.CallToolResult, types.GetFindingOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionFindingGet)
|
|
if err != nil {
|
|
return nil, types.GetFindingOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
finding, err := prb.Findings.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetFindingOutput{}, fmt.Errorf("cannot get finding: %w", err)
|
|
}
|
|
|
|
return nil, types.GetFindingOutput{
|
|
Finding: types.NewFinding(finding),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddFindingTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddFindingInput) (*mcp.CallToolResult, types.AddFindingOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionFindingCreate)
|
|
if err != nil {
|
|
return nil, types.AddFindingOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
finding, err := svc.Findings.Create(
|
|
ctx, scope,
|
|
&probo.CreateFindingRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Kind: input.Kind,
|
|
Description: input.Description,
|
|
Source: input.Source,
|
|
IdentifiedOn: input.IdentifiedOn,
|
|
RootCause: input.RootCause,
|
|
CorrectiveAction: input.CorrectiveAction,
|
|
OwnerID: input.OwnerID,
|
|
DueDate: input.DueDate,
|
|
Status: input.Status,
|
|
Priority: input.Priority,
|
|
RiskID: input.RiskID,
|
|
EffectivenessCheck: input.EffectivenessCheck,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddFindingOutput{}, fmt.Errorf("failed to create finding: %w", err)
|
|
}
|
|
|
|
return nil, types.AddFindingOutput{
|
|
Finding: types.NewFinding(finding),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateFindingTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateFindingInput) (*mcp.CallToolResult, types.UpdateFindingOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionFindingUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateFindingOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
finding, err := svc.Findings.Update(
|
|
ctx, scope,
|
|
&probo.UpdateFindingRequest{
|
|
ID: input.ID,
|
|
Description: UnwrapOmittable(input.Description),
|
|
Source: UnwrapOmittable(input.Source),
|
|
IdentifiedOn: UnwrapOmittable(input.IdentifiedOn),
|
|
RootCause: UnwrapOmittable(input.RootCause),
|
|
CorrectiveAction: UnwrapOmittable(input.CorrectiveAction),
|
|
OwnerID: input.OwnerID,
|
|
DueDate: UnwrapOmittable(input.DueDate),
|
|
Status: input.Status,
|
|
Priority: input.Priority,
|
|
RiskID: UnwrapOmittable(input.RiskID),
|
|
EffectivenessCheck: UnwrapOmittable(input.EffectivenessCheck),
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateFindingOutput{}, fmt.Errorf("failed to update finding: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateFindingOutput{
|
|
Finding: types.NewFinding(finding),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListObligationsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListObligationsInput) (*mcp.CallToolResult, types.ListObligationsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionObligationList)
|
|
if err != nil {
|
|
return nil, types.ListObligationsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ObligationOrderField]{
|
|
Field: coredata.ObligationOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ObligationOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
page, err := prb.Obligations.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization obligations: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListObligationsOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetObligationTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetObligationInput) (*mcp.CallToolResult, types.GetObligationOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionObligationGet)
|
|
if err != nil {
|
|
return nil, types.GetObligationOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
obligation, err := prb.Obligations.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetObligationOutput{}, fmt.Errorf("failed to get obligation: %w", err)
|
|
}
|
|
|
|
return nil, types.GetObligationOutput{
|
|
Obligation: types.NewObligation(obligation),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddObligationTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddObligationInput) (*mcp.CallToolResult, types.AddObligationOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionObligationCreate)
|
|
if err != nil {
|
|
return nil, types.AddObligationOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
obligation, err := svc.Obligations.Create(
|
|
ctx, scope,
|
|
&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,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddObligationOutput{}, fmt.Errorf("failed to create obligation: %w", err)
|
|
}
|
|
|
|
return nil, types.AddObligationOutput{
|
|
Obligation: types.NewObligation(obligation),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateObligationTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateObligationInput) (*mcp.CallToolResult, types.UpdateObligationOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionObligationUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateObligationOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
obligation, err := svc.Obligations.Update(
|
|
ctx, scope,
|
|
&probo.UpdateObligationRequest{
|
|
ID: input.ID,
|
|
Area: UnwrapOmittable(input.Area),
|
|
Source: UnwrapOmittable(input.Source),
|
|
Requirement: UnwrapOmittable(input.Requirement),
|
|
ActionsToBeImplemented: UnwrapOmittable(input.ActionsToBeImplemented),
|
|
Regulator: UnwrapOmittable(input.Regulator),
|
|
OwnerID: input.OwnerID,
|
|
LastReviewDate: UnwrapOmittable(input.LastReviewDate),
|
|
DueDate: UnwrapOmittable(input.DueDate),
|
|
Status: input.Status,
|
|
Type: input.Type,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateObligationOutput{}, fmt.Errorf("failed to update obligation: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateObligationOutput{
|
|
Obligation: types.NewObligation(obligation),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListProcessingActivitiesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListProcessingActivitiesInput) (*mcp.CallToolResult, types.ListProcessingActivitiesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionProcessingActivityList)
|
|
if err != nil {
|
|
return nil, types.ListProcessingActivitiesOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ProcessingActivityOrderField]{
|
|
Field: coredata.ProcessingActivityOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ProcessingActivityOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
page, err := prb.ProcessingActivities.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization processing activities: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListProcessingActivitiesOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetProcessingActivityTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetProcessingActivityInput) (*mcp.CallToolResult, types.GetProcessingActivityOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionProcessingActivityGet)
|
|
if err != nil {
|
|
return nil, types.GetProcessingActivityOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
processingActivity, err := prb.ProcessingActivities.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetProcessingActivityOutput{}, fmt.Errorf("failed to get processing activity: %w", err)
|
|
}
|
|
|
|
return nil, types.GetProcessingActivityOutput{
|
|
ProcessingActivity: types.NewProcessingActivity(processingActivity),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddProcessingActivityTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddProcessingActivityInput) (*mcp.CallToolResult, types.AddProcessingActivityOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionProcessingActivityCreate)
|
|
if err != nil {
|
|
return nil, types.AddProcessingActivityOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
processingActivity, err := svc.ProcessingActivities.Create(
|
|
ctx, scope,
|
|
&probo.CreateProcessingActivityRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Name: input.Name,
|
|
Purpose: input.Purpose,
|
|
DataSubjectCategory: input.DataSubjectCategory,
|
|
PersonalDataCategory: input.PersonalDataCategory,
|
|
SpecialOrCriminalData: input.SpecialOrCriminalData,
|
|
ConsentEvidenceLink: input.ConsentEvidenceLink,
|
|
LawfulBasis: input.LawfulBasis,
|
|
Recipients: input.Recipients,
|
|
Location: input.Location,
|
|
InternationalTransfers: input.InternationalTransfers,
|
|
TransferSafeguard: input.TransferSafeguard,
|
|
RetentionPeriod: input.RetentionPeriod,
|
|
SecurityMeasures: input.SecurityMeasures,
|
|
DataProtectionImpactAssessmentNeeded: input.DataProtectionImpactAssessmentNeeded,
|
|
TransferImpactAssessmentNeeded: input.TransferImpactAssessmentNeeded,
|
|
LastReviewDate: input.LastReviewDate,
|
|
NextReviewDate: input.NextReviewDate,
|
|
Role: input.Role,
|
|
DataProtectionOfficerID: input.DataProtectionOfficerID,
|
|
ThirdPartyIDs: input.ThirdPartyIds,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddProcessingActivityOutput{}, fmt.Errorf("failed to create processing activity: %w", err)
|
|
}
|
|
|
|
return nil, types.AddProcessingActivityOutput{
|
|
ProcessingActivity: types.NewProcessingActivity(processingActivity),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateProcessingActivityTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateProcessingActivityInput) (*mcp.CallToolResult, types.UpdateProcessingActivityOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionProcessingActivityUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateProcessingActivityOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
var thirdPartyIDs *[]gid.GID
|
|
if input.ThirdPartyIds != nil {
|
|
thirdPartyIDs = &input.ThirdPartyIds
|
|
}
|
|
|
|
processingActivity, err := svc.ProcessingActivities.Update(
|
|
ctx, scope,
|
|
&probo.UpdateProcessingActivityRequest{
|
|
ID: input.ID,
|
|
Name: input.Name,
|
|
Purpose: UnwrapOmittable(input.Purpose),
|
|
DataSubjectCategory: UnwrapOmittable(input.DataSubjectCategory),
|
|
PersonalDataCategory: UnwrapOmittable(input.PersonalDataCategory),
|
|
SpecialOrCriminalData: input.SpecialOrCriminalData,
|
|
ConsentEvidenceLink: UnwrapOmittable(input.ConsentEvidenceLink),
|
|
LawfulBasis: input.LawfulBasis,
|
|
Recipients: UnwrapOmittable(input.Recipients),
|
|
Location: UnwrapOmittable(input.Location),
|
|
InternationalTransfers: input.InternationalTransfers,
|
|
TransferSafeguard: UnwrapOmittable(input.TransferSafeguard),
|
|
RetentionPeriod: UnwrapOmittable(input.RetentionPeriod),
|
|
SecurityMeasures: UnwrapOmittable(input.SecurityMeasures),
|
|
DataProtectionImpactAssessmentNeeded: input.DataProtectionImpactAssessmentNeeded,
|
|
TransferImpactAssessmentNeeded: input.TransferImpactAssessmentNeeded,
|
|
LastReviewDate: UnwrapOmittable(input.LastReviewDate),
|
|
NextReviewDate: UnwrapOmittable(input.NextReviewDate),
|
|
Role: input.Role,
|
|
DataProtectionOfficerID: UnwrapOmittable(input.DataProtectionOfficerID),
|
|
ThirdPartyIDs: thirdPartyIDs,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateProcessingActivityOutput{}, fmt.Errorf("failed to update processing activity: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateProcessingActivityOutput{
|
|
ProcessingActivity: types.NewProcessingActivity(processingActivity),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteProcessingActivityTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteProcessingActivityInput) (*mcp.CallToolResult, types.DeleteProcessingActivityOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionProcessingActivityDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteProcessingActivityOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.ProcessingActivities.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteProcessingActivityOutput{}, fmt.Errorf("failed to delete processing activity: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteProcessingActivityOutput{
|
|
DeletedProcessingActivityID: input.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListDataProtectionImpactAssessmentsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListDataProtectionImpactAssessmentsInput) (*mcp.CallToolResult, types.ListDataProtectionImpactAssessmentsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionDataProtectionImpactAssessmentList)
|
|
if err != nil {
|
|
return nil, types.ListDataProtectionImpactAssessmentsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.DataProtectionImpactAssessmentOrderField]{
|
|
Field: coredata.DataProtectionImpactAssessmentOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.DataProtectionImpactAssessmentOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
page, err := prb.DataProtectionImpactAssessments.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization data protection impact assessments: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListDataProtectionImpactAssessmentsOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetDataProtectionImpactAssessmentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetDataProtectionImpactAssessmentInput) (*mcp.CallToolResult, types.GetDataProtectionImpactAssessmentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDataProtectionImpactAssessmentGet)
|
|
if err != nil {
|
|
return nil, types.GetDataProtectionImpactAssessmentOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
dpia, err := prb.DataProtectionImpactAssessments.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetDataProtectionImpactAssessmentOutput{}, fmt.Errorf("failed to get data protection impact assessment: %w", err)
|
|
}
|
|
|
|
return nil, types.GetDataProtectionImpactAssessmentOutput{
|
|
DataProtectionImpactAssessment: types.NewDataProtectionImpactAssessment(dpia),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddDataProtectionImpactAssessmentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddDataProtectionImpactAssessmentInput) (*mcp.CallToolResult, types.AddDataProtectionImpactAssessmentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ProcessingActivityID, probo.ActionDataProtectionImpactAssessmentCreate)
|
|
if err != nil {
|
|
return nil, types.AddDataProtectionImpactAssessmentOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
dpia, err := svc.DataProtectionImpactAssessments.Create(
|
|
ctx, scope,
|
|
&probo.CreateDataProtectionImpactAssessmentRequest{
|
|
ProcessingActivityID: input.ProcessingActivityID,
|
|
Description: input.Description,
|
|
NecessityAndProportionality: input.NecessityAndProportionality,
|
|
PotentialRisk: input.PotentialRisk,
|
|
Mitigations: input.Mitigations,
|
|
ResidualRisk: input.ResidualRisk,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddDataProtectionImpactAssessmentOutput{}, fmt.Errorf("failed to create data protection impact assessment: %w", err)
|
|
}
|
|
|
|
return nil, types.AddDataProtectionImpactAssessmentOutput{
|
|
DataProtectionImpactAssessment: types.NewDataProtectionImpactAssessment(dpia),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateDataProtectionImpactAssessmentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateDataProtectionImpactAssessmentInput) (*mcp.CallToolResult, types.UpdateDataProtectionImpactAssessmentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDataProtectionImpactAssessmentUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateDataProtectionImpactAssessmentOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
dpia, err := svc.DataProtectionImpactAssessments.Update(
|
|
ctx, scope,
|
|
&probo.UpdateDataProtectionImpactAssessmentRequest{
|
|
ID: input.ID,
|
|
Description: UnwrapOmittable(input.Description),
|
|
NecessityAndProportionality: UnwrapOmittable(input.NecessityAndProportionality),
|
|
PotentialRisk: UnwrapOmittable(input.PotentialRisk),
|
|
Mitigations: UnwrapOmittable(input.Mitigations),
|
|
ResidualRisk: input.ResidualRisk,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateDataProtectionImpactAssessmentOutput{}, fmt.Errorf("failed to update data protection impact assessment: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateDataProtectionImpactAssessmentOutput{
|
|
DataProtectionImpactAssessment: types.NewDataProtectionImpactAssessment(dpia),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListTransferImpactAssessmentsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListTransferImpactAssessmentsInput) (*mcp.CallToolResult, types.ListTransferImpactAssessmentsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionTransferImpactAssessmentList)
|
|
if err != nil {
|
|
return nil, types.ListTransferImpactAssessmentsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.TransferImpactAssessmentOrderField]{
|
|
Field: coredata.TransferImpactAssessmentOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.TransferImpactAssessmentOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
page, err := prb.TransferImpactAssessments.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization transfer impact assessments: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListTransferImpactAssessmentsOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetTransferImpactAssessmentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetTransferImpactAssessmentInput) (*mcp.CallToolResult, types.GetTransferImpactAssessmentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTransferImpactAssessmentGet)
|
|
if err != nil {
|
|
return nil, types.GetTransferImpactAssessmentOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
tia, err := prb.TransferImpactAssessments.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetTransferImpactAssessmentOutput{}, fmt.Errorf("failed to get transfer impact assessment: %w", err)
|
|
}
|
|
|
|
return nil, types.GetTransferImpactAssessmentOutput{
|
|
TransferImpactAssessment: types.NewTransferImpactAssessment(tia),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddTransferImpactAssessmentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddTransferImpactAssessmentInput) (*mcp.CallToolResult, types.AddTransferImpactAssessmentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ProcessingActivityID, probo.ActionTransferImpactAssessmentCreate)
|
|
if err != nil {
|
|
return nil, types.AddTransferImpactAssessmentOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
tia, err := svc.TransferImpactAssessments.Create(
|
|
ctx, scope,
|
|
&probo.CreateTransferImpactAssessmentRequest{
|
|
ProcessingActivityID: input.ProcessingActivityID,
|
|
DataSubjects: input.DataSubjects,
|
|
LegalMechanism: input.LegalMechanism,
|
|
Transfer: input.Transfer,
|
|
LocalLawRisk: input.LocalLawRisk,
|
|
SupplementaryMeasures: input.SupplementaryMeasures,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddTransferImpactAssessmentOutput{}, fmt.Errorf("failed to create transfer impact assessment: %w", err)
|
|
}
|
|
|
|
return nil, types.AddTransferImpactAssessmentOutput{
|
|
TransferImpactAssessment: types.NewTransferImpactAssessment(tia),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateTransferImpactAssessmentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateTransferImpactAssessmentInput) (*mcp.CallToolResult, types.UpdateTransferImpactAssessmentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTransferImpactAssessmentUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateTransferImpactAssessmentOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
tia, err := svc.TransferImpactAssessments.Update(
|
|
ctx, scope,
|
|
&probo.UpdateTransferImpactAssessmentRequest{
|
|
ID: input.ID,
|
|
DataSubjects: UnwrapOmittable(input.DataSubjects),
|
|
LegalMechanism: UnwrapOmittable(input.LegalMechanism),
|
|
Transfer: UnwrapOmittable(input.Transfer),
|
|
LocalLawRisk: UnwrapOmittable(input.LocalLawRisk),
|
|
SupplementaryMeasures: UnwrapOmittable(input.SupplementaryMeasures),
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateTransferImpactAssessmentOutput{}, fmt.Errorf("failed to update transfer impact assessment: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateTransferImpactAssessmentOutput{
|
|
TransferImpactAssessment: types.NewTransferImpactAssessment(tia),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteTransferImpactAssessmentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteTransferImpactAssessmentInput) (*mcp.CallToolResult, types.DeleteTransferImpactAssessmentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTransferImpactAssessmentDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteTransferImpactAssessmentOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.TransferImpactAssessments.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteTransferImpactAssessmentOutput{}, fmt.Errorf("failed to delete transfer impact assessment: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteTransferImpactAssessmentOutput{
|
|
DeletedTransferImpactAssessmentID: input.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListAuditsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListAuditsInput) (*mcp.CallToolResult, types.ListAuditsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionAuditList)
|
|
if err != nil {
|
|
return nil, types.ListAuditsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.AuditOrderField]{
|
|
Field: coredata.AuditOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.AuditOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
page, err := prb.Audits.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization audits: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListAuditsOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetAuditTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetAuditInput) (*mcp.CallToolResult, types.GetAuditOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionAuditGet)
|
|
if err != nil {
|
|
return nil, types.GetAuditOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
audit, err := prb.Audits.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetAuditOutput{}, fmt.Errorf("cannot get audit: %w", err)
|
|
}
|
|
|
|
var file *coredata.File
|
|
if audit.ReportFileID != nil {
|
|
file, err = prb.Files.Get(ctx, scope, *audit.ReportFileID)
|
|
if err != nil {
|
|
return nil, types.GetAuditOutput{}, fmt.Errorf("cannot get audit report file: %w", err)
|
|
}
|
|
}
|
|
|
|
return nil, types.GetAuditOutput{
|
|
Audit: types.NewAudit(audit, file),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddAuditTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddAuditInput) (*mcp.CallToolResult, types.AddAuditOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionAuditCreate)
|
|
if err != nil {
|
|
return nil, types.AddAuditOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
audit, err := svc.Audits.Create(
|
|
ctx, scope,
|
|
&probo.CreateAuditRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Name: input.Name,
|
|
ValidFrom: input.ValidFrom,
|
|
ValidUntil: input.ValidUntil,
|
|
State: input.State,
|
|
FrameworkID: input.FrameworkID,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddAuditOutput{}, fmt.Errorf("failed to create audit: %w", err)
|
|
}
|
|
|
|
return nil, types.AddAuditOutput{
|
|
Audit: types.NewAudit(audit, nil),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateAuditTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateAuditInput) (*mcp.CallToolResult, types.UpdateAuditOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionAuditUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateAuditOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
audit, err := svc.Audits.Update(
|
|
ctx, scope,
|
|
&probo.UpdateAuditRequest{
|
|
ID: input.ID,
|
|
Name: UnwrapOmittable(input.Name),
|
|
ValidFrom: input.ValidFrom,
|
|
ValidUntil: input.ValidUntil,
|
|
State: input.State,
|
|
TrustCenterVisibility: input.TrustCenterVisibility,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateAuditOutput{}, fmt.Errorf("cannot update audit: %w", err)
|
|
}
|
|
|
|
var file *coredata.File
|
|
if audit.ReportFileID != nil {
|
|
file, err = svc.Files.Get(ctx, scope, *audit.ReportFileID)
|
|
if err != nil {
|
|
return nil, types.UpdateAuditOutput{}, fmt.Errorf("cannot get audit report file: %w", err)
|
|
}
|
|
}
|
|
|
|
return nil, types.UpdateAuditOutput{
|
|
Audit: types.NewAudit(audit, file),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListControlsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlsInput) (*mcp.CallToolResult, types.ListControlsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionControlList)
|
|
if err != nil {
|
|
return nil, types.ListControlsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ControlOrderField]{
|
|
Field: coredata.ControlOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ControlOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
var controlFilter = coredata.NewControlFilter(nil)
|
|
if input.Filter != nil {
|
|
controlFilter = coredata.NewControlFilter(input.Filter.Query)
|
|
}
|
|
|
|
var (
|
|
controlPage *page.Page[*coredata.Control, coredata.ControlOrderField]
|
|
)
|
|
|
|
if input.Filter != nil && input.Filter.FrameworkID != nil {
|
|
controlPage, err = prb.Controls.ListForFrameworkID(ctx, scope, *input.Filter.FrameworkID, cursor, controlFilter)
|
|
} else {
|
|
controlPage, err = prb.Controls.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor, controlFilter)
|
|
}
|
|
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization controls: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListControlsOutput(controlPage), nil
|
|
}
|
|
|
|
func (r *Resolver) GetControlTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetControlInput) (*mcp.CallToolResult, types.GetControlOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionControlGet)
|
|
if err != nil {
|
|
return nil, types.GetControlOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
control, err := prb.Controls.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetControlOutput{}, fmt.Errorf("failed to get control: %w", err)
|
|
}
|
|
|
|
return nil, types.GetControlOutput{
|
|
Control: types.NewControl(control),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddControlTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddControlInput) (*mcp.CallToolResult, types.AddControlOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.FrameworkID, probo.ActionControlCreate)
|
|
if err != nil {
|
|
return nil, types.AddControlOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
control, err := svc.Controls.Create(
|
|
ctx, scope,
|
|
probo.CreateControlRequest{
|
|
FrameworkID: input.FrameworkID,
|
|
Name: input.Name,
|
|
Description: input.Description,
|
|
SectionTitle: input.SectionTitle,
|
|
BestPractice: input.BestPractice,
|
|
MaturityLevel: coredata.ControlMaturityLevel(input.MaturityLevel),
|
|
NotImplementedJustification: input.NotImplementedJustification,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddControlOutput{}, fmt.Errorf("failed to create control: %w", err)
|
|
}
|
|
|
|
return nil, types.AddControlOutput{
|
|
Control: types.NewControl(control),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateControlTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateControlInput) (*mcp.CallToolResult, types.UpdateControlOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionControlUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateControlOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
var maturityLevel *coredata.ControlMaturityLevel
|
|
|
|
if input.MaturityLevel != nil {
|
|
v := coredata.ControlMaturityLevel(*input.MaturityLevel)
|
|
maturityLevel = &v
|
|
}
|
|
|
|
control, err := svc.Controls.Update(
|
|
ctx, scope,
|
|
probo.UpdateControlRequest{
|
|
ID: input.ID,
|
|
Name: input.Name,
|
|
Description: UnwrapOmittable(input.Description),
|
|
SectionTitle: input.SectionTitle,
|
|
BestPractice: input.BestPractice,
|
|
MaturityLevel: maturityLevel,
|
|
NotImplementedJustification: UnwrapOmittable(input.NotImplementedJustification),
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateControlOutput{}, fmt.Errorf("failed to update control: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateControlOutput{
|
|
Control: types.NewControl(control),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) LinkControlTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkControlInput) (*mcp.CallToolResult, types.LinkControlOutput, error) {
|
|
svc := r.proboSvc
|
|
|
|
switch input.ResourceID.EntityType() {
|
|
case coredata.MeasureEntityType:
|
|
scope, err := r.Authorize(ctx, input.ControlID, probo.ActionControlMeasureMappingCreate)
|
|
if err != nil {
|
|
return nil, types.LinkControlOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Controls.CreateMeasureMapping(ctx, scope, input.ControlID, input.ResourceID); err != nil {
|
|
return nil, types.LinkControlOutput{}, fmt.Errorf("failed to link control to measure: %w", err)
|
|
}
|
|
case coredata.DocumentEntityType:
|
|
scope, err := r.Authorize(ctx, input.ControlID, probo.ActionControlDocumentMappingCreate)
|
|
if err != nil {
|
|
return nil, types.LinkControlOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Controls.CreateDocumentMapping(ctx, scope, input.ControlID, input.ResourceID); err != nil {
|
|
return nil, types.LinkControlOutput{}, fmt.Errorf("failed to link control to document: %w", err)
|
|
}
|
|
case coredata.AuditEntityType:
|
|
scope, err := r.Authorize(ctx, input.ControlID, probo.ActionControlAuditMappingCreate)
|
|
if err != nil {
|
|
return nil, types.LinkControlOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Controls.CreateAuditMapping(ctx, scope, input.ControlID, input.ResourceID); err != nil {
|
|
return nil, types.LinkControlOutput{}, fmt.Errorf("failed to link control to audit: %w", err)
|
|
}
|
|
case coredata.ObligationEntityType:
|
|
scope, err := r.Authorize(ctx, input.ControlID, probo.ActionControlObligationMappingCreate)
|
|
if err != nil {
|
|
return nil, types.LinkControlOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Controls.CreateObligationMapping(ctx, scope, input.ControlID, input.ResourceID); err != nil {
|
|
return nil, types.LinkControlOutput{}, fmt.Errorf("failed to link control to obligation: %w", err)
|
|
}
|
|
default:
|
|
return nil, types.LinkControlOutput{}, fmt.Errorf("unsupported resource type for control linking: entity type %d", input.ResourceID.EntityType())
|
|
}
|
|
|
|
return nil, types.LinkControlOutput{}, nil
|
|
}
|
|
|
|
func (r *Resolver) UnlinkControlTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkControlInput) (*mcp.CallToolResult, types.UnlinkControlOutput, error) {
|
|
svc := r.proboSvc
|
|
|
|
switch input.ResourceID.EntityType() {
|
|
case coredata.MeasureEntityType:
|
|
scope, err := r.Authorize(ctx, input.ControlID, probo.ActionControlMeasureMappingDelete)
|
|
if err != nil {
|
|
return nil, types.UnlinkControlOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Controls.DeleteMeasureMapping(ctx, scope, input.ControlID, input.ResourceID); err != nil {
|
|
return nil, types.UnlinkControlOutput{}, fmt.Errorf("failed to unlink control from measure: %w", err)
|
|
}
|
|
case coredata.DocumentEntityType:
|
|
scope, err := r.Authorize(ctx, input.ControlID, probo.ActionControlDocumentMappingDelete)
|
|
if err != nil {
|
|
return nil, types.UnlinkControlOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Controls.DeleteDocumentMapping(ctx, scope, input.ControlID, input.ResourceID); err != nil {
|
|
return nil, types.UnlinkControlOutput{}, fmt.Errorf("failed to unlink control from document: %w", err)
|
|
}
|
|
case coredata.AuditEntityType:
|
|
scope, err := r.Authorize(ctx, input.ControlID, probo.ActionControlAuditMappingDelete)
|
|
if err != nil {
|
|
return nil, types.UnlinkControlOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Controls.DeleteAuditMapping(ctx, scope, input.ControlID, input.ResourceID); err != nil {
|
|
return nil, types.UnlinkControlOutput{}, fmt.Errorf("failed to unlink control from audit: %w", err)
|
|
}
|
|
case coredata.ObligationEntityType:
|
|
scope, err := r.Authorize(ctx, input.ControlID, probo.ActionControlObligationMappingDelete)
|
|
if err != nil {
|
|
return nil, types.UnlinkControlOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Controls.DeleteObligationMapping(ctx, scope, input.ControlID, input.ResourceID); err != nil {
|
|
return nil, types.UnlinkControlOutput{}, fmt.Errorf("failed to unlink control from obligation: %w", err)
|
|
}
|
|
default:
|
|
return nil, types.UnlinkControlOutput{}, fmt.Errorf("unsupported resource type for control unlinking: entity type %d", input.ResourceID.EntityType())
|
|
}
|
|
|
|
return nil, types.UnlinkControlOutput{}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListControlObligationsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlObligationsInput) (*mcp.CallToolResult, types.ListControlObligationsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ControlID, probo.ActionControlGet)
|
|
if err != nil {
|
|
return nil, types.ListControlObligationsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ObligationOrderField]{
|
|
Field: coredata.ObligationOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ObligationOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
obligationPage, err := prb.Obligations.ListForControlID(ctx, scope, input.ControlID, cursor)
|
|
if err != nil {
|
|
return nil, types.ListControlObligationsOutput{}, fmt.Errorf("failed to list control obligations: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListControlObligationsOutput(obligationPage), nil
|
|
}
|
|
|
|
func (r *Resolver) ListControlMeasuresTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlMeasuresInput) (*mcp.CallToolResult, types.ListControlMeasuresOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ControlID, probo.ActionControlGet)
|
|
if err != nil {
|
|
return nil, types.ListControlMeasuresOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.MeasureOrderField]{
|
|
Field: coredata.MeasureOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.MeasureOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
measurePage, err := prb.Measures.ListForControlID(ctx, scope, input.ControlID, cursor, coredata.NewMeasureFilter(nil, nil, nil))
|
|
if err != nil {
|
|
return nil, types.ListControlMeasuresOutput{}, fmt.Errorf("failed to list control measures: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListControlMeasuresOutput(measurePage), nil
|
|
}
|
|
|
|
func (r *Resolver) ListControlDocumentsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlDocumentsInput) (*mcp.CallToolResult, types.ListControlDocumentsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ControlID, probo.ActionControlGet)
|
|
if err != nil {
|
|
return nil, types.ListControlDocumentsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
|
Field: coredata.DocumentOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
docPage, err := prb.Documents.ListForControlID(ctx, scope, input.ControlID, cursor, coredata.NewDocumentFilter(nil))
|
|
if err != nil {
|
|
return nil, types.ListControlDocumentsOutput{}, fmt.Errorf("failed to list control documents: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListControlDocumentsOutput(docPage), nil
|
|
}
|
|
|
|
func (r *Resolver) ListControlAuditsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListControlAuditsInput) (*mcp.CallToolResult, types.ListControlAuditsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ControlID, probo.ActionControlGet)
|
|
if err != nil {
|
|
return nil, types.ListControlAuditsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.AuditOrderField]{
|
|
Field: coredata.AuditOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.AuditOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
auditPage, err := prb.Audits.ListForControlID(ctx, scope, input.ControlID, cursor)
|
|
if err != nil {
|
|
return nil, types.ListControlAuditsOutput{}, fmt.Errorf("failed to list control audits: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListControlAuditsOutput(auditPage), nil
|
|
}
|
|
|
|
func (r *Resolver) ListRiskObligationsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListRiskObligationsInput) (*mcp.CallToolResult, types.ListRiskObligationsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskID, probo.ActionRiskGet)
|
|
if err != nil {
|
|
return nil, types.ListRiskObligationsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ObligationOrderField]{
|
|
Field: coredata.ObligationOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ObligationOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
obligationPage, err := prb.Obligations.ListForRiskID(ctx, scope, input.RiskID, cursor)
|
|
if err != nil {
|
|
return nil, types.ListRiskObligationsOutput{}, fmt.Errorf("failed to list risk obligations: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListRiskObligationsOutput(obligationPage), nil
|
|
}
|
|
|
|
func (r *Resolver) LinkRiskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkRiskInput) (*mcp.CallToolResult, types.LinkRiskOutput, error) {
|
|
svc := r.proboSvc
|
|
|
|
switch input.ResourceID.EntityType() {
|
|
case coredata.DocumentEntityType:
|
|
scope, err := r.Authorize(ctx, input.RiskID, probo.ActionRiskDocumentMappingCreate)
|
|
if err != nil {
|
|
return nil, types.LinkRiskOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Risks.CreateDocumentMapping(ctx, scope, input.RiskID, input.ResourceID); err != nil {
|
|
return nil, types.LinkRiskOutput{}, fmt.Errorf("failed to link risk to document: %w", err)
|
|
}
|
|
case coredata.MeasureEntityType:
|
|
scope, err := r.Authorize(ctx, input.RiskID, probo.ActionRiskMeasureMappingCreate)
|
|
if err != nil {
|
|
return nil, types.LinkRiskOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Risks.CreateMeasureMapping(ctx, scope, input.RiskID, input.ResourceID); err != nil {
|
|
return nil, types.LinkRiskOutput{}, fmt.Errorf("failed to link risk to measure: %w", err)
|
|
}
|
|
case coredata.ObligationEntityType:
|
|
scope, err := r.Authorize(ctx, input.RiskID, probo.ActionRiskObligationMappingCreate)
|
|
if err != nil {
|
|
return nil, types.LinkRiskOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Risks.CreateObligationMapping(ctx, scope, input.RiskID, input.ResourceID); err != nil {
|
|
return nil, types.LinkRiskOutput{}, fmt.Errorf("failed to link risk to obligation: %w", err)
|
|
}
|
|
default:
|
|
return nil, types.LinkRiskOutput{}, fmt.Errorf("unsupported resource type for risk linking: entity type %d", input.ResourceID.EntityType())
|
|
}
|
|
|
|
return nil, types.LinkRiskOutput{}, nil
|
|
}
|
|
|
|
func (r *Resolver) UnlinkRiskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkRiskInput) (*mcp.CallToolResult, types.UnlinkRiskOutput, error) {
|
|
svc := r.proboSvc
|
|
|
|
switch input.ResourceID.EntityType() {
|
|
case coredata.DocumentEntityType:
|
|
scope, err := r.Authorize(ctx, input.RiskID, probo.ActionRiskDocumentMappingDelete)
|
|
if err != nil {
|
|
return nil, types.UnlinkRiskOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Risks.DeleteDocumentMapping(ctx, scope, input.RiskID, input.ResourceID); err != nil {
|
|
return nil, types.UnlinkRiskOutput{}, fmt.Errorf("failed to unlink risk from document: %w", err)
|
|
}
|
|
case coredata.MeasureEntityType:
|
|
scope, err := r.Authorize(ctx, input.RiskID, probo.ActionRiskMeasureMappingDelete)
|
|
if err != nil {
|
|
return nil, types.UnlinkRiskOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Risks.DeleteMeasureMapping(ctx, scope, input.RiskID, input.ResourceID); err != nil {
|
|
return nil, types.UnlinkRiskOutput{}, fmt.Errorf("failed to unlink risk from measure: %w", err)
|
|
}
|
|
case coredata.ObligationEntityType:
|
|
scope, err := r.Authorize(ctx, input.RiskID, probo.ActionRiskObligationMappingDelete)
|
|
if err != nil {
|
|
return nil, types.UnlinkRiskOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Risks.DeleteObligationMapping(ctx, scope, input.RiskID, input.ResourceID); err != nil {
|
|
return nil, types.UnlinkRiskOutput{}, fmt.Errorf("failed to unlink risk from obligation: %w", err)
|
|
}
|
|
default:
|
|
return nil, types.UnlinkRiskOutput{}, fmt.Errorf("unsupported resource type for risk unlinking: entity type %d", input.ResourceID.EntityType())
|
|
}
|
|
|
|
return nil, types.UnlinkRiskOutput{}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListTasksTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListTasksInput) (*mcp.CallToolResult, types.ListTasksOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionTaskList)
|
|
if err != nil {
|
|
return nil, types.ListTasksOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.TaskOrderField]{
|
|
Field: coredata.TaskOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.TaskOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
page, err := prb.Tasks.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization tasks: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListTasksOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetTaskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetTaskInput) (*mcp.CallToolResult, types.GetTaskOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTaskGet)
|
|
if err != nil {
|
|
return nil, types.GetTaskOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
task, err := prb.Tasks.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetTaskOutput{}, fmt.Errorf("failed to get task: %w", err)
|
|
}
|
|
|
|
return nil, types.GetTaskOutput{
|
|
Task: types.NewTask(task),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddTaskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddTaskInput) (*mcp.CallToolResult, types.AddTaskOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionTaskCreate)
|
|
if err != nil {
|
|
return nil, types.AddTaskOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
priority := coredata.TaskPriorityMedium
|
|
if input.Priority != nil {
|
|
priority = *input.Priority
|
|
}
|
|
|
|
task, err := svc.Tasks.Create(
|
|
ctx, scope,
|
|
probo.CreateTaskRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
MeasureID: input.MeasureID,
|
|
Name: input.Name,
|
|
Description: input.Description,
|
|
Priority: priority,
|
|
TimeEstimate: input.TimeEstimate,
|
|
Deadline: input.Deadline,
|
|
AssignedToID: input.AssignedToID,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddTaskOutput{}, fmt.Errorf("failed to create task: %w", err)
|
|
}
|
|
|
|
return nil, types.AddTaskOutput{
|
|
Task: types.NewTask(task),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateTaskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateTaskInput) (*mcp.CallToolResult, types.UpdateTaskOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTaskUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateTaskOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
task, err := svc.Tasks.Update(
|
|
ctx, scope,
|
|
probo.UpdateTaskRequest{
|
|
TaskID: input.ID,
|
|
Name: input.Name,
|
|
Description: UnwrapOmittable(input.Description),
|
|
State: input.State,
|
|
Priority: input.Priority,
|
|
Rank: input.Rank,
|
|
TimeEstimate: UnwrapOmittable(input.TimeEstimate),
|
|
Deadline: UnwrapOmittable(input.Deadline),
|
|
AssignedToID: UnwrapOmittable(input.AssignedToID),
|
|
MeasureID: UnwrapOmittable(input.MeasureID),
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateTaskOutput{}, fmt.Errorf("failed to update task: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateTaskOutput{
|
|
Task: types.NewTask(task),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AssignTaskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AssignTaskInput) (*mcp.CallToolResult, types.AssignTaskOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTaskAssign)
|
|
if err != nil {
|
|
return nil, types.AssignTaskOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
task, err := svc.Tasks.Assign(ctx, scope, input.ID, input.AssignedToID)
|
|
if err != nil {
|
|
return nil, types.AssignTaskOutput{}, fmt.Errorf("failed to assign task: %w", err)
|
|
}
|
|
|
|
return nil, types.AssignTaskOutput{
|
|
Task: types.NewTask(task),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UnassignTaskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnassignTaskInput) (*mcp.CallToolResult, types.UnassignTaskOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTaskUnassign)
|
|
if err != nil {
|
|
return nil, types.UnassignTaskOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
task, err := svc.Tasks.Unassign(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.UnassignTaskOutput{}, fmt.Errorf("failed to unassign task: %w", err)
|
|
}
|
|
|
|
return nil, types.UnassignTaskOutput{
|
|
Task: types.NewTask(task),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteTaskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteTaskInput) (*mcp.CallToolResult, types.DeleteTaskOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTaskDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteTaskOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.Tasks.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteTaskOutput{}, fmt.Errorf("failed to delete task: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteTaskOutput{
|
|
DeletedTaskID: input.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListDocumentsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListDocumentsInput) (*mcp.CallToolResult, types.ListDocumentsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionDocumentList)
|
|
if err != nil {
|
|
return nil, types.ListDocumentsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
|
Field: coredata.DocumentOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
documentFilter := coredata.NewDocumentFilter(nil).
|
|
WithStatus([]coredata.DocumentStatus{coredata.DocumentStatusActive})
|
|
|
|
if input.Filter != nil {
|
|
var query *string
|
|
if input.Filter.Query != nil && *input.Filter.Query != "" {
|
|
query = input.Filter.Query
|
|
}
|
|
|
|
documentFilter = coredata.NewDocumentFilter(query).
|
|
WithWriteModes(input.Filter.WriteModes).
|
|
WithDocumentTypes(input.Filter.DocumentTypes).
|
|
WithClassifications(input.Filter.Classifications).
|
|
WithStatus(input.Filter.Status)
|
|
|
|
if len(input.Filter.Status) == 0 {
|
|
documentFilter = documentFilter.WithStatus([]coredata.DocumentStatus{coredata.DocumentStatusActive})
|
|
}
|
|
}
|
|
|
|
docPage, err := prb.Documents.ListByOrganizationID(ctx, scope, input.OrganizationID, cursor, documentFilter)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization documents: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListDocumentsOutput(docPage), nil
|
|
}
|
|
|
|
func (r *Resolver) GetDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetDocumentInput) (*mcp.CallToolResult, types.GetDocumentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDocumentGet)
|
|
if err != nil {
|
|
return nil, types.GetDocumentOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
document, err := prb.Documents.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot get document: %w", err))
|
|
}
|
|
|
|
return nil, types.GetDocumentOutput{
|
|
Document: types.NewDocument(document),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddDocumentInput) (*mcp.CallToolResult, types.AddDocumentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionDocumentCreate)
|
|
if err != nil {
|
|
return nil, types.AddDocumentOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
var trustCenterVisibility *coredata.TrustCenterVisibility
|
|
if input.TrustCenterVisibility != nil {
|
|
trustCenterVisibility = input.TrustCenterVisibility
|
|
}
|
|
|
|
contentJSON, err := markdownToProseMirrorJSON(input.Content)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot convert markdown to prosemirror: %w", err))
|
|
}
|
|
|
|
document, documentVersion, err := svc.Documents.Create(
|
|
ctx, scope,
|
|
probo.CreateDocumentRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Title: input.Title,
|
|
Content: contentJSON,
|
|
Classification: input.Classification,
|
|
DocumentType: input.DocumentType,
|
|
TrustCenterVisibility: trustCenterVisibility,
|
|
DefaultApproverIDs: input.DefaultApproverIds,
|
|
},
|
|
)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot create document: %w", err))
|
|
}
|
|
|
|
return nil, types.NewAddDocumentOutput(document, documentVersion), nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateDocumentInput) (*mcp.CallToolResult, types.UpdateDocumentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDocumentUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateDocumentOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
var defaultApproverIDs *[]gid.GID
|
|
if input.DefaultApproverIds != nil {
|
|
defaultApproverIDs = &input.DefaultApproverIds
|
|
}
|
|
|
|
var content *string
|
|
|
|
if input.Content != nil {
|
|
c, err := markdownToProseMirrorJSON(*input.Content)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot convert markdown to prosemirror: %w", err))
|
|
}
|
|
|
|
content = &c
|
|
}
|
|
|
|
document, documentVersion, _, err := svc.Documents.Update(
|
|
ctx, scope,
|
|
probo.UpdateDocumentRequest{
|
|
DocumentID: input.ID,
|
|
Title: input.Title,
|
|
Content: content,
|
|
Classification: input.Classification,
|
|
DocumentType: input.DocumentType,
|
|
TrustCenterVisibility: input.TrustCenterVisibility,
|
|
DefaultApproverIDs: defaultApproverIDs,
|
|
},
|
|
)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot update document: %w", err))
|
|
}
|
|
|
|
output := types.UpdateDocumentOutput{
|
|
Document: types.NewDocument(document),
|
|
}
|
|
|
|
if documentVersion != nil {
|
|
output.DocumentVersion = types.NewDocumentVersion(documentVersion)
|
|
}
|
|
|
|
return nil, output, nil
|
|
}
|
|
|
|
func (r *Resolver) ListDocumentVersionsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListDocumentVersionsInput) (*mcp.CallToolResult, types.ListDocumentVersionsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.DocumentID, probo.ActionDocumentVersionList)
|
|
if err != nil {
|
|
return nil, types.ListDocumentVersionsOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.DocumentVersionOrderField]{
|
|
Field: coredata.DocumentVersionOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.DocumentVersionOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
svc := r.proboSvc
|
|
|
|
versionFilter := coredata.NewDocumentVersionFilter()
|
|
if input.Filter != nil && len(input.Filter.Statuses) > 0 {
|
|
versionFilter = versionFilter.WithStatuses(input.Filter.Statuses...)
|
|
}
|
|
|
|
versionPage, err := svc.Documents.ListVersions(ctx, scope, input.DocumentID, cursor, versionFilter)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list document versions: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListDocumentVersionsOutput(versionPage), nil
|
|
}
|
|
|
|
func (r *Resolver) GetDocumentVersionTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetDocumentVersionInput) (*mcp.CallToolResult, types.GetDocumentVersionOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDocumentVersionGet)
|
|
if err != nil {
|
|
return nil, types.GetDocumentVersionOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
version, err := svc.Documents.GetVersion(ctx, scope, input.ID)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot get document version: %w", err))
|
|
}
|
|
|
|
return nil, types.GetDocumentVersionOutput{
|
|
DocumentVersion: types.NewDocumentVersion(version),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListDocumentVersionSignaturesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListDocumentVersionSignaturesInput) (*mcp.CallToolResult, types.ListDocumentVersionSignaturesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionSignatureList)
|
|
if err != nil {
|
|
return nil, types.ListDocumentVersionSignaturesOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.DocumentVersionSignatureOrderField]{
|
|
Field: coredata.DocumentVersionSignatureOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.DocumentVersionSignatureOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
var (
|
|
signatureStates []coredata.DocumentVersionSignatureState
|
|
activeContract *bool
|
|
profileState *coredata.ProfileState
|
|
)
|
|
|
|
if input.Filter != nil {
|
|
if input.Filter.States != nil {
|
|
signatureStates = input.Filter.States
|
|
}
|
|
|
|
if input.Filter.ActiveContract != nil {
|
|
activeContract = input.Filter.ActiveContract
|
|
}
|
|
|
|
if input.Filter.State != nil {
|
|
profileState = input.Filter.State
|
|
}
|
|
}
|
|
|
|
signatureFilter := coredata.NewDocumentVersionSignatureFilter(signatureStates, activeContract, profileState)
|
|
|
|
page, err := prb.Documents.ListSignatures(ctx, scope, input.DocumentVersionID, cursor, signatureFilter)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list document version signatures: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListDocumentVersionSignaturesOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetDocumentVersionSignatureTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetDocumentVersionSignatureInput) (*mcp.CallToolResult, types.GetDocumentVersionSignatureOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDocumentVersionSignatureGet)
|
|
if err != nil {
|
|
return nil, types.GetDocumentVersionSignatureOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
signature, err := prb.Documents.GetVersionSignature(ctx, scope, input.ID)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot get document version signature: %w", err))
|
|
}
|
|
|
|
return nil, types.GetDocumentVersionSignatureOutput{
|
|
DocumentVersionSignature: types.NewDocumentVersionSignature(signature),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) RequestDocumentVersionSignatureTool(ctx context.Context, req *mcp.CallToolRequest, input *types.RequestDocumentVersionSignatureInput) (*mcp.CallToolResult, types.RequestDocumentVersionSignatureOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionSignatureRequest)
|
|
if err != nil {
|
|
return nil, types.RequestDocumentVersionSignatureOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
documentVersionSignature, err := svc.Documents.RequestSignature(
|
|
ctx, scope,
|
|
probo.RequestSignatureRequest{
|
|
DocumentVersionID: input.DocumentVersionID,
|
|
Signatory: input.SignatoryID,
|
|
},
|
|
)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot request signature: %w", err))
|
|
}
|
|
|
|
return nil, types.RequestDocumentVersionSignatureOutput{
|
|
DocumentVersionSignature: types.NewDocumentVersionSignature(documentVersionSignature),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteDocumentInput) (*mcp.CallToolResult, types.DeleteDocumentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.DocumentID, probo.ActionDocumentDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteDocumentOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.Documents.SoftDelete(ctx, scope, input.DocumentID)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot soft delete document: %w", err))
|
|
}
|
|
|
|
return nil, types.DeleteDocumentOutput{
|
|
DeletedDocumentID: input.DocumentID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) CancelSignatureRequestTool(ctx context.Context, req *mcp.CallToolRequest, input *types.CancelSignatureRequestInput) (*mcp.CallToolResult, types.CancelSignatureRequestOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.DocumentVersionSignatureID, probo.ActionDocumentVersionCancelSignature)
|
|
if err != nil {
|
|
return nil, types.CancelSignatureRequestOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.Documents.CancelSignatureRequest(ctx, scope, input.DocumentVersionSignatureID)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot cancel signature request: %w", err))
|
|
}
|
|
|
|
return nil, types.CancelSignatureRequestOutput{
|
|
DeletedDocumentVersionSignatureID: input.DocumentVersionSignatureID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteRiskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteRiskInput) (*mcp.CallToolResult, types.DeleteRiskOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteRiskOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.Risks.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteRiskOutput{}, fmt.Errorf("failed to delete risk: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteRiskOutput{
|
|
DeletedRiskID: input.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteMeasureTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteMeasureInput) (*mcp.CallToolResult, types.DeleteMeasureOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionMeasureDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteMeasureOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.Measures.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteMeasureOutput{}, fmt.Errorf("failed to delete measure: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteMeasureOutput{
|
|
DeletedMeasureID: input.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListMeasureRisksTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListMeasureRisksInput) (*mcp.CallToolResult, types.ListMeasureRisksOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.MeasureID, probo.ActionMeasureGet)
|
|
if err != nil {
|
|
return nil, types.ListMeasureRisksOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.RiskOrderField]{
|
|
Field: coredata.RiskOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.RiskOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
riskPage, err := prb.Risks.ListForMeasureID(ctx, scope, input.MeasureID, cursor, coredata.NewRiskFilter(nil))
|
|
if err != nil {
|
|
return nil, types.ListMeasureRisksOutput{}, fmt.Errorf("failed to list measure risks: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListMeasureRisksOutput(riskPage), nil
|
|
}
|
|
|
|
func (r *Resolver) ListMeasureControlsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListMeasureControlsInput) (*mcp.CallToolResult, types.ListMeasureControlsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.MeasureID, probo.ActionMeasureGet)
|
|
if err != nil {
|
|
return nil, types.ListMeasureControlsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ControlOrderField]{
|
|
Field: coredata.ControlOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ControlOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
controlPage, err := prb.Controls.ListForMeasureID(ctx, scope, input.MeasureID, cursor, coredata.NewControlFilter(nil))
|
|
if err != nil {
|
|
return nil, types.ListMeasureControlsOutput{}, fmt.Errorf("failed to list measure controls: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListMeasureControlsOutput(controlPage), nil
|
|
}
|
|
|
|
func (r *Resolver) ListMeasureTasksTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListMeasureTasksInput) (*mcp.CallToolResult, types.ListMeasureTasksOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.MeasureID, probo.ActionMeasureGet)
|
|
if err != nil {
|
|
return nil, types.ListMeasureTasksOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.TaskOrderField]{
|
|
Field: coredata.TaskOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.TaskOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
taskPage, err := prb.Tasks.ListForMeasureID(ctx, scope, input.MeasureID, cursor)
|
|
if err != nil {
|
|
return nil, types.ListMeasureTasksOutput{}, fmt.Errorf("failed to list measure tasks: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListMeasureTasksOutput(taskPage), nil
|
|
}
|
|
|
|
func (r *Resolver) ListMeasureEvidencesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListMeasureEvidencesInput) (*mcp.CallToolResult, types.ListMeasureEvidencesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.MeasureID, probo.ActionMeasureGet)
|
|
if err != nil {
|
|
return nil, types.ListMeasureEvidencesOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.EvidenceOrderField]{
|
|
Field: coredata.EvidenceOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
evidencePage, err := prb.Evidences.ListForMeasureID(ctx, scope, input.MeasureID, cursor)
|
|
if err != nil {
|
|
return nil, types.ListMeasureEvidencesOutput{}, fmt.Errorf("failed to list measure evidences: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListMeasureEvidencesOutput(evidencePage), nil
|
|
}
|
|
|
|
func (r *Resolver) LinkMeasureTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkMeasureInput) (*mcp.CallToolResult, types.LinkMeasureOutput, error) {
|
|
svc := r.proboSvc
|
|
|
|
switch input.ResourceID.EntityType() {
|
|
case coredata.ControlEntityType:
|
|
scope, err := r.Authorize(ctx, input.MeasureID, probo.ActionControlMeasureMappingCreate)
|
|
if err != nil {
|
|
return nil, types.LinkMeasureOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Controls.CreateMeasureMapping(ctx, scope, input.ResourceID, input.MeasureID); err != nil {
|
|
return nil, types.LinkMeasureOutput{}, fmt.Errorf("failed to link measure to control: %w", err)
|
|
}
|
|
case coredata.RiskEntityType:
|
|
scope, err := r.Authorize(ctx, input.MeasureID, probo.ActionRiskMeasureMappingCreate)
|
|
if err != nil {
|
|
return nil, types.LinkMeasureOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Risks.CreateMeasureMapping(ctx, scope, input.ResourceID, input.MeasureID); err != nil {
|
|
return nil, types.LinkMeasureOutput{}, fmt.Errorf("failed to link measure to risk: %w", err)
|
|
}
|
|
case coredata.DocumentEntityType:
|
|
scope, err := r.Authorize(ctx, input.MeasureID, probo.ActionMeasureDocumentMappingCreate)
|
|
if err != nil {
|
|
return nil, types.LinkMeasureOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Measures.CreateDocumentMapping(ctx, scope, input.MeasureID, input.ResourceID); err != nil {
|
|
return nil, types.LinkMeasureOutput{}, fmt.Errorf("failed to link measure to document: %w", err)
|
|
}
|
|
case coredata.ThirdPartyEntityType:
|
|
scope, err := r.Authorize(ctx, input.MeasureID, probo.ActionMeasureThirdPartyMappingCreate)
|
|
if err != nil {
|
|
return nil, types.LinkMeasureOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Measures.CreateThirdPartyMapping(ctx, scope, input.MeasureID, input.ResourceID); err != nil {
|
|
return nil, types.LinkMeasureOutput{}, fmt.Errorf("failed to link measure to third party: %w", err)
|
|
}
|
|
default:
|
|
return nil, types.LinkMeasureOutput{}, fmt.Errorf("unsupported resource type for measure linking: entity type %d", input.ResourceID.EntityType())
|
|
}
|
|
|
|
return nil, types.LinkMeasureOutput{}, nil
|
|
}
|
|
|
|
func (r *Resolver) UnlinkMeasureTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkMeasureInput) (*mcp.CallToolResult, types.UnlinkMeasureOutput, error) {
|
|
svc := r.proboSvc
|
|
|
|
switch input.ResourceID.EntityType() {
|
|
case coredata.ControlEntityType:
|
|
scope, err := r.Authorize(ctx, input.MeasureID, probo.ActionControlMeasureMappingDelete)
|
|
if err != nil {
|
|
return nil, types.UnlinkMeasureOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Controls.DeleteMeasureMapping(ctx, scope, input.ResourceID, input.MeasureID); err != nil {
|
|
return nil, types.UnlinkMeasureOutput{}, fmt.Errorf("failed to unlink measure from control: %w", err)
|
|
}
|
|
case coredata.RiskEntityType:
|
|
scope, err := r.Authorize(ctx, input.MeasureID, probo.ActionRiskMeasureMappingDelete)
|
|
if err != nil {
|
|
return nil, types.UnlinkMeasureOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Risks.DeleteMeasureMapping(ctx, scope, input.ResourceID, input.MeasureID); err != nil {
|
|
return nil, types.UnlinkMeasureOutput{}, fmt.Errorf("failed to unlink measure from risk: %w", err)
|
|
}
|
|
case coredata.DocumentEntityType:
|
|
scope, err := r.Authorize(ctx, input.MeasureID, probo.ActionMeasureDocumentMappingDelete)
|
|
if err != nil {
|
|
return nil, types.UnlinkMeasureOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Measures.DeleteDocumentMapping(ctx, scope, input.MeasureID, input.ResourceID); err != nil {
|
|
return nil, types.UnlinkMeasureOutput{}, fmt.Errorf("failed to unlink measure from document: %w", err)
|
|
}
|
|
case coredata.ThirdPartyEntityType:
|
|
scope, err := r.Authorize(ctx, input.MeasureID, probo.ActionMeasureThirdPartyMappingDelete)
|
|
if err != nil {
|
|
return nil, types.UnlinkMeasureOutput{}, err
|
|
}
|
|
|
|
if _, _, err := svc.Measures.DeleteThirdPartyMapping(ctx, scope, input.MeasureID, input.ResourceID); err != nil {
|
|
return nil, types.UnlinkMeasureOutput{}, fmt.Errorf("failed to unlink measure from third party: %w", err)
|
|
}
|
|
default:
|
|
return nil, types.UnlinkMeasureOutput{}, fmt.Errorf("unsupported resource type for measure unlinking: entity type %d", input.ResourceID.EntityType())
|
|
}
|
|
|
|
return nil, types.UnlinkMeasureOutput{}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListUsersTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListUsersInput) (*mcp.CallToolResult, types.ListUsersOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.OrganizationID, iam.ActionMembershipProfileList); err != nil {
|
|
return nil, types.ListUsersOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.MembershipProfileOrderField]{
|
|
Field: coredata.MembershipProfileOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.MembershipProfileOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
filter := coredata.NewMembershipProfileFilter(nil).WithMembership()
|
|
if input.Filter != nil {
|
|
filter = coredata.NewMembershipProfileFilter(input.Filter.ContractEnded).WithMembership()
|
|
if input.Filter.State != nil {
|
|
filter.WithState(*input.Filter.State)
|
|
}
|
|
}
|
|
|
|
pageResult, err := r.iamSvc.OrganizationService.ListProfiles(ctx, input.OrganizationID, cursor, filter)
|
|
if err != nil {
|
|
return nil, types.ListUsersOutput{}, fmt.Errorf("list users: %w", err)
|
|
}
|
|
|
|
users := make([]*types.Profile, 0, len(pageResult.Data))
|
|
for _, p := range pageResult.Data {
|
|
users = append(users, types.NewProfile(p))
|
|
}
|
|
|
|
var nextCursor *page.CursorKey
|
|
|
|
if len(pageResult.Data) > 0 && pageResult.Cursor != nil {
|
|
cursorKey := pageResult.Data[len(pageResult.Data)-1].CursorKey(pageResult.Cursor.OrderBy.Field)
|
|
nextCursor = &cursorKey
|
|
}
|
|
|
|
return nil, types.ListUsersOutput{
|
|
Users: users,
|
|
NextCursor: nextCursor,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) GetUserTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetUserInput) (*mcp.CallToolResult, types.GetUserOutput, error) {
|
|
profile, err := r.iamSvc.OrganizationService.GetProfile(ctx, input.ID)
|
|
if err != nil {
|
|
if _, ok := errors.AsType[*iam.ErrProfileNotFound](err); ok {
|
|
return nil, types.GetUserOutput{}, fmt.Errorf("user not found: %w", err)
|
|
}
|
|
|
|
return nil, types.GetUserOutput{}, fmt.Errorf("get user: %w", err)
|
|
}
|
|
|
|
if _, err := r.Authorize(ctx, profile.OrganizationID, iam.ActionMembershipProfileGet); err != nil {
|
|
return nil, types.GetUserOutput{}, err
|
|
}
|
|
|
|
return nil, types.GetUserOutput{User: types.NewProfile(profile)}, nil
|
|
}
|
|
|
|
func (r *Resolver) CreateUserTool(ctx context.Context, req *mcp.CallToolRequest, input *types.CreateUserInput) (*mcp.CallToolResult, types.CreateUserOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.OrganizationID, iam.ActionMembershipProfileCreate); err != nil {
|
|
return nil, types.CreateUserOutput{}, err
|
|
}
|
|
|
|
var contractStart, contractEnd **time.Time
|
|
if input.ContractStartDate != nil {
|
|
contractStart = &input.ContractStartDate
|
|
}
|
|
|
|
if input.ContractEndDate != nil {
|
|
contractEnd = &input.ContractEndDate
|
|
}
|
|
|
|
profile, err := r.iamSvc.OrganizationService.CreateUser(ctx, &iam.CreateUserRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
EmailAddress: input.EmailAddress,
|
|
Role: input.Role,
|
|
FullName: input.FullName,
|
|
AdditionalEmailAddresses: input.AdditionalEmailAddresses,
|
|
Kind: input.Kind,
|
|
Position: input.Position,
|
|
ContractStartDate: contractStart,
|
|
ContractEndDate: contractEnd,
|
|
})
|
|
if err != nil {
|
|
if _, ok := errors.AsType[*iam.ErrUserAlreadyExists](err); ok {
|
|
return nil, types.CreateUserOutput{}, fmt.Errorf("user with email already exists: %w", err)
|
|
}
|
|
|
|
return nil, types.CreateUserOutput{}, fmt.Errorf("create user: %w", err)
|
|
}
|
|
|
|
return nil, types.CreateUserOutput{User: types.NewProfile(profile)}, nil
|
|
}
|
|
|
|
func (r *Resolver) InviteUserTool(ctx context.Context, req *mcp.CallToolRequest, input *types.InviteUserInput) (*mcp.CallToolResult, types.InviteUserOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.ProfileID, iam.ActionInvitationCreate); err != nil {
|
|
return nil, types.InviteUserOutput{}, err
|
|
}
|
|
|
|
invitation, err := r.iamSvc.OrganizationService.InviteUser(ctx, &iam.CreateInvitationRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
ProfileID: input.ProfileID,
|
|
})
|
|
if err != nil {
|
|
if _, ok := errors.AsType[*iam.ErrOrganizationNotFound](err); ok {
|
|
return nil, types.InviteUserOutput{}, fmt.Errorf("organization not found: %w", err)
|
|
}
|
|
|
|
if _, ok := errors.AsType[*iam.ErrUserAlreadyExists](err); ok {
|
|
return nil, types.InviteUserOutput{}, fmt.Errorf("user already in organization: %w", err)
|
|
}
|
|
|
|
return nil, types.InviteUserOutput{}, fmt.Errorf("invite user: %w", err)
|
|
}
|
|
|
|
return nil, types.InviteUserOutput{InvitationID: invitation.ID}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateUserTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateUserInput) (*mcp.CallToolResult, types.UpdateUserOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.ID, iam.ActionMembershipProfileUpdate); err != nil {
|
|
return nil, types.UpdateUserOutput{}, err
|
|
}
|
|
|
|
var additionalEmails []mail.Addr
|
|
if input.AdditionalEmailAddresses != nil {
|
|
additionalEmails = *input.AdditionalEmailAddresses
|
|
}
|
|
|
|
var position *string
|
|
if p := UnwrapOmittable(input.Position); p != nil {
|
|
position = *p
|
|
}
|
|
|
|
var contractStart, contractEnd **time.Time
|
|
if p := UnwrapOmittable(input.ContractStartDate); p != nil {
|
|
contractStart = p
|
|
}
|
|
|
|
if p := UnwrapOmittable(input.ContractEndDate); p != nil {
|
|
contractEnd = p
|
|
}
|
|
|
|
profile, err := r.iamSvc.OrganizationService.UpdateUser(ctx, &iam.UpdateUserRequest{
|
|
ID: input.ID,
|
|
FullName: input.FullName,
|
|
AdditionalEmailAddresses: additionalEmails,
|
|
Kind: input.Kind,
|
|
Position: position,
|
|
ContractStartDate: contractStart,
|
|
ContractEndDate: contractEnd,
|
|
})
|
|
if err != nil {
|
|
return nil, types.UpdateUserOutput{}, fmt.Errorf("update user: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateUserOutput{User: types.NewProfile(profile)}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateMembershipTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateMembershipInput) (*mcp.CallToolResult, types.UpdateMembershipOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.MembershipID, iam.ActionMembershipUpdate); err != nil {
|
|
return nil, types.UpdateMembershipOutput{}, err
|
|
}
|
|
|
|
if input.Role == coredata.MembershipRoleOwner {
|
|
if _, err := r.Authorize(ctx, input.MembershipID, iam.ActionMembershipRoleSetOwner); err != nil {
|
|
return nil, types.UpdateMembershipOutput{}, err
|
|
}
|
|
}
|
|
|
|
membership, err := r.iamSvc.OrganizationService.UpdateMembership(ctx, input.OrganizationID, input.MembershipID, input.Role)
|
|
if err != nil {
|
|
return nil, types.UpdateMembershipOutput{}, fmt.Errorf("update membership: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateMembershipOutput{
|
|
Membership: &types.Membership{
|
|
ID: membership.ID,
|
|
Role: membership.Role,
|
|
CreatedAt: membership.CreatedAt,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) RemoveUserTool(ctx context.Context, req *mcp.CallToolRequest, input *types.RemoveUserInput) (*mcp.CallToolResult, types.RemoveUserOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.ProfileID, iam.ActionMembershipProfileDelete); err != nil {
|
|
return nil, types.RemoveUserOutput{}, err
|
|
}
|
|
|
|
err := r.iamSvc.OrganizationService.RemoveUser(ctx, input.OrganizationID, input.ProfileID)
|
|
if err != nil {
|
|
if _, ok := errors.AsType[*iam.ErrUserManagedBySCIM](err); ok {
|
|
return nil, types.RemoveUserOutput{}, fmt.Errorf("user is managed by SCIM and cannot be removed: %w", err)
|
|
}
|
|
|
|
if _, ok := errors.AsType[*iam.ErrLastActiveOwner](err); ok {
|
|
return nil, types.RemoveUserOutput{}, fmt.Errorf("cannot remove last active owner: %w", err)
|
|
}
|
|
|
|
return nil, types.RemoveUserOutput{}, fmt.Errorf("remove user: %w", err)
|
|
}
|
|
|
|
return nil, types.RemoveUserOutput{DeletedUserID: input.ProfileID}, nil
|
|
}
|
|
|
|
func (r *Resolver) ArchiveUserTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ArchiveUserInput) (*mcp.CallToolResult, types.ArchiveUserOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ProfileID, iam.ActionMembershipProfileDelete)
|
|
if err != nil {
|
|
return nil, types.ArchiveUserOutput{}, err
|
|
}
|
|
|
|
err = r.iamSvc.OrganizationService.ArchiveUser(ctx, scope, input.OrganizationID, input.ProfileID)
|
|
if err != nil {
|
|
if _, ok := errors.AsType[*iam.ErrUserManagedBySCIM](err); ok {
|
|
return nil, types.ArchiveUserOutput{}, fmt.Errorf("user is managed by SCIM and cannot be archived: %w", err)
|
|
}
|
|
|
|
if _, ok := errors.AsType[*iam.ErrLastActiveOwner](err); ok {
|
|
return nil, types.ArchiveUserOutput{}, fmt.Errorf("cannot archive last active owner: %w", err)
|
|
}
|
|
|
|
return nil, types.ArchiveUserOutput{}, fmt.Errorf("archive user: %w", err)
|
|
}
|
|
|
|
return nil, types.ArchiveUserOutput{ArchivedUserID: input.ProfileID}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteDataProtectionImpactAssessmentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteDataProtectionImpactAssessmentInput) (*mcp.CallToolResult, types.DeleteDataProtectionImpactAssessmentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDataProtectionImpactAssessmentDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteDataProtectionImpactAssessmentOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.DataProtectionImpactAssessments.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteDataProtectionImpactAssessmentOutput{}, fmt.Errorf("failed to delete data protection impact assessment: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteDataProtectionImpactAssessmentOutput{
|
|
DeletedDataProtectionImpactAssessmentID: input.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListStatementsOfApplicabilityTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListStatementsOfApplicabilityInput) (*mcp.CallToolResult, types.ListStatementsOfApplicabilityOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionStatementOfApplicabilityList)
|
|
if err != nil {
|
|
return nil, types.ListStatementsOfApplicabilityOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.StatementOfApplicabilityOrderField]{
|
|
Field: coredata.StatementOfApplicabilityOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.StatementOfApplicabilityOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
pg, err := prb.StatementsOfApplicability.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
return nil, types.ListStatementsOfApplicabilityOutput{}, fmt.Errorf("failed to list statements of applicability: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListStatementsOfApplicabilityOutput(pg), nil
|
|
}
|
|
|
|
func (r *Resolver) GetStatementOfApplicabilityTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetStatementOfApplicabilityInput) (*mcp.CallToolResult, types.GetStatementOfApplicabilityOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionStatementOfApplicabilityGet)
|
|
if err != nil {
|
|
return nil, types.GetStatementOfApplicabilityOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
soa, err := prb.StatementsOfApplicability.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetStatementOfApplicabilityOutput{}, fmt.Errorf("failed to get statement of applicability: %w", err)
|
|
}
|
|
|
|
return nil, types.GetStatementOfApplicabilityOutput{
|
|
StatementOfApplicability: types.NewStatementOfApplicability(soa),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddStatementOfApplicabilityTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddStatementOfApplicabilityInput) (*mcp.CallToolResult, types.AddStatementOfApplicabilityOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionStatementOfApplicabilityCreate)
|
|
if err != nil {
|
|
return nil, types.AddStatementOfApplicabilityOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
soa, err := svc.StatementsOfApplicability.Create(ctx, scope, probo.CreateStatementOfApplicabilityRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Name: input.Name,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddStatementOfApplicabilityOutput{}, fmt.Errorf("failed to create statement of applicability: %w", err)
|
|
}
|
|
|
|
return nil, types.AddStatementOfApplicabilityOutput{
|
|
StatementOfApplicability: types.NewStatementOfApplicability(soa),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateStatementOfApplicabilityTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateStatementOfApplicabilityInput) (*mcp.CallToolResult, types.UpdateStatementOfApplicabilityOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionStatementOfApplicabilityUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateStatementOfApplicabilityOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
soa, err := svc.StatementsOfApplicability.Update(ctx, scope, probo.UpdateStatementOfApplicabilityRequest{
|
|
StatementOfApplicabilityID: input.ID,
|
|
Name: input.Name,
|
|
})
|
|
if err != nil {
|
|
return nil, types.UpdateStatementOfApplicabilityOutput{}, fmt.Errorf("failed to update statement of applicability: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateStatementOfApplicabilityOutput{
|
|
StatementOfApplicability: types.NewStatementOfApplicability(soa),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteStatementOfApplicabilityTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteStatementOfApplicabilityInput) (*mcp.CallToolResult, types.DeleteStatementOfApplicabilityOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionStatementOfApplicabilityDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteStatementOfApplicabilityOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.StatementsOfApplicability.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteStatementOfApplicabilityOutput{}, fmt.Errorf("failed to delete statement of applicability: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteStatementOfApplicabilityOutput{
|
|
DeletedStatementOfApplicabilityID: input.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListApplicabilityStatementsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListApplicabilityStatementsInput) (*mcp.CallToolResult, types.ListApplicabilityStatementsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.StatementOfApplicabilityID, probo.ActionApplicabilityStatementList)
|
|
if err != nil {
|
|
return nil, types.ListApplicabilityStatementsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ApplicabilityStatementOrderField]{
|
|
Field: coredata.ApplicabilityStatementOrderFieldControlSectionTitle,
|
|
Direction: page.OrderDirectionAsc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ApplicabilityStatementOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
pg, err := prb.StatementsOfApplicability.ListApplicabilityStatements(ctx, scope, input.StatementOfApplicabilityID, cursor)
|
|
if err != nil {
|
|
return nil, types.ListApplicabilityStatementsOutput{}, fmt.Errorf("failed to list applicability statements: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListApplicabilityStatementsOutput(pg), nil
|
|
}
|
|
|
|
func (r *Resolver) GetApplicabilityStatementTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetApplicabilityStatementInput) (*mcp.CallToolResult, types.GetApplicabilityStatementOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionApplicabilityStatementGet)
|
|
if err != nil {
|
|
return nil, types.GetApplicabilityStatementOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
stmt, err := prb.StatementsOfApplicability.GetApplicabilityStatement(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetApplicabilityStatementOutput{}, fmt.Errorf("failed to get applicability statement: %w", err)
|
|
}
|
|
|
|
return nil, types.GetApplicabilityStatementOutput{
|
|
ApplicabilityStatement: types.NewApplicabilityStatement(stmt),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddApplicabilityStatementTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddApplicabilityStatementInput) (*mcp.CallToolResult, types.AddApplicabilityStatementOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.StatementOfApplicabilityID, probo.ActionApplicabilityStatementCreate)
|
|
if err != nil {
|
|
return nil, types.AddApplicabilityStatementOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
stmt, err := svc.StatementsOfApplicability.CreateApplicabilityStatement(
|
|
ctx, scope,
|
|
input.StatementOfApplicabilityID,
|
|
input.ControlID,
|
|
input.Applicability,
|
|
input.Justification,
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddApplicabilityStatementOutput{}, fmt.Errorf("failed to create applicability statement: %w", err)
|
|
}
|
|
|
|
return nil, types.AddApplicabilityStatementOutput{
|
|
ApplicabilityStatement: types.NewApplicabilityStatement(stmt),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateApplicabilityStatementTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateApplicabilityStatementInput) (*mcp.CallToolResult, types.UpdateApplicabilityStatementOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionApplicabilityStatementUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateApplicabilityStatementOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
stmt, err := svc.StatementsOfApplicability.UpdateApplicabilityStatement(
|
|
ctx, scope,
|
|
input.ID,
|
|
input.Applicability,
|
|
input.Justification,
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateApplicabilityStatementOutput{}, fmt.Errorf("failed to update applicability statement: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateApplicabilityStatementOutput{
|
|
ApplicabilityStatement: types.NewApplicabilityStatement(stmt),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteApplicabilityStatementTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteApplicabilityStatementInput) (*mcp.CallToolResult, types.DeleteApplicabilityStatementOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionApplicabilityStatementDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteApplicabilityStatementOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.StatementsOfApplicability.DeleteApplicabilityStatement(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteApplicabilityStatementOutput{}, fmt.Errorf("failed to delete applicability statement: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteApplicabilityStatementOutput{
|
|
DeletedApplicabilityStatementID: input.ID,
|
|
}, nil
|
|
}
|
|
|
|
// ListThirdPartyRiskAssessmentsTool handles the listThirdPartyRiskAssessments tool
|
|
// List all risk assessments for a thirdParty
|
|
func (r *Resolver) ListThirdPartyRiskAssessmentsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListThirdPartyRiskAssessmentsInput) (*mcp.CallToolResult, types.ListThirdPartyRiskAssessmentsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyRiskAssessmentList)
|
|
if err != nil {
|
|
return nil, types.ListThirdPartyRiskAssessmentsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ThirdPartyRiskAssessmentOrderField]{
|
|
Field: coredata.ThirdPartyRiskAssessmentOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ThirdPartyRiskAssessmentOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := prb.ThirdParties.ListRiskAssessments(ctx, scope, input.ThirdPartyID, cursor)
|
|
if err != nil {
|
|
return nil, types.ListThirdPartyRiskAssessmentsOutput{}, fmt.Errorf("cannot list thirdParty risk assessments: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListThirdPartyRiskAssessmentsOutput(p), nil
|
|
}
|
|
|
|
// AddThirdPartyRiskAssessmentTool handles the addThirdPartyRiskAssessment tool
|
|
// Add a new risk assessment for a thirdParty
|
|
func (r *Resolver) AddThirdPartyRiskAssessmentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddThirdPartyRiskAssessmentInput) (*mcp.CallToolResult, types.AddThirdPartyRiskAssessmentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyRiskAssessmentCreate)
|
|
if err != nil {
|
|
return nil, types.AddThirdPartyRiskAssessmentOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
assessment, err := prb.ThirdParties.CreateRiskAssessment(
|
|
ctx, scope,
|
|
probo.CreateThirdPartyRiskAssessmentRequest{
|
|
ThirdPartyID: input.ThirdPartyID,
|
|
ExpiresAt: input.ExpiresAt,
|
|
DataSensitivity: input.DataSensitivity,
|
|
BusinessImpact: input.BusinessImpact,
|
|
Notes: input.Notes,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddThirdPartyRiskAssessmentOutput{}, fmt.Errorf("failed to create thirdParty risk assessment: %w", err)
|
|
}
|
|
|
|
return nil, types.NewAddThirdPartyRiskAssessmentOutput(assessment), nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteThirdPartyTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteThirdPartyInput) (*mcp.CallToolResult, types.DeleteThirdPartyOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionThirdPartyDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteThirdPartyOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.ThirdParties.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteThirdPartyOutput{}, fmt.Errorf("failed to delete thirdParty: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteThirdPartyOutput{
|
|
DeletedThirdPartyID: input.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteFindingTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteFindingInput) (*mcp.CallToolResult, types.DeleteFindingOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionFindingDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteFindingOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.Findings.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteFindingOutput{}, fmt.Errorf("cannot delete finding: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteFindingOutput{
|
|
DeletedFindingID: input.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) LinkFindingAuditTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkFindingAuditInput) (*mcp.CallToolResult, types.LinkFindingAuditOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.FindingID, probo.ActionFindingAuditMappingCreate)
|
|
if err != nil {
|
|
return nil, types.LinkFindingAuditOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
finding, audit, err := svc.Findings.CreateAuditMapping(ctx, scope, input.FindingID, input.AuditID, input.ReferenceID)
|
|
if err != nil {
|
|
return nil, types.LinkFindingAuditOutput{}, fmt.Errorf("cannot link finding to audit: %w", err)
|
|
}
|
|
|
|
return nil, types.LinkFindingAuditOutput{
|
|
Finding: types.NewFinding(finding),
|
|
Audit: types.NewAudit(audit, nil),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UnlinkFindingAuditTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkFindingAuditInput) (*mcp.CallToolResult, types.UnlinkFindingAuditOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.FindingID, probo.ActionFindingAuditMappingDelete)
|
|
if err != nil {
|
|
return nil, types.UnlinkFindingAuditOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
finding, audit, err := svc.Findings.DeleteAuditMapping(ctx, scope, input.FindingID, input.AuditID)
|
|
if err != nil {
|
|
return nil, types.UnlinkFindingAuditOutput{}, fmt.Errorf("cannot unlink finding from audit: %w", err)
|
|
}
|
|
|
|
return nil, types.UnlinkFindingAuditOutput{
|
|
DeletedFindingID: finding.ID,
|
|
DeletedAuditID: audit.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListFindingAuditsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListFindingAuditsInput) (*mcp.CallToolResult, types.ListFindingAuditsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.FindingID, probo.ActionFindingGet)
|
|
if err != nil {
|
|
return nil, types.ListFindingAuditsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.AuditOrderField]{
|
|
Field: coredata.AuditOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.AuditOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
auditPage, err := prb.Audits.ListForFindingID(ctx, scope, input.FindingID, cursor)
|
|
if err != nil {
|
|
return nil, types.ListFindingAuditsOutput{}, fmt.Errorf("cannot list finding audits: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListFindingAuditsOutput(auditPage), nil
|
|
}
|
|
|
|
// ListAccessReviewCampaignsTool handles the listAccessReviewCampaigns tool
|
|
// List access review campaigns for an organization
|
|
func (r *Resolver) ListAccessReviewCampaignsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListAccessReviewCampaignsInput) (*mcp.CallToolResult, types.ListAccessReviewCampaignsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionAccessReviewCampaignList)
|
|
if err != nil {
|
|
return nil, types.ListAccessReviewCampaignsOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.AccessReviewCampaignOrderField]{
|
|
Field: coredata.AccessReviewCampaignOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.AccessReviewCampaignOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := r.accessReview.Campaigns(scope).ListForOrganizationID(ctx, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list access review campaigns: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListAccessReviewCampaignsOutput(p), nil
|
|
}
|
|
|
|
// ListAccessEntriesTool handles the listAccessEntries tool
|
|
// List access entries for a campaign with optional filters
|
|
func (r *Resolver) ListAccessEntriesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListAccessEntriesInput) (*mcp.CallToolResult, types.ListAccessEntriesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CampaignID, probo.ActionAccessEntryList)
|
|
if err != nil {
|
|
return nil, types.ListAccessEntriesOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.AccessEntryOrderField]{
|
|
Field: coredata.AccessEntryOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.AccessEntryOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
var filter *coredata.AccessEntryFilter
|
|
if input.Filter != nil {
|
|
filter = &coredata.AccessEntryFilter{
|
|
Decision: input.Filter.Decision,
|
|
Flag: input.Filter.Flag,
|
|
IncrementalTag: input.Filter.IncrementalTag,
|
|
IsAdmin: input.Filter.IsAdmin,
|
|
Active: input.Filter.Active,
|
|
AuthMethod: input.Filter.AuthMethod,
|
|
AccountType: input.Filter.AccountType,
|
|
}
|
|
}
|
|
|
|
var p *page.Page[*coredata.AccessEntry, coredata.AccessEntryOrderField]
|
|
|
|
if input.AccessSourceID != nil {
|
|
var err error
|
|
|
|
p, err = r.accessReview.Entries(scope).ListForCampaignIDAndSourceID(
|
|
ctx,
|
|
input.CampaignID,
|
|
*input.AccessSourceID,
|
|
cursor,
|
|
filter,
|
|
)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list access entries: %w", err))
|
|
}
|
|
} else {
|
|
var err error
|
|
|
|
p, err = r.accessReview.Entries(scope).ListForCampaignID(ctx, input.CampaignID, cursor, filter)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list access entries: %w", err))
|
|
}
|
|
}
|
|
|
|
return nil, types.NewListAccessEntriesOutput(p), nil
|
|
}
|
|
|
|
// GetAccessReviewCampaignStatisticsTool handles the getAccessReviewCampaignStatistics tool
|
|
// Get statistics for an access review campaign
|
|
func (r *Resolver) GetAccessReviewCampaignStatisticsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetAccessReviewCampaignStatisticsInput) (*mcp.CallToolResult, types.GetAccessReviewCampaignStatisticsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CampaignID, probo.ActionAccessReviewCampaignGet)
|
|
if err != nil {
|
|
return nil, types.GetAccessReviewCampaignStatisticsOutput{}, err
|
|
}
|
|
|
|
stats, err := r.accessReview.Entries(scope).Statistics(ctx, input.CampaignID)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot get campaign statistics: %w", err))
|
|
}
|
|
|
|
return nil, types.GetAccessReviewCampaignStatisticsOutput{
|
|
Statistics: types.NewAccessEntryStatistics(stats),
|
|
}, nil
|
|
}
|
|
|
|
// RecordAccessEntryDecisionTool handles the recordAccessEntryDecision tool
|
|
// Record a decision on an access entry
|
|
func (r *Resolver) RecordAccessEntryDecisionTool(ctx context.Context, req *mcp.CallToolRequest, input *types.RecordAccessEntryDecisionInput) (*mcp.CallToolResult, types.RecordAccessEntryDecisionOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.AccessEntryID, probo.ActionAccessEntryDecide)
|
|
if err != nil {
|
|
return nil, types.RecordAccessEntryDecisionOutput{}, err
|
|
}
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, types.RecordAccessEntryDecisionOutput{}, fmt.Errorf("no identity in context")
|
|
}
|
|
|
|
decisionReq := accessreview.RecordAccessEntryDecisionRequest{
|
|
EntryID: input.AccessEntryID,
|
|
Decision: input.Decision,
|
|
DecisionNote: input.DecisionNote,
|
|
}
|
|
|
|
organizationID, err := r.accessReview.ResolveEntryOrganizationID(ctx, input.AccessEntryID)
|
|
if err == nil {
|
|
profile, err := r.iamSvc.OrganizationService.GetProfileForIdentityAndOrganization(ctx, identity.ID, organizationID)
|
|
if err == nil {
|
|
decisionReq.DecidedByID = &profile.ID
|
|
}
|
|
}
|
|
|
|
entry, err := r.accessReview.Entries(scope).RecordDecision(ctx, decisionReq)
|
|
if err != nil {
|
|
return nil, types.RecordAccessEntryDecisionOutput{}, fmt.Errorf("cannot record decision: %w", err)
|
|
}
|
|
|
|
return nil, types.RecordAccessEntryDecisionOutput{
|
|
AccessEntry: types.NewAccessEntry(entry),
|
|
}, nil
|
|
}
|
|
|
|
// RecordAccessEntryDecisionsTool handles the recordAccessEntryDecisions tool
|
|
// Record decisions on multiple access entries in a single batch
|
|
func (r *Resolver) RecordAccessEntryDecisionsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.RecordAccessEntryDecisionsInput) (*mcp.CallToolResult, types.RecordAccessEntryDecisionsOutput, error) {
|
|
if len(input.Decisions) == 0 {
|
|
return nil, types.RecordAccessEntryDecisionsOutput{
|
|
AccessEntries: []*types.AccessEntry{},
|
|
}, nil
|
|
}
|
|
|
|
const maxBatchSize = 100
|
|
if len(input.Decisions) > maxBatchSize {
|
|
return nil, types.RecordAccessEntryDecisionsOutput{}, fmt.Errorf("cannot record decisions: batch size %d exceeds maximum of %d", len(input.Decisions), maxBatchSize)
|
|
}
|
|
|
|
// Authorize each entry individually to prevent cross-org bypass.
|
|
for _, d := range input.Decisions {
|
|
if _, err := r.Authorize(ctx, d.AccessEntryID, probo.ActionAccessEntryDecide); err != nil {
|
|
return nil, types.RecordAccessEntryDecisionsOutput{}, err
|
|
}
|
|
}
|
|
|
|
scope := coredata.NewScopeFromObjectID(input.Decisions[0].AccessEntryID)
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, types.RecordAccessEntryDecisionsOutput{}, fmt.Errorf("no identity in context")
|
|
}
|
|
|
|
// Cache profile lookups per organization so we resolve the correct
|
|
// decidedByID for each entry even when a batch spans multiple orgs.
|
|
profileCache := make(map[gid.GID]*gid.GID)
|
|
|
|
decisions := make([]accessreview.RecordAccessEntryDecisionRequest, len(input.Decisions))
|
|
for i, d := range input.Decisions {
|
|
var decidedByID *gid.GID
|
|
|
|
organizationID, err := r.accessReview.ResolveEntryOrganizationID(ctx, d.AccessEntryID)
|
|
if err == nil {
|
|
if cached, ok := profileCache[organizationID]; ok {
|
|
decidedByID = cached
|
|
} else {
|
|
profile, err := r.iamSvc.OrganizationService.GetProfileForIdentityAndOrganization(ctx, identity.ID, organizationID)
|
|
if err == nil {
|
|
decidedByID = &profile.ID
|
|
}
|
|
|
|
profileCache[organizationID] = decidedByID
|
|
}
|
|
}
|
|
|
|
decisions[i] = accessreview.RecordAccessEntryDecisionRequest{
|
|
EntryID: d.AccessEntryID,
|
|
Decision: d.Decision,
|
|
DecisionNote: d.DecisionNote,
|
|
DecidedByID: decidedByID,
|
|
}
|
|
}
|
|
|
|
entries, err := r.accessReview.Entries(scope).RecordDecisions(ctx, decisions)
|
|
if err != nil {
|
|
return nil, types.RecordAccessEntryDecisionsOutput{}, fmt.Errorf("cannot record decisions: %w", err)
|
|
}
|
|
|
|
accessEntries := make([]*types.AccessEntry, len(entries))
|
|
for i, e := range entries {
|
|
accessEntries[i] = types.NewAccessEntry(e)
|
|
}
|
|
|
|
return nil, types.RecordAccessEntryDecisionsOutput{
|
|
AccessEntries: accessEntries,
|
|
}, nil
|
|
}
|
|
|
|
// CloseAccessReviewCampaignTool handles the closeAccessReviewCampaign tool
|
|
// Close an access review campaign
|
|
func (r *Resolver) CloseAccessReviewCampaignTool(ctx context.Context, req *mcp.CallToolRequest, input *types.CloseAccessReviewCampaignInput) (*mcp.CallToolResult, types.CloseAccessReviewCampaignOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CampaignID, probo.ActionAccessReviewCampaignClose)
|
|
if err != nil {
|
|
return nil, types.CloseAccessReviewCampaignOutput{}, err
|
|
}
|
|
|
|
campaign, err := r.accessReview.Campaigns(scope).Close(ctx, input.CampaignID)
|
|
if err != nil {
|
|
return nil, types.CloseAccessReviewCampaignOutput{}, fmt.Errorf("cannot close campaign: %w", err)
|
|
}
|
|
|
|
return nil, types.CloseAccessReviewCampaignOutput{
|
|
Campaign: types.NewAccessReviewCampaign(campaign),
|
|
}, nil
|
|
}
|
|
|
|
// ListAccessSourcesTool handles the listAccessSources tool
|
|
// List access sources for an organization
|
|
func (r *Resolver) ListAccessSourcesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListAccessSourcesInput) (*mcp.CallToolResult, types.ListAccessSourcesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionAccessSourceList)
|
|
if err != nil {
|
|
return nil, types.ListAccessSourcesOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.AccessSourceOrderField]{
|
|
Field: coredata.AccessSourceOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.AccessSourceOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := r.accessReview.Sources(scope).ListForOrganizationID(ctx, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list access sources: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListAccessSourcesOutput(p), nil
|
|
}
|
|
|
|
// CreateAccessSourceTool handles the createAccessSource tool
|
|
// Create a new access source for an organization
|
|
func (r *Resolver) CreateAccessSourceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.CreateAccessSourceInput) (*mcp.CallToolResult, types.CreateAccessSourceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionAccessSourceCreate)
|
|
if err != nil {
|
|
return nil, types.CreateAccessSourceOutput{}, err
|
|
}
|
|
|
|
source, err := r.accessReview.Sources(scope).Create(ctx, accessreview.CreateAccessSourceRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
ConnectorID: input.ConnectorID,
|
|
Name: input.Name,
|
|
Category: coredata.AccessSourceCategorySaaS,
|
|
CsvData: input.CsvData,
|
|
})
|
|
if err != nil {
|
|
return nil, types.CreateAccessSourceOutput{}, fmt.Errorf("cannot create access source: %w", err)
|
|
}
|
|
|
|
return nil, types.CreateAccessSourceOutput{
|
|
AccessSource: types.NewAccessSource(source),
|
|
}, nil
|
|
}
|
|
|
|
// UpdateAccessSourceTool handles the updateAccessSource tool
|
|
// Update an existing access source
|
|
func (r *Resolver) UpdateAccessSourceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateAccessSourceInput) (*mcp.CallToolResult, types.UpdateAccessSourceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.AccessSourceID, probo.ActionAccessSourceUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateAccessSourceOutput{}, err
|
|
}
|
|
|
|
updateReq := accessreview.UpdateAccessSourceRequest{
|
|
AccessSourceID: input.AccessSourceID,
|
|
Name: input.Name,
|
|
}
|
|
|
|
if rawConnectorID := UnwrapOmittable(input.ConnectorID); rawConnectorID != nil {
|
|
if *rawConnectorID != nil {
|
|
id, err := gid.ParseGID(**rawConnectorID)
|
|
if err != nil {
|
|
return nil, types.UpdateAccessSourceOutput{}, fmt.Errorf("cannot parse connector_id: %w", err)
|
|
}
|
|
|
|
idPtr := &id
|
|
updateReq.ConnectorID = &idPtr
|
|
} else {
|
|
var nilGID *gid.GID
|
|
|
|
updateReq.ConnectorID = &nilGID
|
|
}
|
|
}
|
|
|
|
if rawCsvData := UnwrapOmittable(input.CsvData); rawCsvData != nil {
|
|
updateReq.CsvData = rawCsvData
|
|
}
|
|
|
|
source, err := r.accessReview.Sources(scope).Update(ctx, updateReq)
|
|
if err != nil {
|
|
return nil, types.UpdateAccessSourceOutput{}, fmt.Errorf("cannot update access source: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateAccessSourceOutput{
|
|
AccessSource: types.NewAccessSource(source),
|
|
}, nil
|
|
}
|
|
|
|
// DeleteAccessSourceTool handles the deleteAccessSource tool
|
|
// Delete an access source
|
|
func (r *Resolver) DeleteAccessSourceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteAccessSourceInput) (*mcp.CallToolResult, types.DeleteAccessSourceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.AccessSourceID, probo.ActionAccessSourceDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteAccessSourceOutput{}, err
|
|
}
|
|
|
|
if err := r.accessReview.Sources(scope).Delete(ctx, input.AccessSourceID); err != nil {
|
|
return nil, types.DeleteAccessSourceOutput{}, fmt.Errorf("cannot delete access source: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteAccessSourceOutput{
|
|
DeletedAccessSourceID: input.AccessSourceID,
|
|
}, nil
|
|
}
|
|
|
|
// CreateAccessReviewCampaignTool handles the createAccessReviewCampaign tool
|
|
// Create a new access review campaign for an organization
|
|
func (r *Resolver) CreateAccessReviewCampaignTool(ctx context.Context, req *mcp.CallToolRequest, input *types.CreateAccessReviewCampaignInput) (*mcp.CallToolResult, types.CreateAccessReviewCampaignOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionAccessReviewCampaignCreate)
|
|
if err != nil {
|
|
return nil, types.CreateAccessReviewCampaignOutput{}, err
|
|
}
|
|
|
|
var description string
|
|
if input.Description != nil {
|
|
description = *input.Description
|
|
}
|
|
|
|
campaign, err := r.accessReview.Campaigns(scope).Create(ctx, accessreview.CreateAccessReviewCampaignRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Name: input.Name,
|
|
Description: description,
|
|
FrameworkControls: input.FrameworkControls,
|
|
AccessSourceIDs: input.AccessSourceIds,
|
|
})
|
|
if err != nil {
|
|
return nil, types.CreateAccessReviewCampaignOutput{}, fmt.Errorf("cannot create access review campaign: %w", err)
|
|
}
|
|
|
|
return nil, types.CreateAccessReviewCampaignOutput{
|
|
Campaign: types.NewAccessReviewCampaign(campaign),
|
|
}, nil
|
|
}
|
|
|
|
// UpdateAccessReviewCampaignTool handles the updateAccessReviewCampaign tool
|
|
// Update an existing access review campaign
|
|
func (r *Resolver) UpdateAccessReviewCampaignTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateAccessReviewCampaignInput) (*mcp.CallToolResult, types.UpdateAccessReviewCampaignOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CampaignID, probo.ActionAccessReviewCampaignUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateAccessReviewCampaignOutput{}, err
|
|
}
|
|
|
|
updateReq := accessreview.UpdateAccessReviewCampaignRequest{
|
|
CampaignID: input.CampaignID,
|
|
Name: input.Name,
|
|
Description: input.Description,
|
|
}
|
|
|
|
if rawControls := UnwrapOmittable(input.FrameworkControls); rawControls != nil {
|
|
if *rawControls != nil {
|
|
controls := make([]string, 0, len(**rawControls))
|
|
for _, v := range **rawControls {
|
|
if s, ok := v.(string); ok {
|
|
controls = append(controls, s)
|
|
}
|
|
}
|
|
|
|
updateReq.FrameworkControls = &controls
|
|
} else {
|
|
empty := []string{}
|
|
updateReq.FrameworkControls = &empty
|
|
}
|
|
}
|
|
|
|
campaign, err := r.accessReview.Campaigns(scope).Update(ctx, updateReq)
|
|
if err != nil {
|
|
return nil, types.UpdateAccessReviewCampaignOutput{}, fmt.Errorf("cannot update access review campaign: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateAccessReviewCampaignOutput{
|
|
Campaign: types.NewAccessReviewCampaign(campaign),
|
|
}, nil
|
|
}
|
|
|
|
// DeleteAccessReviewCampaignTool handles the deleteAccessReviewCampaign tool
|
|
// Delete an access review campaign
|
|
func (r *Resolver) DeleteAccessReviewCampaignTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteAccessReviewCampaignInput) (*mcp.CallToolResult, types.DeleteAccessReviewCampaignOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CampaignID, probo.ActionAccessReviewCampaignDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteAccessReviewCampaignOutput{}, err
|
|
}
|
|
|
|
if err := r.accessReview.Campaigns(scope).Delete(ctx, input.CampaignID); err != nil {
|
|
return nil, types.DeleteAccessReviewCampaignOutput{}, fmt.Errorf("cannot delete access review campaign: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteAccessReviewCampaignOutput{
|
|
DeletedCampaignID: input.CampaignID,
|
|
}, nil
|
|
}
|
|
|
|
// StartAccessReviewCampaignTool handles the startAccessReviewCampaign tool
|
|
// Start an access review campaign
|
|
func (r *Resolver) StartAccessReviewCampaignTool(ctx context.Context, req *mcp.CallToolRequest, input *types.StartAccessReviewCampaignInput) (*mcp.CallToolResult, types.StartAccessReviewCampaignOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CampaignID, probo.ActionAccessReviewCampaignStart)
|
|
if err != nil {
|
|
return nil, types.StartAccessReviewCampaignOutput{}, err
|
|
}
|
|
|
|
campaign, err := r.accessReview.Campaigns(scope).Start(ctx, input.CampaignID)
|
|
if err != nil {
|
|
return nil, types.StartAccessReviewCampaignOutput{}, fmt.Errorf("cannot start access review campaign: %w", err)
|
|
}
|
|
|
|
return nil, types.StartAccessReviewCampaignOutput{
|
|
Campaign: types.NewAccessReviewCampaign(campaign),
|
|
}, nil
|
|
}
|
|
|
|
// CancelAccessReviewCampaignTool handles the cancelAccessReviewCampaign tool
|
|
// Cancel an in-progress access review campaign
|
|
func (r *Resolver) CancelAccessReviewCampaignTool(ctx context.Context, req *mcp.CallToolRequest, input *types.CancelAccessReviewCampaignInput) (*mcp.CallToolResult, types.CancelAccessReviewCampaignOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CampaignID, probo.ActionAccessReviewCampaignCancel)
|
|
if err != nil {
|
|
return nil, types.CancelAccessReviewCampaignOutput{}, err
|
|
}
|
|
|
|
campaign, err := r.accessReview.Campaigns(scope).Cancel(ctx, input.CampaignID)
|
|
if err != nil {
|
|
return nil, types.CancelAccessReviewCampaignOutput{}, fmt.Errorf("cannot cancel access review campaign: %w", err)
|
|
}
|
|
|
|
return nil, types.CancelAccessReviewCampaignOutput{
|
|
Campaign: types.NewAccessReviewCampaign(campaign),
|
|
}, nil
|
|
}
|
|
|
|
// AddAccessReviewCampaignScopeSourceTool handles the addAccessReviewCampaignScopeSource tool
|
|
// Add an access source to an access review campaign's scope
|
|
func (r *Resolver) AddAccessReviewCampaignScopeSourceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddAccessReviewCampaignScopeSourceInput) (*mcp.CallToolResult, types.AddAccessReviewCampaignScopeSourceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CampaignID, probo.ActionAccessReviewCampaignAddScopeSource)
|
|
if err != nil {
|
|
return nil, types.AddAccessReviewCampaignScopeSourceOutput{}, err
|
|
}
|
|
|
|
campaign, err := r.accessReview.Campaigns(scope).AddScopeSource(ctx, accessreview.AddCampaignScopeSourceRequest{
|
|
CampaignID: input.CampaignID,
|
|
AccessSourceID: input.AccessSourceID,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddAccessReviewCampaignScopeSourceOutput{}, fmt.Errorf("cannot add scope source to access review campaign: %w", err)
|
|
}
|
|
|
|
return nil, types.AddAccessReviewCampaignScopeSourceOutput{
|
|
Campaign: types.NewAccessReviewCampaign(campaign),
|
|
}, nil
|
|
}
|
|
|
|
// RemoveAccessReviewCampaignScopeSourceTool handles the removeAccessReviewCampaignScopeSource tool
|
|
// Remove an access source from an access review campaign's scope
|
|
func (r *Resolver) RemoveAccessReviewCampaignScopeSourceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.RemoveAccessReviewCampaignScopeSourceInput) (*mcp.CallToolResult, types.RemoveAccessReviewCampaignScopeSourceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CampaignID, probo.ActionAccessReviewCampaignRemoveScopeSource)
|
|
if err != nil {
|
|
return nil, types.RemoveAccessReviewCampaignScopeSourceOutput{}, err
|
|
}
|
|
|
|
campaign, err := r.accessReview.Campaigns(scope).RemoveScopeSource(ctx, accessreview.RemoveCampaignScopeSourceRequest{
|
|
CampaignID: input.CampaignID,
|
|
AccessSourceID: input.AccessSourceID,
|
|
})
|
|
if err != nil {
|
|
return nil, types.RemoveAccessReviewCampaignScopeSourceOutput{}, fmt.Errorf("cannot remove scope source from access review campaign: %w", err)
|
|
}
|
|
|
|
return nil, types.RemoveAccessReviewCampaignScopeSourceOutput{
|
|
Campaign: types.NewAccessReviewCampaign(campaign),
|
|
}, nil
|
|
}
|
|
|
|
// FlagAccessEntryTool handles the flagAccessEntry tool
|
|
// Flag an access entry during review
|
|
func (r *Resolver) FlagAccessEntryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.FlagAccessEntryInput) (*mcp.CallToolResult, types.FlagAccessEntryOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.AccessEntryID, probo.ActionAccessEntryFlag)
|
|
if err != nil {
|
|
return nil, types.FlagAccessEntryOutput{}, err
|
|
}
|
|
|
|
entry, err := r.accessReview.Entries(scope).FlagEntry(ctx, accessreview.FlagAccessEntryRequest{
|
|
EntryID: input.AccessEntryID,
|
|
Flags: input.Flags,
|
|
FlagReasons: input.FlagReasons,
|
|
})
|
|
if err != nil {
|
|
return nil, types.FlagAccessEntryOutput{}, fmt.Errorf("cannot flag access entry: %w", err)
|
|
}
|
|
|
|
return nil, types.FlagAccessEntryOutput{
|
|
AccessEntry: types.NewAccessEntry(entry),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) GetAuditReportUrlTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetAuditReportUrlInput) (*mcp.CallToolResult, types.GetAuditReportUrlOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionReportGetReportUrl)
|
|
if err != nil {
|
|
return nil, types.GetAuditReportUrlOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
url, err := prb.Audits.GenerateReportURL(ctx, scope, input.ID, 15*time.Minute)
|
|
if err != nil {
|
|
return nil, types.GetAuditReportUrlOutput{}, fmt.Errorf("cannot generate audit report URL: %w", err)
|
|
}
|
|
|
|
return nil, types.GetAuditReportUrlOutput{
|
|
URL: *url,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ArchiveDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ArchiveDocumentInput) (*mcp.CallToolResult, types.ArchiveDocumentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDocumentArchive)
|
|
if err != nil {
|
|
return nil, types.ArchiveDocumentOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
document, err := svc.Documents.Archive(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.ArchiveDocumentOutput{}, fmt.Errorf("cannot archive document: %w", err)
|
|
}
|
|
|
|
return nil, types.ArchiveDocumentOutput{
|
|
Document: types.NewDocument(document),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UnarchiveDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnarchiveDocumentInput) (*mcp.CallToolResult, types.UnarchiveDocumentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDocumentUnarchive)
|
|
if err != nil {
|
|
return nil, types.UnarchiveDocumentOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
document, err := svc.Documents.Unarchive(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.UnarchiveDocumentOutput{}, fmt.Errorf("cannot unarchive document: %w", err)
|
|
}
|
|
|
|
return nil, types.UnarchiveDocumentOutput{
|
|
Document: types.NewDocument(document),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) GetOrganizationContextTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetOrganizationContextInput) (*mcp.CallToolResult, types.GetOrganizationContextOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionOrganizationContextGet)
|
|
if err != nil {
|
|
return nil, types.GetOrganizationContextOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
orgContext, err := prb.Organizations.GetContext(ctx, scope, input.OrganizationID)
|
|
if err != nil {
|
|
return nil, types.GetOrganizationContextOutput{}, fmt.Errorf("cannot get organization context: %w", err)
|
|
}
|
|
|
|
return nil, types.GetOrganizationContextOutput{
|
|
OrganizationContext: types.NewOrganizationContext(orgContext),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateOrganizationContextTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateOrganizationContextInput) (*mcp.CallToolResult, types.UpdateOrganizationContextOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionOrganizationContextUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateOrganizationContextOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
orgContext, err := prb.Organizations.UpdateContext(
|
|
ctx, scope,
|
|
probo.UpdateOrganizationContextRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Product: &input.Product,
|
|
Architecture: &input.Architecture,
|
|
Team: &input.Team,
|
|
Processes: &input.Processes,
|
|
Customers: &input.Customers,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateOrganizationContextOutput{}, fmt.Errorf("cannot update organization context: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateOrganizationContextOutput{
|
|
OrganizationContext: types.NewOrganizationContext(orgContext),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) GetAuditLogEntryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetAuditLogEntryInput) (*mcp.CallToolResult, types.GetAuditLogEntryOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.ID, iam.ActionAuditLogEntryGet); err != nil {
|
|
return nil, types.GetAuditLogEntryOutput{}, err
|
|
}
|
|
|
|
entry, err := r.iamSvc.OrganizationService.GetAuditLogEntry(ctx, input.ID)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot get audit log entry: %w", err))
|
|
}
|
|
|
|
return nil, types.GetAuditLogEntryOutput{
|
|
AuditLogEntry: types.NewAuditLogEntry(entry),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListAuditLogEntriesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListAuditLogEntriesInput) (*mcp.CallToolResult, types.ListAuditLogEntriesOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.OrganizationID, iam.ActionAuditLogEntryList); err != nil {
|
|
return nil, types.ListAuditLogEntriesOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.AuditLogEntryOrderField]{
|
|
Field: coredata.AuditLogEntryOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
filter := coredata.NewAuditLogEntryFilter()
|
|
|
|
if input.Filter != nil {
|
|
if input.Filter.Action != nil {
|
|
filter.WithAction(*input.Filter.Action)
|
|
}
|
|
|
|
if input.Filter.ActorID != nil {
|
|
filter.WithActorID(*input.Filter.ActorID)
|
|
}
|
|
|
|
if input.Filter.ResourceType != nil {
|
|
filter.WithResourceType(*input.Filter.ResourceType)
|
|
}
|
|
|
|
if input.Filter.ResourceID != nil {
|
|
filter.WithResourceID(*input.Filter.ResourceID)
|
|
}
|
|
}
|
|
|
|
p, err := r.iamSvc.OrganizationService.ListAuditLogEntries(ctx, input.OrganizationID, cursor, filter)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list audit log entries: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListAuditLogEntriesOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) ListMeasureDocumentsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListMeasureDocumentsInput) (*mcp.CallToolResult, types.ListMeasureDocumentsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.MeasureID, probo.ActionMeasureGet)
|
|
if err != nil {
|
|
return nil, types.ListMeasureDocumentsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
|
Field: coredata.DocumentOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
docPage, err := prb.Documents.ListForMeasureID(ctx, scope, input.MeasureID, cursor, coredata.NewDocumentFilter(nil))
|
|
if err != nil {
|
|
return nil, types.ListMeasureDocumentsOutput{}, fmt.Errorf("failed to list measure documents: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListMeasureDocumentsOutput(docPage), nil
|
|
}
|
|
|
|
func (r *Resolver) VoidDocumentVersionApprovalTool(ctx context.Context, req *mcp.CallToolRequest, input *types.VoidDocumentVersionApprovalInput) (*mcp.CallToolResult, types.VoidDocumentVersionApprovalOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionVoidApproval)
|
|
if err != nil {
|
|
return nil, types.VoidDocumentVersionApprovalOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
_, documentVersion, err := svc.DocumentApprovals.VoidApproval(ctx, scope, input.DocumentVersionID)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot void document version approval: %w", err))
|
|
}
|
|
|
|
return nil, types.VoidDocumentVersionApprovalOutput{
|
|
DocumentVersion: types.NewDocumentVersion(documentVersion),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) SendSigningNotificationsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.SendSigningNotificationsInput) (*mcp.CallToolResult, types.SendSigningNotificationsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionDocumentSendSigningNotifications)
|
|
if err != nil {
|
|
return nil, types.SendSigningNotificationsOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.Documents.SendSigningNotifications(ctx, scope, input.OrganizationID)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot send signing notifications: %w", err))
|
|
}
|
|
|
|
return nil, types.SendSigningNotificationsOutput{
|
|
Success: true,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteDocumentDraftTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteDocumentDraftInput) (*mcp.CallToolResult, types.DeleteDocumentDraftOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDocumentDeleteDraft)
|
|
if err != nil {
|
|
return nil, types.DeleteDocumentDraftOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
document, err := svc.Documents.DeleteDraft(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteDocumentDraftOutput{}, fmt.Errorf("cannot delete document draft: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteDocumentDraftOutput{
|
|
Document: types.NewDocument(document),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) PublishStatementOfApplicabilityTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishStatementOfApplicabilityInput) (*mcp.CallToolResult, types.PublishStatementOfApplicabilityOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionStatementOfApplicabilityPublish)
|
|
if err != nil {
|
|
return nil, types.PublishStatementOfApplicabilityOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
document, documentVersion, err := svc.GeneratedDocuments.PublishStatementOfApplicability(ctx, scope, input.ID, input.ApproverIds, input.Minor)
|
|
if err != nil {
|
|
return nil, types.PublishStatementOfApplicabilityOutput{}, fmt.Errorf("cannot publish statement of applicability: %w", err)
|
|
}
|
|
|
|
return nil, types.PublishStatementOfApplicabilityOutput{
|
|
DocumentID: document.ID,
|
|
DocumentVersionID: documentVersion.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListWebhookSubscriptionsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListWebhookSubscriptionsInput) (*mcp.CallToolResult, types.ListWebhookSubscriptionsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionWebhookSubscriptionList)
|
|
if err != nil {
|
|
return nil, types.ListWebhookSubscriptionsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.WebhookSubscriptionOrderField]{
|
|
Field: coredata.WebhookSubscriptionOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.WebhookSubscriptionOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
page, err := prb.WebhookSubscriptions.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list webhook subscriptions: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListWebhookSubscriptionsOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) GetWebhookSubscriptionTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetWebhookSubscriptionInput) (*mcp.CallToolResult, types.GetWebhookSubscriptionOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionWebhookSubscriptionGet)
|
|
if err != nil {
|
|
return nil, types.GetWebhookSubscriptionOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
subscription, err := prb.WebhookSubscriptions.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetWebhookSubscriptionOutput{}, fmt.Errorf("failed to get webhook subscription: %w", err)
|
|
}
|
|
|
|
return nil, types.GetWebhookSubscriptionOutput{
|
|
WebhookSubscription: types.NewWebhookSubscription(subscription),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) CreateWebhookSubscriptionTool(ctx context.Context, req *mcp.CallToolRequest, input *types.CreateWebhookSubscriptionInput) (*mcp.CallToolResult, types.CreateWebhookSubscriptionOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionWebhookSubscriptionCreate)
|
|
if err != nil {
|
|
return nil, types.CreateWebhookSubscriptionOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
subscription, err := prb.WebhookSubscriptions.Create(
|
|
ctx, scope,
|
|
probo.CreateWebhookSubscriptionRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
EndpointURL: input.EndpointURL,
|
|
SelectedEvents: input.SelectedEvents,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.CreateWebhookSubscriptionOutput{}, fmt.Errorf("failed to create webhook subscription: %w", err)
|
|
}
|
|
|
|
return nil, types.CreateWebhookSubscriptionOutput{
|
|
WebhookSubscription: types.NewWebhookSubscription(subscription),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateWebhookSubscriptionTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateWebhookSubscriptionInput) (*mcp.CallToolResult, types.UpdateWebhookSubscriptionOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionWebhookSubscriptionUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateWebhookSubscriptionOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
subscription, err := prb.WebhookSubscriptions.Update(
|
|
ctx, scope,
|
|
probo.UpdateWebhookSubscriptionRequest{
|
|
WebhookSubscriptionID: input.ID,
|
|
EndpointURL: input.EndpointURL,
|
|
SelectedEvents: input.SelectedEvents,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateWebhookSubscriptionOutput{}, fmt.Errorf("failed to update webhook subscription: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateWebhookSubscriptionOutput{
|
|
WebhookSubscription: types.NewWebhookSubscription(subscription),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteWebhookSubscriptionTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteWebhookSubscriptionInput) (*mcp.CallToolResult, types.DeleteWebhookSubscriptionOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionWebhookSubscriptionDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteWebhookSubscriptionOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
err = prb.WebhookSubscriptions.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteWebhookSubscriptionOutput{}, fmt.Errorf("failed to delete webhook subscription: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteWebhookSubscriptionOutput{
|
|
DeletedWebhookSubscriptionID: input.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListWebhookEventsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListWebhookEventsInput) (*mcp.CallToolResult, types.ListWebhookEventsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.WebhookSubscriptionID, probo.ActionWebhookSubscriptionGet)
|
|
if err != nil {
|
|
return nil, types.ListWebhookEventsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.WebhookEventOrderField]{
|
|
Field: coredata.WebhookEventOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.WebhookEventOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
page, err := prb.WebhookSubscriptions.ListEventsForSubscriptionID(ctx, scope, input.WebhookSubscriptionID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list webhook events: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListWebhookEventsOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) ListDocumentVersionApprovalQuorumsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListDocumentVersionApprovalQuorumsInput) (*mcp.CallToolResult, types.ListDocumentVersionApprovalQuorumsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionApprovalList)
|
|
if err != nil {
|
|
return nil, types.ListDocumentVersionApprovalQuorumsOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.DocumentVersionApprovalQuorumOrderField]{
|
|
Field: coredata.DocumentVersionApprovalQuorumOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.DocumentVersionApprovalQuorumOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := svc.DocumentApprovals.ListQuorums(ctx, scope, input.DocumentVersionID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list approval quorums: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListDocumentVersionApprovalQuorumsOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetDocumentVersionApprovalQuorumTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetDocumentVersionApprovalQuorumInput) (*mcp.CallToolResult, types.GetDocumentVersionApprovalQuorumOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDocumentVersionApprovalList)
|
|
if err != nil {
|
|
return nil, types.GetDocumentVersionApprovalQuorumOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
quorum, err := svc.DocumentApprovals.GetQuorum(ctx, scope, input.ID)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot get approval quorum: %w", err))
|
|
}
|
|
|
|
return nil, types.GetDocumentVersionApprovalQuorumOutput{
|
|
ApprovalQuorum: types.NewDocumentVersionApprovalQuorum(quorum),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListDocumentVersionApprovalDecisionsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListDocumentVersionApprovalDecisionsInput) (*mcp.CallToolResult, types.ListDocumentVersionApprovalDecisionsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.QuorumID, probo.ActionDocumentVersionApprovalList)
|
|
if err != nil {
|
|
return nil, types.ListDocumentVersionApprovalDecisionsOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.DocumentVersionApprovalDecisionOrderField]{
|
|
Field: coredata.DocumentVersionApprovalDecisionOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.DocumentVersionApprovalDecisionOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
var states []coredata.DocumentVersionApprovalDecisionState
|
|
if input.Filter != nil {
|
|
states = input.Filter.States
|
|
}
|
|
|
|
filter := coredata.NewDocumentVersionApprovalDecisionFilter(states)
|
|
|
|
p, err := svc.DocumentApprovals.ListDecisions(ctx, scope, input.QuorumID, cursor, filter)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list approval decisions: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListDocumentVersionApprovalDecisionsOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetDocumentVersionApprovalDecisionTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetDocumentVersionApprovalDecisionInput) (*mcp.CallToolResult, types.GetDocumentVersionApprovalDecisionOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDocumentVersionApprovalList)
|
|
if err != nil {
|
|
return nil, types.GetDocumentVersionApprovalDecisionOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
decision, err := svc.DocumentApprovals.GetDecision(ctx, scope, input.ID)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot get approval decision: %w", err))
|
|
}
|
|
|
|
return nil, types.GetDocumentVersionApprovalDecisionOutput{
|
|
ApprovalDecision: types.NewDocumentVersionApprovalDecision(decision),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) PublishDataListTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishDataListInput) (*mcp.CallToolResult, types.PublishDataListOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionDatumPublish)
|
|
if err != nil {
|
|
return nil, types.PublishDataListOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
document, documentVersion, err := svc.GeneratedDocuments.PublishDataList(ctx, scope, input.OrganizationID, input.ApproverIds, input.Minor)
|
|
if err != nil {
|
|
return nil, types.PublishDataListOutput{}, fmt.Errorf("cannot publish data list: %w", err)
|
|
}
|
|
|
|
return nil, types.PublishDataListOutput{
|
|
DocumentID: document.ID,
|
|
DocumentVersionID: documentVersion.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) PublishAssetListTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishAssetListInput) (*mcp.CallToolResult, types.PublishAssetListOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionAssetPublish)
|
|
if err != nil {
|
|
return nil, types.PublishAssetListOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
document, documentVersion, err := svc.GeneratedDocuments.PublishAssetList(ctx, scope, input.OrganizationID, input.ApproverIds, input.Minor)
|
|
if err != nil {
|
|
return nil, types.PublishAssetListOutput{}, fmt.Errorf("cannot publish asset list: %w", err)
|
|
}
|
|
|
|
return nil, types.PublishAssetListOutput{
|
|
DocumentID: document.ID,
|
|
DocumentVersionID: documentVersion.ID,
|
|
}, nil
|
|
}
|
|
|
|
// ListThirdPartyContactsTool handles the listThirdPartyContacts tool
|
|
// List all contacts for a thirdParty
|
|
func (r *Resolver) ListThirdPartyContactsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListThirdPartyContactsInput) (*mcp.CallToolResult, types.ListThirdPartyContactsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyContactList)
|
|
if err != nil {
|
|
return nil, types.ListThirdPartyContactsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ThirdPartyContactOrderField]{
|
|
Field: coredata.ThirdPartyContactOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ThirdPartyContactOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := prb.ThirdPartyContacts.List(ctx, scope, input.ThirdPartyID, cursor)
|
|
if err != nil {
|
|
return nil, types.ListThirdPartyContactsOutput{}, fmt.Errorf("cannot list thirdParty contacts: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListThirdPartyContactsOutput(p), nil
|
|
}
|
|
|
|
// AddThirdPartyContactTool handles the addThirdPartyContact tool
|
|
// Add a new contact to a thirdParty
|
|
func (r *Resolver) AddThirdPartyContactTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddThirdPartyContactInput) (*mcp.CallToolResult, types.AddThirdPartyContactOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyContactCreate)
|
|
if err != nil {
|
|
return nil, types.AddThirdPartyContactOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
emailAddr, err := mail.ParseAddr(input.Email)
|
|
if err != nil {
|
|
return nil, types.AddThirdPartyContactOutput{}, fmt.Errorf("invalid email address: %w", err)
|
|
}
|
|
|
|
thirdPartyContact, err := prb.ThirdPartyContacts.Create(ctx, scope, probo.CreateThirdPartyContactRequest{
|
|
ThirdPartyID: input.ThirdPartyID,
|
|
FullName: &input.FullName,
|
|
Email: &emailAddr,
|
|
Phone: &input.Phone,
|
|
Role: &input.Role,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddThirdPartyContactOutput{}, fmt.Errorf("cannot create thirdParty contact: %w", err)
|
|
}
|
|
|
|
return nil, types.AddThirdPartyContactOutput{
|
|
ThirdPartyContact: types.NewThirdPartyContact(thirdPartyContact),
|
|
}, nil
|
|
}
|
|
|
|
// UpdateThirdPartyContactTool handles the updateThirdPartyContact tool
|
|
// Update an existing thirdParty contact
|
|
func (r *Resolver) UpdateThirdPartyContactTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateThirdPartyContactInput) (*mcp.CallToolResult, types.UpdateThirdPartyContactOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionThirdPartyContactUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateThirdPartyContactOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
updateReq := probo.UpdateThirdPartyContactRequest{
|
|
ID: input.ID,
|
|
}
|
|
|
|
if input.FullName != nil {
|
|
updateReq.FullName = &input.FullName
|
|
}
|
|
|
|
if input.Email != nil {
|
|
emailAddr, err := mail.ParseAddr(*input.Email)
|
|
if err != nil {
|
|
return nil, types.UpdateThirdPartyContactOutput{}, fmt.Errorf("invalid email address: %w", err)
|
|
}
|
|
|
|
emailPtr := &emailAddr
|
|
updateReq.Email = &emailPtr
|
|
}
|
|
|
|
if input.Phone != nil {
|
|
updateReq.Phone = &input.Phone
|
|
}
|
|
|
|
if input.Role != nil {
|
|
updateReq.Role = &input.Role
|
|
}
|
|
|
|
thirdPartyContact, err := prb.ThirdPartyContacts.Update(ctx, scope, updateReq)
|
|
if err != nil {
|
|
return nil, types.UpdateThirdPartyContactOutput{}, fmt.Errorf("cannot update thirdParty contact: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateThirdPartyContactOutput{
|
|
ThirdPartyContact: types.NewThirdPartyContact(thirdPartyContact),
|
|
}, nil
|
|
}
|
|
|
|
// DeleteThirdPartyContactTool handles the deleteThirdPartyContact tool
|
|
// Delete a thirdParty contact
|
|
func (r *Resolver) DeleteThirdPartyContactTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteThirdPartyContactInput) (*mcp.CallToolResult, types.DeleteThirdPartyContactOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionThirdPartyContactDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteThirdPartyContactOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
err = prb.ThirdPartyContacts.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteThirdPartyContactOutput{}, fmt.Errorf("cannot delete thirdParty contact: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteThirdPartyContactOutput{
|
|
DeletedThirdPartyContactID: input.ID,
|
|
}, nil
|
|
}
|
|
|
|
// ListThirdPartyServicesTool handles the listThirdPartyServices tool
|
|
// List all services for a thirdParty
|
|
func (r *Resolver) ListThirdPartyServicesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListThirdPartyServicesInput) (*mcp.CallToolResult, types.ListThirdPartyServicesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyServiceList)
|
|
if err != nil {
|
|
return nil, types.ListThirdPartyServicesOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ThirdPartyServiceOrderField]{
|
|
Field: coredata.ThirdPartyServiceOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ThirdPartyServiceOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := prb.ThirdPartyServices.List(ctx, scope, input.ThirdPartyID, cursor)
|
|
if err != nil {
|
|
return nil, types.ListThirdPartyServicesOutput{}, fmt.Errorf("cannot list thirdParty services: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListThirdPartyServicesOutput(p), nil
|
|
}
|
|
|
|
// AddThirdPartyServiceTool handles the addThirdPartyService tool
|
|
// Add a new service to a thirdParty
|
|
func (r *Resolver) AddThirdPartyServiceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddThirdPartyServiceInput) (*mcp.CallToolResult, types.AddThirdPartyServiceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyServiceCreate)
|
|
if err != nil {
|
|
return nil, types.AddThirdPartyServiceOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
thirdPartyService, err := prb.ThirdPartyServices.Create(ctx, scope, probo.CreateThirdPartyServiceRequest{
|
|
ThirdPartyID: input.ThirdPartyID,
|
|
Name: input.Name,
|
|
Description: input.Description,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddThirdPartyServiceOutput{}, fmt.Errorf("cannot create thirdParty service: %w", err)
|
|
}
|
|
|
|
return nil, types.AddThirdPartyServiceOutput{
|
|
ThirdPartyService: types.NewThirdPartyService(thirdPartyService),
|
|
}, nil
|
|
}
|
|
|
|
// UpdateThirdPartyServiceTool handles the updateThirdPartyService tool
|
|
// Update an existing thirdParty service
|
|
func (r *Resolver) UpdateThirdPartyServiceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateThirdPartyServiceInput) (*mcp.CallToolResult, types.UpdateThirdPartyServiceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionThirdPartyServiceUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateThirdPartyServiceOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
updateReq := probo.UpdateThirdPartyServiceRequest{
|
|
ID: input.ID,
|
|
}
|
|
|
|
if input.Name != nil {
|
|
updateReq.Name = input.Name
|
|
}
|
|
|
|
if input.Description != nil {
|
|
updateReq.Description = &input.Description
|
|
}
|
|
|
|
thirdPartyService, err := prb.ThirdPartyServices.Update(ctx, scope, updateReq)
|
|
if err != nil {
|
|
return nil, types.UpdateThirdPartyServiceOutput{}, fmt.Errorf("cannot update thirdParty service: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateThirdPartyServiceOutput{
|
|
ThirdPartyService: types.NewThirdPartyService(thirdPartyService),
|
|
}, nil
|
|
}
|
|
|
|
// DeleteThirdPartyServiceTool handles the deleteThirdPartyService tool
|
|
// Delete a thirdParty service
|
|
func (r *Resolver) DeleteThirdPartyServiceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteThirdPartyServiceInput) (*mcp.CallToolResult, types.DeleteThirdPartyServiceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionThirdPartyServiceDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteThirdPartyServiceOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
err = prb.ThirdPartyServices.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteThirdPartyServiceOutput{}, fmt.Errorf("cannot delete thirdParty service: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteThirdPartyServiceOutput{
|
|
DeletedThirdPartyServiceID: input.ID,
|
|
}, nil
|
|
}
|
|
func (r *Resolver) DeleteAssetTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteAssetInput) (*mcp.CallToolResult, types.DeleteAssetOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionAssetDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteAssetOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.Assets.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteAssetOutput{}, fmt.Errorf("failed to delete asset: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteAssetOutput{
|
|
DeletedAssetID: input.ID,
|
|
}, nil
|
|
}
|
|
func (r *Resolver) DeleteDatumTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteDatumInput) (*mcp.CallToolResult, types.DeleteDatumOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionDatumDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteDatumOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.Data.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteDatumOutput{}, fmt.Errorf("failed to delete datum: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteDatumOutput{
|
|
DeletedDatumID: input.ID,
|
|
}, nil
|
|
}
|
|
func (r *Resolver) DeleteObligationTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteObligationInput) (*mcp.CallToolResult, types.DeleteObligationOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionObligationDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteObligationOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.Obligations.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteObligationOutput{}, fmt.Errorf("failed to delete obligation: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteObligationOutput{
|
|
DeletedObligationID: input.ID,
|
|
}, nil
|
|
}
|
|
func (r *Resolver) DeleteAuditTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteAuditInput) (*mcp.CallToolResult, types.DeleteAuditOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionAuditDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteAuditOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.Audits.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteAuditOutput{}, fmt.Errorf("failed to delete audit: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteAuditOutput{
|
|
DeletedAuditID: input.ID,
|
|
}, nil
|
|
}
|
|
func (r *Resolver) ListRightsRequestsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListRightsRequestsInput) (*mcp.CallToolResult, types.ListRightsRequestsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionRightsRequestList)
|
|
if err != nil {
|
|
return nil, types.ListRightsRequestsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.RightsRequestOrderField]{
|
|
Field: coredata.RightsRequestOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.RightsRequestOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
page, err := prb.RightsRequests.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list organization rights requests: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListRightsRequestsOutput(page), nil
|
|
}
|
|
func (r *Resolver) GetRightsRequestTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetRightsRequestInput) (*mcp.CallToolResult, types.GetRightsRequestOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRightsRequestGet)
|
|
if err != nil {
|
|
return nil, types.GetRightsRequestOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
rightsRequest, err := prb.RightsRequests.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetRightsRequestOutput{}, fmt.Errorf("failed to get rights request: %w", err)
|
|
}
|
|
|
|
return nil, types.GetRightsRequestOutput{
|
|
RightsRequest: types.NewRightsRequest(rightsRequest),
|
|
}, nil
|
|
}
|
|
func (r *Resolver) AddRightsRequestTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddRightsRequestInput) (*mcp.CallToolResult, types.AddRightsRequestOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionRightsRequestCreate)
|
|
if err != nil {
|
|
return nil, types.AddRightsRequestOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
rightsRequest, err := svc.RightsRequests.Create(
|
|
ctx, scope,
|
|
&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,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddRightsRequestOutput{}, fmt.Errorf("failed to create rights request: %w", err)
|
|
}
|
|
|
|
return nil, types.AddRightsRequestOutput{
|
|
RightsRequest: types.NewRightsRequest(rightsRequest),
|
|
}, nil
|
|
}
|
|
func (r *Resolver) UpdateRightsRequestTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateRightsRequestInput) (*mcp.CallToolResult, types.UpdateRightsRequestOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRightsRequestUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateRightsRequestOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
var dataSubject **string
|
|
if input.DataSubject != nil {
|
|
dataSubject = &input.DataSubject
|
|
}
|
|
|
|
rightsRequest, err := svc.RightsRequests.Update(
|
|
ctx, scope,
|
|
&probo.UpdateRightsRequestRequest{
|
|
ID: input.ID,
|
|
RequestType: input.RequestType,
|
|
RequestState: input.RequestState,
|
|
DataSubject: dataSubject,
|
|
Contact: UnwrapOmittable(input.Contact),
|
|
Details: UnwrapOmittable(input.Details),
|
|
Deadline: UnwrapOmittable(input.Deadline),
|
|
ActionTaken: UnwrapOmittable(input.ActionTaken),
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.UpdateRightsRequestOutput{}, fmt.Errorf("failed to update rights request: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateRightsRequestOutput{
|
|
RightsRequest: types.NewRightsRequest(rightsRequest),
|
|
}, nil
|
|
}
|
|
func (r *Resolver) DeleteRightsRequestTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteRightsRequestInput) (*mcp.CallToolResult, types.DeleteRightsRequestOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRightsRequestDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteRightsRequestOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
err = svc.RightsRequests.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteRightsRequestOutput{}, fmt.Errorf("failed to delete rights request: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteRightsRequestOutput{
|
|
DeletedRightsRequestID: input.ID,
|
|
}, nil
|
|
}
|
|
|
|
// GetTrustCenterTool handles the getTrustCenter tool
|
|
// Get the trust center for an organization
|
|
func (r *Resolver) GetTrustCenterTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetTrustCenterInput) (*mcp.CallToolResult, types.GetTrustCenterOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionTrustCenterGet)
|
|
if err != nil {
|
|
return nil, types.GetTrustCenterOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
trustCenter, err := prb.TrustCenters.GetByOrganizationID(ctx, scope, input.OrganizationID)
|
|
if err != nil {
|
|
return nil, types.GetTrustCenterOutput{}, fmt.Errorf("cannot get trust center: %w", err)
|
|
}
|
|
|
|
tc := types.NewTrustCenter(trustCenter)
|
|
|
|
if trustCenter.LogoFileID != nil {
|
|
logo, err := r.loadFile(ctx, scope, *trustCenter.LogoFileID)
|
|
if err != nil {
|
|
return nil, types.GetTrustCenterOutput{}, err
|
|
}
|
|
|
|
tc.Logo = logo
|
|
}
|
|
|
|
if trustCenter.DarkLogoFileID != nil {
|
|
darkLogo, err := r.loadFile(ctx, scope, *trustCenter.DarkLogoFileID)
|
|
if err != nil {
|
|
return nil, types.GetTrustCenterOutput{}, err
|
|
}
|
|
|
|
tc.DarkLogo = darkLogo
|
|
}
|
|
|
|
if trustCenter.NonDisclosureAgreementFileID != nil {
|
|
nda, err := r.loadFile(ctx, scope, *trustCenter.NonDisclosureAgreementFileID)
|
|
if err != nil {
|
|
return nil, types.GetTrustCenterOutput{}, err
|
|
}
|
|
|
|
tc.Nda = nda
|
|
}
|
|
|
|
return nil, types.GetTrustCenterOutput{TrustCenter: tc}, nil
|
|
}
|
|
|
|
// UpdateTrustCenterTool handles the updateTrustCenter tool
|
|
// Update the trust center settings
|
|
func (r *Resolver) UpdateTrustCenterTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateTrustCenterInput) (*mcp.CallToolResult, types.UpdateTrustCenterOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateTrustCenterOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
updateReq := &probo.UpdateTrustCenterRequest{
|
|
ID: input.TrustCenterID,
|
|
}
|
|
|
|
if active := UnwrapOmittable(input.Active); active != nil {
|
|
updateReq.Active = *active
|
|
}
|
|
|
|
if sei := UnwrapOmittable(input.SearchEngineIndexing); sei != nil {
|
|
updateReq.SearchEngineIndexing = *sei
|
|
}
|
|
|
|
trustCenter, _, err := prb.TrustCenters.Update(ctx, scope, updateReq)
|
|
if err != nil {
|
|
return nil, types.UpdateTrustCenterOutput{}, fmt.Errorf("cannot update trust center: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateTrustCenterOutput{TrustCenter: types.NewTrustCenter(trustCenter)}, nil
|
|
}
|
|
|
|
// ListTrustCenterReferencesTool handles the listTrustCenterReferences tool
|
|
// List all references for a trust center
|
|
func (r *Resolver) ListTrustCenterReferencesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListTrustCenterReferencesInput) (*mcp.CallToolResult, types.ListTrustCenterReferencesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterReferenceList)
|
|
if err != nil {
|
|
return nil, types.ListTrustCenterReferencesOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.TrustCenterReferenceOrderField]{
|
|
Field: coredata.TrustCenterReferenceOrderFieldRank,
|
|
Direction: page.OrderDirectionAsc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.TrustCenterReferenceOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := prb.TrustCenterReferences.ListForTrustCenterID(ctx, scope, input.TrustCenterID, cursor)
|
|
if err != nil {
|
|
return nil, types.ListTrustCenterReferencesOutput{}, fmt.Errorf("cannot list trust center references: %w", err)
|
|
}
|
|
|
|
refs := make([]*types.TrustCenterReference, 0, len(p.Data))
|
|
for _, reference := range p.Data {
|
|
ref := types.NewTrustCenterReference(reference)
|
|
|
|
logo, err := r.loadFile(ctx, scope, reference.LogoFileID)
|
|
if err != nil {
|
|
return nil, types.ListTrustCenterReferencesOutput{}, err
|
|
}
|
|
|
|
ref.Logo = logo
|
|
|
|
refs = append(refs, ref)
|
|
}
|
|
|
|
return nil, types.NewListTrustCenterReferencesOutput(refs, p), nil
|
|
}
|
|
|
|
// AddTrustCenterReferenceTool handles the addTrustCenterReference tool
|
|
// Add a new reference to the trust center
|
|
func (r *Resolver) AddTrustCenterReferenceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddTrustCenterReferenceInput) (*mcp.CallToolResult, types.AddTrustCenterReferenceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterReferenceCreate)
|
|
if err != nil {
|
|
return nil, types.AddTrustCenterReferenceOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
var websiteURL string
|
|
if input.WebsiteURL != nil {
|
|
websiteURL = *input.WebsiteURL
|
|
}
|
|
|
|
reference, err := prb.TrustCenterReferences.Create(
|
|
ctx, scope,
|
|
&probo.CreateTrustCenterReferenceRequest{
|
|
TrustCenterID: input.TrustCenterID,
|
|
Name: input.Name,
|
|
Description: input.Description,
|
|
WebsiteURL: websiteURL,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddTrustCenterReferenceOutput{}, fmt.Errorf("cannot add trust center reference: %w", err)
|
|
}
|
|
|
|
return nil, types.AddTrustCenterReferenceOutput{TrustCenterReference: types.NewTrustCenterReference(reference)}, nil
|
|
}
|
|
|
|
// UpdateTrustCenterReferenceTool handles the updateTrustCenterReference tool
|
|
// Update a trust center reference
|
|
func (r *Resolver) UpdateTrustCenterReferenceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateTrustCenterReferenceInput) (*mcp.CallToolResult, types.UpdateTrustCenterReferenceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTrustCenterReferenceUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateTrustCenterReferenceOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
updateRefReq := &probo.UpdateTrustCenterReferenceRequest{
|
|
ID: input.ID,
|
|
Description: UnwrapOmittable(input.Description),
|
|
}
|
|
|
|
if name := UnwrapOmittable(input.Name); name != nil {
|
|
updateRefReq.Name = *name
|
|
}
|
|
|
|
if websiteURL := UnwrapOmittable(input.WebsiteURL); websiteURL != nil {
|
|
updateRefReq.WebsiteURL = *websiteURL
|
|
}
|
|
|
|
if rank := UnwrapOmittable(input.Rank); rank != nil {
|
|
updateRefReq.Rank = *rank
|
|
}
|
|
|
|
reference, err := prb.TrustCenterReferences.Update(ctx, scope, updateRefReq)
|
|
if err != nil {
|
|
return nil, types.UpdateTrustCenterReferenceOutput{}, fmt.Errorf("cannot update trust center reference: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateTrustCenterReferenceOutput{TrustCenterReference: types.NewTrustCenterReference(reference)}, nil
|
|
}
|
|
|
|
// DeleteTrustCenterReferenceTool handles the deleteTrustCenterReference tool
|
|
// Delete a trust center reference
|
|
func (r *Resolver) DeleteTrustCenterReferenceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteTrustCenterReferenceInput) (*mcp.CallToolResult, types.DeleteTrustCenterReferenceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTrustCenterReferenceDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteTrustCenterReferenceOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
err = prb.TrustCenterReferences.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteTrustCenterReferenceOutput{}, fmt.Errorf("cannot delete trust center reference: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteTrustCenterReferenceOutput{DeletedTrustCenterReferenceID: input.ID}, nil
|
|
}
|
|
|
|
// ListTrustCenterFilesTool handles the listTrustCenterFiles tool
|
|
// List all files for the trust center
|
|
func (r *Resolver) ListTrustCenterFilesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListTrustCenterFilesInput) (*mcp.CallToolResult, types.ListTrustCenterFilesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionTrustCenterFileList)
|
|
if err != nil {
|
|
return nil, types.ListTrustCenterFilesOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.TrustCenterFileOrderField]{
|
|
Field: coredata.TrustCenterFileOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.TrustCenterFileOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
filter := coredata.NewTrustCenterFileFilter()
|
|
|
|
p, err := prb.TrustCenterFiles.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor, filter)
|
|
if err != nil {
|
|
return nil, types.ListTrustCenterFilesOutput{}, fmt.Errorf("cannot list trust center files: %w", err)
|
|
}
|
|
|
|
files := make([]*types.TrustCenterFile, 0, len(p.Data))
|
|
for _, f := range p.Data {
|
|
file, err := r.loadFile(ctx, scope, f.FileID)
|
|
if err != nil {
|
|
return nil, types.ListTrustCenterFilesOutput{}, err
|
|
}
|
|
|
|
files = append(files, types.NewTrustCenterFile(f, file))
|
|
}
|
|
|
|
return nil, types.NewListTrustCenterFilesOutput(files, p), nil
|
|
}
|
|
|
|
// DeleteTrustCenterFileTool handles the deleteTrustCenterFile tool
|
|
// Delete a trust center file
|
|
func (r *Resolver) DeleteTrustCenterFileTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteTrustCenterFileInput) (*mcp.CallToolResult, types.DeleteTrustCenterFileOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTrustCenterFileDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteTrustCenterFileOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
err = prb.TrustCenterFiles.Delete(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeleteTrustCenterFileOutput{}, fmt.Errorf("cannot delete trust center file: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteTrustCenterFileOutput{DeletedTrustCenterFileID: input.ID}, nil
|
|
}
|
|
|
|
// ListComplianceExternalURLsTool handles the listComplianceExternalURLs tool
|
|
// List all external URLs for a trust center
|
|
func (r *Resolver) ListComplianceExternalURLsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListComplianceExternalURLsInput) (*mcp.CallToolResult, types.ListComplianceExternalURLsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.TrustCenterID, probo.ActionComplianceExternalURLList)
|
|
if err != nil {
|
|
return nil, types.ListComplianceExternalURLsOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ComplianceExternalURLOrderField]{
|
|
Field: coredata.ComplianceExternalURLOrderFieldRank,
|
|
Direction: page.OrderDirectionAsc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ComplianceExternalURLOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := prb.ComplianceExternalURLs.List(ctx, scope, input.TrustCenterID, cursor)
|
|
if err != nil {
|
|
return nil, types.ListComplianceExternalURLsOutput{}, fmt.Errorf("cannot list compliance external URLs: %w", err)
|
|
}
|
|
|
|
return nil, types.NewListComplianceExternalURLsOutput(p), nil
|
|
}
|
|
|
|
// AddComplianceExternalURLTool handles the addComplianceExternalURL tool
|
|
// Add a new external URL to the trust center
|
|
func (r *Resolver) AddComplianceExternalURLTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddComplianceExternalURLInput) (*mcp.CallToolResult, types.AddComplianceExternalURLOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.TrustCenterID, probo.ActionComplianceExternalURLCreate)
|
|
if err != nil {
|
|
return nil, types.AddComplianceExternalURLOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
item, err := prb.ComplianceExternalURLs.Create(
|
|
ctx, scope,
|
|
&probo.CreateComplianceExternalURLRequest{
|
|
TrustCenterID: input.TrustCenterID,
|
|
Name: input.Name,
|
|
URL: input.URL,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.AddComplianceExternalURLOutput{}, fmt.Errorf("cannot add compliance external URL: %w", err)
|
|
}
|
|
|
|
return nil, types.AddComplianceExternalURLOutput{ComplianceExternalURL: types.NewComplianceExternalURL(item)}, nil
|
|
}
|
|
|
|
// UpdateComplianceExternalURLTool handles the updateComplianceExternalURL tool
|
|
// Update a compliance external URL
|
|
func (r *Resolver) UpdateComplianceExternalURLTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateComplianceExternalURLInput) (*mcp.CallToolResult, types.UpdateComplianceExternalURLOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionComplianceExternalURLUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateComplianceExternalURLOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
updateURLReq := &probo.UpdateComplianceExternalURLRequest{
|
|
ID: input.ID,
|
|
}
|
|
|
|
if name := UnwrapOmittable(input.Name); name != nil && *name != nil {
|
|
updateURLReq.Name = **name
|
|
}
|
|
|
|
if u := UnwrapOmittable(input.URL); u != nil && *u != nil {
|
|
updateURLReq.URL = **u
|
|
}
|
|
|
|
if rank := UnwrapOmittable(input.Rank); rank != nil {
|
|
updateURLReq.Rank = *rank
|
|
}
|
|
|
|
item, err := prb.ComplianceExternalURLs.Update(ctx, scope, updateURLReq)
|
|
if err != nil {
|
|
return nil, types.UpdateComplianceExternalURLOutput{}, fmt.Errorf("cannot update compliance external URL: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateComplianceExternalURLOutput{ComplianceExternalURL: types.NewComplianceExternalURL(item)}, nil
|
|
}
|
|
|
|
// DeleteComplianceExternalURLTool handles the deleteComplianceExternalURL tool
|
|
// Delete a compliance external URL
|
|
func (r *Resolver) DeleteComplianceExternalURLTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteComplianceExternalURLInput) (*mcp.CallToolResult, types.DeleteComplianceExternalURLOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionComplianceExternalURLDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteComplianceExternalURLOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
err = prb.ComplianceExternalURLs.Delete(
|
|
ctx, scope,
|
|
&probo.DeleteComplianceExternalURLRequest{
|
|
ID: input.ID,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.DeleteComplianceExternalURLOutput{}, fmt.Errorf("cannot delete compliance external URL: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteComplianceExternalURLOutput{DeletedComplianceExternalURLID: input.ID}, nil
|
|
}
|
|
|
|
// CreateCustomDomainTool handles the createCustomDomain tool
|
|
// Create a custom domain for the organization
|
|
func (r *Resolver) CreateCustomDomainTool(ctx context.Context, req *mcp.CallToolRequest, input *types.CreateCustomDomainInput) (*mcp.CallToolResult, types.CreateCustomDomainOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionCustomDomainCreate)
|
|
if err != nil {
|
|
return nil, types.CreateCustomDomainOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
domain, err := prb.CustomDomains.CreateCustomDomain(
|
|
ctx, scope,
|
|
probo.CreateCustomDomainRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Domain: input.Domain,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, types.CreateCustomDomainOutput{}, fmt.Errorf("cannot create custom domain: %w", err)
|
|
}
|
|
|
|
return nil, types.CreateCustomDomainOutput{CustomDomain: types.NewCustomDomain(domain)}, nil
|
|
}
|
|
|
|
// DeleteCustomDomainTool handles the deleteCustomDomain tool
|
|
// Delete the custom domain for the organization
|
|
func (r *Resolver) DeleteCustomDomainTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteCustomDomainInput) (*mcp.CallToolResult, types.DeleteCustomDomainOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionCustomDomainDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteCustomDomainOutput{}, err
|
|
}
|
|
|
|
prb := r.proboSvc
|
|
|
|
domain, err := prb.CustomDomains.GetOrganizationCustomDomain(ctx, scope, input.OrganizationID)
|
|
if err != nil {
|
|
return nil, types.DeleteCustomDomainOutput{}, fmt.Errorf("cannot get custom domain: %w", err)
|
|
}
|
|
|
|
if domain == nil {
|
|
return nil, types.DeleteCustomDomainOutput{}, fmt.Errorf("organization has no custom domain")
|
|
}
|
|
|
|
deletedDomain := types.NewCustomDomain(domain)
|
|
|
|
if err := prb.CustomDomains.DeleteCustomDomain(ctx, scope, input.OrganizationID); err != nil {
|
|
return nil, types.DeleteCustomDomainOutput{}, fmt.Errorf("cannot delete custom domain: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteCustomDomainOutput{DeletedCustomDomain: deletedDomain}, nil
|
|
}
|
|
|
|
func (r *Resolver) VetThirdPartyTool(ctx context.Context, req *mcp.CallToolRequest, input *types.VetThirdPartyInput) (*mcp.CallToolResult, types.VetThirdPartyOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionThirdPartyVet)
|
|
if err != nil {
|
|
return nil, types.VetThirdPartyOutput{}, err
|
|
}
|
|
|
|
svc := r.thirdPartySvc
|
|
|
|
thirdParty, err := svc.Vet(
|
|
ctx, scope,
|
|
thirdparty.VetRequest{
|
|
ID: input.ID,
|
|
WebsiteURL: input.WebsiteURL,
|
|
Procedure: input.Procedure,
|
|
},
|
|
)
|
|
if err != nil {
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, types.VetThirdPartyOutput{}, validationErrors
|
|
}
|
|
|
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
return nil, types.VetThirdPartyOutput{}, fmt.Errorf("resource not found")
|
|
}
|
|
|
|
if errors.Is(err, thirdparty.ErrVettingDisabled) {
|
|
return nil, types.VetThirdPartyOutput{}, fmt.Errorf("vetting is not configured")
|
|
}
|
|
|
|
if errors.Is(err, thirdparty.ErrVettingInProgress) {
|
|
return nil, types.VetThirdPartyOutput{}, fmt.Errorf("vetting is already in progress")
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot vet thirdParty", log.Error(err))
|
|
|
|
return nil, types.VetThirdPartyOutput{}, fmt.Errorf("internal server error")
|
|
}
|
|
|
|
return nil, types.VetThirdPartyOutput{
|
|
ThirdParty: types.NewThirdParty(thirdParty),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) PublishFindingListTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishFindingListInput) (*mcp.CallToolResult, types.PublishFindingListOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionFindingPublish)
|
|
if err != nil {
|
|
return nil, types.PublishFindingListOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
document, documentVersion, err := svc.GeneratedDocuments.PublishFindingList(ctx, scope, input.OrganizationID, input.ApproverIds, input.Minor)
|
|
if err != nil {
|
|
return nil, types.PublishFindingListOutput{}, fmt.Errorf("cannot publish finding list: %w", err)
|
|
}
|
|
|
|
return nil, types.PublishFindingListOutput{
|
|
DocumentID: document.ID,
|
|
DocumentVersionID: documentVersion.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) PublishObligationListTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishObligationListInput) (*mcp.CallToolResult, types.PublishObligationListOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionObligationPublish)
|
|
if err != nil {
|
|
return nil, types.PublishObligationListOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
document, documentVersion, err := svc.GeneratedDocuments.PublishObligationList(ctx, scope, input.OrganizationID, input.ApproverIds, input.Minor)
|
|
if err != nil {
|
|
return nil, types.PublishObligationListOutput{}, fmt.Errorf("cannot publish obligation list: %w", err)
|
|
}
|
|
|
|
return nil, types.PublishObligationListOutput{
|
|
DocumentID: document.ID,
|
|
DocumentVersionID: documentVersion.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) PublishProcessingActivityListTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishProcessingActivityListInput) (*mcp.CallToolResult, types.PublishProcessingActivityListOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionProcessingActivityPublish)
|
|
if err != nil {
|
|
return nil, types.PublishProcessingActivityListOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
document, documentVersion, err := svc.GeneratedDocuments.PublishProcessingActivityList(ctx, scope, input.OrganizationID, input.ApproverIds, input.Minor)
|
|
if err != nil {
|
|
return nil, types.PublishProcessingActivityListOutput{}, fmt.Errorf("cannot publish processing activity list: %w", err)
|
|
}
|
|
|
|
return nil, types.PublishProcessingActivityListOutput{
|
|
DocumentID: document.ID,
|
|
DocumentVersionID: documentVersion.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) PublishDataProtectionImpactAssessmentListTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishDataProtectionImpactAssessmentListInput) (*mcp.CallToolResult, types.PublishDataProtectionImpactAssessmentListOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionDataProtectionImpactAssessmentPublish)
|
|
if err != nil {
|
|
return nil, types.PublishDataProtectionImpactAssessmentListOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
document, documentVersion, err := svc.GeneratedDocuments.PublishDataProtectionImpactAssessmentList(ctx, scope, input.OrganizationID, input.ApproverIds, input.Minor)
|
|
if err != nil {
|
|
return nil, types.PublishDataProtectionImpactAssessmentListOutput{}, fmt.Errorf("cannot publish DPIA list: %w", err)
|
|
}
|
|
|
|
return nil, types.PublishDataProtectionImpactAssessmentListOutput{
|
|
DocumentID: document.ID,
|
|
DocumentVersionID: documentVersion.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) PublishTransferImpactAssessmentListTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishTransferImpactAssessmentListInput) (*mcp.CallToolResult, types.PublishTransferImpactAssessmentListOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionTransferImpactAssessmentPublish)
|
|
if err != nil {
|
|
return nil, types.PublishTransferImpactAssessmentListOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
document, documentVersion, err := svc.GeneratedDocuments.PublishTransferImpactAssessmentList(ctx, scope, input.OrganizationID, input.ApproverIds, input.Minor)
|
|
if err != nil {
|
|
return nil, types.PublishTransferImpactAssessmentListOutput{}, fmt.Errorf("cannot publish TIA list: %w", err)
|
|
}
|
|
|
|
return nil, types.PublishTransferImpactAssessmentListOutput{
|
|
DocumentID: document.ID,
|
|
DocumentVersionID: documentVersion.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) PublishThirdPartyListTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishThirdPartyListInput) (*mcp.CallToolResult, types.PublishThirdPartyListOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionThirdPartyPublish)
|
|
if err != nil {
|
|
return nil, types.PublishThirdPartyListOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
document, documentVersion, err := svc.GeneratedDocuments.PublishThirdPartyList(ctx, scope, input.OrganizationID, input.ApproverIds, input.Minor)
|
|
if err != nil {
|
|
return nil, types.PublishThirdPartyListOutput{}, fmt.Errorf("cannot publish thirdParty list: %w", err)
|
|
}
|
|
|
|
return nil, types.PublishThirdPartyListOutput{
|
|
DocumentID: document.ID,
|
|
DocumentVersionID: documentVersion.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListCookieBannersTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListCookieBannersInput) (*mcp.CallToolResult, types.ListCookieBannersOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionCookieBannerList)
|
|
if err != nil {
|
|
return nil, types.ListCookieBannersOutput{}, err
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, page.OrderBy[coredata.CookieBannerOrderField]{Field: coredata.CookieBannerOrderFieldCreatedAt, Direction: page.OrderDirectionDesc})
|
|
|
|
banners, err := r.cookieBanner.ListCookieBannersForOrganization(ctx, scope, input.OrganizationID, cursor, coredata.NewCookieBannerFilter(nil))
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list cookie banners: %w", err))
|
|
}
|
|
|
|
p := page.NewPage(banners, cursor)
|
|
|
|
return nil, types.NewListCookieBannersOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetCookieBannerTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetCookieBannerInput) (*mcp.CallToolResult, types.GetCookieBannerOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionCookieBannerGet)
|
|
if err != nil {
|
|
return nil, types.GetCookieBannerOutput{}, err
|
|
}
|
|
|
|
banner, err := r.cookieBanner.GetCookieBanner(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetCookieBannerOutput{}, fmt.Errorf("cannot get cookie banner: %w", err)
|
|
}
|
|
|
|
return nil, types.GetCookieBannerOutput{CookieBanner: types.NewCookieBanner(banner)}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddCookieBannerTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddCookieBannerInput) (*mcp.CallToolResult, types.AddCookieBannerOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionCookieBannerCreate)
|
|
if err != nil {
|
|
return nil, types.AddCookieBannerOutput{}, err
|
|
}
|
|
|
|
banner, err := r.cookieBanner.CreateCookieBanner(ctx, scope, cookiebanner.CreateCookieBannerRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Name: input.Name,
|
|
Origin: input.Origin,
|
|
PrivacyPolicyURL: input.PrivacyPolicyURL,
|
|
CookiePolicyURL: input.CookiePolicyURL,
|
|
ConsentExpiryDays: input.ConsentExpiryDays,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddCookieBannerOutput{}, fmt.Errorf("cannot create cookie banner: %w", err)
|
|
}
|
|
|
|
return nil, types.AddCookieBannerOutput{CookieBanner: types.NewCookieBanner(banner)}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateCookieBannerTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateCookieBannerInput) (*mcp.CallToolResult, types.UpdateCookieBannerOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionCookieBannerUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateCookieBannerOutput{}, err
|
|
}
|
|
|
|
updateReq := cookiebanner.UpdateCookieBannerRequest{CookieBannerID: input.ID}
|
|
if v := UnwrapOmittable(input.Name); v != nil && *v != nil {
|
|
updateReq.Name = *v
|
|
}
|
|
|
|
if v := UnwrapOmittable(input.PrivacyPolicyURL); v != nil && *v != nil {
|
|
updateReq.PrivacyPolicyURL = *v
|
|
}
|
|
|
|
if v := UnwrapOmittable(input.CookiePolicyURL); v != nil && *v != nil {
|
|
updateReq.CookiePolicyURL = *v
|
|
}
|
|
|
|
if v := UnwrapOmittable(input.ConsentExpiryDays); v != nil && *v != nil {
|
|
updateReq.ConsentExpiryDays = *v
|
|
}
|
|
|
|
if v := UnwrapOmittable(input.DefaultLanguage); v != nil && *v != nil {
|
|
updateReq.DefaultLanguage = *v
|
|
}
|
|
|
|
banner, err := r.cookieBanner.UpdateCookieBanner(ctx, scope, updateReq)
|
|
if err != nil {
|
|
return nil, types.UpdateCookieBannerOutput{}, fmt.Errorf("cannot update cookie banner: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateCookieBannerOutput{CookieBanner: types.NewCookieBanner(banner)}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteCookieBannerTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteCookieBannerInput) (*mcp.CallToolResult, types.DeleteCookieBannerOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionCookieBannerDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteCookieBannerOutput{}, err
|
|
}
|
|
|
|
if err := r.cookieBanner.DeleteCookieBanner(ctx, scope, input.ID); err != nil {
|
|
return nil, types.DeleteCookieBannerOutput{}, fmt.Errorf("cannot delete cookie banner: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteCookieBannerOutput{DeletedID: input.ID}, nil
|
|
}
|
|
|
|
func (r *Resolver) ActivateCookieBannerTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ActivateCookieBannerInput) (*mcp.CallToolResult, types.ActivateCookieBannerOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionCookieBannerActivate)
|
|
if err != nil {
|
|
return nil, types.ActivateCookieBannerOutput{}, err
|
|
}
|
|
|
|
banner, err := r.cookieBanner.ActivateCookieBanner(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.ActivateCookieBannerOutput{}, fmt.Errorf("cannot activate cookie banner: %w", err)
|
|
}
|
|
|
|
return nil, types.ActivateCookieBannerOutput{CookieBanner: types.NewCookieBanner(banner)}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeactivateCookieBannerTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeactivateCookieBannerInput) (*mcp.CallToolResult, types.DeactivateCookieBannerOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionCookieBannerDeactivate)
|
|
if err != nil {
|
|
return nil, types.DeactivateCookieBannerOutput{}, err
|
|
}
|
|
|
|
banner, err := r.cookieBanner.DeactivateCookieBanner(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.DeactivateCookieBannerOutput{}, fmt.Errorf("cannot deactivate cookie banner: %w", err)
|
|
}
|
|
|
|
return nil, types.DeactivateCookieBannerOutput{CookieBanner: types.NewCookieBanner(banner)}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListCookieCategoriesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListCookieCategoriesInput) (*mcp.CallToolResult, types.ListCookieCategoriesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CookieBannerID, probo.ActionCookieCategoryList)
|
|
if err != nil {
|
|
return nil, types.ListCookieCategoriesOutput{}, err
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, page.OrderBy[coredata.CookieCategoryOrderField]{Field: coredata.CookieCategoryOrderFieldRank, Direction: page.OrderDirectionAsc})
|
|
|
|
categories, err := r.cookieBanner.ListCategoriesForBanner(ctx, scope, input.CookieBannerID, cursor, coredata.NewCookieCategoryFilter(new(coredata.CookieCategoryKindUncategorised)))
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list cookie categories: %w", err))
|
|
}
|
|
|
|
p := page.NewPage(categories, cursor)
|
|
|
|
return nil, types.NewListCookieCategoriesOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetCookieCategoryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetCookieCategoryInput) (*mcp.CallToolResult, types.GetCookieCategoryOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionCookieCategoryGet)
|
|
if err != nil {
|
|
return nil, types.GetCookieCategoryOutput{}, err
|
|
}
|
|
|
|
category, err := r.cookieBanner.GetCookieCategory(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetCookieCategoryOutput{}, fmt.Errorf("cannot get cookie category: %w", err)
|
|
}
|
|
|
|
return nil, types.GetCookieCategoryOutput{CookieCategory: types.NewCookieCategory(category)}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddCookieCategoryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddCookieCategoryInput) (*mcp.CallToolResult, types.AddCookieCategoryOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CookieBannerID, probo.ActionCookieCategoryCreate)
|
|
if err != nil {
|
|
return nil, types.AddCookieCategoryOutput{}, err
|
|
}
|
|
|
|
category, err := r.cookieBanner.CreateCookieCategory(ctx, scope, cookiebanner.CreateCookieCategoryRequest{
|
|
CookieBannerID: input.CookieBannerID,
|
|
Name: input.Name,
|
|
Slug: input.Slug,
|
|
Description: input.Description,
|
|
Rank: input.Rank,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddCookieCategoryOutput{}, fmt.Errorf("cannot create cookie category: %w", err)
|
|
}
|
|
|
|
return nil, types.AddCookieCategoryOutput{CookieCategory: types.NewCookieCategory(category)}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateCookieCategoryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateCookieCategoryInput) (*mcp.CallToolResult, types.UpdateCookieCategoryOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionCookieCategoryUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateCookieCategoryOutput{}, err
|
|
}
|
|
|
|
updateReq := cookiebanner.UpdateCookieCategoryRequest{CookieCategoryID: input.ID}
|
|
if v := UnwrapOmittable(input.Name); v != nil && *v != nil {
|
|
updateReq.Name = *v
|
|
}
|
|
|
|
if v := UnwrapOmittable(input.Slug); v != nil && *v != nil {
|
|
updateReq.Slug = *v
|
|
}
|
|
|
|
if v := UnwrapOmittable(input.Description); v != nil && *v != nil {
|
|
updateReq.Description = *v
|
|
}
|
|
|
|
category, err := r.cookieBanner.UpdateCookieCategory(ctx, scope, updateReq)
|
|
if err != nil {
|
|
return nil, types.UpdateCookieCategoryOutput{}, fmt.Errorf("cannot update cookie category: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateCookieCategoryOutput{CookieCategory: types.NewCookieCategory(category)}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteCookieCategoryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteCookieCategoryInput) (*mcp.CallToolResult, types.DeleteCookieCategoryOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionCookieCategoryDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteCookieCategoryOutput{}, err
|
|
}
|
|
|
|
if err := r.cookieBanner.DeleteCookieCategory(ctx, scope, input.ID); err != nil {
|
|
return nil, types.DeleteCookieCategoryOutput{}, fmt.Errorf("cannot delete cookie category: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteCookieCategoryOutput{DeletedID: input.ID}, nil
|
|
}
|
|
|
|
func (r *Resolver) ReorderCookieCategoryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ReorderCookieCategoryInput) (*mcp.CallToolResult, types.ReorderCookieCategoryOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionCookieCategoryUpdate)
|
|
if err != nil {
|
|
return nil, types.ReorderCookieCategoryOutput{}, err
|
|
}
|
|
|
|
_, err = r.cookieBanner.ReorderCookieCategory(ctx, scope, cookiebanner.ReorderCookieCategoryRequest{
|
|
CookieCategoryID: input.ID,
|
|
Rank: input.Rank,
|
|
})
|
|
if err != nil {
|
|
return nil, types.ReorderCookieCategoryOutput{}, fmt.Errorf("cannot reorder cookie category: %w", err)
|
|
}
|
|
|
|
category, err := r.cookieBanner.GetCookieCategory(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.ReorderCookieCategoryOutput{}, fmt.Errorf("cannot get cookie category: %w", err)
|
|
}
|
|
|
|
return nil, types.ReorderCookieCategoryOutput{CookieCategory: types.NewCookieCategory(category)}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListTrackerPatternsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListTrackerPatternsInput) (*mcp.CallToolResult, types.ListTrackerPatternsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CookieCategoryID, probo.ActionTrackerPatternList)
|
|
if err != nil {
|
|
return nil, types.ListTrackerPatternsOutput{}, err
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, page.OrderBy[coredata.TrackerPatternOrderField]{Field: coredata.TrackerPatternOrderFieldCreatedAt, Direction: page.OrderDirectionAsc})
|
|
|
|
patterns, err := r.cookieBanner.ListTrackerPatternsForCategory(ctx, scope, input.CookieCategoryID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list tracker patterns: %w", err))
|
|
}
|
|
|
|
p := page.NewPage(patterns, cursor)
|
|
|
|
return nil, types.NewListTrackerPatternsOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetTrackerPatternTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetTrackerPatternInput) (*mcp.CallToolResult, types.GetTrackerPatternOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTrackerPatternGet)
|
|
if err != nil {
|
|
return nil, types.GetTrackerPatternOutput{}, err
|
|
}
|
|
|
|
pattern, err := r.cookieBanner.GetTrackerPattern(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetTrackerPatternOutput{}, fmt.Errorf("cannot get tracker pattern: %w", err)
|
|
}
|
|
|
|
return nil, types.GetTrackerPatternOutput{TrackerPattern: types.NewTrackerPattern(pattern)}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddTrackerPatternTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddTrackerPatternInput) (*mcp.CallToolResult, types.AddTrackerPatternOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CookieCategoryID, probo.ActionTrackerPatternCreate)
|
|
if err != nil {
|
|
return nil, types.AddTrackerPatternOutput{}, err
|
|
}
|
|
|
|
pattern, err := r.cookieBanner.CreateTrackerPattern(ctx, scope, cookiebanner.CreateTrackerPatternRequest{
|
|
CookieCategoryID: input.CookieCategoryID,
|
|
TrackerType: coredata.TrackerType(input.TrackerType),
|
|
Pattern: input.Pattern,
|
|
MatchType: coredata.TrackerPatternMatchType(input.MatchType),
|
|
DisplayName: input.DisplayName,
|
|
MaxAgeSeconds: input.MaxAgeSeconds,
|
|
Description: input.Description,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddTrackerPatternOutput{}, fmt.Errorf("cannot create tracker pattern: %w", err)
|
|
}
|
|
|
|
return nil, types.AddTrackerPatternOutput{TrackerPattern: types.NewTrackerPattern(pattern)}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateTrackerPatternTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateTrackerPatternInput) (*mcp.CallToolResult, types.UpdateTrackerPatternOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTrackerPatternUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateTrackerPatternOutput{}, err
|
|
}
|
|
|
|
updateReq := cookiebanner.UpdateTrackerPatternRequest{TrackerPatternID: input.ID}
|
|
if input.MaxAgeSeconds.IsSet() {
|
|
val, _ := input.MaxAgeSeconds.Value()
|
|
updateReq.MaxAgeSeconds = &val
|
|
}
|
|
|
|
if v := UnwrapOmittable(input.Description); v != nil && *v != nil {
|
|
updateReq.Description = *v
|
|
}
|
|
|
|
if v := UnwrapOmittable(input.Excluded); v != nil && *v != nil {
|
|
updateReq.Excluded = *v
|
|
}
|
|
|
|
pattern, err := r.cookieBanner.UpdateTrackerPattern(ctx, scope, updateReq)
|
|
if err != nil {
|
|
return nil, types.UpdateTrackerPatternOutput{}, fmt.Errorf("cannot update tracker pattern: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateTrackerPatternOutput{TrackerPattern: types.NewTrackerPattern(pattern)}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteTrackerPatternTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteTrackerPatternInput) (*mcp.CallToolResult, types.DeleteTrackerPatternOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTrackerPatternDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteTrackerPatternOutput{}, err
|
|
}
|
|
|
|
if err := r.cookieBanner.DeleteTrackerPattern(ctx, scope, input.ID); err != nil {
|
|
return nil, types.DeleteTrackerPatternOutput{}, fmt.Errorf("cannot delete tracker pattern: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteTrackerPatternOutput{DeletedID: input.ID}, nil
|
|
}
|
|
|
|
func (r *Resolver) MoveTrackerPatternToCategoryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.MoveTrackerPatternToCategoryInput) (*mcp.CallToolResult, types.MoveTrackerPatternToCategoryOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.TrackerPatternID, probo.ActionTrackerPatternUpdate)
|
|
if err != nil {
|
|
return nil, types.MoveTrackerPatternToCategoryOutput{}, err
|
|
}
|
|
|
|
result, err := r.cookieBanner.MoveTrackerPatternToCategory(ctx, scope, cookiebanner.MoveTrackerPatternToCategoryRequest{
|
|
TrackerPatternID: input.TrackerPatternID,
|
|
TargetCookieCategoryID: input.TargetCookieCategoryID,
|
|
})
|
|
if err != nil {
|
|
return nil, types.MoveTrackerPatternToCategoryOutput{}, fmt.Errorf("cannot move tracker pattern: %w", err)
|
|
}
|
|
|
|
return nil, types.MoveTrackerPatternToCategoryOutput{TrackerPattern: types.NewTrackerPattern(result.TrackerPattern)}, nil
|
|
}
|
|
|
|
func (r *Resolver) PublishCookieBannerVersionTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishCookieBannerVersionInput) (*mcp.CallToolResult, types.PublishCookieBannerVersionOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerVersionPublish)
|
|
if err != nil {
|
|
return nil, types.PublishCookieBannerVersionOutput{}, err
|
|
}
|
|
|
|
version, err := r.cookieBanner.PublishCookieBannerVersion(ctx, scope, input.CookieBannerID)
|
|
if err != nil {
|
|
return nil, types.PublishCookieBannerVersionOutput{}, fmt.Errorf("cannot publish cookie banner version: %w", err)
|
|
}
|
|
|
|
return nil, types.PublishCookieBannerVersionOutput{CookieBannerVersion: types.NewCookieBannerVersion(version)}, nil
|
|
}
|
|
|
|
func (r *Resolver) RegenerateCookieBannerTrackerPolicyTool(ctx context.Context, req *mcp.CallToolRequest, input *types.RegenerateCookieBannerTrackerPolicyInput) (*mcp.CallToolResult, types.RegenerateCookieBannerTrackerPolicyOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerRegeneratePolicy)
|
|
if err != nil {
|
|
return nil, types.RegenerateCookieBannerTrackerPolicyOutput{}, err
|
|
}
|
|
|
|
banner, err := r.cookieBanner.RegenerateTrackerPolicy(ctx, scope, input.CookieBannerID)
|
|
if err != nil {
|
|
return nil, types.RegenerateCookieBannerTrackerPolicyOutput{}, fmt.Errorf("cannot regenerate cookie banner tracker policy: %w", err)
|
|
}
|
|
|
|
return nil, types.RegenerateCookieBannerTrackerPolicyOutput{CookieBanner: types.NewCookieBanner(banner)}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListCookieBannerVersionsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListCookieBannerVersionsInput) (*mcp.CallToolResult, types.ListCookieBannerVersionsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerVersionList)
|
|
if err != nil {
|
|
return nil, types.ListCookieBannerVersionsOutput{}, err
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, page.OrderBy[coredata.CookieBannerVersionOrderField]{Field: coredata.CookieBannerVersionOrderFieldCreatedAt, Direction: page.OrderDirectionDesc})
|
|
|
|
versions, err := r.cookieBanner.ListCookieBannerVersionsForBanner(ctx, scope, input.CookieBannerID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list cookie banner versions: %w", err))
|
|
}
|
|
|
|
p := page.NewPage(versions, cursor)
|
|
|
|
return nil, types.NewListCookieBannerVersionsOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) UpsertCookieBannerTranslationTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpsertCookieBannerTranslationInput) (*mcp.CallToolResult, types.UpsertCookieBannerTranslationOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerUpdate)
|
|
if err != nil {
|
|
return nil, types.UpsertCookieBannerTranslationOutput{}, err
|
|
}
|
|
|
|
translation, err := r.cookieBanner.UpsertCookieBannerTranslation(ctx, scope, cookiebanner.UpsertCookieBannerTranslationRequest{
|
|
CookieBannerID: input.CookieBannerID,
|
|
Language: input.Language,
|
|
Translations: json.RawMessage(input.Translations),
|
|
})
|
|
if err != nil {
|
|
return nil, types.UpsertCookieBannerTranslationOutput{}, fmt.Errorf("cannot upsert cookie banner translation: %w", err)
|
|
}
|
|
|
|
return nil, types.UpsertCookieBannerTranslationOutput{CookieBannerTranslation: types.NewCookieBannerTranslation(translation)}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListCookieConsentRecordsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListCookieConsentRecordsInput) (*mcp.CallToolResult, types.ListCookieConsentRecordsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CookieBannerID, probo.ActionCookieConsentRecordList)
|
|
if err != nil {
|
|
return nil, types.ListCookieConsentRecordsOutput{}, err
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, page.OrderBy[coredata.CookieConsentRecordOrderField]{Field: coredata.CookieConsentRecordOrderFieldCreatedAt, Direction: page.OrderDirectionDesc})
|
|
|
|
var action *coredata.CookieConsentAction
|
|
|
|
if input.Action != nil {
|
|
a := coredata.CookieConsentAction(*input.Action)
|
|
action = &a
|
|
}
|
|
|
|
filter := coredata.NewCookieConsentRecordFilter(action, input.VisitorID, input.Version)
|
|
|
|
records, err := r.cookieBanner.ListCookieConsentRecordsForBanner(ctx, scope, input.CookieBannerID, cursor, filter)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list cookie consent records: %w", err))
|
|
}
|
|
|
|
p := page.NewPage(records, cursor)
|
|
|
|
return nil, types.NewListCookieConsentRecordsOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetCookieConsentRecordTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetCookieConsentRecordInput) (*mcp.CallToolResult, types.GetCookieConsentRecordOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionCookieConsentRecordList)
|
|
if err != nil {
|
|
return nil, types.GetCookieConsentRecordOutput{}, err
|
|
}
|
|
|
|
record, err := r.cookieBanner.GetCookieConsentRecord(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetCookieConsentRecordOutput{}, fmt.Errorf("cannot get cookie consent record: %w", err)
|
|
}
|
|
|
|
return nil, types.GetCookieConsentRecordOutput{CookieConsentRecord: types.NewCookieConsentRecord(record)}, nil
|
|
}
|
|
|
|
func (r *Resolver) PublishRiskListTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishRiskListInput) (*mcp.CallToolResult, types.PublishRiskListOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionRiskPublish)
|
|
if err != nil {
|
|
return nil, types.PublishRiskListOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
document, documentVersion, err := svc.GeneratedDocuments.PublishRiskList(ctx, scope, input.OrganizationID, input.ApproverIds, input.Minor)
|
|
if err != nil {
|
|
return nil, types.PublishRiskListOutput{}, fmt.Errorf("cannot publish risk list: %w", err)
|
|
}
|
|
|
|
return nil, types.PublishRiskListOutput{
|
|
DocumentID: document.ID,
|
|
DocumentVersionID: documentVersion.ID,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) GetSCIMConfigurationTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetSCIMConfigurationInput) (*mcp.CallToolResult, types.GetSCIMConfigurationOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.OrganizationID, iam.ActionSCIMConfigurationGet); err != nil {
|
|
return nil, types.GetSCIMConfigurationOutput{}, err
|
|
}
|
|
|
|
config, err := r.iamSvc.OrganizationService.GetSCIMConfiguration(ctx, input.OrganizationID)
|
|
if err != nil {
|
|
if _, ok := errors.AsType[*iam.ErrNoSCIMConfigurationFound](err); ok {
|
|
return nil, types.GetSCIMConfigurationOutput{}, fmt.Errorf("SCIM configuration not found")
|
|
}
|
|
|
|
panic(fmt.Errorf("cannot get SCIM configuration: %w", err))
|
|
}
|
|
|
|
return nil, types.GetSCIMConfigurationOutput{ScimConfiguration: types.NewSCIMConfiguration(config)}, nil
|
|
}
|
|
|
|
func (r *Resolver) CreateSCIMConfigurationTool(ctx context.Context, req *mcp.CallToolRequest, input *types.CreateSCIMConfigurationInput) (*mcp.CallToolResult, types.CreateSCIMConfigurationOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.OrganizationID, iam.ActionSCIMConfigurationCreate); err != nil {
|
|
return nil, types.CreateSCIMConfigurationOutput{}, err
|
|
}
|
|
|
|
config, token, err := r.iamSvc.OrganizationService.CreateSCIMConfiguration(ctx, input.OrganizationID)
|
|
if err != nil {
|
|
return nil, types.CreateSCIMConfigurationOutput{}, fmt.Errorf("cannot create SCIM configuration: %w", err)
|
|
}
|
|
|
|
output := types.CreateSCIMConfigurationOutput{
|
|
ScimConfiguration: types.NewSCIMConfiguration(config),
|
|
Token: token,
|
|
}
|
|
|
|
if input.ConnectorID != nil {
|
|
bridge, err := r.iamSvc.OrganizationService.CreateSCIMBridge(ctx, input.OrganizationID, config.ID, *input.ConnectorID)
|
|
if err != nil {
|
|
return nil, types.CreateSCIMConfigurationOutput{}, fmt.Errorf("cannot create SCIM bridge: %w", err)
|
|
}
|
|
|
|
output.ScimBridge = types.NewSCIMBridge(bridge)
|
|
}
|
|
|
|
return nil, output, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteSCIMConfigurationTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteSCIMConfigurationInput) (*mcp.CallToolResult, types.DeleteSCIMConfigurationOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.OrganizationID, iam.ActionSCIMConfigurationDelete); err != nil {
|
|
return nil, types.DeleteSCIMConfigurationOutput{}, err
|
|
}
|
|
|
|
err := r.iamSvc.OrganizationService.DeleteSCIMConfiguration(ctx, input.OrganizationID, input.ScimConfigurationID)
|
|
if err != nil {
|
|
return nil, types.DeleteSCIMConfigurationOutput{}, fmt.Errorf("cannot delete SCIM configuration: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteSCIMConfigurationOutput{DeletedScimConfigurationID: input.ScimConfigurationID}, nil
|
|
}
|
|
|
|
func (r *Resolver) RegenerateSCIMTokenTool(ctx context.Context, req *mcp.CallToolRequest, input *types.RegenerateSCIMTokenInput) (*mcp.CallToolResult, types.RegenerateSCIMTokenOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.ScimConfigurationID, iam.ActionSCIMConfigurationUpdate); err != nil {
|
|
return nil, types.RegenerateSCIMTokenOutput{}, err
|
|
}
|
|
|
|
config, token, err := r.iamSvc.OrganizationService.RegenerateSCIMToken(ctx, input.OrganizationID, input.ScimConfigurationID)
|
|
if err != nil {
|
|
return nil, types.RegenerateSCIMTokenOutput{}, fmt.Errorf("cannot regenerate SCIM token: %w", err)
|
|
}
|
|
|
|
return nil, types.RegenerateSCIMTokenOutput{
|
|
ScimConfiguration: types.NewSCIMConfiguration(config),
|
|
Token: token,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) GetSCIMBridgeTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetSCIMBridgeInput) (*mcp.CallToolResult, types.GetSCIMBridgeOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.ID, iam.ActionSCIMBridgeGet); err != nil {
|
|
return nil, types.GetSCIMBridgeOutput{}, err
|
|
}
|
|
|
|
bridge, err := r.iamSvc.OrganizationService.GetSCIMBridgeByID(ctx, input.ID)
|
|
if err != nil {
|
|
if _, ok := errors.AsType[*iam.ErrSCIMBridgeNotFound](err); ok {
|
|
return nil, types.GetSCIMBridgeOutput{}, fmt.Errorf("SCIM bridge %s not found", input.ID)
|
|
}
|
|
|
|
panic(fmt.Errorf("cannot get SCIM bridge: %w", err))
|
|
}
|
|
|
|
return nil, types.GetSCIMBridgeOutput{ScimBridge: types.NewSCIMBridge(bridge)}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateSCIMBridgeTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateSCIMBridgeInput) (*mcp.CallToolResult, types.UpdateSCIMBridgeOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.ScimBridgeID, iam.ActionSCIMBridgeUpdate); err != nil {
|
|
return nil, types.UpdateSCIMBridgeOutput{}, err
|
|
}
|
|
|
|
bridge, err := r.iamSvc.OrganizationService.UpdateSCIMBridge(ctx, input.OrganizationID, input.ScimBridgeID, input.ExcludedUserNames)
|
|
if err != nil {
|
|
return nil, types.UpdateSCIMBridgeOutput{}, fmt.Errorf("cannot update SCIM bridge: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateSCIMBridgeOutput{ScimBridge: types.NewSCIMBridge(bridge)}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListSCIMEventsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListSCIMEventsInput) (*mcp.CallToolResult, types.ListSCIMEventsOutput, error) {
|
|
if _, err := r.Authorize(ctx, input.ScimConfigurationID, iam.ActionSCIMEventList); err != nil {
|
|
return nil, types.ListSCIMEventsOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.SCIMEventOrderField]{
|
|
Field: coredata.SCIMEventOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.SCIMEventOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := r.iamSvc.OrganizationService.ListSCIMEventsByConfigID(ctx, input.ScimConfigurationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list SCIM events: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListSCIMEventsOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) PublishDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishDocumentInput) (*mcp.CallToolResult, types.PublishDocumentOutput, error) {
|
|
action := probo.ActionDocumentVersionPublish
|
|
if !input.Minor && len(input.ApproverIds) > 0 {
|
|
action = probo.ActionDocumentVersionRequestApproval
|
|
}
|
|
|
|
scope, err := r.Authorize(ctx, input.DocumentID, action)
|
|
if err != nil {
|
|
return nil, types.PublishDocumentOutput{}, err
|
|
}
|
|
|
|
svc := r.proboSvc
|
|
|
|
result, err := svc.Documents.PublishVersion(ctx, scope, probo.PublishDocumentRequest{
|
|
DocumentID: input.DocumentID,
|
|
Minor: input.Minor,
|
|
ApproverIDs: input.ApproverIds,
|
|
Changelog: input.Changelog,
|
|
})
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot publish document: %w", err))
|
|
}
|
|
|
|
output := types.PublishDocumentOutput{
|
|
Document: types.NewDocument(result.Document),
|
|
DocumentVersion: types.NewDocumentVersion(result.Version),
|
|
}
|
|
|
|
if result.Quorum != nil {
|
|
output.ApprovalQuorum = types.NewDocumentVersionApprovalQuorum(result.Quorum)
|
|
}
|
|
|
|
return nil, output, nil
|
|
}
|
|
|
|
func (r *Resolver) ListTrackerResourcesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListTrackerResourcesInput) (*mcp.CallToolResult, types.ListTrackerResourcesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CookieCategoryID, probo.ActionTrackerResourceList)
|
|
if err != nil {
|
|
return nil, types.ListTrackerResourcesOutput{}, err
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, page.OrderBy[coredata.TrackerResourceOrderField]{Field: coredata.TrackerResourceOrderFieldCreatedAt, Direction: page.OrderDirectionAsc})
|
|
|
|
resources, err := r.cookieBanner.ListTrackerResourcesForCategory(ctx, scope, input.CookieCategoryID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list tracker resources: %w", err))
|
|
}
|
|
|
|
p := page.NewPage(resources, cursor)
|
|
|
|
return nil, types.NewListTrackerResourcesOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetTrackerResourceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetTrackerResourceInput) (*mcp.CallToolResult, types.GetTrackerResourceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTrackerResourceGet)
|
|
if err != nil {
|
|
return nil, types.GetTrackerResourceOutput{}, err
|
|
}
|
|
|
|
resource, err := r.cookieBanner.GetTrackerResource(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetTrackerResourceOutput{}, fmt.Errorf("cannot get tracker resource: %w", err)
|
|
}
|
|
|
|
return nil, types.GetTrackerResourceOutput{TrackerResource: types.NewTrackerResource(resource)}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddTrackerResourceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddTrackerResourceInput) (*mcp.CallToolResult, types.AddTrackerResourceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.CookieCategoryID, probo.ActionTrackerResourceCreate)
|
|
if err != nil {
|
|
return nil, types.AddTrackerResourceOutput{}, err
|
|
}
|
|
|
|
description := ""
|
|
if input.Description != nil {
|
|
description = *input.Description
|
|
}
|
|
|
|
resource, err := r.cookieBanner.CreateTrackerResource(ctx, scope, cookiebanner.CreateTrackerResourceRequest{
|
|
CookieCategoryID: input.CookieCategoryID,
|
|
ResourceType: coredata.TrackerResourceType(input.ResourceType),
|
|
Origin: input.Origin,
|
|
Path: input.Path,
|
|
DisplayName: input.DisplayName,
|
|
Description: description,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddTrackerResourceOutput{}, fmt.Errorf("cannot create tracker resource: %w", err)
|
|
}
|
|
|
|
return nil, types.AddTrackerResourceOutput{TrackerResource: types.NewTrackerResource(resource)}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateTrackerResourceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateTrackerResourceInput) (*mcp.CallToolResult, types.UpdateTrackerResourceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTrackerResourceUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateTrackerResourceOutput{}, err
|
|
}
|
|
|
|
updateReq := cookiebanner.UpdateTrackerResourceRequest{TrackerResourceID: input.ID}
|
|
if v := UnwrapOmittable(input.DisplayName); v != nil && *v != nil {
|
|
updateReq.DisplayName = *v
|
|
}
|
|
|
|
if v := UnwrapOmittable(input.Description); v != nil && *v != nil {
|
|
updateReq.Description = *v
|
|
}
|
|
|
|
if v := UnwrapOmittable(input.Excluded); v != nil && *v != nil {
|
|
updateReq.Excluded = *v
|
|
}
|
|
|
|
resource, err := r.cookieBanner.UpdateTrackerResource(ctx, scope, updateReq)
|
|
if err != nil {
|
|
return nil, types.UpdateTrackerResourceOutput{}, fmt.Errorf("cannot update tracker resource: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateTrackerResourceOutput{TrackerResource: types.NewTrackerResource(resource)}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteTrackerResourceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteTrackerResourceInput) (*mcp.CallToolResult, types.DeleteTrackerResourceOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionTrackerResourceDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteTrackerResourceOutput{}, err
|
|
}
|
|
|
|
if err := r.cookieBanner.DeleteTrackerResource(ctx, scope, input.ID); err != nil {
|
|
return nil, types.DeleteTrackerResourceOutput{}, fmt.Errorf("cannot delete tracker resource: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteTrackerResourceOutput{DeletedID: input.ID}, nil
|
|
}
|
|
|
|
func (r *Resolver) MoveTrackerResourceToCategoryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.MoveTrackerResourceToCategoryInput) (*mcp.CallToolResult, types.MoveTrackerResourceToCategoryOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.TrackerResourceID, probo.ActionTrackerResourceUpdate)
|
|
if err != nil {
|
|
return nil, types.MoveTrackerResourceToCategoryOutput{}, err
|
|
}
|
|
|
|
result, err := r.cookieBanner.MoveTrackerResourceToCategory(ctx, scope, cookiebanner.MoveTrackerResourceToCategoryRequest{
|
|
TrackerResourceID: input.TrackerResourceID,
|
|
TargetCookieCategoryID: input.TargetCookieCategoryID,
|
|
})
|
|
if err != nil {
|
|
return nil, types.MoveTrackerResourceToCategoryOutput{}, fmt.Errorf("cannot move tracker resource: %w", err)
|
|
}
|
|
|
|
return nil, types.MoveTrackerResourceToCategoryOutput{TrackerResource: types.NewTrackerResource(result.TrackerResource)}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListChildThirdPartiesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListChildThirdPartiesInput) (*mcp.CallToolResult, types.ListChildThirdPartiesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ParentThirdPartyID, probo.ActionThirdPartyRelationList)
|
|
if err != nil {
|
|
return nil, types.ListChildThirdPartiesOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ThirdPartyOrderField]{
|
|
Field: coredata.ThirdPartyOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ThirdPartyOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
page, err := r.proboSvc.ThirdParties.ListForParentThirdPartyID(ctx, scope, input.ParentThirdPartyID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list child third parties: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListChildThirdPartiesOutput(page), nil
|
|
}
|
|
|
|
func (r *Resolver) ListRiskAssessmentsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListRiskAssessmentsInput) (*mcp.CallToolResult, types.ListRiskAssessmentsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionRiskAssessmentList)
|
|
if err != nil {
|
|
return nil, types.ListRiskAssessmentsOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.RiskAssessmentOrderField]{
|
|
Field: coredata.RiskAssessmentOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.RiskAssessmentOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := r.riskManagement.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list risk assessments: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListRiskAssessmentsOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetRiskAssessmentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetRiskAssessmentInput) (*mcp.CallToolResult, types.GetRiskAssessmentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentGet)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentOutput{}, err
|
|
}
|
|
|
|
ra, err := r.riskManagement.Get(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentOutput{}, fmt.Errorf("failed to get risk assessment: %w", err)
|
|
}
|
|
|
|
return nil, types.GetRiskAssessmentOutput{
|
|
RiskAssessment: types.NewRiskAssessment(ra),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddRiskAssessmentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddRiskAssessmentInput) (*mcp.CallToolResult, types.AddRiskAssessmentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionRiskAssessmentCreate)
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentOutput{}, err
|
|
}
|
|
|
|
ra, err := r.riskManagement.Create(ctx, scope, riskmanagement.CreateRiskAssessmentRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Name: input.Name,
|
|
Description: input.Description,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentOutput{}, fmt.Errorf("failed to create risk assessment: %w", err)
|
|
}
|
|
|
|
return nil, types.AddRiskAssessmentOutput{
|
|
RiskAssessment: types.NewRiskAssessment(ra),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateRiskAssessmentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateRiskAssessmentInput) (*mcp.CallToolResult, types.UpdateRiskAssessmentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentOutput{}, err
|
|
}
|
|
|
|
ra, err := r.riskManagement.Update(ctx, scope, riskmanagement.UpdateRiskAssessmentRequest{
|
|
ID: input.ID,
|
|
Name: input.Name,
|
|
Description: UnwrapOmittable(input.Description),
|
|
})
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentOutput{}, fmt.Errorf("failed to update risk assessment: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateRiskAssessmentOutput{
|
|
RiskAssessment: types.NewRiskAssessment(ra),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteRiskAssessmentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteRiskAssessmentInput) (*mcp.CallToolResult, types.DeleteRiskAssessmentOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteRiskAssessmentOutput{}, err
|
|
}
|
|
|
|
if err := r.riskManagement.Delete(ctx, scope, input.ID); err != nil {
|
|
return nil, types.DeleteRiskAssessmentOutput{}, fmt.Errorf("failed to delete risk assessment: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteRiskAssessmentOutput{
|
|
DeletedRiskAssessmentID: input.ID,
|
|
}, nil
|
|
}
|
|
func (r *Resolver) ListRiskAssessmentScopesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListRiskAssessmentScopesInput) (*mcp.CallToolResult, types.ListRiskAssessmentScopesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentID, probo.ActionRiskAssessmentScopeList)
|
|
if err != nil {
|
|
return nil, types.ListRiskAssessmentScopesOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.RiskAssessmentScopeOrderField]{
|
|
Field: coredata.RiskAssessmentScopeOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.RiskAssessmentScopeOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := r.riskManagement.ListScopesForRiskAssessmentID(ctx, scope, input.RiskAssessmentID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list risk assessment scopes: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListRiskAssessmentScopesOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetRiskAssessmentScopeTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetRiskAssessmentScopeInput) (*mcp.CallToolResult, types.GetRiskAssessmentScopeOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentScopeGet)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentScopeOutput{}, err
|
|
}
|
|
|
|
s, err := r.riskManagement.GetScope(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentScopeOutput{}, fmt.Errorf("failed to get risk assessment scope: %w", err)
|
|
}
|
|
|
|
return nil, types.GetRiskAssessmentScopeOutput{
|
|
RiskAssessmentScope: types.NewRiskAssessmentScope(s),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddRiskAssessmentScopeTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddRiskAssessmentScopeInput) (*mcp.CallToolResult, types.AddRiskAssessmentScopeOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentID, probo.ActionRiskAssessmentScopeCreate)
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentScopeOutput{}, err
|
|
}
|
|
|
|
s, err := r.riskManagement.CreateScope(ctx, scope, riskmanagement.CreateRiskAssessmentScopeRequest{
|
|
RiskAssessmentID: input.RiskAssessmentID,
|
|
Name: input.Name,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentScopeOutput{}, fmt.Errorf("failed to create risk assessment scope: %w", err)
|
|
}
|
|
|
|
return nil, types.AddRiskAssessmentScopeOutput{
|
|
RiskAssessmentScope: types.NewRiskAssessmentScope(s),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateRiskAssessmentScopeTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateRiskAssessmentScopeInput) (*mcp.CallToolResult, types.UpdateRiskAssessmentScopeOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentScopeUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentScopeOutput{}, err
|
|
}
|
|
|
|
s, err := r.riskManagement.UpdateScope(ctx, scope, riskmanagement.UpdateRiskAssessmentScopeRequest{
|
|
ID: input.ID,
|
|
Name: input.Name,
|
|
})
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentScopeOutput{}, fmt.Errorf("failed to update risk assessment scope: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateRiskAssessmentScopeOutput{
|
|
RiskAssessmentScope: types.NewRiskAssessmentScope(s),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteRiskAssessmentScopeTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteRiskAssessmentScopeInput) (*mcp.CallToolResult, types.DeleteRiskAssessmentScopeOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentScopeDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteRiskAssessmentScopeOutput{}, err
|
|
}
|
|
|
|
if err := r.riskManagement.DeleteScope(ctx, scope, input.ID); err != nil {
|
|
return nil, types.DeleteRiskAssessmentScopeOutput{}, fmt.Errorf("failed to delete risk assessment scope: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteRiskAssessmentScopeOutput{
|
|
DeletedRiskAssessmentScopeID: input.ID,
|
|
}, nil
|
|
}
|
|
func (r *Resolver) ListRiskAssessmentNodesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListRiskAssessmentNodesInput) (*mcp.CallToolResult, types.ListRiskAssessmentNodesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScopeID, probo.ActionRiskAssessmentNodeList)
|
|
if err != nil {
|
|
return nil, types.ListRiskAssessmentNodesOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.RiskAssessmentNodeOrderField]{
|
|
Field: coredata.RiskAssessmentNodeOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.RiskAssessmentNodeOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := r.riskManagement.ListNodesForScopeID(ctx, scope, input.RiskAssessmentScopeID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list risk assessment nodes: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListRiskAssessmentNodesOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetRiskAssessmentNodeTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetRiskAssessmentNodeInput) (*mcp.CallToolResult, types.GetRiskAssessmentNodeOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentNodeGet)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentNodeOutput{}, err
|
|
}
|
|
|
|
n, err := r.riskManagement.GetNode(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentNodeOutput{}, fmt.Errorf("failed to get risk assessment node: %w", err)
|
|
}
|
|
|
|
return nil, types.GetRiskAssessmentNodeOutput{
|
|
RiskAssessmentNode: types.NewRiskAssessmentNode(n),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddRiskAssessmentNodeTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddRiskAssessmentNodeInput) (*mcp.CallToolResult, types.AddRiskAssessmentNodeOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScopeID, probo.ActionRiskAssessmentNodeCreate)
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentNodeOutput{}, err
|
|
}
|
|
|
|
n, err := r.riskManagement.CreateNode(ctx, scope, riskmanagement.CreateRiskAssessmentNodeRequest{
|
|
RiskAssessmentScopeID: input.RiskAssessmentScopeID,
|
|
BoundaryID: input.BoundaryID,
|
|
NodeType: input.NodeType,
|
|
Name: input.Name,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentNodeOutput{}, fmt.Errorf("failed to create risk assessment node: %w", err)
|
|
}
|
|
|
|
return nil, types.AddRiskAssessmentNodeOutput{
|
|
RiskAssessmentNode: types.NewRiskAssessmentNode(n),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateRiskAssessmentNodeTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateRiskAssessmentNodeInput) (*mcp.CallToolResult, types.UpdateRiskAssessmentNodeOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentNodeUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentNodeOutput{}, err
|
|
}
|
|
|
|
var boundaryID **gid.GID
|
|
if input.BoundaryID != nil {
|
|
boundaryID = &input.BoundaryID
|
|
}
|
|
|
|
n, err := r.riskManagement.UpdateNode(ctx, scope, riskmanagement.UpdateRiskAssessmentNodeRequest{
|
|
ID: input.ID,
|
|
BoundaryID: boundaryID,
|
|
NodeType: input.NodeType,
|
|
Name: input.Name,
|
|
})
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentNodeOutput{}, fmt.Errorf("failed to update risk assessment node: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateRiskAssessmentNodeOutput{
|
|
RiskAssessmentNode: types.NewRiskAssessmentNode(n),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteRiskAssessmentNodeTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteRiskAssessmentNodeInput) (*mcp.CallToolResult, types.DeleteRiskAssessmentNodeOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentNodeDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteRiskAssessmentNodeOutput{}, err
|
|
}
|
|
|
|
if err := r.riskManagement.DeleteNode(ctx, scope, input.ID); err != nil {
|
|
return nil, types.DeleteRiskAssessmentNodeOutput{}, fmt.Errorf("failed to delete risk assessment node: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteRiskAssessmentNodeOutput{
|
|
DeletedRiskAssessmentNodeID: input.ID,
|
|
}, nil
|
|
}
|
|
func (r *Resolver) ListRiskAssessmentProcessesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListRiskAssessmentProcessesInput) (*mcp.CallToolResult, types.ListRiskAssessmentProcessesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScopeID, probo.ActionRiskAssessmentProcessList)
|
|
if err != nil {
|
|
return nil, types.ListRiskAssessmentProcessesOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.RiskAssessmentProcessOrderField]{
|
|
Field: coredata.RiskAssessmentProcessOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.RiskAssessmentProcessOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := r.riskManagement.ListProcessesForScopeID(ctx, scope, input.RiskAssessmentScopeID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list risk assessment processes: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListRiskAssessmentProcessesOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetRiskAssessmentProcessTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetRiskAssessmentProcessInput) (*mcp.CallToolResult, types.GetRiskAssessmentProcessOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentProcessGet)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentProcessOutput{}, err
|
|
}
|
|
|
|
p, err := r.riskManagement.GetProcess(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentProcessOutput{}, fmt.Errorf("failed to get risk assessment process: %w", err)
|
|
}
|
|
|
|
return nil, types.GetRiskAssessmentProcessOutput{
|
|
RiskAssessmentProcess: types.NewRiskAssessmentProcess(p),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddRiskAssessmentProcessTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddRiskAssessmentProcessInput) (*mcp.CallToolResult, types.AddRiskAssessmentProcessOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScopeID, probo.ActionRiskAssessmentProcessCreate)
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentProcessOutput{}, err
|
|
}
|
|
|
|
p, err := r.riskManagement.CreateProcess(ctx, scope, riskmanagement.CreateRiskAssessmentProcessRequest{
|
|
RiskAssessmentScopeID: input.RiskAssessmentScopeID,
|
|
SourceNodeID: input.SourceNodeID,
|
|
TargetNodeID: input.TargetNodeID,
|
|
Name: input.Name,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentProcessOutput{}, fmt.Errorf("failed to create risk assessment process: %w", err)
|
|
}
|
|
|
|
return nil, types.AddRiskAssessmentProcessOutput{
|
|
RiskAssessmentProcess: types.NewRiskAssessmentProcess(p),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateRiskAssessmentProcessTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateRiskAssessmentProcessInput) (*mcp.CallToolResult, types.UpdateRiskAssessmentProcessOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentProcessUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentProcessOutput{}, err
|
|
}
|
|
|
|
p, err := r.riskManagement.UpdateProcess(ctx, scope, riskmanagement.UpdateRiskAssessmentProcessRequest{
|
|
ID: input.ID,
|
|
SourceNodeID: input.SourceNodeID,
|
|
TargetNodeID: input.TargetNodeID,
|
|
Name: input.Name,
|
|
})
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentProcessOutput{}, fmt.Errorf("failed to update risk assessment process: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateRiskAssessmentProcessOutput{
|
|
RiskAssessmentProcess: types.NewRiskAssessmentProcess(p),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteRiskAssessmentProcessTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteRiskAssessmentProcessInput) (*mcp.CallToolResult, types.DeleteRiskAssessmentProcessOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentProcessDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteRiskAssessmentProcessOutput{}, err
|
|
}
|
|
|
|
if err := r.riskManagement.DeleteProcess(ctx, scope, input.ID); err != nil {
|
|
return nil, types.DeleteRiskAssessmentProcessOutput{}, fmt.Errorf("failed to delete risk assessment process: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteRiskAssessmentProcessOutput{
|
|
DeletedRiskAssessmentProcessID: input.ID,
|
|
}, nil
|
|
}
|
|
func (r *Resolver) ListRiskAssessmentThreatsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListRiskAssessmentThreatsInput) (*mcp.CallToolResult, types.ListRiskAssessmentThreatsOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScopeID, probo.ActionRiskAssessmentThreatList)
|
|
if err != nil {
|
|
return nil, types.ListRiskAssessmentThreatsOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.RiskAssessmentThreatOrderField]{
|
|
Field: coredata.RiskAssessmentThreatOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.RiskAssessmentThreatOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := r.riskManagement.ListThreatsForScopeID(ctx, scope, input.RiskAssessmentScopeID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list risk assessment threats: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListRiskAssessmentThreatsOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetRiskAssessmentThreatTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetRiskAssessmentThreatInput) (*mcp.CallToolResult, types.GetRiskAssessmentThreatOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentThreatGet)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentThreatOutput{}, err
|
|
}
|
|
|
|
t, err := r.riskManagement.GetThreat(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentThreatOutput{}, fmt.Errorf("failed to get risk assessment threat: %w", err)
|
|
}
|
|
|
|
return nil, types.GetRiskAssessmentThreatOutput{
|
|
RiskAssessmentThreat: types.NewRiskAssessmentThreat(t),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddRiskAssessmentThreatTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddRiskAssessmentThreatInput) (*mcp.CallToolResult, types.AddRiskAssessmentThreatOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScopeID, probo.ActionRiskAssessmentThreatCreate)
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentThreatOutput{}, err
|
|
}
|
|
|
|
t, err := r.riskManagement.CreateThreat(ctx, scope, riskmanagement.CreateRiskAssessmentThreatRequest{
|
|
RiskAssessmentScopeID: input.RiskAssessmentScopeID,
|
|
ProcessID: input.ProcessID,
|
|
Name: input.Name,
|
|
Category: input.Category,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentThreatOutput{}, fmt.Errorf("failed to create risk assessment threat: %w", err)
|
|
}
|
|
|
|
return nil, types.AddRiskAssessmentThreatOutput{
|
|
RiskAssessmentThreat: types.NewRiskAssessmentThreat(t),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateRiskAssessmentThreatTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateRiskAssessmentThreatInput) (*mcp.CallToolResult, types.UpdateRiskAssessmentThreatOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentThreatUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentThreatOutput{}, err
|
|
}
|
|
|
|
t, err := r.riskManagement.UpdateThreat(ctx, scope, riskmanagement.UpdateRiskAssessmentThreatRequest{
|
|
ID: input.ID,
|
|
ProcessID: input.ProcessID,
|
|
Name: input.Name,
|
|
Category: input.Category,
|
|
})
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentThreatOutput{}, fmt.Errorf("failed to update risk assessment threat: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateRiskAssessmentThreatOutput{
|
|
RiskAssessmentThreat: types.NewRiskAssessmentThreat(t),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteRiskAssessmentThreatTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteRiskAssessmentThreatInput) (*mcp.CallToolResult, types.DeleteRiskAssessmentThreatOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentThreatDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteRiskAssessmentThreatOutput{}, err
|
|
}
|
|
|
|
if err := r.riskManagement.DeleteThreat(ctx, scope, input.ID); err != nil {
|
|
return nil, types.DeleteRiskAssessmentThreatOutput{}, fmt.Errorf("failed to delete risk assessment threat: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteRiskAssessmentThreatOutput{
|
|
DeletedRiskAssessmentThreatID: input.ID,
|
|
}, nil
|
|
}
|
|
func (r *Resolver) ListRiskAssessmentScenariosTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListRiskAssessmentScenariosInput) (*mcp.CallToolResult, types.ListRiskAssessmentScenariosOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScopeID, probo.ActionRiskAssessmentScenarioList)
|
|
if err != nil {
|
|
return nil, types.ListRiskAssessmentScenariosOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.RiskAssessmentScenarioOrderField]{
|
|
Field: coredata.RiskAssessmentScenarioOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.RiskAssessmentScenarioOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := r.riskManagement.ListScenariosForScopeID(ctx, scope, input.RiskAssessmentScopeID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list risk assessment scenarios: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListRiskAssessmentScenariosOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetRiskAssessmentScenarioTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetRiskAssessmentScenarioInput) (*mcp.CallToolResult, types.GetRiskAssessmentScenarioOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentScenarioGet)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentScenarioOutput{}, err
|
|
}
|
|
|
|
s, err := r.riskManagement.GetScenario(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentScenarioOutput{}, fmt.Errorf("failed to get risk assessment scenario: %w", err)
|
|
}
|
|
|
|
return nil, types.GetRiskAssessmentScenarioOutput{
|
|
RiskAssessmentScenario: types.NewRiskAssessmentScenario(s),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddRiskAssessmentScenarioTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddRiskAssessmentScenarioInput) (*mcp.CallToolResult, types.AddRiskAssessmentScenarioOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScopeID, probo.ActionRiskAssessmentScenarioCreate)
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentScenarioOutput{}, err
|
|
}
|
|
|
|
s, err := r.riskManagement.CreateScenario(ctx, scope, riskmanagement.CreateRiskAssessmentScenarioRequest{
|
|
RiskAssessmentScopeID: input.RiskAssessmentScopeID,
|
|
Name: input.Name,
|
|
Description: input.Description,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentScenarioOutput{}, fmt.Errorf("failed to create risk assessment scenario: %w", err)
|
|
}
|
|
|
|
return nil, types.AddRiskAssessmentScenarioOutput{
|
|
RiskAssessmentScenario: types.NewRiskAssessmentScenario(s),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateRiskAssessmentScenarioTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateRiskAssessmentScenarioInput) (*mcp.CallToolResult, types.UpdateRiskAssessmentScenarioOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentScenarioUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentScenarioOutput{}, err
|
|
}
|
|
|
|
s, err := r.riskManagement.UpdateScenario(ctx, scope, riskmanagement.UpdateRiskAssessmentScenarioRequest{
|
|
ID: input.ID,
|
|
Name: input.Name,
|
|
Description: UnwrapOmittable(input.Description),
|
|
})
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentScenarioOutput{}, fmt.Errorf("failed to update risk assessment scenario: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateRiskAssessmentScenarioOutput{
|
|
RiskAssessmentScenario: types.NewRiskAssessmentScenario(s),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteRiskAssessmentScenarioTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteRiskAssessmentScenarioInput) (*mcp.CallToolResult, types.DeleteRiskAssessmentScenarioOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentScenarioDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteRiskAssessmentScenarioOutput{}, err
|
|
}
|
|
|
|
if err := r.riskManagement.DeleteScenario(ctx, scope, input.ID); err != nil {
|
|
return nil, types.DeleteRiskAssessmentScenarioOutput{}, fmt.Errorf("failed to delete risk assessment scenario: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteRiskAssessmentScenarioOutput{
|
|
DeletedRiskAssessmentScenarioID: input.ID,
|
|
}, nil
|
|
}
|
|
func (r *Resolver) LinkRiskAssessmentScenarioThreatTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkRiskAssessmentScenarioThreatInput) (*mcp.CallToolResult, types.LinkRiskAssessmentScenarioThreatOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScenarioID, probo.ActionRiskAssessmentScenarioThreatLink)
|
|
if err != nil {
|
|
return nil, types.LinkRiskAssessmentScenarioThreatOutput{}, err
|
|
}
|
|
|
|
err = r.riskManagement.LinkScenarioThreat(ctx, scope, riskmanagement.LinkRiskAssessmentScenarioThreatRequest{
|
|
RiskAssessmentScenarioID: input.RiskAssessmentScenarioID,
|
|
ThreatID: input.ThreatID,
|
|
})
|
|
if err != nil {
|
|
return nil, types.LinkRiskAssessmentScenarioThreatOutput{}, fmt.Errorf("failed to link scenario threat: %w", err)
|
|
}
|
|
|
|
return nil, types.LinkRiskAssessmentScenarioThreatOutput{}, nil
|
|
}
|
|
|
|
func (r *Resolver) UnlinkRiskAssessmentScenarioThreatTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkRiskAssessmentScenarioThreatInput) (*mcp.CallToolResult, types.UnlinkRiskAssessmentScenarioThreatOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScenarioID, probo.ActionRiskAssessmentScenarioThreatUnlink)
|
|
if err != nil {
|
|
return nil, types.UnlinkRiskAssessmentScenarioThreatOutput{}, err
|
|
}
|
|
|
|
if err := r.riskManagement.UnlinkScenarioThreat(
|
|
ctx,
|
|
scope,
|
|
riskmanagement.UnlinkRiskAssessmentScenarioThreatRequest{
|
|
RiskAssessmentScenarioID: input.RiskAssessmentScenarioID,
|
|
ThreatID: input.ThreatID,
|
|
},
|
|
); err != nil {
|
|
return nil, types.UnlinkRiskAssessmentScenarioThreatOutput{}, fmt.Errorf("failed to unlink scenario threat: %w", err)
|
|
}
|
|
|
|
return nil, types.UnlinkRiskAssessmentScenarioThreatOutput{}, nil
|
|
}
|
|
|
|
func (r *Resolver) LinkRiskAssessmentScenarioRiskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.LinkRiskAssessmentScenarioRiskInput) (*mcp.CallToolResult, types.LinkRiskAssessmentScenarioRiskOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScenarioID, probo.ActionRiskAssessmentScenarioRiskLink)
|
|
if err != nil {
|
|
return nil, types.LinkRiskAssessmentScenarioRiskOutput{}, err
|
|
}
|
|
|
|
if err := r.riskManagement.LinkScenarioRisk(
|
|
ctx,
|
|
scope,
|
|
riskmanagement.LinkRiskAssessmentScenarioRiskRequest{
|
|
RiskAssessmentScenarioID: input.RiskAssessmentScenarioID,
|
|
RiskID: input.RiskID,
|
|
},
|
|
); err != nil {
|
|
return nil, types.LinkRiskAssessmentScenarioRiskOutput{}, fmt.Errorf("failed to link scenario risk: %w", err)
|
|
}
|
|
|
|
return nil, types.LinkRiskAssessmentScenarioRiskOutput{}, nil
|
|
}
|
|
|
|
func (r *Resolver) UnlinkRiskAssessmentScenarioRiskTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnlinkRiskAssessmentScenarioRiskInput) (*mcp.CallToolResult, types.UnlinkRiskAssessmentScenarioRiskOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScenarioID, probo.ActionRiskAssessmentScenarioRiskUnlink)
|
|
if err != nil {
|
|
return nil, types.UnlinkRiskAssessmentScenarioRiskOutput{}, err
|
|
}
|
|
|
|
if err := r.riskManagement.UnlinkScenarioRisk(
|
|
ctx,
|
|
scope,
|
|
riskmanagement.UnlinkRiskAssessmentScenarioRiskRequest{
|
|
RiskAssessmentScenarioID: input.RiskAssessmentScenarioID,
|
|
RiskID: input.RiskID,
|
|
},
|
|
); err != nil {
|
|
return nil, types.UnlinkRiskAssessmentScenarioRiskOutput{}, fmt.Errorf("failed to unlink scenario risk: %w", err)
|
|
}
|
|
|
|
return nil, types.UnlinkRiskAssessmentScenarioRiskOutput{}, nil
|
|
}
|
|
|
|
func (r *Resolver) GetRiskAssessmentScopeMermaidChartTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetRiskAssessmentScopeMermaidChartInput) (*mcp.CallToolResult, types.GetRiskAssessmentScopeMermaidChartOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentScopeGet)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentScopeMermaidChartOutput{}, err
|
|
}
|
|
|
|
chart, err := r.riskManagement.BuildScopeMermaidChart(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentScopeMermaidChartOutput{}, fmt.Errorf("failed to build mermaid chart: %w", err)
|
|
}
|
|
|
|
return nil, types.GetRiskAssessmentScopeMermaidChartOutput{
|
|
MermaidChart: chart,
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) ListRiskAssessmentBoundariesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListRiskAssessmentBoundariesInput) (*mcp.CallToolResult, types.ListRiskAssessmentBoundariesOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScopeID, probo.ActionRiskAssessmentBoundaryList)
|
|
if err != nil {
|
|
return nil, types.ListRiskAssessmentBoundariesOutput{}, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.RiskAssessmentBoundaryOrderField]{
|
|
Field: coredata.RiskAssessmentBoundaryOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
if input.OrderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.RiskAssessmentBoundaryOrderField]{
|
|
Field: input.OrderBy.Field,
|
|
Direction: input.OrderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy)
|
|
|
|
p, err := r.riskManagement.ListBoundariesForScopeID(ctx, scope, input.RiskAssessmentScopeID, cursor)
|
|
if err != nil {
|
|
panic(fmt.Errorf("cannot list risk assessment boundaries: %w", err))
|
|
}
|
|
|
|
return nil, types.NewListRiskAssessmentBoundariesOutput(p), nil
|
|
}
|
|
|
|
func (r *Resolver) GetRiskAssessmentBoundaryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetRiskAssessmentBoundaryInput) (*mcp.CallToolResult, types.GetRiskAssessmentBoundaryOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentBoundaryGet)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentBoundaryOutput{}, err
|
|
}
|
|
|
|
b, err := r.riskManagement.GetBoundary(ctx, scope, input.ID)
|
|
if err != nil {
|
|
return nil, types.GetRiskAssessmentBoundaryOutput{}, fmt.Errorf("failed to get risk assessment boundary: %w", err)
|
|
}
|
|
|
|
return nil, types.GetRiskAssessmentBoundaryOutput{
|
|
RiskAssessmentBoundary: types.NewRiskAssessmentBoundary(b),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) AddRiskAssessmentBoundaryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddRiskAssessmentBoundaryInput) (*mcp.CallToolResult, types.AddRiskAssessmentBoundaryOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.RiskAssessmentScopeID, probo.ActionRiskAssessmentBoundaryCreate)
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentBoundaryOutput{}, err
|
|
}
|
|
|
|
b, err := r.riskManagement.CreateBoundary(ctx, scope, riskmanagement.CreateRiskAssessmentBoundaryRequest{
|
|
RiskAssessmentScopeID: input.RiskAssessmentScopeID,
|
|
ParentBoundaryID: input.ParentBoundaryID,
|
|
Name: input.Name,
|
|
})
|
|
if err != nil {
|
|
return nil, types.AddRiskAssessmentBoundaryOutput{}, fmt.Errorf("failed to create risk assessment boundary: %w", err)
|
|
}
|
|
|
|
return nil, types.AddRiskAssessmentBoundaryOutput{
|
|
RiskAssessmentBoundary: types.NewRiskAssessmentBoundary(b),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) UpdateRiskAssessmentBoundaryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateRiskAssessmentBoundaryInput) (*mcp.CallToolResult, types.UpdateRiskAssessmentBoundaryOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentBoundaryUpdate)
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentBoundaryOutput{}, err
|
|
}
|
|
|
|
var parentBoundaryID **gid.GID
|
|
if input.ParentBoundaryID != nil {
|
|
parentBoundaryID = &input.ParentBoundaryID
|
|
}
|
|
|
|
b, err := r.riskManagement.UpdateBoundary(ctx, scope, riskmanagement.UpdateRiskAssessmentBoundaryRequest{
|
|
ID: input.ID,
|
|
ParentBoundaryID: parentBoundaryID,
|
|
Name: input.Name,
|
|
})
|
|
if err != nil {
|
|
return nil, types.UpdateRiskAssessmentBoundaryOutput{}, fmt.Errorf("failed to update risk assessment boundary: %w", err)
|
|
}
|
|
|
|
return nil, types.UpdateRiskAssessmentBoundaryOutput{
|
|
RiskAssessmentBoundary: types.NewRiskAssessmentBoundary(b),
|
|
}, nil
|
|
}
|
|
|
|
func (r *Resolver) DeleteRiskAssessmentBoundaryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteRiskAssessmentBoundaryInput) (*mcp.CallToolResult, types.DeleteRiskAssessmentBoundaryOutput, error) {
|
|
scope, err := r.Authorize(ctx, input.ID, probo.ActionRiskAssessmentBoundaryDelete)
|
|
if err != nil {
|
|
return nil, types.DeleteRiskAssessmentBoundaryOutput{}, err
|
|
}
|
|
|
|
if err := r.riskManagement.DeleteBoundary(ctx, scope, input.ID); err != nil {
|
|
return nil, types.DeleteRiskAssessmentBoundaryOutput{}, fmt.Errorf("failed to delete risk assessment boundary: %w", err)
|
|
}
|
|
|
|
return nil, types.DeleteRiskAssessmentBoundaryOutput{
|
|
DeletedRiskAssessmentBoundaryID: input.ID,
|
|
}, nil
|
|
}
|