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>
1323 lines
48 KiB
Go
1323 lines
48 KiB
Go
package console_v1
|
|
|
|
// This file will be automatically regenerated based on the schema, any resolver
|
|
// implementations
|
|
// will be copied through when generating and any unknown code will be moved to the end.
|
|
// Code generated by github.com/99designs/gqlgen version v0.17.90
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
pgx "github.com/jackc/pgx/v5"
|
|
"github.com/vikstrous/dataloadgen"
|
|
"go.gearno.de/kit/log"
|
|
"go.probo.inc/probo/pkg/coredata"
|
|
"go.probo.inc/probo/pkg/iam"
|
|
"go.probo.inc/probo/pkg/page"
|
|
"go.probo.inc/probo/pkg/probo"
|
|
"go.probo.inc/probo/pkg/server/api/console/v1/dataloader"
|
|
"go.probo.inc/probo/pkg/server/api/console/v1/schema"
|
|
"go.probo.inc/probo/pkg/server/api/console/v1/types"
|
|
"go.probo.inc/probo/pkg/server/gqlutils"
|
|
"go.probo.inc/probo/pkg/thirdparty"
|
|
"go.probo.inc/probo/pkg/validator"
|
|
)
|
|
|
|
// CreateThirdParty is the resolver for the createThirdParty field.
|
|
func (r *mutationResolver) CreateThirdParty(ctx context.Context, input types.CreateThirdPartyInput) (*types.CreateThirdPartyPayload, error) {
|
|
scope, err := r.authorize(ctx, input.OrganizationID, probo.ActionThirdPartyCreate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if input.ParentThirdPartyID != nil {
|
|
if _, err := r.authorize(ctx, *input.ParentThirdPartyID, probo.ActionThirdPartyRelationCreate); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
thirdParty, err := r.probo.ThirdParties.Create(
|
|
ctx, scope,
|
|
probo.CreateThirdPartyRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
Name: input.Name,
|
|
Description: input.Description,
|
|
StatusPageURL: input.StatusPageURL,
|
|
TermsOfServiceURL: input.TermsOfServiceURL,
|
|
PrivacyPolicyURL: input.PrivacyPolicyURL,
|
|
ServiceLevelAgreementURL: input.ServiceLevelAgreementURL,
|
|
LegalName: input.LegalName,
|
|
HeadquarterAddress: input.HeadquarterAddress,
|
|
WebsiteURL: input.WebsiteURL,
|
|
Category: input.Category,
|
|
DataProcessingAgreementURL: input.DataProcessingAgreementURL,
|
|
BusinessAssociateAgreementURL: input.BusinessAssociateAgreementURL,
|
|
SubprocessorsListURL: input.SubprocessorsListURL,
|
|
Certifications: input.Certifications,
|
|
SecurityPageURL: input.SecurityPageURL,
|
|
TrustPageURL: input.TrustPageURL,
|
|
BusinessOwnerID: input.BusinessOwnerID,
|
|
SecurityOwnerID: input.SecurityOwnerID,
|
|
Countries: input.Countries,
|
|
ParentThirdPartyID: input.ParentThirdPartyID,
|
|
},
|
|
)
|
|
if err != nil {
|
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
|
return nil, gqlutils.Conflict(ctx, err)
|
|
}
|
|
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot create thirdParty", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.CreateThirdPartyPayload{
|
|
ThirdPartyEdge: types.NewThirdPartyEdge(thirdParty, coredata.ThirdPartyOrderFieldName),
|
|
}, nil
|
|
}
|
|
|
|
// ImportThirdPartyFromCommon is the resolver for the importThirdPartyFromCommon field.
|
|
func (r *mutationResolver) ImportThirdPartyFromCommon(ctx context.Context, input types.ImportThirdPartyFromCommonInput) (*types.ImportThirdPartyFromCommonPayload, error) {
|
|
scope, err := r.authorize(ctx, input.OrganizationID, probo.ActionThirdPartyCreate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdParty, created, err := r.probo.ThirdParties.ImportFromCommon(
|
|
ctx, scope,
|
|
probo.ImportThirdPartyFromCommonRequest{
|
|
OrganizationID: input.OrganizationID,
|
|
CommonThirdPartyID: input.CommonThirdPartyID,
|
|
},
|
|
)
|
|
if err != nil {
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot import thirdParty from common", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.ImportThirdPartyFromCommonPayload{
|
|
ThirdPartyEdge: types.NewThirdPartyEdge(thirdParty, coredata.ThirdPartyOrderFieldName),
|
|
Created: created,
|
|
}, nil
|
|
}
|
|
|
|
// UpdateThirdParty is the resolver for the updateThirdParty field.
|
|
func (r *mutationResolver) UpdateThirdParty(ctx context.Context, input types.UpdateThirdPartyInput) (*types.UpdateThirdPartyPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ID, probo.ActionThirdPartyUpdate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdParty, err := r.probo.ThirdParties.Update(
|
|
ctx, scope,
|
|
probo.UpdateThirdPartyRequest{
|
|
ID: input.ID,
|
|
Name: input.Name,
|
|
Description: gqlutils.UnwrapOmittable(input.Description),
|
|
StatusPageURL: gqlutils.UnwrapOmittable(input.StatusPageURL),
|
|
TermsOfServiceURL: gqlutils.UnwrapOmittable(input.TermsOfServiceURL),
|
|
PrivacyPolicyURL: gqlutils.UnwrapOmittable(input.PrivacyPolicyURL),
|
|
ServiceLevelAgreementURL: gqlutils.UnwrapOmittable(input.ServiceLevelAgreementURL),
|
|
DataProcessingAgreementURL: gqlutils.UnwrapOmittable(input.DataProcessingAgreementURL),
|
|
BusinessAssociateAgreementURL: gqlutils.UnwrapOmittable(input.BusinessAssociateAgreementURL),
|
|
SubprocessorsListURL: gqlutils.UnwrapOmittable(input.SubprocessorsListURL),
|
|
SecurityPageURL: gqlutils.UnwrapOmittable(input.SecurityPageURL),
|
|
TrustPageURL: gqlutils.UnwrapOmittable(input.TrustPageURL),
|
|
HeadquarterAddress: gqlutils.UnwrapOmittable(input.HeadquarterAddress),
|
|
LegalName: gqlutils.UnwrapOmittable(input.LegalName),
|
|
WebsiteURL: gqlutils.UnwrapOmittable(input.WebsiteURL),
|
|
Category: input.Category,
|
|
Certifications: input.Certifications,
|
|
BusinessOwnerID: gqlutils.UnwrapOmittable(input.BusinessOwnerID),
|
|
SecurityOwnerID: gqlutils.UnwrapOmittable(input.SecurityOwnerID),
|
|
ShowOnTrustCenter: input.ShowOnTrustCenter,
|
|
Countries: input.Countries,
|
|
},
|
|
)
|
|
if err != nil {
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot update thirdParty", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.UpdateThirdPartyPayload{
|
|
ThirdParty: types.NewThirdParty(thirdParty),
|
|
}, nil
|
|
}
|
|
|
|
// DeleteThirdParty is the resolver for the deleteThirdParty field.
|
|
func (r *mutationResolver) DeleteThirdParty(ctx context.Context, input types.DeleteThirdPartyInput) (*types.DeleteThirdPartyPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyDelete)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := r.probo.ThirdParties.Delete(ctx, scope, input.ThirdPartyID); err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot delete thirdParty", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.DeleteThirdPartyPayload{
|
|
DeletedThirdPartyID: input.ThirdPartyID,
|
|
}, nil
|
|
}
|
|
|
|
// CreateThirdPartyContact is the resolver for the createThirdPartyContact field.
|
|
func (r *mutationResolver) CreateThirdPartyContact(ctx context.Context, input types.CreateThirdPartyContactInput) (*types.CreateThirdPartyContactPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyContactCreate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req := probo.CreateThirdPartyContactRequest{
|
|
ThirdPartyID: input.ThirdPartyID,
|
|
FullName: input.FullName,
|
|
Email: input.Email,
|
|
Phone: input.Phone,
|
|
Role: input.Role,
|
|
}
|
|
|
|
thirdPartyContact, err := r.probo.ThirdPartyContacts.Create(ctx, scope, req)
|
|
if err != nil {
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot create thirdParty contact", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.CreateThirdPartyContactPayload{
|
|
ThirdPartyContactEdge: types.NewThirdPartyContactEdge(thirdPartyContact, coredata.ThirdPartyContactOrderFieldCreatedAt),
|
|
}, nil
|
|
}
|
|
|
|
// UpdateThirdPartyContact is the resolver for the updateThirdPartyContact field.
|
|
func (r *mutationResolver) UpdateThirdPartyContact(ctx context.Context, input types.UpdateThirdPartyContactInput) (*types.UpdateThirdPartyContactPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ID, probo.ActionThirdPartyContactUpdate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req := probo.UpdateThirdPartyContactRequest{
|
|
ID: input.ID,
|
|
FullName: gqlutils.UnwrapOmittable(input.FullName),
|
|
Email: gqlutils.UnwrapOmittable(input.Email),
|
|
Phone: gqlutils.UnwrapOmittable(input.Phone),
|
|
Role: gqlutils.UnwrapOmittable(input.Role),
|
|
}
|
|
|
|
thirdPartyContact, err := r.probo.ThirdPartyContacts.Update(ctx, scope, req)
|
|
if err != nil {
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot update thirdParty contact", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.UpdateThirdPartyContactPayload{
|
|
ThirdPartyContact: types.NewThirdPartyContact(thirdPartyContact),
|
|
}, nil
|
|
}
|
|
|
|
// DeleteThirdPartyContact is the resolver for the deleteThirdPartyContact field.
|
|
func (r *mutationResolver) DeleteThirdPartyContact(ctx context.Context, input types.DeleteThirdPartyContactInput) (*types.DeleteThirdPartyContactPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ThirdPartyContactID, probo.ActionThirdPartyContactDelete)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := r.probo.ThirdPartyContacts.Delete(ctx, scope, input.ThirdPartyContactID); err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot delete thirdParty contact", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.DeleteThirdPartyContactPayload{
|
|
DeletedThirdPartyContactID: input.ThirdPartyContactID,
|
|
}, nil
|
|
}
|
|
|
|
// CreateThirdPartyService is the resolver for the createThirdPartyService field.
|
|
func (r *mutationResolver) CreateThirdPartyService(ctx context.Context, input types.CreateThirdPartyServiceInput) (*types.CreateThirdPartyServicePayload, error) {
|
|
scope, err := r.authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyServiceCreate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req := probo.CreateThirdPartyServiceRequest{
|
|
ThirdPartyID: input.ThirdPartyID,
|
|
Name: input.Name,
|
|
Description: input.Description,
|
|
}
|
|
|
|
thirdPartyService, err := r.probo.ThirdPartyServices.Create(ctx, scope, req)
|
|
if err != nil {
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot create thirdParty service", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.CreateThirdPartyServicePayload{
|
|
ThirdPartyServiceEdge: types.NewThirdPartyServiceEdge(thirdPartyService, coredata.ThirdPartyServiceOrderFieldCreatedAt),
|
|
}, nil
|
|
}
|
|
|
|
// UpdateThirdPartyService is the resolver for the updateThirdPartyService field.
|
|
func (r *mutationResolver) UpdateThirdPartyService(ctx context.Context, input types.UpdateThirdPartyServiceInput) (*types.UpdateThirdPartyServicePayload, error) {
|
|
scope, err := r.authorize(ctx, input.ID, probo.ActionThirdPartyServiceUpdate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req := probo.UpdateThirdPartyServiceRequest{
|
|
ID: input.ID,
|
|
Name: input.Name,
|
|
Description: gqlutils.UnwrapOmittable(input.Description),
|
|
}
|
|
|
|
thirdPartyService, err := r.probo.ThirdPartyServices.Update(ctx, scope, req)
|
|
if err != nil {
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot update thirdParty service", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.UpdateThirdPartyServicePayload{
|
|
ThirdPartyService: types.NewThirdPartyService(thirdPartyService),
|
|
}, nil
|
|
}
|
|
|
|
// DeleteThirdPartyService is the resolver for the deleteThirdPartyService field.
|
|
func (r *mutationResolver) DeleteThirdPartyService(ctx context.Context, input types.DeleteThirdPartyServiceInput) (*types.DeleteThirdPartyServicePayload, error) {
|
|
scope, err := r.authorize(ctx, input.ThirdPartyServiceID, probo.ActionThirdPartyServiceDelete)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := r.probo.ThirdPartyServices.Delete(ctx, scope, input.ThirdPartyServiceID); err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot delete thirdParty service", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.DeleteThirdPartyServicePayload{
|
|
DeletedThirdPartyServiceID: input.ThirdPartyServiceID,
|
|
}, nil
|
|
}
|
|
|
|
// UploadThirdPartyComplianceReport is the resolver for the uploadThirdPartyComplianceReport field.
|
|
func (r *mutationResolver) UploadThirdPartyComplianceReport(ctx context.Context, input types.UploadThirdPartyComplianceReportInput) (*types.UploadThirdPartyComplianceReportPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyComplianceReportUpload)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdPartyComplianceReport, err := r.probo.ThirdPartyComplianceReports.Upload(
|
|
ctx, scope,
|
|
input.ThirdPartyID,
|
|
&probo.ThirdPartyComplianceReportCreateRequest{
|
|
File: probo.FileUpload{Filename: input.File.Filename, Size: input.File.Size, Content: input.File.File, ContentType: input.File.ContentType},
|
|
ReportDate: input.ReportDate,
|
|
ValidUntil: input.ValidUntil,
|
|
ReportName: input.ReportName,
|
|
},
|
|
)
|
|
if err != nil {
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot upload thirdParty compliance report", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.UploadThirdPartyComplianceReportPayload{
|
|
ThirdPartyComplianceReportEdge: types.NewThirdPartyComplianceReportEdge(thirdPartyComplianceReport, coredata.ThirdPartyComplianceReportOrderFieldCreatedAt),
|
|
}, nil
|
|
}
|
|
|
|
// DeleteThirdPartyComplianceReport is the resolver for the deleteThirdPartyComplianceReport field.
|
|
func (r *mutationResolver) DeleteThirdPartyComplianceReport(ctx context.Context, input types.DeleteThirdPartyComplianceReportInput) (*types.DeleteThirdPartyComplianceReportPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ReportID, probo.ActionThirdPartyComplianceReportDelete)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := r.probo.ThirdPartyComplianceReports.Delete(ctx, scope, input.ReportID); err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot delete thirdParty compliance report", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.DeleteThirdPartyComplianceReportPayload{
|
|
DeletedThirdPartyComplianceReportID: input.ReportID,
|
|
}, nil
|
|
}
|
|
|
|
// UploadThirdPartyBusinessAssociateAgreement is the resolver for the uploadThirdPartyBusinessAssociateAgreement field.
|
|
func (r *mutationResolver) UploadThirdPartyBusinessAssociateAgreement(ctx context.Context, input types.UploadThirdPartyBusinessAssociateAgreementInput) (*types.UploadThirdPartyBusinessAssociateAgreementPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyBusinessAssociateAgreementUpload)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdPartyBusinessAssociateAgreement, _, err := r.probo.ThirdPartyBusinessAssociateAgreements.Upload(
|
|
ctx, scope,
|
|
input.ThirdPartyID,
|
|
&probo.ThirdPartyBusinessAssociateAgreementCreateRequest{
|
|
File: input.File.File,
|
|
ValidFrom: input.ValidFrom,
|
|
ValidUntil: input.ValidUntil,
|
|
FileName: input.FileName,
|
|
},
|
|
)
|
|
if err != nil {
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot upload thirdParty business associate agreement", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.UploadThirdPartyBusinessAssociateAgreementPayload{
|
|
ThirdPartyBusinessAssociateAgreement: types.NewThirdPartyBusinessAssociateAgreement(thirdPartyBusinessAssociateAgreement),
|
|
}, nil
|
|
}
|
|
|
|
// UpdateThirdPartyBusinessAssociateAgreement is the resolver for the updateThirdPartyBusinessAssociateAgreement field.
|
|
func (r *mutationResolver) UpdateThirdPartyBusinessAssociateAgreement(ctx context.Context, input types.UpdateThirdPartyBusinessAssociateAgreementInput) (*types.UpdateThirdPartyBusinessAssociateAgreementPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyBusinessAssociateAgreementUpdate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdPartyBusinessAssociateAgreement, _, err := r.probo.ThirdPartyBusinessAssociateAgreements.Update(
|
|
ctx, scope,
|
|
input.ThirdPartyID,
|
|
&probo.ThirdPartyBusinessAssociateAgreementUpdateRequest{
|
|
ValidFrom: gqlutils.UnwrapOmittable(input.ValidFrom),
|
|
ValidUntil: gqlutils.UnwrapOmittable(input.ValidUntil),
|
|
},
|
|
)
|
|
if err != nil {
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot update thirdParty business associate agreement", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.UpdateThirdPartyBusinessAssociateAgreementPayload{
|
|
ThirdPartyBusinessAssociateAgreement: types.NewThirdPartyBusinessAssociateAgreement(thirdPartyBusinessAssociateAgreement),
|
|
}, nil
|
|
}
|
|
|
|
// DeleteThirdPartyBusinessAssociateAgreement is the resolver for the deleteThirdPartyBusinessAssociateAgreement field.
|
|
func (r *mutationResolver) DeleteThirdPartyBusinessAssociateAgreement(ctx context.Context, input types.DeleteThirdPartyBusinessAssociateAgreementInput) (*types.DeleteThirdPartyBusinessAssociateAgreementPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyBusinessAssociateAgreementDelete)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := r.probo.ThirdPartyBusinessAssociateAgreements.DeleteByThirdPartyID(ctx, scope, input.ThirdPartyID); err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot delete thirdParty business associate agreement", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.DeleteThirdPartyBusinessAssociateAgreementPayload{
|
|
DeletedThirdPartyID: input.ThirdPartyID,
|
|
}, nil
|
|
}
|
|
|
|
// UploadThirdPartyDataPrivacyAgreement is the resolver for the uploadThirdPartyDataPrivacyAgreement field.
|
|
func (r *mutationResolver) UploadThirdPartyDataPrivacyAgreement(ctx context.Context, input types.UploadThirdPartyDataPrivacyAgreementInput) (*types.UploadThirdPartyDataPrivacyAgreementPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyDataPrivacyAgreementUpload)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdPartyDataPrivacyAgreement, _, err := r.probo.ThirdPartyDataPrivacyAgreements.Upload(
|
|
ctx, scope,
|
|
input.ThirdPartyID,
|
|
&probo.ThirdPartyDataPrivacyAgreementCreateRequest{
|
|
File: input.File.File,
|
|
ValidFrom: input.ValidFrom,
|
|
ValidUntil: input.ValidUntil,
|
|
FileName: input.FileName,
|
|
},
|
|
)
|
|
if err != nil {
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot upload thirdParty data privacy agreement", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.UploadThirdPartyDataPrivacyAgreementPayload{
|
|
ThirdPartyDataPrivacyAgreement: types.NewThirdPartyDataPrivacyAgreement(thirdPartyDataPrivacyAgreement),
|
|
}, nil
|
|
}
|
|
|
|
// UpdateThirdPartyDataPrivacyAgreement is the resolver for the updateThirdPartyDataPrivacyAgreement field.
|
|
func (r *mutationResolver) UpdateThirdPartyDataPrivacyAgreement(ctx context.Context, input types.UpdateThirdPartyDataPrivacyAgreementInput) (*types.UpdateThirdPartyDataPrivacyAgreementPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyDataPrivacyAgreementUpdate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdPartyDataPrivacyAgreement, _, err := r.probo.ThirdPartyDataPrivacyAgreements.Update(
|
|
ctx, scope,
|
|
input.ThirdPartyID,
|
|
&probo.ThirdPartyDataPrivacyAgreementUpdateRequest{
|
|
ValidFrom: gqlutils.UnwrapOmittable(input.ValidFrom),
|
|
ValidUntil: gqlutils.UnwrapOmittable(input.ValidUntil),
|
|
},
|
|
)
|
|
if err != nil {
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot update thirdParty data privacy agreement", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.UpdateThirdPartyDataPrivacyAgreementPayload{
|
|
ThirdPartyDataPrivacyAgreement: types.NewThirdPartyDataPrivacyAgreement(thirdPartyDataPrivacyAgreement),
|
|
}, nil
|
|
}
|
|
|
|
// DeleteThirdPartyDataPrivacyAgreement is the resolver for the deleteThirdPartyDataPrivacyAgreement field.
|
|
func (r *mutationResolver) DeleteThirdPartyDataPrivacyAgreement(ctx context.Context, input types.DeleteThirdPartyDataPrivacyAgreementInput) (*types.DeleteThirdPartyDataPrivacyAgreementPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyDataPrivacyAgreementDelete)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := r.probo.ThirdPartyDataPrivacyAgreements.DeleteByThirdPartyID(ctx, scope, input.ThirdPartyID); err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot delete thirdParty data privacy agreement", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.DeleteThirdPartyDataPrivacyAgreementPayload{
|
|
DeletedThirdPartyID: input.ThirdPartyID,
|
|
}, nil
|
|
}
|
|
|
|
// CreateThirdPartyRiskAssessment is the resolver for the createThirdPartyRiskAssessment field.
|
|
func (r *mutationResolver) CreateThirdPartyRiskAssessment(ctx context.Context, input types.CreateThirdPartyRiskAssessmentInput) (*types.CreateThirdPartyRiskAssessmentPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ThirdPartyID, probo.ActionThirdPartyRiskAssessmentCreate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdPartyRiskAssessment, err := r.probo.ThirdParties.CreateRiskAssessment(
|
|
ctx, scope,
|
|
probo.CreateThirdPartyRiskAssessmentRequest{
|
|
ThirdPartyID: input.ThirdPartyID,
|
|
ExpiresAt: input.ExpiresAt,
|
|
DataSensitivity: input.DataSensitivity,
|
|
BusinessImpact: input.BusinessImpact,
|
|
Notes: input.Notes,
|
|
},
|
|
)
|
|
if err != nil {
|
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot create thirdParty risk assessment", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.CreateThirdPartyRiskAssessmentPayload{
|
|
ThirdPartyRiskAssessmentEdge: types.NewThirdPartyRiskAssessmentEdge(thirdPartyRiskAssessment, coredata.ThirdPartyRiskAssessmentOrderFieldCreatedAt),
|
|
}, nil
|
|
}
|
|
|
|
// VetThirdParty is the resolver for the vetThirdParty field.
|
|
func (r *mutationResolver) VetThirdParty(ctx context.Context, input types.VetThirdPartyInput) (*types.VetThirdPartyPayload, error) {
|
|
scope, err := r.authorize(ctx, input.ID, probo.ActionThirdPartyVet)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdParty, err := r.thirdParty.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, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
}
|
|
|
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
return nil, gqlutils.NotFound(ctx, err)
|
|
}
|
|
|
|
if errors.Is(err, thirdparty.ErrVettingDisabled) {
|
|
return nil, gqlutils.Unavailable(ctx, thirdparty.ErrVettingDisabled)
|
|
}
|
|
|
|
if errors.Is(err, thirdparty.ErrVettingInProgress) {
|
|
return nil, gqlutils.Conflict(ctx, thirdparty.ErrVettingInProgress)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot vet thirdParty", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.VetThirdPartyPayload{
|
|
ThirdParty: types.NewThirdParty(thirdParty),
|
|
}, nil
|
|
}
|
|
|
|
// PublishThirdPartyList is the resolver for the publishThirdPartyList field.
|
|
func (r *mutationResolver) PublishThirdPartyList(ctx context.Context, input types.PublishThirdPartyListInput) (*types.PublishThirdPartyListPayload, error) {
|
|
scope, err := r.authorize(ctx, input.OrganizationID, probo.ActionThirdPartyPublish)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
document, documentVersion, err := r.probo.GeneratedDocuments.PublishThirdPartyList(ctx, scope, input.OrganizationID, input.ApproverIds, input.Minor)
|
|
if err != nil {
|
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
|
return nil, gqlutils.Conflict(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot publish thirdParty list", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.PublishThirdPartyListPayload{
|
|
DocumentEdge: types.NewDocumentEdge(document, coredata.DocumentOrderFieldCreatedAt),
|
|
DocumentVersionEdge: types.NewDocumentVersionEdge(documentVersion, coredata.DocumentVersionOrderFieldCreatedAt),
|
|
}, nil
|
|
}
|
|
|
|
// Organization is the resolver for the organization field.
|
|
func (r *thirdPartyResolver) Organization(ctx context.Context, obj *types.ThirdParty) (*types.Organization, error) {
|
|
if _, err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
loaders := dataloader.FromContext(ctx)
|
|
|
|
organization, err := loaders.Organization.Load(ctx, obj.Organization.ID)
|
|
if err != nil {
|
|
if errors.Is(err, coredata.ErrResourceNotFound) || errors.Is(err, dataloadgen.ErrNotFound) {
|
|
return nil, gqlutils.NotFound(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get organization", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewOrganization(organization), nil
|
|
}
|
|
|
|
// ComplianceReports is the resolver for the complianceReports field.
|
|
func (r *thirdPartyResolver) ComplianceReports(ctx context.Context, obj *types.ThirdParty, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ThirdPartyComplianceReportOrderBy) (*types.ThirdPartyComplianceReportConnection, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyComplianceReportList)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ThirdPartyComplianceReportOrderField]{
|
|
Field: coredata.ThirdPartyComplianceReportOrderFieldReportDate,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if orderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ThirdPartyComplianceReportOrderField]{
|
|
Field: orderBy.Field,
|
|
Direction: orderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
page, err := r.probo.ThirdPartyComplianceReports.ListForThirdPartyID(ctx, scope, obj.ID, cursor)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list thirdParty compliance reports", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewThirdPartyComplianceReportConnection(page), nil
|
|
}
|
|
|
|
// BusinessAssociateAgreement is the resolver for the businessAssociateAgreement field.
|
|
func (r *thirdPartyResolver) BusinessAssociateAgreement(ctx context.Context, obj *types.ThirdParty) (*types.ThirdPartyBusinessAssociateAgreement, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyBusinessAssociateAgreementGet)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdPartyBusinessAssociateAgreement, _, err := r.probo.ThirdPartyBusinessAssociateAgreements.GetByThirdPartyID(ctx, scope, obj.ID)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return nil, nil
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get thirdParty business associate agreement", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewThirdPartyBusinessAssociateAgreement(thirdPartyBusinessAssociateAgreement), nil
|
|
}
|
|
|
|
// DataPrivacyAgreement is the resolver for the dataPrivacyAgreement field.
|
|
func (r *thirdPartyResolver) DataPrivacyAgreement(ctx context.Context, obj *types.ThirdParty) (*types.ThirdPartyDataPrivacyAgreement, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyDataPrivacyAgreementGet)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdPartyDataPrivacyAgreement, _, err := r.probo.ThirdPartyDataPrivacyAgreements.GetByThirdPartyID(ctx, scope, obj.ID)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return nil, nil
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get thirdParty data privacy agreement", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewThirdPartyDataPrivacyAgreement(thirdPartyDataPrivacyAgreement), nil
|
|
}
|
|
|
|
// Contacts is the resolver for the contacts field.
|
|
func (r *thirdPartyResolver) Contacts(ctx context.Context, obj *types.ThirdParty, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ThirdPartyContactOrderBy) (*types.ThirdPartyContactConnection, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyContactList)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ThirdPartyContactOrderField]{
|
|
Field: coredata.ThirdPartyContactOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if orderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ThirdPartyContactOrderField]{
|
|
Field: orderBy.Field,
|
|
Direction: orderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
page, err := r.probo.ThirdPartyContacts.List(ctx, scope, obj.ID, cursor)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list thirdParty contacts", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewThirdPartyContactConnection(page), nil
|
|
}
|
|
|
|
// Services is the resolver for the services field.
|
|
func (r *thirdPartyResolver) Services(ctx context.Context, obj *types.ThirdParty, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ThirdPartyServiceOrderBy) (*types.ThirdPartyServiceConnection, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyServiceList)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ThirdPartyServiceOrderField]{
|
|
Field: coredata.ThirdPartyServiceOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if orderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ThirdPartyServiceOrderField]{
|
|
Field: orderBy.Field,
|
|
Direction: orderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
page, err := r.probo.ThirdPartyServices.List(ctx, scope, obj.ID, cursor)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list thirdParty services", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewThirdPartyServiceConnection(page), nil
|
|
}
|
|
|
|
// RiskAssessments is the resolver for the riskAssessments field.
|
|
func (r *thirdPartyResolver) RiskAssessments(ctx context.Context, obj *types.ThirdParty, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ThirdPartyRiskAssessmentOrder) (*types.ThirdPartyRiskAssessmentConnection, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyRiskAssessmentList)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ThirdPartyRiskAssessmentOrderField]{
|
|
Field: coredata.ThirdPartyRiskAssessmentOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
|
|
if orderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ThirdPartyRiskAssessmentOrderField]{
|
|
Field: orderBy.Field,
|
|
Direction: orderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
page, err := r.probo.ThirdParties.ListRiskAssessments(ctx, scope, obj.ID, cursor)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list thirdParty risk assessments", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewThirdPartyRiskAssessmentConnection(page), nil
|
|
}
|
|
|
|
// Measures is the resolver for the measures field.
|
|
func (r *thirdPartyResolver) Measures(ctx context.Context, obj *types.ThirdParty, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) (*types.MeasureConnection, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionMeasureList)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.MeasureOrderField]{
|
|
Field: coredata.MeasureOrderFieldCreatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
if orderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.MeasureOrderField]{
|
|
Field: orderBy.Field,
|
|
Direction: orderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
var measureFilter = coredata.NewMeasureFilter(nil, nil, nil)
|
|
if filter != nil {
|
|
measureFilter = coredata.NewMeasureFilter(filter.Query, filter.State, filter.Category)
|
|
}
|
|
|
|
page, err := r.probo.Measures.ListForThirdPartyID(ctx, scope, obj.ID, cursor, measureFilter)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list third party measures", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewMeasureConnection(page, r, obj.ID, measureFilter), nil
|
|
}
|
|
|
|
// BusinessOwner is the resolver for the businessOwner field.
|
|
func (r *thirdPartyResolver) BusinessOwner(ctx context.Context, obj *types.ThirdParty) (*types.Profile, error) {
|
|
if _, err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if obj.BusinessOwner == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
loaders := dataloader.FromContext(ctx)
|
|
|
|
businessOwner, err := loaders.Profile.Load(ctx, obj.BusinessOwner.ID)
|
|
if err != nil {
|
|
if errors.Is(err, coredata.ErrResourceNotFound) || errors.Is(err, dataloadgen.ErrNotFound) {
|
|
return nil, gqlutils.NotFound(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get business owner", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewProfile(businessOwner), nil
|
|
}
|
|
|
|
// SecurityOwner is the resolver for the securityOwner field.
|
|
func (r *thirdPartyResolver) SecurityOwner(ctx context.Context, obj *types.ThirdParty) (*types.Profile, error) {
|
|
if _, err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if obj.SecurityOwner == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
loaders := dataloader.FromContext(ctx)
|
|
|
|
securityOwner, err := loaders.Profile.Load(ctx, obj.SecurityOwner.ID)
|
|
if err != nil {
|
|
if errors.Is(err, coredata.ErrResourceNotFound) || errors.Is(err, dataloadgen.ErrNotFound) {
|
|
return nil, gqlutils.NotFound(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get security owner", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewProfile(securityOwner), nil
|
|
}
|
|
|
|
// ParentThirdParty is the resolver for the parentThirdParty field.
|
|
func (r *thirdPartyResolver) ParentThirdParty(ctx context.Context, obj *types.ThirdParty) (*types.ThirdParty, error) {
|
|
if obj.ParentThirdParty == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
if _, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyGet); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
loaders := dataloader.FromContext(ctx)
|
|
|
|
parent, err := loaders.ThirdParty.Load(ctx, obj.ParentThirdParty.ID)
|
|
if err != nil {
|
|
if errors.Is(err, coredata.ErrResourceNotFound) || errors.Is(err, dataloadgen.ErrNotFound) {
|
|
return nil, gqlutils.NotFound(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot load parent third party", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewThirdParty(parent), nil
|
|
}
|
|
|
|
// Ancestors is the resolver for the ancestors field.
|
|
func (r *thirdPartyResolver) Ancestors(ctx context.Context, obj *types.ThirdParty) ([]*types.ThirdParty, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyGet)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ancestors, err := r.probo.ThirdParties.GetAncestors(ctx, scope, obj.ID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot load ancestors", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
result := make([]*types.ThirdParty, len(ancestors))
|
|
for i, a := range ancestors {
|
|
result[i] = types.NewThirdParty(a)
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// ChildThirdParties is the resolver for the childThirdParties field.
|
|
func (r *thirdPartyResolver) ChildThirdParties(ctx context.Context, obj *types.ThirdParty, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ThirdPartyOrderBy) (*types.ThirdPartyConnection, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyRelationList)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ThirdPartyOrderField]{
|
|
Field: coredata.ThirdPartyOrderFieldName,
|
|
Direction: page.OrderDirectionAsc,
|
|
}
|
|
if orderBy != nil {
|
|
pageOrderBy = page.OrderBy[coredata.ThirdPartyOrderField]{
|
|
Field: orderBy.Field,
|
|
Direction: orderBy.Direction,
|
|
}
|
|
}
|
|
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
page, err := r.probo.ThirdParties.ListForParentThirdPartyID(ctx, scope, obj.ID, cursor)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list child third parties", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewThirdPartyConnection(page, r, obj.ID, nil), nil
|
|
}
|
|
|
|
// VettingStatus is the resolver for the vettingStatus field.
|
|
func (r *thirdPartyResolver) VettingStatus(ctx context.Context, obj *types.ThirdParty) (*coredata.ThirdPartyVettingStatus, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyGet)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
status, err := r.thirdParty.VettingStatus(ctx, scope, obj.ID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot get vetting status", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return status, nil
|
|
}
|
|
|
|
// Permission is the resolver for the permission field.
|
|
func (r *thirdPartyResolver) Permission(ctx context.Context, obj *types.ThirdParty, action string) (bool, error) {
|
|
return r.Resolver.Permission(ctx, obj, action)
|
|
}
|
|
|
|
// ThirdParty is the resolver for the thirdParty field.
|
|
func (r *thirdPartyBusinessAssociateAgreementResolver) ThirdParty(ctx context.Context, obj *types.ThirdPartyBusinessAssociateAgreement) (*types.ThirdParty, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyGet)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdParty, err := r.probo.ThirdParties.Get(ctx, scope, obj.ID)
|
|
if err != nil {
|
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
return nil, gqlutils.NotFound(ctx, err)
|
|
}
|
|
|
|
return nil, fmt.Errorf("cannot get thirdParty: %w", err)
|
|
}
|
|
|
|
return types.NewThirdParty(thirdParty), nil
|
|
}
|
|
|
|
// File is the resolver for the file field.
|
|
func (r *thirdPartyBusinessAssociateAgreementResolver) File(ctx context.Context, obj *types.ThirdPartyBusinessAssociateAgreement) (*types.File, error) {
|
|
if _, err := r.authorize(ctx, obj.ID, probo.ActionFileGet); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return r.loadFile(ctx, obj.File.ID)
|
|
}
|
|
|
|
// Permission is the resolver for the permission field.
|
|
func (r *thirdPartyBusinessAssociateAgreementResolver) Permission(ctx context.Context, obj *types.ThirdPartyBusinessAssociateAgreement, action string) (bool, error) {
|
|
return r.Resolver.Permission(ctx, obj, action)
|
|
}
|
|
|
|
// ThirdParty is the resolver for the thirdParty field.
|
|
func (r *thirdPartyComplianceReportResolver) ThirdParty(ctx context.Context, obj *types.ThirdPartyComplianceReport) (*types.ThirdParty, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyGet)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdParty, err := r.probo.ThirdParties.Get(ctx, scope, obj.ID)
|
|
if err != nil {
|
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
return nil, gqlutils.NotFound(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get thirdParty", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewThirdParty(thirdParty), nil
|
|
}
|
|
|
|
// File is the resolver for the file field.
|
|
func (r *thirdPartyComplianceReportResolver) File(ctx context.Context, obj *types.ThirdPartyComplianceReport) (*types.File, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionFileGet)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
evidence, err := r.probo.ThirdPartyComplianceReports.Get(ctx, scope, obj.ID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot load evidence", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
if evidence.ReportFileId == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
file, err := r.probo.Files.Get(ctx, scope, *evidence.ReportFileId)
|
|
if err != nil {
|
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
return nil, gqlutils.NotFound(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot load evidence file", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewFile(file, r.fileManager), nil
|
|
}
|
|
|
|
// Permission is the resolver for the permission field.
|
|
func (r *thirdPartyComplianceReportResolver) Permission(ctx context.Context, obj *types.ThirdPartyComplianceReport, action string) (bool, error) {
|
|
return r.Resolver.Permission(ctx, obj, action)
|
|
}
|
|
|
|
// TotalCount is the resolver for the totalCount field.
|
|
func (r *thirdPartyConnectionResolver) TotalCount(ctx context.Context, obj *types.ThirdPartyConnection) (int, error) {
|
|
scope, err := r.authorize(ctx, obj.ParentID, probo.ActionThirdPartyList)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
switch obj.Resolver.(type) {
|
|
case *organizationResolver:
|
|
count, err := r.probo.ThirdParties.CountForOrganizationID(ctx, scope, obj.ParentID, obj.Filters)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot count thirdParties", log.Error(err))
|
|
return 0, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return count, nil
|
|
case *assetResolver:
|
|
count, err := r.probo.ThirdParties.CountForAssetID(ctx, scope, obj.ParentID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot count thirdParties", log.Error(err))
|
|
return 0, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return count, nil
|
|
case *datumResolver:
|
|
count, err := r.probo.ThirdParties.CountForDatumID(ctx, scope, obj.ParentID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot count thirdParties", log.Error(err))
|
|
return 0, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return count, nil
|
|
case *thirdPartyResolver:
|
|
if _, err := r.authorize(ctx, obj.ParentID, probo.ActionThirdPartyRelationList); err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
count, err := r.probo.ThirdParties.CountForParentThirdPartyID(ctx, scope, obj.ParentID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot count child third parties", log.Error(err))
|
|
return 0, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return count, nil
|
|
case *measureResolver:
|
|
count, err := r.probo.ThirdParties.CountForMeasureID(ctx, scope, obj.ParentID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot count thirdParties", log.Error(err))
|
|
return 0, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return count, nil
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "unsupported resolver")
|
|
|
|
return 0, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
// ThirdParty is the resolver for the thirdParty field.
|
|
func (r *thirdPartyContactResolver) ThirdParty(ctx context.Context, obj *types.ThirdPartyContact) (*types.ThirdParty, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyGet)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Get the thirdParty contact to access the ThirdPartyID
|
|
thirdPartyContact, err := r.probo.ThirdPartyContacts.Get(ctx, scope, obj.ID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot get thirdParty contact", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
thirdParty, err := r.probo.ThirdParties.Get(ctx, scope, thirdPartyContact.ThirdPartyID)
|
|
if err != nil {
|
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
return nil, gqlutils.NotFound(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get thirdParty", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewThirdParty(thirdParty), nil
|
|
}
|
|
|
|
// Permission is the resolver for the permission field.
|
|
func (r *thirdPartyContactResolver) Permission(ctx context.Context, obj *types.ThirdPartyContact, action string) (bool, error) {
|
|
return r.Resolver.Permission(ctx, obj, action)
|
|
}
|
|
|
|
// ThirdParty is the resolver for the thirdParty field.
|
|
func (r *thirdPartyDataPrivacyAgreementResolver) ThirdParty(ctx context.Context, obj *types.ThirdPartyDataPrivacyAgreement) (*types.ThirdParty, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyGet)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdParty, err := r.probo.ThirdParties.Get(ctx, scope, obj.ID)
|
|
if err != nil {
|
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
return nil, gqlutils.NotFound(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get thirdParty", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewThirdParty(thirdParty), nil
|
|
}
|
|
|
|
// File is the resolver for the file field.
|
|
func (r *thirdPartyDataPrivacyAgreementResolver) File(ctx context.Context, obj *types.ThirdPartyDataPrivacyAgreement) (*types.File, error) {
|
|
if _, err := r.authorize(ctx, obj.ID, probo.ActionFileGet); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return r.loadFile(ctx, obj.File.ID)
|
|
}
|
|
|
|
// Permission is the resolver for the permission field.
|
|
func (r *thirdPartyDataPrivacyAgreementResolver) Permission(ctx context.Context, obj *types.ThirdPartyDataPrivacyAgreement, action string) (bool, error) {
|
|
return r.Resolver.Permission(ctx, obj, action)
|
|
}
|
|
|
|
// ThirdParty is the resolver for the thirdParty field.
|
|
func (r *thirdPartyRiskAssessmentResolver) ThirdParty(ctx context.Context, obj *types.ThirdPartyRiskAssessment) (*types.ThirdParty, error) {
|
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyGet)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
thirdParty, err := r.probo.ThirdParties.GetByRiskAssessmentID(ctx, scope, obj.ID)
|
|
if err != nil {
|
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
return nil, gqlutils.NotFound(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get thirdParty", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewThirdParty(thirdParty), nil
|
|
}
|
|
|
|
// Permission is the resolver for the permission field.
|
|
func (r *thirdPartyRiskAssessmentResolver) Permission(ctx context.Context, obj *types.ThirdPartyRiskAssessment, action string) (bool, error) {
|
|
return r.Resolver.Permission(ctx, obj, action)
|
|
}
|
|
|
|
// ThirdParty is the resolver for the thirdParty field.
|
|
func (r *thirdPartyServiceResolver) ThirdParty(ctx context.Context, obj *types.ThirdPartyService) (*types.ThirdParty, error) {
|
|
if _, err := r.authorize(ctx, obj.ID, probo.ActionThirdPartyGet); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
loaders := dataloader.FromContext(ctx)
|
|
|
|
thirdParty, err := loaders.ThirdParty.Load(ctx, obj.ThirdParty.ID)
|
|
if err != nil {
|
|
if errors.Is(err, coredata.ErrResourceNotFound) || errors.Is(err, dataloadgen.ErrNotFound) {
|
|
return nil, gqlutils.NotFound(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get thirdParty", log.Error(err))
|
|
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewThirdParty(thirdParty), nil
|
|
}
|
|
|
|
// Permission is the resolver for the permission field.
|
|
func (r *thirdPartyServiceResolver) Permission(ctx context.Context, obj *types.ThirdPartyService, action string) (bool, error) {
|
|
return r.Resolver.Permission(ctx, obj, action)
|
|
}
|
|
|
|
// ThirdParty returns schema.ThirdPartyResolver implementation.
|
|
func (r *Resolver) ThirdParty() schema.ThirdPartyResolver { return &thirdPartyResolver{r} }
|
|
|
|
// ThirdPartyBusinessAssociateAgreement returns schema.ThirdPartyBusinessAssociateAgreementResolver implementation.
|
|
func (r *Resolver) ThirdPartyBusinessAssociateAgreement() schema.ThirdPartyBusinessAssociateAgreementResolver {
|
|
return &thirdPartyBusinessAssociateAgreementResolver{r}
|
|
}
|
|
|
|
// ThirdPartyComplianceReport returns schema.ThirdPartyComplianceReportResolver implementation.
|
|
func (r *Resolver) ThirdPartyComplianceReport() schema.ThirdPartyComplianceReportResolver {
|
|
return &thirdPartyComplianceReportResolver{r}
|
|
}
|
|
|
|
// ThirdPartyConnection returns schema.ThirdPartyConnectionResolver implementation.
|
|
func (r *Resolver) ThirdPartyConnection() schema.ThirdPartyConnectionResolver {
|
|
return &thirdPartyConnectionResolver{r}
|
|
}
|
|
|
|
// ThirdPartyContact returns schema.ThirdPartyContactResolver implementation.
|
|
func (r *Resolver) ThirdPartyContact() schema.ThirdPartyContactResolver {
|
|
return &thirdPartyContactResolver{r}
|
|
}
|
|
|
|
// ThirdPartyDataPrivacyAgreement returns schema.ThirdPartyDataPrivacyAgreementResolver implementation.
|
|
func (r *Resolver) ThirdPartyDataPrivacyAgreement() schema.ThirdPartyDataPrivacyAgreementResolver {
|
|
return &thirdPartyDataPrivacyAgreementResolver{r}
|
|
}
|
|
|
|
// ThirdPartyRiskAssessment returns schema.ThirdPartyRiskAssessmentResolver implementation.
|
|
func (r *Resolver) ThirdPartyRiskAssessment() schema.ThirdPartyRiskAssessmentResolver {
|
|
return &thirdPartyRiskAssessmentResolver{r}
|
|
}
|
|
|
|
// ThirdPartyService returns schema.ThirdPartyServiceResolver implementation.
|
|
func (r *Resolver) ThirdPartyService() schema.ThirdPartyServiceResolver {
|
|
return &thirdPartyServiceResolver{r}
|
|
}
|
|
|
|
type thirdPartyResolver struct{ *Resolver }
|
|
type thirdPartyBusinessAssociateAgreementResolver struct{ *Resolver }
|
|
type thirdPartyComplianceReportResolver struct{ *Resolver }
|
|
type thirdPartyConnectionResolver struct{ *Resolver }
|
|
type thirdPartyContactResolver struct{ *Resolver }
|
|
type thirdPartyDataPrivacyAgreementResolver struct{ *Resolver }
|
|
type thirdPartyRiskAssessmentResolver struct{ *Resolver }
|
|
type thirdPartyServiceResolver struct{ *Resolver }
|