Files
probo/pkg/server/api/console/v1/vendor_resolvers.go
Aurélien Sibiril 509d0c88b1 Add vendor assessment agent
Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-04-24 08:43:14 +02:00

1111 lines
41 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.87
import (
"context"
"errors"
"fmt"
"time"
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/validator"
)
// CreateVendor is the resolver for the createVendor field.
func (r *mutationResolver) CreateVendor(ctx context.Context, input types.CreateVendorInput) (*types.CreateVendorPayload, error) {
if err := r.authorize(ctx, input.OrganizationID, probo.ActionVendorCreate); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
vendor, err := prb.Vendors.Create(
ctx,
probo.CreateVendorRequest{
OrganizationID: input.OrganizationID,
Name: input.Name,
Description: input.Description,
StatusPageURL: input.StatusPageURL,
TermsOfServiceURL: input.TermsOfServiceURL,
PrivacyPolicyURL: input.PrivacyPolicyURL,
ServiceLevelAgreementURL: input.ServiceLevelAgreementURL,
LegalName: input.LegalName,
HeadquarterAddress: input.HeadquarterAddress,
WebsiteURL: input.WebsiteURL,
Category: input.Category,
DataProcessingAgreementURL: input.DataProcessingAgreementURL,
BusinessAssociateAgreementURL: input.BusinessAssociateAgreementURL,
SubprocessorsListURL: input.SubprocessorsListURL,
Certifications: input.Certifications,
SecurityPageURL: input.SecurityPageURL,
TrustPageURL: input.TrustPageURL,
BusinessOwnerID: input.BusinessOwnerID,
SecurityOwnerID: input.SecurityOwnerID,
Countries: input.Countries,
},
)
if err != nil {
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
return nil, gqlutils.Conflict(ctx, err)
}
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
}
r.logger.ErrorCtx(ctx, "cannot create vendor", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.CreateVendorPayload{
VendorEdge: types.NewVendorEdge(vendor, coredata.VendorOrderFieldName),
}, nil
}
// UpdateVendor is the resolver for the updateVendor field.
func (r *mutationResolver) UpdateVendor(ctx context.Context, input types.UpdateVendorInput) (*types.UpdateVendorPayload, error) {
if err := r.authorize(ctx, input.ID, probo.ActionVendorUpdate); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.ID.TenantID())
vendor, err := prb.Vendors.Update(
ctx,
probo.UpdateVendorRequest{
ID: input.ID,
Name: input.Name,
Description: gqlutils.UnwrapOmittable(input.Description),
StatusPageURL: gqlutils.UnwrapOmittable(input.StatusPageURL),
TermsOfServiceURL: gqlutils.UnwrapOmittable(input.TermsOfServiceURL),
PrivacyPolicyURL: gqlutils.UnwrapOmittable(input.PrivacyPolicyURL),
ServiceLevelAgreementURL: gqlutils.UnwrapOmittable(input.ServiceLevelAgreementURL),
DataProcessingAgreementURL: gqlutils.UnwrapOmittable(input.DataProcessingAgreementURL),
BusinessAssociateAgreementURL: gqlutils.UnwrapOmittable(input.BusinessAssociateAgreementURL),
SubprocessorsListURL: gqlutils.UnwrapOmittable(input.SubprocessorsListURL),
SecurityPageURL: gqlutils.UnwrapOmittable(input.SecurityPageURL),
TrustPageURL: gqlutils.UnwrapOmittable(input.TrustPageURL),
HeadquarterAddress: gqlutils.UnwrapOmittable(input.HeadquarterAddress),
LegalName: gqlutils.UnwrapOmittable(input.LegalName),
WebsiteURL: gqlutils.UnwrapOmittable(input.WebsiteURL),
Category: input.Category,
Certifications: input.Certifications,
BusinessOwnerID: gqlutils.UnwrapOmittable(input.BusinessOwnerID),
SecurityOwnerID: gqlutils.UnwrapOmittable(input.SecurityOwnerID),
ShowOnTrustCenter: input.ShowOnTrustCenter,
Countries: input.Countries,
},
)
if err != nil {
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
}
r.logger.ErrorCtx(ctx, "cannot update vendor", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.UpdateVendorPayload{
Vendor: types.NewVendor(vendor),
}, nil
}
// DeleteVendor is the resolver for the deleteVendor field.
func (r *mutationResolver) DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (*types.DeleteVendorPayload, error) {
if err := r.authorize(ctx, input.VendorID, probo.ActionVendorDelete); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.VendorID.TenantID())
err := prb.Vendors.Delete(ctx, input.VendorID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot delete vendor", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.DeleteVendorPayload{
DeletedVendorID: input.VendorID,
}, nil
}
// CreateVendorContact is the resolver for the createVendorContact field.
func (r *mutationResolver) CreateVendorContact(ctx context.Context, input types.CreateVendorContactInput) (*types.CreateVendorContactPayload, error) {
if err := r.authorize(ctx, input.VendorID, probo.ActionVendorContactCreate); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.VendorID.TenantID())
req := probo.CreateVendorContactRequest{
VendorID: input.VendorID,
FullName: input.FullName,
Email: input.Email,
Phone: input.Phone,
Role: input.Role,
}
vendorContact, err := prb.VendorContacts.Create(ctx, req)
if err != nil {
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
}
r.logger.ErrorCtx(ctx, "cannot create vendor contact", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.CreateVendorContactPayload{
VendorContactEdge: types.NewVendorContactEdge(vendorContact, coredata.VendorContactOrderFieldCreatedAt),
}, nil
}
// UpdateVendorContact is the resolver for the updateVendorContact field.
func (r *mutationResolver) UpdateVendorContact(ctx context.Context, input types.UpdateVendorContactInput) (*types.UpdateVendorContactPayload, error) {
if err := r.authorize(ctx, input.ID, probo.ActionVendorContactUpdate); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.ID.TenantID())
req := probo.UpdateVendorContactRequest{
ID: input.ID,
FullName: gqlutils.UnwrapOmittable(input.FullName),
Email: gqlutils.UnwrapOmittable(input.Email),
Phone: gqlutils.UnwrapOmittable(input.Phone),
Role: gqlutils.UnwrapOmittable(input.Role),
}
vendorContact, err := prb.VendorContacts.Update(ctx, req)
if err != nil {
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
}
r.logger.ErrorCtx(ctx, "cannot update vendor contact", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.UpdateVendorContactPayload{
VendorContact: types.NewVendorContact(vendorContact),
}, nil
}
// DeleteVendorContact is the resolver for the deleteVendorContact field.
func (r *mutationResolver) DeleteVendorContact(ctx context.Context, input types.DeleteVendorContactInput) (*types.DeleteVendorContactPayload, error) {
if err := r.authorize(ctx, input.VendorContactID, probo.ActionVendorContactDelete); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.VendorContactID.TenantID())
err := prb.VendorContacts.Delete(ctx, input.VendorContactID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot delete vendor contact", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.DeleteVendorContactPayload{
DeletedVendorContactID: input.VendorContactID,
}, nil
}
// CreateVendorService is the resolver for the createVendorService field.
func (r *mutationResolver) CreateVendorService(ctx context.Context, input types.CreateVendorServiceInput) (*types.CreateVendorServicePayload, error) {
if err := r.authorize(ctx, input.VendorID, probo.ActionVendorServiceCreate); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.VendorID.TenantID())
req := probo.CreateVendorServiceRequest{
VendorID: input.VendorID,
Name: input.Name,
Description: input.Description,
}
vendorService, err := prb.VendorServices.Create(ctx, req)
if err != nil {
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
}
r.logger.ErrorCtx(ctx, "cannot create vendor service", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.CreateVendorServicePayload{
VendorServiceEdge: types.NewVendorServiceEdge(vendorService, coredata.VendorServiceOrderFieldCreatedAt),
}, nil
}
// UpdateVendorService is the resolver for the updateVendorService field.
func (r *mutationResolver) UpdateVendorService(ctx context.Context, input types.UpdateVendorServiceInput) (*types.UpdateVendorServicePayload, error) {
if err := r.authorize(ctx, input.ID, probo.ActionVendorServiceUpdate); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.ID.TenantID())
req := probo.UpdateVendorServiceRequest{
ID: input.ID,
Name: input.Name,
Description: gqlutils.UnwrapOmittable(input.Description),
}
vendorService, err := prb.VendorServices.Update(ctx, req)
if err != nil {
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
}
r.logger.ErrorCtx(ctx, "cannot update vendor service", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.UpdateVendorServicePayload{
VendorService: types.NewVendorService(vendorService),
}, nil
}
// DeleteVendorService is the resolver for the deleteVendorService field.
func (r *mutationResolver) DeleteVendorService(ctx context.Context, input types.DeleteVendorServiceInput) (*types.DeleteVendorServicePayload, error) {
if err := r.authorize(ctx, input.VendorServiceID, probo.ActionVendorServiceDelete); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.VendorServiceID.TenantID())
err := prb.VendorServices.Delete(ctx, input.VendorServiceID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot delete vendor service", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.DeleteVendorServicePayload{
DeletedVendorServiceID: input.VendorServiceID,
}, nil
}
// UploadVendorComplianceReport is the resolver for the uploadVendorComplianceReport field.
func (r *mutationResolver) UploadVendorComplianceReport(ctx context.Context, input types.UploadVendorComplianceReportInput) (*types.UploadVendorComplianceReportPayload, error) {
if err := r.authorize(ctx, input.VendorID, probo.ActionVendorComplianceReportUpload); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.VendorID.TenantID())
vendorComplianceReport, err := prb.VendorComplianceReports.Upload(
ctx,
input.VendorID,
&probo.VendorComplianceReportCreateRequest{
File: probo.FileUpload{Filename: input.File.Filename, Size: input.File.Size, Content: input.File.File, ContentType: input.File.ContentType},
ReportDate: input.ReportDate,
ValidUntil: input.ValidUntil,
ReportName: input.ReportName,
},
)
if err != nil {
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
}
r.logger.ErrorCtx(ctx, "cannot upload vendor compliance report", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.UploadVendorComplianceReportPayload{
VendorComplianceReportEdge: types.NewVendorComplianceReportEdge(vendorComplianceReport, coredata.VendorComplianceReportOrderFieldCreatedAt),
}, nil
}
// DeleteVendorComplianceReport is the resolver for the deleteVendorComplianceReport field.
func (r *mutationResolver) DeleteVendorComplianceReport(ctx context.Context, input types.DeleteVendorComplianceReportInput) (*types.DeleteVendorComplianceReportPayload, error) {
if err := r.authorize(ctx, input.ReportID, probo.ActionVendorComplianceReportDelete); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.ReportID.TenantID())
err := prb.VendorComplianceReports.Delete(ctx, input.ReportID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot delete vendor compliance report", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.DeleteVendorComplianceReportPayload{
DeletedVendorComplianceReportID: input.ReportID,
}, nil
}
// UploadVendorBusinessAssociateAgreement is the resolver for the uploadVendorBusinessAssociateAgreement field.
func (r *mutationResolver) UploadVendorBusinessAssociateAgreement(ctx context.Context, input types.UploadVendorBusinessAssociateAgreementInput) (*types.UploadVendorBusinessAssociateAgreementPayload, error) {
if err := r.authorize(ctx, input.VendorID, probo.ActionVendorBusinessAssociateAgreementUpload); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.VendorID.TenantID())
vendorBusinessAssociateAgreement, file, err := prb.VendorBusinessAssociateAgreements.Upload(
ctx,
input.VendorID,
&probo.VendorBusinessAssociateAgreementCreateRequest{
File: input.File.File,
ValidFrom: input.ValidFrom,
ValidUntil: input.ValidUntil,
FileName: input.FileName,
},
)
if err != nil {
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
}
r.logger.ErrorCtx(ctx, "cannot upload vendor business associate agreement", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.UploadVendorBusinessAssociateAgreementPayload{
VendorBusinessAssociateAgreement: types.NewVendorBusinessAssociateAgreement(vendorBusinessAssociateAgreement, file),
}, nil
}
// UpdateVendorBusinessAssociateAgreement is the resolver for the updateVendorBusinessAssociateAgreement field.
func (r *mutationResolver) UpdateVendorBusinessAssociateAgreement(ctx context.Context, input types.UpdateVendorBusinessAssociateAgreementInput) (*types.UpdateVendorBusinessAssociateAgreementPayload, error) {
if err := r.authorize(ctx, input.VendorID, probo.ActionVendorBusinessAssociateAgreementUpdate); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.VendorID.TenantID())
vendorBusinessAssociateAgreement, file, err := prb.VendorBusinessAssociateAgreements.Update(
ctx,
input.VendorID,
&probo.VendorBusinessAssociateAgreementUpdateRequest{
ValidFrom: gqlutils.UnwrapOmittable(input.ValidFrom),
ValidUntil: gqlutils.UnwrapOmittable(input.ValidUntil),
},
)
if err != nil {
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
}
r.logger.ErrorCtx(ctx, "cannot update vendor business associate agreement", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.UpdateVendorBusinessAssociateAgreementPayload{
VendorBusinessAssociateAgreement: types.NewVendorBusinessAssociateAgreement(vendorBusinessAssociateAgreement, file),
}, nil
}
// DeleteVendorBusinessAssociateAgreement is the resolver for the deleteVendorBusinessAssociateAgreement field.
func (r *mutationResolver) DeleteVendorBusinessAssociateAgreement(ctx context.Context, input types.DeleteVendorBusinessAssociateAgreementInput) (*types.DeleteVendorBusinessAssociateAgreementPayload, error) {
if err := r.authorize(ctx, input.VendorID, probo.ActionVendorBusinessAssociateAgreementDelete); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.VendorID.TenantID())
err := prb.VendorBusinessAssociateAgreements.DeleteByVendorID(ctx, input.VendorID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot delete vendor business associate agreement", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.DeleteVendorBusinessAssociateAgreementPayload{
DeletedVendorID: input.VendorID,
}, nil
}
// UploadVendorDataPrivacyAgreement is the resolver for the uploadVendorDataPrivacyAgreement field.
func (r *mutationResolver) UploadVendorDataPrivacyAgreement(ctx context.Context, input types.UploadVendorDataPrivacyAgreementInput) (*types.UploadVendorDataPrivacyAgreementPayload, error) {
if err := r.authorize(ctx, input.VendorID, probo.ActionVendorDataPrivacyAgreementUpload); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.VendorID.TenantID())
vendorDataPrivacyAgreement, file, err := prb.VendorDataPrivacyAgreements.Upload(
ctx,
input.VendorID,
&probo.VendorDataPrivacyAgreementCreateRequest{
File: input.File.File,
ValidFrom: input.ValidFrom,
ValidUntil: input.ValidUntil,
FileName: input.FileName,
},
)
if err != nil {
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
}
r.logger.ErrorCtx(ctx, "cannot upload vendor data privacy agreement", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.UploadVendorDataPrivacyAgreementPayload{
VendorDataPrivacyAgreement: types.NewVendorDataPrivacyAgreement(vendorDataPrivacyAgreement, file),
}, nil
}
// UpdateVendorDataPrivacyAgreement is the resolver for the updateVendorDataPrivacyAgreement field.
func (r *mutationResolver) UpdateVendorDataPrivacyAgreement(ctx context.Context, input types.UpdateVendorDataPrivacyAgreementInput) (*types.UpdateVendorDataPrivacyAgreementPayload, error) {
if err := r.authorize(ctx, input.VendorID, probo.ActionVendorDataPrivacyAgreementUpdate); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.VendorID.TenantID())
vendorDataPrivacyAgreement, file, err := prb.VendorDataPrivacyAgreements.Update(
ctx,
input.VendorID,
&probo.VendorDataPrivacyAgreementUpdateRequest{
ValidFrom: gqlutils.UnwrapOmittable(input.ValidFrom),
ValidUntil: gqlutils.UnwrapOmittable(input.ValidUntil),
},
)
if err != nil {
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
}
r.logger.ErrorCtx(ctx, "cannot update vendor data privacy agreement", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.UpdateVendorDataPrivacyAgreementPayload{
VendorDataPrivacyAgreement: types.NewVendorDataPrivacyAgreement(vendorDataPrivacyAgreement, file),
}, nil
}
// DeleteVendorDataPrivacyAgreement is the resolver for the deleteVendorDataPrivacyAgreement field.
func (r *mutationResolver) DeleteVendorDataPrivacyAgreement(ctx context.Context, input types.DeleteVendorDataPrivacyAgreementInput) (*types.DeleteVendorDataPrivacyAgreementPayload, error) {
if err := r.authorize(ctx, input.VendorID, probo.ActionVendorDataPrivacyAgreementDelete); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.VendorID.TenantID())
err := prb.VendorDataPrivacyAgreements.DeleteByVendorID(ctx, input.VendorID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot delete vendor data privacy agreement", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.DeleteVendorDataPrivacyAgreementPayload{
DeletedVendorID: input.VendorID,
}, nil
}
// CreateVendorRiskAssessment is the resolver for the createVendorRiskAssessment field.
func (r *mutationResolver) CreateVendorRiskAssessment(ctx context.Context, input types.CreateVendorRiskAssessmentInput) (*types.CreateVendorRiskAssessmentPayload, error) {
if err := r.authorize(ctx, input.VendorID, probo.ActionVendorRiskAssessmentCreate); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.VendorID.TenantID())
vendorRiskAssessment, err := prb.Vendors.CreateRiskAssessment(
ctx,
probo.CreateVendorRiskAssessmentRequest{
VendorID: input.VendorID,
ExpiresAt: input.ExpiresAt,
DataSensitivity: input.DataSensitivity,
BusinessImpact: input.BusinessImpact,
Notes: input.Notes,
},
)
if err != nil {
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
}
r.logger.ErrorCtx(ctx, "cannot create vendor risk assessment", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.CreateVendorRiskAssessmentPayload{
VendorRiskAssessmentEdge: types.NewVendorRiskAssessmentEdge(vendorRiskAssessment, coredata.VendorRiskAssessmentOrderFieldCreatedAt),
}, nil
}
// AssessVendor is the resolver for the assessVendor field.
func (r *mutationResolver) AssessVendor(ctx context.Context, input types.AssessVendorInput) (*types.AssessVendorPayload, error) {
if err := r.authorize(ctx, input.ID, probo.ActionVendorAssess); err != nil {
return nil, err
}
prb := r.ProboService(ctx, input.ID.TenantID())
result, err := prb.Vendors.Assess(
ctx,
probo.AssessVendorRequest{
ID: input.ID,
WebsiteURL: input.WebsiteURL,
Procedure: input.Procedure,
},
)
if err != nil {
if errors.Is(err, probo.ErrVendorAssessmentDisabled) {
return nil, gqlutils.Unavailable(ctx, probo.ErrVendorAssessmentDisabled)
}
r.logger.ErrorCtx(ctx, "cannot assess vendor", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return &types.AssessVendorPayload{
Vendor: types.NewVendor(result.Vendor),
Report: result.Report,
Subprocessors: types.NewVendorSubprocessors(result.Subprocessors),
}, nil
}
// Organization is the resolver for the organization field.
func (r *vendorResolver) Organization(ctx context.Context, obj *types.Vendor) (*types.Organization, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil {
return nil, err
}
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 *vendorResolver) ComplianceReports(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorComplianceReportOrderBy) (*types.VendorComplianceReportConnection, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionVendorComplianceReportList); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
pageOrderBy := page.OrderBy[coredata.VendorComplianceReportOrderField]{
Field: coredata.VendorComplianceReportOrderFieldReportDate,
Direction: page.OrderDirectionDesc,
}
if orderBy != nil {
pageOrderBy = page.OrderBy[coredata.VendorComplianceReportOrderField]{
Field: orderBy.Field,
Direction: orderBy.Direction,
}
}
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
page, err := prb.VendorComplianceReports.ListForVendorID(ctx, obj.ID, cursor)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot list vendor compliance reports", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewVendorComplianceReportConnection(page), nil
}
// BusinessAssociateAgreement is the resolver for the businessAssociateAgreement field.
func (r *vendorResolver) BusinessAssociateAgreement(ctx context.Context, obj *types.Vendor) (*types.VendorBusinessAssociateAgreement, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionVendorBusinessAssociateAgreementGet); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
vendorBusinessAssociateAgreement, file, err := prb.VendorBusinessAssociateAgreements.GetByVendorID(ctx, obj.ID)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return nil, nil
}
r.logger.ErrorCtx(ctx, "cannot get vendor business associate agreement", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewVendorBusinessAssociateAgreement(vendorBusinessAssociateAgreement, file), nil
}
// DataPrivacyAgreement is the resolver for the dataPrivacyAgreement field.
func (r *vendorResolver) DataPrivacyAgreement(ctx context.Context, obj *types.Vendor) (*types.VendorDataPrivacyAgreement, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionVendorDataPrivacyAgreementGet); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
vendorDataPrivacyAgreement, file, err := prb.VendorDataPrivacyAgreements.GetByVendorID(ctx, obj.ID)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return nil, nil
}
r.logger.ErrorCtx(ctx, "cannot get vendor data privacy agreement", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewVendorDataPrivacyAgreement(vendorDataPrivacyAgreement, file), nil
}
// Contacts is the resolver for the contacts field.
func (r *vendorResolver) Contacts(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorContactOrderBy) (*types.VendorContactConnection, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionVendorContactList); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
pageOrderBy := page.OrderBy[coredata.VendorContactOrderField]{
Field: coredata.VendorContactOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if orderBy != nil {
pageOrderBy = page.OrderBy[coredata.VendorContactOrderField]{
Field: orderBy.Field,
Direction: orderBy.Direction,
}
}
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
page, err := prb.VendorContacts.List(ctx, obj.ID, cursor)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot list vendor contacts", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewVendorContactConnection(page), nil
}
// Services is the resolver for the services field.
func (r *vendorResolver) Services(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorServiceOrderBy) (*types.VendorServiceConnection, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionVendorServiceList); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
pageOrderBy := page.OrderBy[coredata.VendorServiceOrderField]{
Field: coredata.VendorServiceOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if orderBy != nil {
pageOrderBy = page.OrderBy[coredata.VendorServiceOrderField]{
Field: orderBy.Field,
Direction: orderBy.Direction,
}
}
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
page, err := prb.VendorServices.List(ctx, obj.ID, cursor)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot list vendor services", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewVendorServiceConnection(page), nil
}
// RiskAssessments is the resolver for the riskAssessments field.
func (r *vendorResolver) RiskAssessments(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorRiskAssessmentOrder) (*types.VendorRiskAssessmentConnection, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionVendorRiskAssessmentList); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
pageOrderBy := page.OrderBy[coredata.VendorRiskAssessmentOrderField]{
Field: coredata.VendorRiskAssessmentOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
if orderBy != nil {
pageOrderBy = page.OrderBy[coredata.VendorRiskAssessmentOrderField]{
Field: orderBy.Field,
Direction: orderBy.Direction,
}
}
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
page, err := prb.Vendors.ListRiskAssessments(ctx, obj.ID, cursor)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot list vendor risk assessments", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewVendorRiskAssessmentConnection(page), nil
}
// BusinessOwner is the resolver for the businessOwner field.
func (r *vendorResolver) BusinessOwner(ctx context.Context, obj *types.Vendor) (*types.Profile, error) {
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil {
return nil, err
}
if obj.BusinessOwner == nil {
return nil, nil
}
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 *vendorResolver) SecurityOwner(ctx context.Context, obj *types.Vendor) (*types.Profile, error) {
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil {
return nil, err
}
if obj.SecurityOwner == nil {
return nil, nil
}
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
}
// Permission is the resolver for the permission field.
func (r *vendorResolver) Permission(ctx context.Context, obj *types.Vendor, action string) (bool, error) {
return r.Resolver.Permission(ctx, obj, action)
}
// Vendor is the resolver for the vendor field.
func (r *vendorBusinessAssociateAgreementResolver) Vendor(ctx context.Context, obj *types.VendorBusinessAssociateAgreement) (*types.Vendor, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
vendor, err := prb.Vendors.Get(ctx, obj.ID)
if err != nil {
if errors.Is(err, coredata.ErrResourceNotFound) {
return nil, gqlutils.NotFound(ctx, err)
}
return nil, fmt.Errorf("cannot get vendor: %w", err)
}
return types.NewVendor(vendor), nil
}
// FileURL is the resolver for the fileUrl field.
func (r *vendorBusinessAssociateAgreementResolver) FileURL(ctx context.Context, obj *types.VendorBusinessAssociateAgreement) (string, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionFileDownloadUrl); err != nil {
return "", err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
fileURL, err := prb.VendorBusinessAssociateAgreements.GenerateFileURL(ctx, obj.ID, 1*time.Hour)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot generate file URL", log.Error(err))
return "", gqlutils.Internal(ctx)
}
return fileURL, nil
}
// Permission is the resolver for the permission field.
func (r *vendorBusinessAssociateAgreementResolver) Permission(ctx context.Context, obj *types.VendorBusinessAssociateAgreement, action string) (bool, error) {
return r.Resolver.Permission(ctx, obj, action)
}
// Vendor is the resolver for the vendor field.
func (r *vendorComplianceReportResolver) Vendor(ctx context.Context, obj *types.VendorComplianceReport) (*types.Vendor, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
vendor, err := prb.Vendors.Get(ctx, obj.ID)
if err != nil {
if errors.Is(err, coredata.ErrResourceNotFound) {
return nil, gqlutils.NotFound(ctx, err)
}
r.logger.ErrorCtx(ctx, "cannot get vendor", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewVendor(vendor), nil
}
// File is the resolver for the file field.
func (r *vendorComplianceReportResolver) File(ctx context.Context, obj *types.VendorComplianceReport) (*types.File, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionFileGet); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
evidence, err := prb.VendorComplianceReports.Get(ctx, obj.ID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot load evidence", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
if evidence.ReportFileId == nil {
return nil, nil
}
file, err := prb.Files.Get(ctx, *evidence.ReportFileId)
if err != nil {
if errors.Is(err, coredata.ErrResourceNotFound) {
return nil, gqlutils.NotFound(ctx, err)
}
r.logger.ErrorCtx(ctx, "cannot load evidence file", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewFile(file), nil
}
// Permission is the resolver for the permission field.
func (r *vendorComplianceReportResolver) Permission(ctx context.Context, obj *types.VendorComplianceReport, action string) (bool, error) {
return r.Resolver.Permission(ctx, obj, action)
}
// TotalCount is the resolver for the totalCount field.
func (r *vendorConnectionResolver) TotalCount(ctx context.Context, obj *types.VendorConnection) (int, error) {
if err := r.authorize(ctx, obj.ParentID, probo.ActionVendorList); err != nil {
return 0, err
}
prb := r.ProboService(ctx, obj.ParentID.TenantID())
switch obj.Resolver.(type) {
case *organizationResolver:
count, err := prb.Vendors.CountForOrganizationID(ctx, obj.ParentID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot count vendors", log.Error(err))
return 0, gqlutils.Internal(ctx)
}
return count, nil
case *assetResolver:
count, err := prb.Vendors.CountForAssetID(ctx, obj.ParentID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot count vendors", log.Error(err))
return 0, gqlutils.Internal(ctx)
}
return count, nil
case *datumResolver:
count, err := prb.Vendors.CountForDatumID(ctx, obj.ParentID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot count vendors", log.Error(err))
return 0, gqlutils.Internal(ctx)
}
return count, nil
}
r.logger.ErrorCtx(ctx, "unsupported resolver")
return 0, gqlutils.Internal(ctx)
}
// Vendor is the resolver for the vendor field.
func (r *vendorContactResolver) Vendor(ctx context.Context, obj *types.VendorContact) (*types.Vendor, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
// Get the vendor contact to access the VendorID
vendorContact, err := prb.VendorContacts.Get(ctx, obj.ID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot get vendor contact", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
vendor, err := prb.Vendors.Get(ctx, vendorContact.VendorID)
if err != nil {
if errors.Is(err, coredata.ErrResourceNotFound) {
return nil, gqlutils.NotFound(ctx, err)
}
r.logger.ErrorCtx(ctx, "cannot get vendor", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewVendor(vendor), nil
}
// Permission is the resolver for the permission field.
func (r *vendorContactResolver) Permission(ctx context.Context, obj *types.VendorContact, action string) (bool, error) {
return r.Resolver.Permission(ctx, obj, action)
}
// Vendor is the resolver for the vendor field.
func (r *vendorDataPrivacyAgreementResolver) Vendor(ctx context.Context, obj *types.VendorDataPrivacyAgreement) (*types.Vendor, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
vendor, err := prb.Vendors.Get(ctx, obj.ID)
if err != nil {
if errors.Is(err, coredata.ErrResourceNotFound) {
return nil, gqlutils.NotFound(ctx, err)
}
r.logger.ErrorCtx(ctx, "cannot get vendor", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewVendor(vendor), nil
}
// FileURL is the resolver for the fileUrl field.
func (r *vendorDataPrivacyAgreementResolver) FileURL(ctx context.Context, obj *types.VendorDataPrivacyAgreement) (string, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionFileDownloadUrl); err != nil {
return "", err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
fileURL, err := prb.VendorDataPrivacyAgreements.GenerateFileURL(ctx, obj.ID, 1*time.Hour)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot generate file URL", log.Error(err))
return "", gqlutils.Internal(ctx)
}
return fileURL, nil
}
// Permission is the resolver for the permission field.
func (r *vendorDataPrivacyAgreementResolver) Permission(ctx context.Context, obj *types.VendorDataPrivacyAgreement, action string) (bool, error) {
return r.Resolver.Permission(ctx, obj, action)
}
// Vendor is the resolver for the vendor field.
func (r *vendorRiskAssessmentResolver) Vendor(ctx context.Context, obj *types.VendorRiskAssessment) (*types.Vendor, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil {
return nil, err
}
prb := r.ProboService(ctx, obj.ID.TenantID())
vendor, err := prb.Vendors.GetByRiskAssessmentID(ctx, obj.ID)
if err != nil {
if errors.Is(err, coredata.ErrResourceNotFound) {
return nil, gqlutils.NotFound(ctx, err)
}
r.logger.ErrorCtx(ctx, "cannot get vendor", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewVendor(vendor), nil
}
// Permission is the resolver for the permission field.
func (r *vendorRiskAssessmentResolver) Permission(ctx context.Context, obj *types.VendorRiskAssessment, action string) (bool, error) {
return r.Resolver.Permission(ctx, obj, action)
}
// Vendor is the resolver for the vendor field.
func (r *vendorServiceResolver) Vendor(ctx context.Context, obj *types.VendorService) (*types.Vendor, error) {
if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil {
return nil, err
}
loaders := dataloader.FromContext(ctx)
vendor, err := loaders.Vendor.Load(ctx, obj.Vendor.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 vendor", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
return types.NewVendor(vendor), nil
}
// Permission is the resolver for the permission field.
func (r *vendorServiceResolver) Permission(ctx context.Context, obj *types.VendorService, action string) (bool, error) {
return r.Resolver.Permission(ctx, obj, action)
}
// Vendor returns schema.VendorResolver implementation.
func (r *Resolver) Vendor() schema.VendorResolver { return &vendorResolver{r} }
// VendorBusinessAssociateAgreement returns schema.VendorBusinessAssociateAgreementResolver implementation.
func (r *Resolver) VendorBusinessAssociateAgreement() schema.VendorBusinessAssociateAgreementResolver {
return &vendorBusinessAssociateAgreementResolver{r}
}
// VendorComplianceReport returns schema.VendorComplianceReportResolver implementation.
func (r *Resolver) VendorComplianceReport() schema.VendorComplianceReportResolver {
return &vendorComplianceReportResolver{r}
}
// VendorConnection returns schema.VendorConnectionResolver implementation.
func (r *Resolver) VendorConnection() schema.VendorConnectionResolver {
return &vendorConnectionResolver{r}
}
// VendorContact returns schema.VendorContactResolver implementation.
func (r *Resolver) VendorContact() schema.VendorContactResolver { return &vendorContactResolver{r} }
// VendorDataPrivacyAgreement returns schema.VendorDataPrivacyAgreementResolver implementation.
func (r *Resolver) VendorDataPrivacyAgreement() schema.VendorDataPrivacyAgreementResolver {
return &vendorDataPrivacyAgreementResolver{r}
}
// VendorRiskAssessment returns schema.VendorRiskAssessmentResolver implementation.
func (r *Resolver) VendorRiskAssessment() schema.VendorRiskAssessmentResolver {
return &vendorRiskAssessmentResolver{r}
}
// VendorService returns schema.VendorServiceResolver implementation.
func (r *Resolver) VendorService() schema.VendorServiceResolver { return &vendorServiceResolver{r} }
type vendorResolver struct{ *Resolver }
type vendorBusinessAssociateAgreementResolver struct{ *Resolver }
type vendorComplianceReportResolver struct{ *Resolver }
type vendorConnectionResolver struct{ *Resolver }
type vendorContactResolver struct{ *Resolver }
type vendorDataPrivacyAgreementResolver struct{ *Resolver }
type vendorRiskAssessmentResolver struct{ *Resolver }
type vendorServiceResolver struct{ *Resolver }