The go-sdk v1.6.0 release no longer applies a default CrossOriginProtection when the field is nil in StreamableHTTPOptions, silently removing Origin header verification. Wrap the streamable handler with http.NewCrossOriginProtection().Handler(...) (the recommended replacement, since the SDK field is deprecated). Also regenerate gqlgen resolvers to track v0.17.90. Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
984 lines
35 KiB
Go
984 lines
35 KiB
Go
package trust_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"
|
|
"encoding/base64"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"go.gearno.de/kit/log"
|
|
"go.probo.inc/probo/pkg/coredata"
|
|
"go.probo.inc/probo/pkg/gid"
|
|
"go.probo.inc/probo/pkg/page"
|
|
"go.probo.inc/probo/pkg/server/api/authn"
|
|
"go.probo.inc/probo/pkg/server/api/compliancepage"
|
|
"go.probo.inc/probo/pkg/server/api/trust/v1/schema"
|
|
"go.probo.inc/probo/pkg/server/api/trust/v1/types"
|
|
"go.probo.inc/probo/pkg/server/gqlutils"
|
|
"go.probo.inc/probo/pkg/trust"
|
|
)
|
|
|
|
// Framework is the resolver for the framework field.
|
|
func (r *auditResolver) Framework(ctx context.Context, obj *types.Audit) (*types.Framework, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
audit, err := trustService.Audits.Get(ctx, obj.ID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot load audit", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
framework, err := trustService.Frameworks.Get(ctx, audit.FrameworkID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot load framework", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewFramework(framework), nil
|
|
}
|
|
|
|
// Report is the resolver for the report field.
|
|
func (r *auditResolver) Report(ctx context.Context, obj *types.Audit) (*types.Report, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
audit, err := trustService.Audits.Get(ctx, obj.ID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot load audit", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
if audit.ReportID == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
|
|
report, err := trustService.Reports.Get(ctx, trustCenter.OrganizationID, *audit.ReportID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot load report", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewReport(report), nil
|
|
}
|
|
|
|
// Framework is the resolver for the framework field on ComplianceFramework.
|
|
func (r *complianceFrameworkResolver) Framework(ctx context.Context, obj *types.ComplianceFramework) (*types.Framework, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
framework, err := trustService.Frameworks.Get(ctx, obj.FrameworkID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot load framework", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewFramework(framework), nil
|
|
}
|
|
|
|
// IsUserAuthorized is the resolver for the isUserAuthorized field.
|
|
func (r *documentResolver) IsUserAuthorized(ctx context.Context, obj *types.Document) (bool, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
|
|
document, err := trustService.Documents.Get(ctx, trustCenter.OrganizationID, obj.ID)
|
|
if err != nil {
|
|
if errors.Is(err, trust.ErrDocumentNotFound) || errors.Is(err, trust.ErrDocumentNotVisible) || errors.Is(err, coredata.ErrResourceNotFound) {
|
|
return false, gqlutils.NotFoundf(ctx, "document %q not found", obj.ID)
|
|
}
|
|
if _, ok := errors.AsType[*trust.ErrDocumentArchived](err); ok {
|
|
return false, gqlutils.NotFoundf(ctx, "document %q not found", obj.ID)
|
|
}
|
|
r.logger.ErrorCtx(ctx, "cannot load document", log.Error(err))
|
|
return false, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
if document.TrustCenterVisibility == coredata.TrustCenterVisibilityPublic {
|
|
return true, nil
|
|
}
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return false, nil
|
|
}
|
|
|
|
documentAccess, err := trustService.TrustCenterAccesses.GetDocumentAccess(
|
|
ctx,
|
|
trustCenter.ID,
|
|
identity.ID,
|
|
obj.ID,
|
|
)
|
|
if err != nil {
|
|
if errors.Is(err, trust.ErrMembershipNotFound) ||
|
|
errors.Is(err, trust.ErrUserNotFound) ||
|
|
errors.Is(err, trust.ErrUserInactive) ||
|
|
errors.Is(err, trust.ErrDocumentAccessNotFound) {
|
|
return false, nil
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot check document access", log.Error(err))
|
|
return false, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return documentAccess.Status == coredata.TrustCenterDocumentAccessStatusGranted, nil
|
|
}
|
|
|
|
// Access is the resolver for the access field.
|
|
func (r *documentResolver) Access(ctx context.Context, obj *types.Document) (*types.DocumentAccess, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, nil // User is not authenticated, so no access requested
|
|
}
|
|
|
|
access, err := trustService.TrustCenterAccesses.GetDocumentAccess(
|
|
ctx,
|
|
trustCenter.ID,
|
|
identity.ID,
|
|
obj.ID,
|
|
)
|
|
if err != nil {
|
|
if errors.Is(err, trust.ErrMembershipNotFound) ||
|
|
errors.Is(err, trust.ErrUserNotFound) ||
|
|
errors.Is(err, trust.ErrDocumentAccessNotFound) {
|
|
return nil, nil
|
|
}
|
|
|
|
if errors.Is(err, trust.ErrUserInactive) {
|
|
return nil, gqlutils.Forbidden(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get document access", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.DocumentAccess{
|
|
ID: access.ID,
|
|
Status: access.Status,
|
|
}, nil
|
|
}
|
|
|
|
// LightLogoURL is the resolver for the lightLogoURL field.
|
|
func (r *frameworkResolver) LightLogoURL(ctx context.Context, obj *types.Framework) (*string, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
return trustService.Frameworks.GenerateLightLogoURL(ctx, obj.ID, 1*time.Hour)
|
|
}
|
|
|
|
// DarkLogoURL is the resolver for the darkLogoURL field.
|
|
func (r *frameworkResolver) DarkLogoURL(ctx context.Context, obj *types.Framework) (*string, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
return trustService.Frameworks.GenerateDarkLogoURL(ctx, obj.ID, 1*time.Hour)
|
|
}
|
|
|
|
// RequestAllAccesses is the resolver for the requestAllAccesses field.
|
|
func (r *mutationResolver) RequestAllAccesses(ctx context.Context) (*types.RequestAccessesPayload, error) {
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, gqlutils.Unauthenticatedf(ctx, "authentication is required to request access")
|
|
}
|
|
|
|
access, err := trustService.TrustCenterAccesses.Request(
|
|
ctx,
|
|
&trust.TrustCenterAccessRequest{
|
|
TrustCenterID: trustCenter.ID,
|
|
IdentityID: identity.ID,
|
|
DocumentIDs: nil,
|
|
ReportIDs: nil,
|
|
},
|
|
)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot create trust center access", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.RequestAccessesPayload{
|
|
TrustCenterAccess: &types.TrustCenterAccess{
|
|
ID: access.ID,
|
|
CreatedAt: access.CreatedAt,
|
|
UpdatedAt: access.UpdatedAt,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// ExportDocumentPDF is the resolver for the exportDocumentPDF field.
|
|
func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.ExportDocumentPDFInput) (*types.ExportDocumentPDFPayload, error) {
|
|
trustService := r.TrustService(ctx, input.DocumentID.TenantID())
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
|
|
document, err := trustService.Documents.Get(ctx, trustCenter.OrganizationID, input.DocumentID)
|
|
if err != nil {
|
|
if errors.Is(err, trust.ErrDocumentNotFound) || errors.Is(err, trust.ErrDocumentNotVisible) || errors.Is(err, coredata.ErrResourceNotFound) {
|
|
return nil, gqlutils.NotFoundf(ctx, "document %q not found", input.DocumentID)
|
|
}
|
|
if _, ok := errors.AsType[*trust.ErrDocumentArchived](err); ok {
|
|
return nil, gqlutils.NotFoundf(ctx, "document %q not found", input.DocumentID)
|
|
}
|
|
r.logger.ErrorCtx(ctx, "cannot load document", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
if document.TrustCenterVisibility == coredata.TrustCenterVisibilityPublic {
|
|
pdf, err := trustService.Documents.ExportPDFWithoutWatermark(ctx, input.DocumentID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot export document PDF", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.ExportDocumentPDFPayload{
|
|
Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)),
|
|
}, nil
|
|
}
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, gqlutils.Unauthenticated(ctx, errors.New("unauthenticated"))
|
|
}
|
|
|
|
documentAccess, err := trustService.TrustCenterAccesses.GetDocumentAccess(
|
|
ctx,
|
|
trustCenter.ID,
|
|
identity.ID,
|
|
input.DocumentID,
|
|
)
|
|
if err != nil {
|
|
return nil, nil
|
|
}
|
|
|
|
if documentAccess.Status != coredata.TrustCenterDocumentAccessStatusGranted {
|
|
return nil, gqlutils.Forbiddenf(ctx, "access denied: no permission to access this document")
|
|
}
|
|
|
|
pdf, err := trustService.Documents.ExportPDF(ctx, input.DocumentID, identity.EmailAddress)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot export document PDF", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.ExportDocumentPDFPayload{
|
|
Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)),
|
|
}, nil
|
|
}
|
|
|
|
// ExportReportPDF is the resolver for the exportReportPDF field.
|
|
func (r *mutationResolver) ExportReportPDF(ctx context.Context, input types.ExportReportPDFInput) (*types.ExportReportPDFPayload, error) {
|
|
trustService := r.TrustService(ctx, input.ReportID.TenantID())
|
|
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
|
|
audit, err := trustService.Audits.GetByReportID(ctx, input.ReportID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot load audit", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
if audit.TrustCenterVisibility == coredata.TrustCenterVisibilityPublic {
|
|
pdf, err := trustService.Reports.ExportPDFWithoutWatermark(ctx, input.ReportID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot export report PDF", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.ExportReportPDFPayload{
|
|
Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)),
|
|
}, nil
|
|
}
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
|
}
|
|
|
|
reportAccess, err := trustService.TrustCenterAccesses.GetReportAccess(
|
|
ctx,
|
|
trustCenter.ID,
|
|
identity.ID,
|
|
input.ReportID,
|
|
)
|
|
if err != nil {
|
|
return nil, nil
|
|
}
|
|
|
|
if reportAccess.Status != coredata.TrustCenterDocumentAccessStatusGranted {
|
|
return nil, gqlutils.Forbiddenf(ctx, "access denied: no permission to access this report")
|
|
}
|
|
|
|
pdf, err := trustService.Reports.ExportPDF(ctx, input.ReportID, identity.EmailAddress)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot export report PDF", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.ExportReportPDFPayload{
|
|
Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)),
|
|
}, nil
|
|
}
|
|
|
|
// ExportTrustCenterFile is the resolver for the exportTrustCenterFile field.
|
|
func (r *mutationResolver) ExportTrustCenterFile(ctx context.Context, input types.ExportTrustCenterFileInput) (*types.ExportTrustCenterFilePayload, error) {
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
|
|
|
trustCenterFile, err := trustService.TrustCenterFiles.Get(ctx, trustCenter.OrganizationID, input.TrustCenterFileID)
|
|
if err != nil {
|
|
if errors.Is(err, trust.ErrTrustCenterFileNotFound) || errors.Is(err, trust.ErrTrustCenterFileNotVisible) {
|
|
return nil, gqlutils.NotFoundf(ctx, "trust center file %q not found", input.TrustCenterFileID)
|
|
}
|
|
r.logger.ErrorCtx(ctx, "cannot load trust center file", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
if trustCenterFile.TrustCenterVisibility == coredata.TrustCenterVisibilityPublic {
|
|
fileData, mimeType, err := trustService.TrustCenterFiles.ExportFileWithoutWatermark(ctx, input.TrustCenterFileID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot export trust center file", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.ExportTrustCenterFilePayload{
|
|
Data: fmt.Sprintf("data:%s;base64,%s", mimeType, base64.StdEncoding.EncodeToString(fileData)),
|
|
}, nil
|
|
}
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
|
}
|
|
|
|
fileAccess, err := trustService.TrustCenterAccesses.GetTrustCenterFileAccess(ctx,
|
|
trustCenter.ID,
|
|
identity.ID,
|
|
input.TrustCenterFileID,
|
|
)
|
|
if err != nil {
|
|
return nil, nil
|
|
}
|
|
|
|
if fileAccess.Status != coredata.TrustCenterDocumentAccessStatusGranted {
|
|
return nil, gqlutils.Forbiddenf(ctx, "access denied: no permission to access this file")
|
|
}
|
|
|
|
fileData, mimeType, err := trustService.TrustCenterFiles.ExportFile(ctx, input.TrustCenterFileID, identity.EmailAddress)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot export trust center file", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.ExportTrustCenterFilePayload{
|
|
Data: fmt.Sprintf("data:%s;base64,%s", mimeType, base64.StdEncoding.EncodeToString(fileData)),
|
|
}, nil
|
|
}
|
|
|
|
// RequestDocumentAccess is the resolver for the requestDocumentAccess field.
|
|
func (r *mutationResolver) RequestDocumentAccess(ctx context.Context, input types.RequestDocumentAccessInput) (*types.RequestDocumentAccessPayload, error) {
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
|
|
|
document, err := trustService.Documents.Get(ctx, trustCenter.OrganizationID, input.DocumentID)
|
|
if err != nil {
|
|
if errors.Is(err, trust.ErrDocumentNotFound) || errors.Is(err, trust.ErrDocumentNotVisible) || errors.Is(err, coredata.ErrResourceNotFound) {
|
|
return nil, gqlutils.NotFoundf(ctx, "document %q not found", input.DocumentID)
|
|
}
|
|
if _, ok := errors.AsType[*trust.ErrDocumentArchived](err); ok {
|
|
return nil, gqlutils.NotFoundf(ctx, "document %q not found", input.DocumentID)
|
|
}
|
|
r.logger.ErrorCtx(ctx, "cannot load document", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
if document.TrustCenterVisibility == coredata.TrustCenterVisibilityPublic {
|
|
return nil, gqlutils.Invalidf(
|
|
ctx,
|
|
"document is publicly available and does not require access request",
|
|
)
|
|
}
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, gqlutils.Unauthenticatedf(ctx, "authentication is required to request access")
|
|
}
|
|
|
|
if _, err := trustService.TrustCenterAccesses.Request(
|
|
ctx,
|
|
&trust.TrustCenterAccessRequest{
|
|
TrustCenterID: trustCenter.ID,
|
|
IdentityID: identity.ID,
|
|
DocumentIDs: []gid.GID{input.DocumentID},
|
|
ReportIDs: []gid.GID{},
|
|
TrustCenterFileIDs: []gid.GID{},
|
|
},
|
|
); err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot request document access", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.RequestDocumentAccessPayload{
|
|
Document: types.NewDocument(document),
|
|
}, nil
|
|
}
|
|
|
|
// RequestReportAccess is the resolver for the requestReportAccess field.
|
|
func (r *mutationResolver) RequestReportAccess(ctx context.Context, input types.RequestReportAccessInput) (*types.RequestReportAccessPayload, error) {
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
|
|
|
audit, err := trustService.Audits.GetByReportID(ctx, input.ReportID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot load audit", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
if audit.TrustCenterVisibility == coredata.TrustCenterVisibilityPublic {
|
|
return nil, gqlutils.Invalidf(
|
|
ctx,
|
|
"report is publicly available and does not require access request",
|
|
)
|
|
}
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, gqlutils.Unauthenticatedf(ctx, "authentication is required to request access")
|
|
}
|
|
|
|
if _, err := trustService.TrustCenterAccesses.Request(
|
|
ctx,
|
|
&trust.TrustCenterAccessRequest{
|
|
TrustCenterID: trustCenter.ID,
|
|
IdentityID: identity.ID,
|
|
DocumentIDs: []gid.GID{},
|
|
ReportIDs: []gid.GID{input.ReportID},
|
|
TrustCenterFileIDs: []gid.GID{},
|
|
},
|
|
); err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot request report access", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.RequestReportAccessPayload{
|
|
Audit: types.NewAudit(audit),
|
|
}, nil
|
|
}
|
|
|
|
// RequestTrustCenterFileAccess is the resolver for the requestTrustCenterFileAccess field.
|
|
func (r *mutationResolver) RequestTrustCenterFileAccess(ctx context.Context, input types.RequestTrustCenterFileAccessInput) (*types.RequestFileAccessPayload, error) {
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
|
|
|
trustCenterFile, err := trustService.TrustCenterFiles.Get(ctx, trustCenter.OrganizationID, input.TrustCenterFileID)
|
|
if err != nil {
|
|
if errors.Is(err, trust.ErrTrustCenterFileNotFound) || errors.Is(err, trust.ErrTrustCenterFileNotVisible) {
|
|
return nil, gqlutils.NotFoundf(ctx, "trust center file %q not found", input.TrustCenterFileID)
|
|
}
|
|
r.logger.ErrorCtx(ctx, "cannot load trust center file", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
if trustCenterFile.TrustCenterVisibility == coredata.TrustCenterVisibilityPublic {
|
|
return nil, gqlutils.Invalidf(
|
|
ctx,
|
|
"trust center file is publicly available and does not require access request",
|
|
)
|
|
}
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, gqlutils.Unauthenticatedf(ctx, "authentication is required to request access")
|
|
}
|
|
|
|
if _, err := trustService.TrustCenterAccesses.Request(
|
|
ctx,
|
|
&trust.TrustCenterAccessRequest{
|
|
TrustCenterID: trustCenter.ID,
|
|
IdentityID: identity.ID,
|
|
DocumentIDs: []gid.GID{},
|
|
ReportIDs: []gid.GID{},
|
|
TrustCenterFileIDs: []gid.GID{input.TrustCenterFileID},
|
|
},
|
|
); err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot request trust center file access", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.RequestFileAccessPayload{
|
|
File: types.NewTrustCenterFile(trustCenterFile),
|
|
}, nil
|
|
}
|
|
|
|
// IsUserAuthorized is the resolver for the isUserAuthorized field.
|
|
func (r *reportResolver) IsUserAuthorized(ctx context.Context, obj *types.Report) (bool, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
|
|
audit, err := trustService.Audits.GetByReportID(ctx, obj.ID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot load document", log.Error(err))
|
|
return false, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
if audit.TrustCenterVisibility == coredata.TrustCenterVisibilityPublic {
|
|
return true, nil
|
|
}
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return false, nil
|
|
}
|
|
|
|
reportAccess, err := trustService.TrustCenterAccesses.GetReportAccess(ctx,
|
|
trustCenter.ID,
|
|
identity.ID,
|
|
obj.ID,
|
|
)
|
|
if err != nil {
|
|
if errors.Is(err, trust.ErrMembershipNotFound) ||
|
|
errors.Is(err, trust.ErrUserNotFound) ||
|
|
errors.Is(err, trust.ErrUserInactive) ||
|
|
errors.Is(err, trust.ErrDocumentAccessNotFound) {
|
|
return false, nil
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot check report access", log.Error(err))
|
|
return false, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return reportAccess.Status == coredata.TrustCenterDocumentAccessStatusGranted, nil
|
|
}
|
|
|
|
// Access is the resolver for the access field.
|
|
func (r *reportResolver) Access(ctx context.Context, obj *types.Report) (*types.DocumentAccess, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, nil // User is not authenticated, so no access requested
|
|
}
|
|
|
|
access, err := trustService.TrustCenterAccesses.GetReportAccess(
|
|
ctx,
|
|
trustCenter.ID,
|
|
identity.ID,
|
|
obj.ID,
|
|
)
|
|
if err != nil {
|
|
if errors.Is(err, trust.ErrMembershipNotFound) ||
|
|
errors.Is(err, trust.ErrUserNotFound) ||
|
|
errors.Is(err, trust.ErrDocumentAccessNotFound) {
|
|
return nil, nil
|
|
}
|
|
|
|
if errors.Is(err, trust.ErrUserInactive) {
|
|
return nil, gqlutils.Forbidden(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get audit report access", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.DocumentAccess{
|
|
ID: access.ID,
|
|
Status: access.Status,
|
|
}, nil
|
|
}
|
|
|
|
// TotalCount is the resolver for the totalCount field.
|
|
func (r *subprocessorConnectionResolver) TotalCount(ctx context.Context, obj *types.SubprocessorConnection) (int, error) {
|
|
trustService := r.TrustService(ctx, obj.ParentID.TenantID())
|
|
|
|
switch obj.Resolver.(type) {
|
|
case *trustCenterResolver:
|
|
count, err := trustService.Vendors.CountForTrustCenterId(ctx, obj.ParentID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot count subprocessors", log.Error(err))
|
|
return 0, gqlutils.Internal(ctx)
|
|
}
|
|
return count, nil
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "not implemented: TotalCount for parent type")
|
|
return 0, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
// LogoFileURL is the resolver for the logoFileUrl field.
|
|
func (r *trustCenterResolver) LogoFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
return trustService.TrustCenters.GenerateLogoURL(ctx, obj.ID, 1*time.Hour)
|
|
}
|
|
|
|
// DarkLogoFileURL is the resolver for the darkLogoFileUrl field.
|
|
func (r *trustCenterResolver) DarkLogoFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
return trustService.TrustCenters.GenerateDarkLogoURL(ctx, obj.ID, 1*time.Hour)
|
|
}
|
|
|
|
// NonDisclosureAgreement is the resolver for the nonDisclosureAgreement field.
|
|
func (r *trustCenterResolver) NonDisclosureAgreement(ctx context.Context, obj *types.TrustCenter) (*types.NonDisclosureAgreement, error) {
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
if trustCenter.NonDisclosureAgreementFileID == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
file, err := trustService.TrustCenters.GetNDAFile(ctx, obj.ID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot load NDA file", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
if file == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
return types.NewNonDisclosureAgreement(file), nil
|
|
}
|
|
|
|
// ViewerSubscription is the resolver for the viewerSubscription field.
|
|
func (r *trustCenterResolver) ViewerSubscription(ctx context.Context, obj *types.TrustCenter) (*types.MailingListSubscriber, error) {
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
if trustCenter.MailingListID == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
subscriber, err := r.mailman.GetSubscriber(ctx, *trustCenter.MailingListID, identity.EmailAddress)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot get mailing list subscription", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
if subscriber == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
return types.NewMailingListSubscriber(subscriber), nil
|
|
}
|
|
|
|
// Organization is the resolver for the organization field.
|
|
func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error) {
|
|
return obj.Organization, nil
|
|
}
|
|
|
|
// Documents is the resolver for the documents field.
|
|
func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.DocumentConnection, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
|
Field: coredata.DocumentOrderFieldTitle,
|
|
Direction: page.OrderDirectionAsc,
|
|
}
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
documentPage, err := trustService.Documents.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list public documents", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewDocumentConnection(documentPage), nil
|
|
}
|
|
|
|
// Audits is the resolver for the audits field.
|
|
func (r *trustCenterResolver) Audits(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.AuditConnection, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
pageOrderBy := page.OrderBy[coredata.AuditOrderField]{
|
|
Field: coredata.AuditOrderFieldValidFrom,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
auditPage, err := trustService.Audits.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list public audits", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewAuditConnection(auditPage), nil
|
|
}
|
|
|
|
// Subprocessors is the resolver for the subprocessors field.
|
|
func (r *trustCenterResolver) Subprocessors(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.SubprocessorConnection, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
pageOrderBy := page.OrderBy[coredata.VendorOrderField]{
|
|
Field: coredata.VendorOrderFieldName,
|
|
Direction: page.OrderDirectionAsc,
|
|
}
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
vendorPage, err := trustService.Vendors.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list subprocessors", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewSubprocessorConnection(vendorPage, r, obj.ID), nil
|
|
}
|
|
|
|
// References is the resolver for the references field.
|
|
func (r *trustCenterResolver) References(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.TrustCenterReferenceConnection, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
pageOrderBy := page.OrderBy[coredata.TrustCenterReferenceOrderField]{
|
|
Field: coredata.TrustCenterReferenceOrderFieldRank,
|
|
Direction: page.OrderDirectionAsc,
|
|
}
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
referencePage, err := trustService.TrustCenterReferences.ListForTrustCenterID(ctx, obj.ID, cursor)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list public trust center references", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewTrustCenterReferenceConnection(referencePage), nil
|
|
}
|
|
|
|
// TrustCenterFiles is the resolver for the trustCenterFiles field.
|
|
func (r *trustCenterResolver) TrustCenterFiles(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.TrustCenterFileConnection, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
pageOrderBy := page.OrderBy[coredata.TrustCenterFileOrderField]{
|
|
Field: coredata.TrustCenterFileOrderFieldName,
|
|
Direction: page.OrderDirectionAsc,
|
|
}
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
filter := coredata.NewTrustCenterFileFilter(
|
|
coredata.WithTrustCenterFileVisibilities(
|
|
coredata.TrustCenterVisibilityPublic,
|
|
coredata.TrustCenterVisibilityPrivate,
|
|
),
|
|
)
|
|
trustCenterFilePage, err := trustService.TrustCenterFiles.ListForOrganizationId(ctx, obj.Organization.ID, cursor, filter)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list public trust center files", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewTrustCenterFileConnection(trustCenterFilePage), nil
|
|
}
|
|
|
|
// ComplianceFrameworks is the resolver for the complianceFrameworks field.
|
|
func (r *trustCenterResolver) ComplianceFrameworks(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.ComplianceFrameworkConnection, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ComplianceFrameworkOrderField]{
|
|
Field: coredata.ComplianceFrameworkOrderFieldRank,
|
|
Direction: page.OrderDirectionAsc,
|
|
}
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
cfPage, err := trustService.ComplianceFrameworks.ListByTrustCenterID(ctx, obj.ID, cursor)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list compliance frameworks", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewComplianceFrameworkConnection(cfPage), nil
|
|
}
|
|
|
|
// ExternalUrls is the resolver for the externalUrls field.
|
|
func (r *trustCenterResolver) ExternalUrls(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.ComplianceExternalURLConnection, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
pageOrderBy := page.OrderBy[coredata.ComplianceExternalURLOrderField]{
|
|
Field: coredata.ComplianceExternalURLOrderFieldRank,
|
|
Direction: page.OrderDirectionAsc,
|
|
}
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
result, err := trustService.ComplianceExternalURLs.ListForTrustCenterID(ctx, obj.ID, cursor)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list compliance external URLs", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewComplianceExternalURLConnection(result), nil
|
|
}
|
|
|
|
// Updates is the resolver for the updates field.
|
|
func (r *trustCenterResolver) Updates(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.MailingListUpdateConnection, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
tc, err := trustService.TrustCenters.Get(ctx, obj.ID)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot load trust center", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
if tc.MailingListID == nil {
|
|
return &types.MailingListUpdateConnection{Edges: []*types.MailingListUpdateEdge{}, PageInfo: &types.PageInfo{}}, nil
|
|
}
|
|
|
|
pageOrderBy := page.OrderBy[coredata.MailingListUpdateOrderField]{
|
|
Field: coredata.MailingListUpdateOrderFieldUpdatedAt,
|
|
Direction: page.OrderDirectionDesc,
|
|
}
|
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
|
|
result, err := r.mailman.ListSentMailingListUpdates(ctx, *tc.MailingListID, cursor)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot list mailing list updates", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return types.NewMailingListUpdateConnection(result), nil
|
|
}
|
|
|
|
// IsUserAuthorized is the resolver for the isUserAuthorized field.
|
|
func (r *trustCenterFileResolver) IsUserAuthorized(ctx context.Context, obj *types.TrustCenterFile) (bool, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
|
|
trustCenterFile, err := trustService.TrustCenterFiles.Get(ctx, trustCenter.OrganizationID, obj.ID)
|
|
if err != nil {
|
|
if errors.Is(err, trust.ErrTrustCenterFileNotFound) || errors.Is(err, trust.ErrTrustCenterFileNotVisible) {
|
|
return false, gqlutils.NotFoundf(ctx, "trust center file %q not found", obj.ID)
|
|
}
|
|
r.logger.ErrorCtx(ctx, "cannot load trust center file", log.Error(err))
|
|
return false, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
if trustCenterFile.TrustCenterVisibility == coredata.TrustCenterVisibilityPublic {
|
|
return true, nil
|
|
}
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return false, nil
|
|
}
|
|
|
|
fileAccess, err := trustService.TrustCenterAccesses.GetTrustCenterFileAccess(ctx,
|
|
trustCenter.ID,
|
|
identity.ID,
|
|
obj.ID,
|
|
)
|
|
if err != nil {
|
|
if errors.Is(err, trust.ErrMembershipNotFound) ||
|
|
errors.Is(err, trust.ErrUserNotFound) ||
|
|
errors.Is(err, trust.ErrUserInactive) ||
|
|
errors.Is(err, trust.ErrDocumentAccessNotFound) {
|
|
return false, nil
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot check trust center file access", log.Error(err))
|
|
return false, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return fileAccess.Status == coredata.TrustCenterDocumentAccessStatusGranted, nil
|
|
}
|
|
|
|
// Access is the resolver for the access field.
|
|
func (r *trustCenterFileResolver) Access(ctx context.Context, obj *types.TrustCenterFile) (*types.DocumentAccess, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
|
|
identity := authn.IdentityFromContext(ctx)
|
|
if identity == nil {
|
|
return nil, nil // User is not authenticated, so no access requested
|
|
}
|
|
|
|
access, err := trustService.TrustCenterAccesses.GetTrustCenterFileAccess(
|
|
ctx,
|
|
trustCenter.ID,
|
|
identity.ID,
|
|
obj.ID,
|
|
)
|
|
if err != nil {
|
|
if errors.Is(err, trust.ErrMembershipNotFound) ||
|
|
errors.Is(err, trust.ErrUserNotFound) ||
|
|
errors.Is(err, trust.ErrDocumentAccessNotFound) {
|
|
return nil, nil
|
|
}
|
|
|
|
if errors.Is(err, trust.ErrUserInactive) {
|
|
return nil, gqlutils.Forbidden(ctx, err)
|
|
}
|
|
|
|
r.logger.ErrorCtx(ctx, "cannot get file access", log.Error(err))
|
|
return nil, gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return &types.DocumentAccess{
|
|
ID: access.ID,
|
|
Status: access.Status,
|
|
}, nil
|
|
}
|
|
|
|
// LogoURL is the resolver for the logoUrl field.
|
|
func (r *trustCenterReferenceResolver) LogoURL(ctx context.Context, obj *types.TrustCenterReference) (string, error) {
|
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
|
|
|
logoURL, err := trustService.TrustCenterReferences.GenerateLogoURL(ctx, obj.ID, 1*time.Hour)
|
|
if err != nil {
|
|
r.logger.ErrorCtx(ctx, "cannot generate logo URL", log.Error(err))
|
|
return "", gqlutils.Internal(ctx)
|
|
}
|
|
|
|
return logoURL, nil
|
|
}
|
|
|
|
// Audit returns schema.AuditResolver implementation.
|
|
func (r *Resolver) Audit() schema.AuditResolver { return &auditResolver{r} }
|
|
|
|
// ComplianceFramework returns schema.ComplianceFrameworkResolver implementation.
|
|
func (r *Resolver) ComplianceFramework() schema.ComplianceFrameworkResolver {
|
|
return &complianceFrameworkResolver{r}
|
|
}
|
|
|
|
// Document returns schema.DocumentResolver implementation.
|
|
func (r *Resolver) Document() schema.DocumentResolver { return &documentResolver{r} }
|
|
|
|
// Framework returns schema.FrameworkResolver implementation.
|
|
func (r *Resolver) Framework() schema.FrameworkResolver { return &frameworkResolver{r} }
|
|
|
|
// Report returns schema.ReportResolver implementation.
|
|
func (r *Resolver) Report() schema.ReportResolver { return &reportResolver{r} }
|
|
|
|
// SubprocessorConnection returns schema.SubprocessorConnectionResolver implementation.
|
|
func (r *Resolver) SubprocessorConnection() schema.SubprocessorConnectionResolver {
|
|
return &subprocessorConnectionResolver{r}
|
|
}
|
|
|
|
// TrustCenter returns schema.TrustCenterResolver implementation.
|
|
func (r *Resolver) TrustCenter() schema.TrustCenterResolver { return &trustCenterResolver{r} }
|
|
|
|
// TrustCenterFile returns schema.TrustCenterFileResolver implementation.
|
|
func (r *Resolver) TrustCenterFile() schema.TrustCenterFileResolver {
|
|
return &trustCenterFileResolver{r}
|
|
}
|
|
|
|
// TrustCenterReference returns schema.TrustCenterReferenceResolver implementation.
|
|
func (r *Resolver) TrustCenterReference() schema.TrustCenterReferenceResolver {
|
|
return &trustCenterReferenceResolver{r}
|
|
}
|
|
|
|
type auditResolver struct{ *Resolver }
|
|
type complianceFrameworkResolver struct{ *Resolver }
|
|
type documentResolver struct{ *Resolver }
|
|
type frameworkResolver struct{ *Resolver }
|
|
type reportResolver struct{ *Resolver }
|
|
type subprocessorConnectionResolver struct{ *Resolver }
|
|
type trustCenterResolver struct{ *Resolver }
|
|
type trustCenterFileResolver struct{ *Resolver }
|
|
type trustCenterReferenceResolver struct{ *Resolver }
|