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" "time" "github.com/vikstrous/dataloadgen" "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/gid" "go.probo.inc/probo/pkg/iam" "go.probo.inc/probo/pkg/page" "go.probo.inc/probo/pkg/probo" "go.probo.inc/probo/pkg/server/api/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" ) // Organization is the resolver for the organization field. func (r *auditResolver) Organization(ctx context.Context, obj *types.Audit) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { return nil, err } 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 load organization", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewOrganization(organization), nil } // Framework is the resolver for the framework field. func (r *auditResolver) Framework(ctx context.Context, obj *types.Audit) (*types.Framework, error) { if err := r.authorize(ctx, obj.ID, probo.ActionFrameworkGet); err != nil { return nil, err } loaders := dataloader.FromContext(ctx) framework, err := loaders.Framework.Load(ctx, obj.Framework.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 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) { if err := r.authorize(ctx, obj.ID, probo.ActionReportGet); err != nil { return nil, err } if obj.Report == nil { return nil, nil } loaders := dataloader.FromContext(ctx) report, err := loaders.Report.Load(ctx, obj.Report.ID) if err != nil { if errors.Is(err, dataloadgen.ErrNotFound) { return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot load report", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewReport(report), nil } // ReportURL is the resolver for the reportUrl field. func (r *auditResolver) ReportURL(ctx context.Context, obj *types.Audit) (*string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionReportGetReportUrl); err != nil { return nil, err } if obj.Report == nil { return nil, nil } prb := r.ProboService(ctx, obj.ID.TenantID()) url, err := prb.Audits.GenerateReportURL(ctx, obj.ID, 15*time.Minute) if err != nil { r.logger.ErrorCtx(ctx, "cannot generate report URL", log.Error(err)) return nil, gqlutils.Internal(ctx) } return url, nil } // Controls is the resolver for the controls field. func (r *auditResolver) Controls(ctx context.Context, obj *types.Audit, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ControlOrderField]{ Field: coredata.ControlOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ControlOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var controlFilter = coredata.NewControlFilter(nil) if filter != nil { controlFilter = coredata.NewControlFilter(filter.Query) } page, err := prb.Controls.ListForAuditID(ctx, obj.ID, cursor, controlFilter) if err != nil { r.logger.ErrorCtx(ctx, "cannot list audit controls", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewControlConnection(page, r, obj.ID, controlFilter), nil } // Findings is the resolver for the findings field. func (r *auditResolver) Findings(ctx context.Context, obj *types.Audit, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.FindingOrder, filter *types.FindingFilter) (*types.FindingConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionFindingList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.FindingOrderField]{ Field: coredata.FindingOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.FindingOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var ( kind *coredata.FindingKind status *coredata.FindingStatus priority *coredata.FindingPriority ownerID *gid.GID ) if filter != nil { kind = filter.Kind status = filter.Status priority = filter.Priority ownerID = filter.OwnerID } findingFilter := coredata.NewFindingFilter(nil, kind, status, priority, ownerID) if filter != nil { findingFilter = coredata.NewFindingFilter(&filter.SnapshotID, kind, status, priority, ownerID) } p, err := prb.Findings.ListForAuditID(ctx, obj.ID, cursor, findingFilter) if err != nil { r.logger.ErrorCtx(ctx, "cannot list audit findings", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewFindingConnection(p, r, obj.ID, filter), nil } // Permission is the resolver for the permission field. func (r *auditResolver) Permission(ctx context.Context, obj *types.Audit, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *auditConnectionResolver) TotalCount(ctx context.Context, obj *types.AuditConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionAuditList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Audits.CountForOrganizationID(ctx, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count audits", log.Error(err)) return 0, gqlutils.Internal(ctx) } return count, nil case *findingResolver: count, err := prb.Audits.CountForFindingID(ctx, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count audits", log.Error(err)) return 0, gqlutils.Internal(ctx) } return count, nil case *controlResolver: count, err := prb.Audits.CountForControlID(ctx, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count audits", log.Error(err)) return 0, gqlutils.Internal(ctx) } return count, nil default: r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver)) return 0, gqlutils.Internal(ctx) } } // Organization is the resolver for the organization field. func (r *findingResolver) Organization(ctx context.Context, obj *types.Finding) (*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 finding organization", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewOrganization(organization), nil } // Audits is the resolver for the audits field. func (r *findingResolver) Audits(ctx context.Context, obj *types.Finding, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AuditOrderBy) (*types.AuditConnection, error) { if err := r.authorize(ctx, obj.ID, probo.ActionAuditList); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.AuditOrderField]{ Field: coredata.AuditOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.AuditOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) p, err := prb.Audits.ListForFindingID(ctx, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list finding audits", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewAuditConnection(p, r, obj.ID), nil } // Owner is the resolver for the owner field. func (r *findingResolver) Owner(ctx context.Context, obj *types.Finding) (*types.Profile, error) { if obj.Owner == nil { return nil, nil } if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil { return nil, err } loaders := dataloader.FromContext(ctx) owner, err := loaders.Profile.Load(ctx, obj.Owner.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 finding owner", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewProfile(owner), nil } // Risk is the resolver for the risk field. func (r *findingResolver) Risk(ctx context.Context, obj *types.Finding) (*types.Risk, error) { if obj.Risk == nil { return nil, nil } if err := r.authorize(ctx, obj.ID, probo.ActionRiskGet); err != nil { return nil, err } loaders := dataloader.FromContext(ctx) risk, err := loaders.Risk.Load(ctx, obj.Risk.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 finding risk", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewRisk(risk), nil } // Permission is the resolver for the permission field. func (r *findingResolver) Permission(ctx context.Context, obj *types.Finding, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *findingConnectionResolver) TotalCount(ctx context.Context, obj *types.FindingConnection) (int, error) { if err := r.authorize(ctx, obj.ParentID, probo.ActionFindingList); err != nil { return 0, err } prb := r.ProboService(ctx, obj.ParentID.TenantID()) var ( kind *coredata.FindingKind status *coredata.FindingStatus priority *coredata.FindingPriority ownerID *gid.GID ) if obj.Filter != nil { kind = obj.Filter.Kind status = obj.Filter.Status priority = obj.Filter.Priority ownerID = obj.Filter.OwnerID } findingFilter := coredata.NewFindingFilter(nil, kind, status, priority, ownerID) if obj.Filter != nil { findingFilter = coredata.NewFindingFilter(&obj.Filter.SnapshotID, kind, status, priority, ownerID) } switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Findings.CountForOrganizationID(ctx, obj.ParentID, findingFilter) if err != nil { r.logger.ErrorCtx(ctx, "cannot count findings", log.Error(err)) return 0, gqlutils.Internal(ctx) } return count, nil case *auditResolver: count, err := prb.Findings.CountForAuditID(ctx, obj.ParentID, findingFilter) if err != nil { r.logger.ErrorCtx(ctx, "cannot count findings", log.Error(err)) return 0, gqlutils.Internal(ctx) } return count, nil } r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver)) return 0, gqlutils.Internal(ctx) } // CreateAudit is the resolver for the createAudit field. func (r *mutationResolver) CreateAudit(ctx context.Context, input types.CreateAuditInput) (*types.CreateAuditPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionAuditCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) req := probo.CreateAuditRequest{ OrganizationID: input.OrganizationID, FrameworkID: input.FrameworkID, Name: input.Name, ValidFrom: input.ValidFrom, ValidUntil: input.ValidUntil, State: input.State, TrustCenterVisibility: input.TrustCenterVisibility, } audit, err := prb.Audits.Create(ctx, &req) if err != nil { if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } r.logger.ErrorCtx(ctx, "cannot create audit", log.Error(err)) return nil, gqlutils.Internal(ctx) } if input.File != nil { uploadReq := probo.UploadAuditReportRequest{ AuditID: audit.ID, File: probo.File{ Content: input.File.File, Filename: input.File.Filename, Size: input.File.Size, ContentType: input.File.ContentType, }, } audit, err = prb.Audits.UploadReport(ctx, uploadReq) if err != nil { if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } r.logger.ErrorCtx(ctx, "cannot upload audit report", log.Error(err)) return nil, gqlutils.Internal(ctx) } } return &types.CreateAuditPayload{ AuditEdge: types.NewAuditEdge(audit, coredata.AuditOrderFieldCreatedAt), }, nil } // UpdateAudit is the resolver for the updateAudit field. func (r *mutationResolver) UpdateAudit(ctx context.Context, input types.UpdateAuditInput) (*types.UpdateAuditPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionAuditUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) req := probo.UpdateAuditRequest{ ID: input.ID, Name: gqlutils.UnwrapOmittable(input.Name), ValidFrom: input.ValidFrom, ValidUntil: input.ValidUntil, State: input.State, TrustCenterVisibility: input.TrustCenterVisibility, } audit, err := prb.Audits.Update(ctx, &req) if err != nil { if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } r.logger.ErrorCtx(ctx, "cannot update audit", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.UpdateAuditPayload{ Audit: types.NewAudit(audit), }, nil } // DeleteAudit is the resolver for the deleteAudit field. func (r *mutationResolver) DeleteAudit(ctx context.Context, input types.DeleteAuditInput) (*types.DeleteAuditPayload, error) { if err := r.authorize(ctx, input.AuditID, probo.ActionAuditDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.AuditID.TenantID()) err := prb.Audits.Delete(ctx, input.AuditID) if err != nil { r.logger.ErrorCtx(ctx, "cannot delete audit", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.DeleteAuditPayload{ DeletedAuditID: &input.AuditID, }, nil } // UploadAuditReport is the resolver for the uploadAuditReport field. func (r *mutationResolver) UploadAuditReport(ctx context.Context, input types.UploadAuditReportInput) (*types.UploadAuditReportPayload, error) { if err := r.authorize(ctx, input.AuditID, probo.ActionAuditReportUpload); err != nil { return nil, err } prb := r.ProboService(ctx, input.AuditID.TenantID()) req := probo.UploadAuditReportRequest{ AuditID: input.AuditID, File: probo.File{ Content: input.File.File, Filename: input.File.Filename, Size: input.File.Size, ContentType: input.File.ContentType, }, } audit, err := prb.Audits.UploadReport(ctx, req) if err != nil { if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } r.logger.ErrorCtx(ctx, "cannot upload audit report", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.UploadAuditReportPayload{ Audit: types.NewAudit(audit), }, nil } // DeleteAuditReport is the resolver for the deleteAuditReport field. func (r *mutationResolver) DeleteAuditReport(ctx context.Context, input types.DeleteAuditReportInput) (*types.DeleteAuditReportPayload, error) { if err := r.authorize(ctx, input.AuditID, probo.ActionAuditReportDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.AuditID.TenantID()) audit, err := prb.Audits.DeleteReport(ctx, input.AuditID) if err != nil { r.logger.ErrorCtx(ctx, "cannot delete audit report", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.DeleteAuditReportPayload{ Audit: types.NewAudit(audit), }, nil } // CreateFinding is the resolver for the createFinding field. func (r *mutationResolver) CreateFinding(ctx context.Context, input types.CreateFindingInput) (*types.CreateFindingPayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionFindingCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) req := probo.CreateFindingRequest{ OrganizationID: input.OrganizationID, Kind: input.Kind, Description: input.Description, Source: input.Source, IdentifiedOn: input.IdentifiedOn, RootCause: input.RootCause, CorrectiveAction: input.CorrectiveAction, OwnerID: input.OwnerID, DueDate: input.DueDate, Status: &input.Status, Priority: &input.Priority, RiskID: input.RiskID, EffectivenessCheck: input.EffectivenessCheck, } finding, err := prb.Findings.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 finding", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.CreateFindingPayload{ FindingEdge: types.NewFindingEdge(finding, coredata.FindingOrderFieldCreatedAt), }, nil } // UpdateFinding is the resolver for the updateFinding field. func (r *mutationResolver) UpdateFinding(ctx context.Context, input types.UpdateFindingInput) (*types.UpdateFindingPayload, error) { if err := r.authorize(ctx, input.ID, probo.ActionFindingUpdate); err != nil { return nil, err } prb := r.ProboService(ctx, input.ID.TenantID()) req := probo.UpdateFindingRequest{ ID: input.ID, Description: gqlutils.UnwrapOmittable(input.Description), Source: gqlutils.UnwrapOmittable(input.Source), IdentifiedOn: gqlutils.UnwrapOmittable(input.IdentifiedOn), RootCause: gqlutils.UnwrapOmittable(input.RootCause), CorrectiveAction: gqlutils.UnwrapOmittable(input.CorrectiveAction), OwnerID: input.OwnerID, DueDate: gqlutils.UnwrapOmittable(input.DueDate), Status: input.Status, Priority: input.Priority, RiskID: gqlutils.UnwrapOmittable(input.RiskID), EffectivenessCheck: gqlutils.UnwrapOmittable(input.EffectivenessCheck), } finding, err := prb.Findings.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 finding", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.UpdateFindingPayload{ Finding: types.NewFinding(finding), }, nil } // DeleteFinding is the resolver for the deleteFinding field. func (r *mutationResolver) DeleteFinding(ctx context.Context, input types.DeleteFindingInput) (*types.DeleteFindingPayload, error) { if err := r.authorize(ctx, input.FindingID, probo.ActionFindingDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.FindingID.TenantID()) err := prb.Findings.Delete(ctx, input.FindingID) if err != nil { r.logger.ErrorCtx(ctx, "cannot delete finding", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.DeleteFindingPayload{ DeletedFindingID: &input.FindingID, }, nil } // CreateFindingAuditMapping is the resolver for the createFindingAuditMapping field. func (r *mutationResolver) CreateFindingAuditMapping(ctx context.Context, input types.CreateFindingAuditMappingInput) (*types.CreateFindingAuditMappingPayload, error) { if err := r.authorize(ctx, input.FindingID, probo.ActionFindingAuditMappingCreate); err != nil { return nil, err } prb := r.ProboService(ctx, input.FindingID.TenantID()) finding, audit, err := prb.Findings.CreateAuditMapping(ctx, input.FindingID, input.AuditID, input.ReferenceID) if err != nil { r.logger.ErrorCtx(ctx, "cannot create finding audit mapping", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.CreateFindingAuditMappingPayload{ FindingEdge: types.NewFindingEdge(finding, coredata.FindingOrderFieldCreatedAt), AuditEdge: types.NewAuditEdge(audit, coredata.AuditOrderFieldCreatedAt), }, nil } // DeleteFindingAuditMapping is the resolver for the deleteFindingAuditMapping field. func (r *mutationResolver) DeleteFindingAuditMapping(ctx context.Context, input types.DeleteFindingAuditMappingInput) (*types.DeleteFindingAuditMappingPayload, error) { if err := r.authorize(ctx, input.FindingID, probo.ActionFindingAuditMappingDelete); err != nil { return nil, err } prb := r.ProboService(ctx, input.FindingID.TenantID()) finding, audit, err := prb.Findings.DeleteAuditMapping(ctx, input.FindingID, input.AuditID) if err != nil { r.logger.ErrorCtx(ctx, "cannot delete finding audit mapping", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.DeleteFindingAuditMappingPayload{ DeletedFindingID: &finding.ID, DeletedAuditID: &audit.ID, }, nil } // DownloadURL is the resolver for the downloadUrl field. func (r *reportResolver) DownloadURL(ctx context.Context, obj *types.Report) (*string, error) { if err := r.authorize(ctx, obj.ID, probo.ActionReportDownloadUrlGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) url, err := prb.Reports.GenerateDownloadURL(ctx, obj.ID, 15*time.Minute) if err != nil { r.logger.ErrorCtx(ctx, "cannot generate download URL", log.Error(err)) return nil, gqlutils.Internal(ctx) } return url, nil } // Audit is the resolver for the audit field. func (r *reportResolver) Audit(ctx context.Context, obj *types.Report) (*types.Audit, error) { if err := r.authorize(ctx, obj.ID, probo.ActionAuditGet); err != nil { return nil, err } prb := r.ProboService(ctx, obj.ID.TenantID()) audit, err := prb.Audits.GetByReportID(ctx, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot load audit for report", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewAudit(audit), nil } // Permission is the resolver for the permission field. func (r *reportResolver) Permission(ctx context.Context, obj *types.Report, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // Audit returns schema.AuditResolver implementation. func (r *Resolver) Audit() schema.AuditResolver { return &auditResolver{r} } // AuditConnection returns schema.AuditConnectionResolver implementation. func (r *Resolver) AuditConnection() schema.AuditConnectionResolver { return &auditConnectionResolver{r} } // Finding returns schema.FindingResolver implementation. func (r *Resolver) Finding() schema.FindingResolver { return &findingResolver{r} } // FindingConnection returns schema.FindingConnectionResolver implementation. func (r *Resolver) FindingConnection() schema.FindingConnectionResolver { return &findingConnectionResolver{r} } // Report returns schema.ReportResolver implementation. func (r *Resolver) Report() schema.ReportResolver { return &reportResolver{r} } type auditResolver struct{ *Resolver } type auditConnectionResolver struct{ *Resolver } type findingResolver struct{ *Resolver } type findingConnectionResolver struct{ *Resolver } type reportResolver struct{ *Resolver }