Consolidate hub type definitions into their own files
Move Organization, Identity, TrustCenter, and Viewer definitions to include all their connection fields directly, removing all extend type blocks for these hub types from entity files. This eliminates the Relay schemaExtensions constraint where extend type could only target types defined in the main schema file. Entity files now only define their own standalone types and extend type Mutation. Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -10,12 +10,9 @@ import (
|
||||
|
||||
"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/server/api/connect/v1/schema"
|
||||
"go.probo.inc/probo/pkg/server/api/connect/v1/types"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils/types/cursor"
|
||||
)
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
@@ -44,50 +41,6 @@ func (r *auditLogEntryConnectionResolver) TotalCount(ctx context.Context, obj *t
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// AuditLogEntries is the resolver for the auditLogEntries field.
|
||||
func (r *organizationResolver) AuditLogEntries(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AuditLogEntryOrderBy, filter *types.AuditLogEntryFilter) (*types.AuditLogEntryConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionAuditLogEntryList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.AuditLogEntryOrderField]{
|
||||
Field: coredata.AuditLogEntryOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.AuditLogEntryOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
c := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
coredataFilter := coredata.NewAuditLogEntryFilter()
|
||||
if filter != nil {
|
||||
if filter.Action != nil {
|
||||
coredataFilter.WithAction(*filter.Action)
|
||||
}
|
||||
if filter.ActorID != nil {
|
||||
coredataFilter.WithActorID(*filter.ActorID)
|
||||
}
|
||||
if filter.ResourceType != nil {
|
||||
coredataFilter.WithResourceType(*filter.ResourceType)
|
||||
}
|
||||
if filter.ResourceID != nil {
|
||||
coredataFilter.WithResourceID(*filter.ResourceID)
|
||||
}
|
||||
}
|
||||
|
||||
p, err := r.iam.OrganizationService.ListAuditLogEntries(ctx, obj.ID, c, coredataFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list audit log entries", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewAuditLogEntryConnection(p, r, obj.ID, coredataFilter), nil
|
||||
}
|
||||
|
||||
// AuditLogEntry returns schema.AuditLogEntryResolver implementation.
|
||||
func (r *Resolver) AuditLogEntry() schema.AuditLogEntryResolver { return &auditLogEntryResolver{r} }
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
@@ -19,13 +18,123 @@ import (
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/iam"
|
||||
"go.probo.inc/probo/pkg/mail"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
"go.probo.inc/probo/pkg/server/api/authn"
|
||||
"go.probo.inc/probo/pkg/server/api/authz"
|
||||
"go.probo.inc/probo/pkg/server/api/connect/v1/schema"
|
||||
"go.probo.inc/probo/pkg/server/api/connect/v1/types"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils/types/cursor"
|
||||
)
|
||||
|
||||
// Profiles is the resolver for the profiles field.
|
||||
func (r *identityResolver) Profiles(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProfileOrderBy, filter *types.ProfileFilter) (*types.ProfileConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileList, authz.WithSkipAssumptionCheck()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filters := coredata.NewMembershipProfileFilter(nil).WithMembership()
|
||||
if filter != nil {
|
||||
filters = coredata.NewMembershipProfileFilter(filter.ExcludeContractEnded).WithMembership()
|
||||
if filter.State != nil {
|
||||
filters.WithState(*filter.State)
|
||||
}
|
||||
}
|
||||
|
||||
if gqlutils.OnlyTotalCountSelected(ctx) {
|
||||
return &types.ProfileConnection{
|
||||
Resolver: r,
|
||||
ParentID: obj.ID,
|
||||
Filters: filters,
|
||||
}, nil
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.MembershipProfileOrderField]{
|
||||
Field: coredata.MembershipProfileOrderFieldFullName,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.MembershipProfileOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := r.iam.AccountService.ListProfilesForIdentity(ctx, obj.ID, cursor, filters)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list profiles", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewProfileConnection(page, r, obj.ID, filters), nil
|
||||
}
|
||||
|
||||
// Sessions is the resolver for the sessions field.
|
||||
func (r *identityResolver) Sessions(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SessionOrder) (*types.SessionConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionSessionList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gqlutils.OnlyTotalCountSelected(ctx) {
|
||||
return &types.SessionConnection{
|
||||
Resolver: r,
|
||||
ParentID: obj.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.SessionOrderField]{
|
||||
Field: coredata.SessionOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.SessionOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := r.iam.AccountService.ListSessions(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list sessions", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewSessionConnection(page, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// PersonalAPIKeys is the resolver for the personalAPIKeys field.
|
||||
func (r *identityResolver) PersonalAPIKeys(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.PersonalAPIKeyConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionPersonalAPIKeyList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gqlutils.OnlyTotalCountSelected(ctx) {
|
||||
return &types.PersonalAPIKeyConnection{
|
||||
Resolver: r,
|
||||
ParentID: obj.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.PersonalAPIKeyOrderField]{
|
||||
Field: coredata.PersonalAPIKeyOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
|
||||
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := r.iam.AccountService.ListPersonalAPIKeys(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list personal api keys", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewPersonalAPIKeyConnection(page, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// SsoLoginURL is the resolver for the ssoLoginURL field.
|
||||
func (r *identityResolver) SsoLoginURL(ctx context.Context, obj *types.Identity) (*string, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionIdentityGet); err != nil {
|
||||
@@ -525,63 +634,6 @@ func (r *mutationResolver) RevokeAllSessions(ctx context.Context) (*types.Revoke
|
||||
return &types.RevokeAllSessionsPayload{RevokedCount: int(revokedCount)}, nil
|
||||
}
|
||||
|
||||
// LogoURL is the resolver for the logoUrl field.
|
||||
func (r *organizationResolver) LogoURL(ctx context.Context, obj *types.Organization) (*string, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionOrganizationGet, authz.WithSkipAssumptionCheck()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
presignedURL, err := r.iam.OrganizationService.GenerateLogoURL(ctx, obj.ID, 1*time.Hour)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot generate logo URL", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return presignedURL, nil
|
||||
}
|
||||
|
||||
// HorizontalLogoURL is the resolver for the horizontalLogoUrl field.
|
||||
func (r *organizationResolver) HorizontalLogoURL(ctx context.Context, obj *types.Organization) (*string, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionOrganizationGet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
presignedURL, err := r.iam.OrganizationService.GenerateHorizontalLogoURL(ctx, obj.ID, 1*time.Hour)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot generate horizontal logo URL", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return presignedURL, nil
|
||||
}
|
||||
|
||||
// Viewer is the resolver for the viewer field.
|
||||
func (r *organizationResolver) Viewer(ctx context.Context, obj *types.Organization) (*types.Profile, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
identity := authn.IdentityFromContext(ctx)
|
||||
|
||||
profile, err := r.iam.OrganizationService.GetProfileForIdentityAndOrganization(ctx, identity.ID, obj.ID)
|
||||
if err != nil {
|
||||
var errNotFound *iam.ErrProfileNotFound
|
||||
if errors.As(err, &errNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get profile", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewProfile(profile), nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *organizationResolver) Permission(ctx context.Context, obj *types.Organization, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// Node is the resolver for the node field.
|
||||
func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error) {
|
||||
var (
|
||||
@@ -797,13 +849,9 @@ func (r *Resolver) Identity() schema.IdentityResolver { return &identityResolver
|
||||
// Mutation returns schema.MutationResolver implementation.
|
||||
func (r *Resolver) Mutation() schema.MutationResolver { return &mutationResolver{r} }
|
||||
|
||||
// Organization returns schema.OrganizationResolver implementation.
|
||||
func (r *Resolver) Organization() schema.OrganizationResolver { return &organizationResolver{r} }
|
||||
|
||||
// Query returns schema.QueryResolver implementation.
|
||||
func (r *Resolver) Query() schema.QueryResolver { return &queryResolver{r} }
|
||||
|
||||
type identityResolver struct{ *Resolver }
|
||||
type mutationResolver struct{ *Resolver }
|
||||
type organizationResolver struct{ *Resolver }
|
||||
type queryResolver struct{ *Resolver }
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
extend type Organization {
|
||||
auditLogEntries(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: AuditLogEntryOrder
|
||||
filter: AuditLogEntryFilter
|
||||
): AuditLogEntryConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum AuditLogActorType
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.AuditLogActorType"
|
||||
|
||||
@@ -66,6 +66,30 @@ type Identity implements Node {
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
profiles(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: ProfileOrder
|
||||
filter: ProfileFilter
|
||||
): ProfileConnection @goField(forceResolver: true)
|
||||
|
||||
sessions(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: SessionOrder
|
||||
): SessionConnection @goField(forceResolver: true)
|
||||
|
||||
personalAPIKeys(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): PersonalAPIKeyConnection @goField(forceResolver: true)
|
||||
|
||||
ssoLoginURL: String
|
||||
@goField(forceResolver: true)
|
||||
@session(required: PRESENT)
|
||||
@@ -75,25 +99,6 @@ type Identity implements Node {
|
||||
@session(required: PRESENT)
|
||||
}
|
||||
|
||||
type Organization implements Node {
|
||||
id: ID!
|
||||
name: String!
|
||||
logoUrl: String @goField(forceResolver: true)
|
||||
horizontalLogoUrl: String @goField(forceResolver: true)
|
||||
email: String
|
||||
description: String
|
||||
websiteUrl: String
|
||||
headquarterAddress: String
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
viewer: Profile @goField(forceResolver: true)
|
||||
|
||||
permission(action: String!): Boolean!
|
||||
@goField(forceResolver: true)
|
||||
@session(required: PRESENT)
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
signIn(input: SignInInput!): SignInPayload @session(required: OPTIONAL)
|
||||
signUp(input: SignUpInput!): SignUpPayload @session(required: NONE)
|
||||
|
||||
@@ -1,3 +1,49 @@
|
||||
type Organization implements Node {
|
||||
id: ID!
|
||||
name: String!
|
||||
logoUrl: String @goField(forceResolver: true)
|
||||
horizontalLogoUrl: String @goField(forceResolver: true)
|
||||
email: String
|
||||
description: String
|
||||
websiteUrl: String
|
||||
headquarterAddress: String
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
profiles(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: ProfileOrder
|
||||
): ProfileConnection @goField(forceResolver: true)
|
||||
|
||||
samlConfigurations(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): SAMLConfigurationConnection @goField(forceResolver: true)
|
||||
|
||||
scimConfiguration: SCIMConfiguration @goField(forceResolver: true)
|
||||
scimBridgeTypes: [SCIMBridgeTypeInfo!]! @goField(forceResolver: true)
|
||||
|
||||
auditLogEntries(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: AuditLogEntryOrder
|
||||
filter: AuditLogEntryFilter
|
||||
): AuditLogEntryConnection! @goField(forceResolver: true)
|
||||
|
||||
viewer: Profile @goField(forceResolver: true)
|
||||
|
||||
permission(action: String!): Boolean!
|
||||
@goField(forceResolver: true)
|
||||
@session(required: PRESENT)
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createOrganization(
|
||||
input: CreateOrganizationInput!
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
extend type Identity {
|
||||
personalAPIKeys(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): PersonalAPIKeyConnection @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type PersonalAPIKey implements Node {
|
||||
id: ID!
|
||||
name: String!
|
||||
|
||||
@@ -1,24 +1,3 @@
|
||||
extend type Identity {
|
||||
profiles(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: ProfileOrder
|
||||
filter: ProfileFilter
|
||||
): ProfileConnection @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
extend type Organization {
|
||||
profiles(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: ProfileOrder
|
||||
): ProfileConnection @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type Profile implements Node {
|
||||
id: ID!
|
||||
fullName: String!
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
extend type Organization {
|
||||
samlConfigurations(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): SAMLConfigurationConnection @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type SAMLConfiguration implements Node {
|
||||
id: ID!
|
||||
emailDomain: String!
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
extend type Organization {
|
||||
scimConfiguration: SCIMConfiguration @goField(forceResolver: true)
|
||||
scimBridgeTypes: [SCIMBridgeTypeInfo!]! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type SCIMConfiguration implements Node {
|
||||
id: ID!
|
||||
endpointUrl: String! @goField(forceResolver: true)
|
||||
|
||||
@@ -13,16 +13,6 @@ input SessionOrder {
|
||||
field: SessionOrderField!
|
||||
}
|
||||
|
||||
extend type Identity {
|
||||
sessions(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: SessionOrder
|
||||
): SessionConnection @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type Session implements Node {
|
||||
id: ID!
|
||||
identity: Identity @goField(forceResolver: true)
|
||||
|
||||
@@ -9,13 +9,19 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.gearno.de/kit/log"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/iam"
|
||||
"go.probo.inc/probo/pkg/iam/scim/bridge/provider/googleworkspace"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
"go.probo.inc/probo/pkg/server/api/authn"
|
||||
"go.probo.inc/probo/pkg/server/api/authz"
|
||||
"go.probo.inc/probo/pkg/server/api/connect/v1/schema"
|
||||
"go.probo.inc/probo/pkg/server/api/connect/v1/types"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils/types/cursor"
|
||||
)
|
||||
|
||||
// CreateOrganization is the resolver for the createOrganization field.
|
||||
@@ -148,3 +154,206 @@ func (r *mutationResolver) DeleteOrganization(ctx context.Context, input types.D
|
||||
func (r *mutationResolver) DeleteOrganizationHorizontalLogo(ctx context.Context, input types.DeleteOrganizationHorizontalLogoInput) (*types.DeleteOrganizationHorizontalLogoPayload, error) {
|
||||
panic(fmt.Errorf("not implemented: DeleteOrganizationHorizontalLogo - deleteOrganizationHorizontalLogo"))
|
||||
}
|
||||
|
||||
// LogoURL is the resolver for the logoUrl field.
|
||||
func (r *organizationResolver) LogoURL(ctx context.Context, obj *types.Organization) (*string, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionOrganizationGet, authz.WithSkipAssumptionCheck()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
presignedURL, err := r.iam.OrganizationService.GenerateLogoURL(ctx, obj.ID, 1*time.Hour)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot generate logo URL", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return presignedURL, nil
|
||||
}
|
||||
|
||||
// HorizontalLogoURL is the resolver for the horizontalLogoUrl field.
|
||||
func (r *organizationResolver) HorizontalLogoURL(ctx context.Context, obj *types.Organization) (*string, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionOrganizationGet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
presignedURL, err := r.iam.OrganizationService.GenerateHorizontalLogoURL(ctx, obj.ID, 1*time.Hour)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot generate horizontal logo URL", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return presignedURL, nil
|
||||
}
|
||||
|
||||
// Profiles is the resolver for the profiles field.
|
||||
func (r *organizationResolver) Profiles(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProfileOrderBy) (*types.ProfileConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filter := coredata.NewMembershipProfileFilter(nil).WithMembership()
|
||||
|
||||
if gqlutils.OnlyTotalCountSelected(ctx) {
|
||||
return &types.ProfileConnection{
|
||||
Resolver: r,
|
||||
ParentID: obj.ID,
|
||||
Filters: filter,
|
||||
}, nil
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.MembershipProfileOrderField]{
|
||||
Field: coredata.MembershipProfileOrderFieldFullName,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.MembershipProfileOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := r.iam.OrganizationService.ListProfiles(ctx, obj.ID, cursor, filter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list profiles", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewProfileConnection(page, r, obj.ID, filter), nil
|
||||
}
|
||||
|
||||
// SamlConfigurations is the resolver for the samlConfigurations field.
|
||||
func (r *organizationResolver) SamlConfigurations(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.SAMLConfigurationConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionSAMLConfigurationList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gqlutils.OnlyTotalCountSelected(ctx) {
|
||||
return &types.SAMLConfigurationConnection{
|
||||
Resolver: r,
|
||||
ParentID: obj.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.SAMLConfigurationOrderField]{
|
||||
Field: coredata.SAMLConfigurationOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
|
||||
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := r.iam.OrganizationService.ListSAMLConfigurations(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list saml configurations", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewSAMLConfigurationConnection(page, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// ScimConfiguration is the resolver for the scimConfiguration field.
|
||||
func (r *organizationResolver) ScimConfiguration(ctx context.Context, obj *types.Organization) (*types.SCIMConfiguration, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionSCIMConfigurationGet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config, err := r.iam.OrganizationService.GetSCIMConfiguration(ctx, obj.ID)
|
||||
if err != nil {
|
||||
var notFound *iam.ErrNoSCIMConfigurationFound
|
||||
if errors.As(err, ¬Found) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get scim configuration", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewSCIMConfiguration(config), nil
|
||||
}
|
||||
|
||||
// ScimBridgeTypes is the resolver for the scimBridgeTypes field.
|
||||
func (r *organizationResolver) ScimBridgeTypes(ctx context.Context, obj *types.Organization) ([]*types.SCIMBridgeTypeInfo, error) {
|
||||
return []*types.SCIMBridgeTypeInfo{
|
||||
{
|
||||
Type: coredata.SCIMBridgeTypeGoogleWorkspace,
|
||||
Oauth2Scopes: googleworkspace.OAuth2Scopes,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AuditLogEntries is the resolver for the auditLogEntries field.
|
||||
func (r *organizationResolver) AuditLogEntries(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AuditLogEntryOrderBy, filter *types.AuditLogEntryFilter) (*types.AuditLogEntryConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionAuditLogEntryList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.AuditLogEntryOrderField]{
|
||||
Field: coredata.AuditLogEntryOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.AuditLogEntryOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
c := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
coredataFilter := coredata.NewAuditLogEntryFilter()
|
||||
if filter != nil {
|
||||
if filter.Action != nil {
|
||||
coredataFilter.WithAction(*filter.Action)
|
||||
}
|
||||
if filter.ActorID != nil {
|
||||
coredataFilter.WithActorID(*filter.ActorID)
|
||||
}
|
||||
if filter.ResourceType != nil {
|
||||
coredataFilter.WithResourceType(*filter.ResourceType)
|
||||
}
|
||||
if filter.ResourceID != nil {
|
||||
coredataFilter.WithResourceID(*filter.ResourceID)
|
||||
}
|
||||
}
|
||||
|
||||
p, err := r.iam.OrganizationService.ListAuditLogEntries(ctx, obj.ID, c, coredataFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list audit log entries", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewAuditLogEntryConnection(p, r, obj.ID, coredataFilter), nil
|
||||
}
|
||||
|
||||
// Viewer is the resolver for the viewer field.
|
||||
func (r *organizationResolver) Viewer(ctx context.Context, obj *types.Organization) (*types.Profile, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
identity := authn.IdentityFromContext(ctx)
|
||||
|
||||
profile, err := r.iam.OrganizationService.GetProfileForIdentityAndOrganization(ctx, identity.ID, obj.ID)
|
||||
if err != nil {
|
||||
var errNotFound *iam.ErrProfileNotFound
|
||||
if errors.As(err, &errNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get profile", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewProfile(profile), nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *organizationResolver) Permission(ctx context.Context, obj *types.Organization, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// Organization returns schema.OrganizationResolver implementation.
|
||||
func (r *Resolver) Organization() schema.OrganizationResolver { return &organizationResolver{r} }
|
||||
|
||||
type organizationResolver struct{ *Resolver }
|
||||
|
||||
@@ -11,43 +11,12 @@ import (
|
||||
"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/server/api/authn"
|
||||
"go.probo.inc/probo/pkg/server/api/connect/v1/schema"
|
||||
"go.probo.inc/probo/pkg/server/api/connect/v1/types"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils/types/cursor"
|
||||
)
|
||||
|
||||
// PersonalAPIKeys is the resolver for the personalAPIKeys field.
|
||||
func (r *identityResolver) PersonalAPIKeys(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.PersonalAPIKeyConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionPersonalAPIKeyList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gqlutils.OnlyTotalCountSelected(ctx) {
|
||||
return &types.PersonalAPIKeyConnection{
|
||||
Resolver: r,
|
||||
ParentID: obj.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.PersonalAPIKeyOrderField]{
|
||||
Field: coredata.PersonalAPIKeyOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
|
||||
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := r.iam.AccountService.ListPersonalAPIKeys(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list personal api keys", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewPersonalAPIKeyConnection(page, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// CreatePersonalAPIKey is the resolver for the createPersonalAPIKey field.
|
||||
func (r *mutationResolver) CreatePersonalAPIKey(ctx context.Context, input types.CreatePersonalAPIKeyInput) (*types.CreatePersonalAPIKeyPayload, error) {
|
||||
identity := authn.IdentityFromContext(ctx)
|
||||
|
||||
@@ -21,50 +21,6 @@ import (
|
||||
"go.probo.inc/probo/pkg/server/gqlutils/types/cursor"
|
||||
)
|
||||
|
||||
// Profiles is the resolver for the profiles field.
|
||||
func (r *identityResolver) Profiles(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProfileOrderBy, filter *types.ProfileFilter) (*types.ProfileConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileList, authz.WithSkipAssumptionCheck()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filters := coredata.NewMembershipProfileFilter(nil).WithMembership()
|
||||
if filter != nil {
|
||||
filters = coredata.NewMembershipProfileFilter(filter.ExcludeContractEnded).WithMembership()
|
||||
if filter.State != nil {
|
||||
filters.WithState(*filter.State)
|
||||
}
|
||||
}
|
||||
|
||||
if gqlutils.OnlyTotalCountSelected(ctx) {
|
||||
return &types.ProfileConnection{
|
||||
Resolver: r,
|
||||
ParentID: obj.ID,
|
||||
Filters: filters,
|
||||
}, nil
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.MembershipProfileOrderField]{
|
||||
Field: coredata.MembershipProfileOrderFieldFullName,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.MembershipProfileOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := r.iam.AccountService.ListProfilesForIdentity(ctx, obj.ID, cursor, filters)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list profiles", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewProfileConnection(page, r, obj.ID, filters), nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *invitationResolver) Permission(ctx context.Context, obj *types.Invitation, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
@@ -268,44 +224,6 @@ func (r *mutationResolver) RemoveUser(ctx context.Context, input types.RemoveUse
|
||||
return &types.RemoveUserPayload{DeletedProfileID: input.ProfileID}, nil
|
||||
}
|
||||
|
||||
// Profiles is the resolver for the profiles field.
|
||||
func (r *organizationResolver) Profiles(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProfileOrderBy) (*types.ProfileConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filter := coredata.NewMembershipProfileFilter(nil).WithMembership()
|
||||
|
||||
if gqlutils.OnlyTotalCountSelected(ctx) {
|
||||
return &types.ProfileConnection{
|
||||
Resolver: r,
|
||||
ParentID: obj.ID,
|
||||
Filters: filter,
|
||||
}, nil
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.MembershipProfileOrderField]{
|
||||
Field: coredata.MembershipProfileOrderFieldFullName,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.MembershipProfileOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := r.iam.OrganizationService.ListProfiles(ctx, obj.ID, cursor, filter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list profiles", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewProfileConnection(page, r, obj.ID, filter), nil
|
||||
}
|
||||
|
||||
// Identity is the resolver for the identity field.
|
||||
func (r *profileResolver) Identity(ctx context.Context, obj *types.Profile) (*types.Identity, error) {
|
||||
if err := r.authorize(
|
||||
|
||||
@@ -12,11 +12,9 @@ import (
|
||||
"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/server/api/connect/v1/schema"
|
||||
"go.probo.inc/probo/pkg/server/api/connect/v1/types"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils/types/cursor"
|
||||
)
|
||||
|
||||
// CreateSAMLConfiguration is the resolver for the createSAMLConfiguration field.
|
||||
@@ -116,35 +114,6 @@ func (r *mutationResolver) DeleteSAMLConfiguration(ctx context.Context, input ty
|
||||
return &types.DeleteSAMLConfigurationPayload{DeletedSamlConfigurationID: input.SamlConfigurationID}, nil
|
||||
}
|
||||
|
||||
// SamlConfigurations is the resolver for the samlConfigurations field.
|
||||
func (r *organizationResolver) SamlConfigurations(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.SAMLConfigurationConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionSAMLConfigurationList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gqlutils.OnlyTotalCountSelected(ctx) {
|
||||
return &types.SAMLConfigurationConnection{
|
||||
Resolver: r,
|
||||
ParentID: obj.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.SAMLConfigurationOrderField]{
|
||||
Field: coredata.SAMLConfigurationOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
|
||||
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := r.iam.OrganizationService.ListSAMLConfigurations(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list saml configurations", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewSAMLConfigurationConnection(page, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// TestLoginURL is the resolver for the testLoginUrl field.
|
||||
func (r *sAMLConfigurationResolver) TestLoginURL(ctx context.Context, obj *types.SAMLConfiguration) (string, error) {
|
||||
return r.baseURL.WithPath("/api/connect/v1/saml/2.0/" + obj.ID.String()).MustString(), nil
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"go.gearno.de/kit/log"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/iam"
|
||||
"go.probo.inc/probo/pkg/iam/scim/bridge/provider/googleworkspace"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
"go.probo.inc/probo/pkg/server/api/connect/v1/schema"
|
||||
"go.probo.inc/probo/pkg/server/api/connect/v1/types"
|
||||
@@ -107,36 +106,6 @@ func (r *mutationResolver) UpdateSCIMBridge(ctx context.Context, input types.Upd
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ScimConfiguration is the resolver for the scimConfiguration field.
|
||||
func (r *organizationResolver) ScimConfiguration(ctx context.Context, obj *types.Organization) (*types.SCIMConfiguration, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionSCIMConfigurationGet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config, err := r.iam.OrganizationService.GetSCIMConfiguration(ctx, obj.ID)
|
||||
if err != nil {
|
||||
var notFound *iam.ErrNoSCIMConfigurationFound
|
||||
if errors.As(err, ¬Found) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get scim configuration", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewSCIMConfiguration(config), nil
|
||||
}
|
||||
|
||||
// ScimBridgeTypes is the resolver for the scimBridgeTypes field.
|
||||
func (r *organizationResolver) ScimBridgeTypes(ctx context.Context, obj *types.Organization) ([]*types.SCIMBridgeTypeInfo, error) {
|
||||
return []*types.SCIMBridgeTypeInfo{
|
||||
{
|
||||
Type: coredata.SCIMBridgeTypeGoogleWorkspace,
|
||||
Oauth2Scopes: googleworkspace.OAuth2Scopes,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ScimConfiguration is the resolver for the scimConfiguration field.
|
||||
func (r *sCIMBridgeResolver) ScimConfiguration(ctx context.Context, obj *types.SCIMBridge) (*types.SCIMConfiguration, error) {
|
||||
if err := r.authorize(ctx, obj.ScimConfiguration.ID, iam.ActionSCIMConfigurationGet); err != nil {
|
||||
|
||||
@@ -9,50 +9,11 @@ import (
|
||||
"context"
|
||||
|
||||
"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/server/api/connect/v1/schema"
|
||||
"go.probo.inc/probo/pkg/server/api/connect/v1/types"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils/types/cursor"
|
||||
)
|
||||
|
||||
// Sessions is the resolver for the sessions field.
|
||||
func (r *identityResolver) Sessions(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SessionOrder) (*types.SessionConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionSessionList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gqlutils.OnlyTotalCountSelected(ctx) {
|
||||
return &types.SessionConnection{
|
||||
Resolver: r,
|
||||
ParentID: obj.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.SessionOrderField]{
|
||||
Field: coredata.SessionOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.SessionOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := r.iam.AccountService.ListSessions(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list sessions", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewSessionConnection(page, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// Identity is the resolver for the identity field.
|
||||
func (r *sessionResolver) Identity(ctx context.Context, obj *types.Session) (*types.Identity, error) {
|
||||
if gqlutils.OnlyIDSelected(ctx) {
|
||||
|
||||
@@ -955,64 +955,6 @@ func (r *mutationResolver) FlagAccessEntry(ctx context.Context, input types.Flag
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AccessSources is the resolver for the accessSources field.
|
||||
func (r *organizationResolver) AccessSources(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AccessSourceOrder) (*types.AccessSourceConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionAccessSourceList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(obj.ID)
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.AccessSourceOrderField]{
|
||||
Field: coredata.AccessSourceOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.AccessSourceOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
p, err := r.accessReview.Sources(scope).ListForOrganizationID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot list access sources: %w", err))
|
||||
}
|
||||
|
||||
return types.NewAccessSourceConnection(p, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// AccessReviewCampaigns is the resolver for the accessReviewCampaigns field.
|
||||
func (r *organizationResolver) AccessReviewCampaigns(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AccessReviewCampaignOrder) (*types.AccessReviewCampaignConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionAccessReviewCampaignList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(obj.ID)
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.AccessReviewCampaignOrderField]{
|
||||
Field: coredata.AccessReviewCampaignOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.AccessReviewCampaignOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
p, err := r.accessReview.Campaigns(scope).ListForOrganizationID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot list access review campaigns: %w", err))
|
||||
}
|
||||
|
||||
return types.NewAccessReviewCampaignConnection(p, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// AccessEntry returns schema.AccessEntryResolver implementation.
|
||||
func (r *Resolver) AccessEntry() schema.AccessEntryResolver { return &accessEntryResolver{r} }
|
||||
|
||||
|
||||
@@ -405,76 +405,6 @@ func (r *mutationResolver) DeleteDatum(ctx context.Context, input types.DeleteDa
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Assets is the resolver for the assets field.
|
||||
func (r *organizationResolver) Assets(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AssetOrderBy, filter *types.AssetFilter) (*types.AssetConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionAssetList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.AssetOrderField]{
|
||||
Field: coredata.AssetOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.AssetOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
assetFilter := coredata.NewAssetFilter(nil)
|
||||
if filter != nil {
|
||||
assetFilter = coredata.NewAssetFilter(&filter.SnapshotID)
|
||||
}
|
||||
|
||||
page, err := prb.Assets.ListForOrganizationID(ctx, obj.ID, cursor, assetFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization assets", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewAssetConnection(page, r, obj.ID, filter), nil
|
||||
}
|
||||
|
||||
// Assets is the resolver for the assets field.
|
||||
func (r *organizationResolver) Data(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DatumOrderBy, filter *types.DatumFilter) (*types.DatumConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionDatumList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.DatumOrderField]{
|
||||
Field: coredata.DatumOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.DatumOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
datumFilter := coredata.NewDatumFilter(nil)
|
||||
if filter != nil {
|
||||
datumFilter = coredata.NewDatumFilter(&filter.SnapshotID)
|
||||
}
|
||||
|
||||
page, err := prb.Data.ListForOrganizationID(ctx, obj.ID, cursor, datumFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization data", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewDataConnection(page, r, obj.ID, filter), nil
|
||||
}
|
||||
|
||||
// Asset returns schema.AssetResolver implementation.
|
||||
func (r *Resolver) Asset() schema.AssetResolver { return &assetResolver{r} }
|
||||
|
||||
|
||||
@@ -677,85 +677,6 @@ func (r *mutationResolver) DeleteFindingAuditMapping(ctx context.Context, input
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Audits is the resolver for the audits field.
|
||||
func (r *organizationResolver) Audits(ctx context.Context, obj *types.Organization, 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)
|
||||
|
||||
page, err := prb.Audits.ListForOrganizationID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization audits", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewAuditConnection(page, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// Findings is the resolver for the findings field.
|
||||
func (r *organizationResolver) Findings(ctx context.Context, obj *types.Organization, 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)
|
||||
}
|
||||
|
||||
page, err := prb.Findings.ListForOrganizationID(ctx, obj.ID, cursor, findingFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization findings", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewFindingConnection(page, r, obj.ID, filter), 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 {
|
||||
|
||||
@@ -10,8 +10,6 @@ import (
|
||||
|
||||
"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/server/api/console/v1/schema"
|
||||
"go.probo.inc/probo/pkg/server/api/console/v1/types"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
@@ -43,50 +41,6 @@ func (r *auditLogEntryConnectionResolver) TotalCount(ctx context.Context, obj *t
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// AuditLogEntries is the resolver for the auditLogEntries field.
|
||||
func (r *organizationResolver) AuditLogEntries(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AuditLogEntryOrderBy, filter *types.AuditLogEntryFilter) (*types.AuditLogEntryConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionAuditLogEntryList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.AuditLogEntryOrderField]{
|
||||
Field: coredata.AuditLogEntryOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.AuditLogEntryOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
coredataFilter := coredata.NewAuditLogEntryFilter()
|
||||
if filter != nil {
|
||||
if filter.Action != nil {
|
||||
coredataFilter.WithAction(*filter.Action)
|
||||
}
|
||||
if filter.ActorID != nil {
|
||||
coredataFilter.WithActorID(*filter.ActorID)
|
||||
}
|
||||
if filter.ResourceType != nil {
|
||||
coredataFilter.WithResourceType(*filter.ResourceType)
|
||||
}
|
||||
if filter.ResourceID != nil {
|
||||
coredataFilter.WithResourceID(*filter.ResourceID)
|
||||
}
|
||||
}
|
||||
|
||||
p, err := r.iam.OrganizationService.ListAuditLogEntries(ctx, obj.ID, cursor, coredataFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list audit log entries", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewAuditLogEntryConnection(p, r, obj.ID, coredataFilter), nil
|
||||
}
|
||||
|
||||
// AuditLogEntry returns schema.AuditLogEntryResolver implementation.
|
||||
func (r *Resolver) AuditLogEntry() schema.AuditLogEntryResolver { return &auditLogEntryResolver{r} }
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"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/server/gqlutils/types/cursor"
|
||||
"go.probo.inc/probo/pkg/validator"
|
||||
)
|
||||
|
||||
@@ -73,117 +72,6 @@ func (r *mutationResolver) UpdateOrganizationContext(ctx context.Context, input
|
||||
}, nil
|
||||
}
|
||||
|
||||
// LogoURL is the resolver for the logoUrl field.
|
||||
func (r *organizationResolver) LogoURL(ctx context.Context, obj *types.Organization) (*string, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGetLogoUrl); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
logoURL, err := prb.Organizations.GenerateLogoURL(ctx, obj.ID, 1*time.Hour)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot generate logo url", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return logoURL, nil
|
||||
}
|
||||
|
||||
// HorizontalLogoURL is the resolver for the horizontalLogoUrl field.
|
||||
func (r *organizationResolver) HorizontalLogoURL(ctx context.Context, obj *types.Organization) (*string, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGetHorizontalLogoUrl); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
horizontalLogoURL, err := prb.Organizations.GenerateHorizontalLogoURL(ctx, obj.ID, 1*time.Hour)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot generate horizontal logo url", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return horizontalLogoURL, nil
|
||||
}
|
||||
|
||||
// Context is the resolver for the context field.
|
||||
func (r *organizationResolver) Context(ctx context.Context, obj *types.Organization) (*types.OrganizationContext, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationContextGet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
orgContext, err := prb.Organizations.GetContext(ctx, obj.ID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot load organization context", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewOrganizationContext(orgContext), nil
|
||||
}
|
||||
|
||||
// Profiles is the resolver for the profiles field.
|
||||
func (r *organizationResolver) Profiles(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProfileOrderBy, filter *types.ProfileFilter) (*types.ProfileConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gqlutils.OnlyTotalCountSelected(ctx) {
|
||||
return &types.ProfileConnection{
|
||||
Resolver: r,
|
||||
ParentID: obj.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
filters := coredata.NewMembershipProfileFilter(nil).WithMembership()
|
||||
if filter != nil {
|
||||
filters = coredata.NewMembershipProfileFilter(filter.ExcludeContractEnded).WithMembership()
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.MembershipProfileOrderField]{
|
||||
Field: coredata.MembershipProfileOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy.Field = coredata.MembershipProfileOrderField(orderBy.Field)
|
||||
pageOrderBy.Direction = page.OrderDirection(orderBy.Direction)
|
||||
}
|
||||
|
||||
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := r.iam.OrganizationService.ListProfiles(ctx, obj.ID, cursor, filters)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list profiles", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewProfileConnection(page, r, obj.ID, filters), nil
|
||||
}
|
||||
|
||||
// MeasureCategories is the resolver for the measureCategories field.
|
||||
func (r *organizationResolver) MeasureCategories(ctx context.Context, obj *types.Organization) ([]string, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionMeasureList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
categories, err := prb.Measures.ListDistinctCategoriesForOrganizationID(ctx, obj.ID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list measure categories", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return categories, nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *organizationResolver) Permission(ctx context.Context, obj *types.Organization, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// Node is the resolver for the node field.
|
||||
func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error) {
|
||||
var (
|
||||
@@ -543,15 +431,170 @@ func (r *queryResolver) Viewer(ctx context.Context) (*types.Viewer, error) {
|
||||
return &types.Viewer{ID: viewerID}, nil
|
||||
}
|
||||
|
||||
// SignableDocuments is the resolver for the signableDocuments field.
|
||||
func (r *viewerResolver) SignableDocuments(ctx context.Context, obj *types.Viewer, organizationID gid.GID, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy) (*types.EmployeeDocumentConnection, error) {
|
||||
if err := r.authorize(ctx, organizationID, probo.ActionEmployeeDocumentList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, organizationID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: coredata.DocumentOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
identity := authn.IdentityFromContext(ctx)
|
||||
|
||||
documentFilter := coredata.NewDocumentFilter(nil).WithEmployeeIdentityID(&identity.ID, coredata.EmployeeFilterModeSignature)
|
||||
|
||||
documentsPage, err := prb.Documents.ListByOrganizationID(ctx, organizationID, cursor, documentFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization signable documents", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
employeeDocuments := make([]*types.EmployeeDocument, len(documentsPage.Data))
|
||||
for i, doc := range documentsPage.Data {
|
||||
employeeDocuments[i] = &types.EmployeeDocument{
|
||||
ID: doc.ID,
|
||||
Title: doc.Title,
|
||||
DocumentType: doc.DocumentType,
|
||||
CreatedAt: doc.CreatedAt,
|
||||
UpdatedAt: doc.UpdatedAt,
|
||||
FilterMode: types.EmployeeDocumentFilterModeSignature,
|
||||
}
|
||||
}
|
||||
|
||||
page := page.NewPage(employeeDocuments, documentsPage.Cursor)
|
||||
|
||||
return types.NewEmployeeDocumentConnection(page), nil
|
||||
}
|
||||
|
||||
// SignableDocument is the resolver for the signableDocument field.
|
||||
func (r *viewerResolver) SignableDocument(ctx context.Context, obj *types.Viewer, id gid.GID) (*types.EmployeeDocument, error) {
|
||||
if err := r.authorize(ctx, id, probo.ActionEmployeeDocumentGet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, id.TenantID())
|
||||
|
||||
identity := authn.IdentityFromContext(ctx)
|
||||
|
||||
documentFilter := coredata.NewDocumentFilter(nil).WithEmployeeIdentityID(&identity.ID, coredata.EmployeeFilterModeSignature)
|
||||
document, err := prb.Documents.GetWithFilter(ctx, id, documentFilter)
|
||||
if err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get signable document", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.EmployeeDocument{
|
||||
ID: document.ID,
|
||||
Title: document.Title,
|
||||
DocumentType: document.DocumentType,
|
||||
CreatedAt: document.CreatedAt,
|
||||
UpdatedAt: document.UpdatedAt,
|
||||
FilterMode: types.EmployeeDocumentFilterModeSignature,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ApprovableDocuments is the resolver for the approvableDocuments field.
|
||||
func (r *viewerResolver) ApprovableDocuments(ctx context.Context, obj *types.Viewer, organizationID gid.GID, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy) (*types.EmployeeDocumentConnection, error) {
|
||||
if err := r.authorize(ctx, organizationID, probo.ActionEmployeeDocumentList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, organizationID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: coredata.DocumentOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
identity := authn.IdentityFromContext(ctx)
|
||||
|
||||
documentFilter := coredata.NewDocumentFilter(nil).WithEmployeeIdentityID(&identity.ID, coredata.EmployeeFilterModeApproval)
|
||||
|
||||
documentsPage, err := prb.Documents.ListByOrganizationID(ctx, organizationID, cursor, documentFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization approvable documents", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
employeeDocuments := make([]*types.EmployeeDocument, len(documentsPage.Data))
|
||||
for i, doc := range documentsPage.Data {
|
||||
employeeDocuments[i] = &types.EmployeeDocument{
|
||||
ID: doc.ID,
|
||||
Title: doc.Title,
|
||||
DocumentType: doc.DocumentType,
|
||||
CreatedAt: doc.CreatedAt,
|
||||
UpdatedAt: doc.UpdatedAt,
|
||||
FilterMode: types.EmployeeDocumentFilterModeApproval,
|
||||
}
|
||||
}
|
||||
|
||||
page := page.NewPage(employeeDocuments, documentsPage.Cursor)
|
||||
|
||||
return types.NewEmployeeDocumentConnection(page), nil
|
||||
}
|
||||
|
||||
// ApprovableDocument is the resolver for the approvableDocument field.
|
||||
func (r *viewerResolver) ApprovableDocument(ctx context.Context, obj *types.Viewer, id gid.GID) (*types.EmployeeDocument, error) {
|
||||
if err := r.authorize(ctx, id, probo.ActionEmployeeDocumentGet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, id.TenantID())
|
||||
|
||||
identity := authn.IdentityFromContext(ctx)
|
||||
|
||||
documentFilter := coredata.NewDocumentFilter(nil).WithEmployeeIdentityID(&identity.ID, coredata.EmployeeFilterModeApproval)
|
||||
document, err := prb.Documents.GetWithFilter(ctx, id, documentFilter)
|
||||
if err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get approvable document", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.EmployeeDocument{
|
||||
ID: document.ID,
|
||||
Title: document.Title,
|
||||
DocumentType: document.DocumentType,
|
||||
CreatedAt: document.CreatedAt,
|
||||
UpdatedAt: document.UpdatedAt,
|
||||
FilterMode: types.EmployeeDocumentFilterModeApproval,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// File returns schema.FileResolver implementation.
|
||||
func (r *Resolver) File() schema.FileResolver { return &fileResolver{r} }
|
||||
|
||||
// Mutation returns schema.MutationResolver implementation.
|
||||
func (r *Resolver) Mutation() schema.MutationResolver { return &mutationResolver{r} }
|
||||
|
||||
// Organization returns schema.OrganizationResolver implementation.
|
||||
func (r *Resolver) Organization() schema.OrganizationResolver { return &organizationResolver{r} }
|
||||
|
||||
// Query returns schema.QueryResolver implementation.
|
||||
func (r *Resolver) Query() schema.QueryResolver { return &queryResolver{r} }
|
||||
|
||||
@@ -560,6 +603,5 @@ func (r *Resolver) Viewer() schema.ViewerResolver { return &viewerResolver{r} }
|
||||
|
||||
type fileResolver struct{ *Resolver }
|
||||
type mutationResolver struct{ *Resolver }
|
||||
type organizationResolver struct{ *Resolver }
|
||||
type queryResolver struct{ *Resolver }
|
||||
type viewerResolver struct{ *Resolver }
|
||||
|
||||
@@ -14,12 +14,10 @@ import (
|
||||
"go.probo.inc/probo/pkg/accessreview/drivers"
|
||||
"go.probo.inc/probo/pkg/connector"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
"go.probo.inc/probo/pkg/probo"
|
||||
"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/slack"
|
||||
)
|
||||
|
||||
// Oauth2Scopes is the resolver for the oauth2Scopes field.
|
||||
@@ -167,96 +165,6 @@ func (r *mutationResolver) DeleteSlackConnection(ctx context.Context, input type
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SlackConnections is the resolver for the slackConnections field.
|
||||
func (r *organizationResolver) SlackConnections(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.SlackConnectionConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionSlackConnectionList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
slackProvider := coredata.ConnectorProviderSlack
|
||||
filter := coredata.NewConnectorProviderFilter(&slackProvider)
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.ConnectorOrderField]{
|
||||
Field: coredata.ConnectorOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := prb.Connectors.ListForOrganizationID(ctx, obj.ID, cursor, filter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization slack connections", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewSlackConnectionConnection(page), nil
|
||||
}
|
||||
|
||||
// SlackOAuth2Scopes is the resolver for the slackOAuth2Scopes field.
|
||||
func (r *organizationResolver) SlackOAuth2Scopes(ctx context.Context, obj *types.Organization) ([]string, error) {
|
||||
return slack.OAuth2Scopes, nil
|
||||
}
|
||||
|
||||
// Connectors is the resolver for the connectors field.
|
||||
func (r *organizationResolver) Connectors(ctx context.Context, obj *types.Organization, filter *types.ConnectorFilter) ([]*types.Connector, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionConnectorList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
connectors, err := prb.Connectors.ListAllForOrganizationID(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot list organization connectors: %w", err))
|
||||
}
|
||||
|
||||
if filter != nil && len(filter.Providers) > 0 {
|
||||
allowed := make(map[coredata.ConnectorProvider]struct{}, len(filter.Providers))
|
||||
for _, provider := range filter.Providers {
|
||||
allowed[provider] = struct{}{}
|
||||
}
|
||||
|
||||
filtered := make(coredata.Connectors, 0, len(connectors))
|
||||
for _, cnnctr := range connectors {
|
||||
if _, ok := allowed[cnnctr.Provider]; ok {
|
||||
filtered = append(filtered, cnnctr)
|
||||
}
|
||||
}
|
||||
connectors = filtered
|
||||
}
|
||||
|
||||
return types.NewConnectors(connectors), nil
|
||||
}
|
||||
|
||||
// ConnectorProviderInfos is the resolver for the connectorProviderInfos field.
|
||||
func (r *organizationResolver) ConnectorProviderInfos(ctx context.Context, obj *types.Organization) ([]*types.ConnectorProviderInfo, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionConnectorList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var infos []*types.ConnectorProviderInfo
|
||||
for _, provider := range coredata.ConnectorProviders() {
|
||||
_, oauthErr := r.connectorRegistry.Get(string(provider))
|
||||
scopes := drivers.ProviderOAuth2Scopes(provider)
|
||||
if scopes == nil {
|
||||
scopes = []string{}
|
||||
}
|
||||
info := &types.ConnectorProviderInfo{
|
||||
Provider: provider,
|
||||
DisplayName: providerDisplayName(provider),
|
||||
OauthConfigured: oauthErr == nil,
|
||||
APIKeySupported: providerSupportsAPIKey(provider),
|
||||
ClientCredentialsSupported: providerSupportsClientCredentials(provider),
|
||||
Oauth2Scopes: scopes,
|
||||
ExtraSettings: providerExtraSettings(provider),
|
||||
}
|
||||
infos = append(infos, info)
|
||||
}
|
||||
return infos, nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *slackConnectionResolver) Permission(ctx context.Context, obj *types.SlackConnection, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
|
||||
@@ -865,76 +865,6 @@ func (r *mutationResolver) ExportStatementOfApplicabilityPDF(ctx context.Context
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Controls is the resolver for the controls field.
|
||||
func (r *organizationResolver) Controls(ctx context.Context, obj *types.Organization, 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.ListForOrganizationID(ctx, obj.ID, cursor, controlFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list controls", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewControlConnection(page, r, obj.ID, controlFilter), nil
|
||||
}
|
||||
|
||||
// StatementsOfApplicability is the resolver for the statementsOfApplicability field.
|
||||
func (r *organizationResolver) StatementsOfApplicability(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.StatementOfApplicabilityOrderBy, filter *types.StatementOfApplicabilityFilter) (*types.StatementOfApplicabilityConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionStatementOfApplicabilityList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.StatementOfApplicabilityOrderField]{
|
||||
Field: coredata.StatementOfApplicabilityOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.StatementOfApplicabilityOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
var statementOfApplicabilityFilter = coredata.NewStatementOfApplicabilityFilter(nil)
|
||||
if filter != nil {
|
||||
statementOfApplicabilityFilter = coredata.NewStatementOfApplicabilityFilter(&filter.SnapshotID)
|
||||
}
|
||||
|
||||
page, err := prb.StatementsOfApplicability.ListForOrganizationID(ctx, obj.ID, cursor, statementOfApplicabilityFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization statements_of_applicability", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewStatementOfApplicabilityConnection(page, r, obj.ID, statementOfApplicabilityFilter), nil
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *statementOfApplicabilityResolver) Organization(ctx context.Context, obj *types.StatementOfApplicability) (*types.Organization, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil {
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
"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/probo"
|
||||
"go.probo.inc/probo/pkg/server/api/console/v1/dataloader"
|
||||
"go.probo.inc/probo/pkg/server/api/console/v1/schema"
|
||||
@@ -326,78 +325,6 @@ func (r *mutationResolver) ExportTransferImpactAssessmentsPDF(ctx context.Contex
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DataProtectionImpactAssessments is the resolver for the dataProtectionImpactAssessments field.
|
||||
func (r *organizationResolver) DataProtectionImpactAssessments(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DataProtectionImpactAssessmentOrderBy, filter *types.DataProtectionImpactAssessmentFilter) (*types.DataProtectionImpactAssessmentConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionDataProtectionImpactAssessmentList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.DataProtectionImpactAssessmentOrderField]{
|
||||
Field: coredata.DataProtectionImpactAssessmentOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.DataProtectionImpactAssessmentOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
dpiaFilter := coredata.NewDataProtectionImpactAssessmentFilter(nil)
|
||||
if filter != nil {
|
||||
dpiaFilter = coredata.NewDataProtectionImpactAssessmentFilter(&filter.SnapshotID)
|
||||
}
|
||||
|
||||
page, err := prb.DataProtectionImpactAssessments.ListForOrganizationID(ctx, obj.ID, cursor, dpiaFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization data protection impact assessments", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewDataProtectionImpactAssessmentConnection(page, r, obj.ID, dpiaFilter), nil
|
||||
}
|
||||
|
||||
// TransferImpactAssessments is the resolver for the transferImpactAssessments field.
|
||||
func (r *organizationResolver) TransferImpactAssessments(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TransferImpactAssessmentOrderBy, filter *types.TransferImpactAssessmentFilter) (*types.TransferImpactAssessmentConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionTransferImpactAssessmentList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.TransferImpactAssessmentOrderField]{
|
||||
Field: coredata.TransferImpactAssessmentOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.TransferImpactAssessmentOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
tiaFilter := coredata.NewTransferImpactAssessmentFilter(nil)
|
||||
if filter != nil {
|
||||
tiaFilter = coredata.NewTransferImpactAssessmentFilter(&filter.SnapshotID)
|
||||
}
|
||||
|
||||
page, err := prb.TransferImpactAssessments.ListForOrganizationID(ctx, obj.ID, cursor, tiaFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization transfer impact assessments", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewTransferImpactAssessmentConnection(page, r, obj.ID, tiaFilter), nil
|
||||
}
|
||||
|
||||
// ProcessingActivity is the resolver for the processingActivity field.
|
||||
func (r *transferImpactAssessmentResolver) ProcessingActivity(ctx context.Context, obj *types.TransferImpactAssessment) (*types.ProcessingActivity, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionProcessingActivityGet); err != nil {
|
||||
|
||||
@@ -1633,202 +1633,6 @@ func (r *mutationResolver) ExportEmployeeDocumentVersionPDF(ctx context.Context,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Documents is the resolver for the documents field.
|
||||
func (r *organizationResolver) Documents(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) (*types.DocumentConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionDocumentList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: coredata.DocumentOrderFieldTitle,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
var documentFilter = coredata.NewDocumentFilter(nil)
|
||||
if filter != nil {
|
||||
documentFilter = coredata.NewDocumentFilter(filter.Query).
|
||||
WithDocumentTypes(filter.DocumentTypes).
|
||||
WithClassifications(filter.Classifications).
|
||||
WithStatus(filter.Status)
|
||||
}
|
||||
|
||||
page, err := prb.Documents.ListByOrganizationID(ctx, obj.ID, cursor, documentFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization documents", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewDocumentConnection(page, r, obj.ID, documentFilter), nil
|
||||
}
|
||||
|
||||
// SignableDocuments is the resolver for the signableDocuments field.
|
||||
func (r *viewerResolver) SignableDocuments(ctx context.Context, obj *types.Viewer, organizationID gid.GID, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy) (*types.EmployeeDocumentConnection, error) {
|
||||
if err := r.authorize(ctx, organizationID, probo.ActionEmployeeDocumentList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, organizationID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: coredata.DocumentOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
identity := authn.IdentityFromContext(ctx)
|
||||
|
||||
documentFilter := coredata.NewDocumentFilter(nil).WithEmployeeIdentityID(&identity.ID, coredata.EmployeeFilterModeSignature)
|
||||
|
||||
documentsPage, err := prb.Documents.ListByOrganizationID(ctx, organizationID, cursor, documentFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization signable documents", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
employeeDocuments := make([]*types.EmployeeDocument, len(documentsPage.Data))
|
||||
for i, doc := range documentsPage.Data {
|
||||
employeeDocuments[i] = &types.EmployeeDocument{
|
||||
ID: doc.ID,
|
||||
Title: doc.Title,
|
||||
DocumentType: doc.DocumentType,
|
||||
CreatedAt: doc.CreatedAt,
|
||||
UpdatedAt: doc.UpdatedAt,
|
||||
FilterMode: types.EmployeeDocumentFilterModeSignature,
|
||||
}
|
||||
}
|
||||
|
||||
page := page.NewPage(employeeDocuments, documentsPage.Cursor)
|
||||
|
||||
return types.NewEmployeeDocumentConnection(page), nil
|
||||
}
|
||||
|
||||
// SignableDocument is the resolver for the signableDocument field.
|
||||
func (r *viewerResolver) SignableDocument(ctx context.Context, obj *types.Viewer, id gid.GID) (*types.EmployeeDocument, error) {
|
||||
if err := r.authorize(ctx, id, probo.ActionEmployeeDocumentGet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, id.TenantID())
|
||||
|
||||
identity := authn.IdentityFromContext(ctx)
|
||||
|
||||
documentFilter := coredata.NewDocumentFilter(nil).WithEmployeeIdentityID(&identity.ID, coredata.EmployeeFilterModeSignature)
|
||||
document, err := prb.Documents.GetWithFilter(ctx, id, documentFilter)
|
||||
if err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get signable document", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.EmployeeDocument{
|
||||
ID: document.ID,
|
||||
Title: document.Title,
|
||||
DocumentType: document.DocumentType,
|
||||
CreatedAt: document.CreatedAt,
|
||||
UpdatedAt: document.UpdatedAt,
|
||||
FilterMode: types.EmployeeDocumentFilterModeSignature,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ApprovableDocuments is the resolver for the approvableDocuments field.
|
||||
func (r *viewerResolver) ApprovableDocuments(ctx context.Context, obj *types.Viewer, organizationID gid.GID, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy) (*types.EmployeeDocumentConnection, error) {
|
||||
if err := r.authorize(ctx, organizationID, probo.ActionEmployeeDocumentList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, organizationID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: coredata.DocumentOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
identity := authn.IdentityFromContext(ctx)
|
||||
|
||||
documentFilter := coredata.NewDocumentFilter(nil).WithEmployeeIdentityID(&identity.ID, coredata.EmployeeFilterModeApproval)
|
||||
|
||||
documentsPage, err := prb.Documents.ListByOrganizationID(ctx, organizationID, cursor, documentFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization approvable documents", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
employeeDocuments := make([]*types.EmployeeDocument, len(documentsPage.Data))
|
||||
for i, doc := range documentsPage.Data {
|
||||
employeeDocuments[i] = &types.EmployeeDocument{
|
||||
ID: doc.ID,
|
||||
Title: doc.Title,
|
||||
DocumentType: doc.DocumentType,
|
||||
CreatedAt: doc.CreatedAt,
|
||||
UpdatedAt: doc.UpdatedAt,
|
||||
FilterMode: types.EmployeeDocumentFilterModeApproval,
|
||||
}
|
||||
}
|
||||
|
||||
page := page.NewPage(employeeDocuments, documentsPage.Cursor)
|
||||
|
||||
return types.NewEmployeeDocumentConnection(page), nil
|
||||
}
|
||||
|
||||
// ApprovableDocument is the resolver for the approvableDocument field.
|
||||
func (r *viewerResolver) ApprovableDocument(ctx context.Context, obj *types.Viewer, id gid.GID) (*types.EmployeeDocument, error) {
|
||||
if err := r.authorize(ctx, id, probo.ActionEmployeeDocumentGet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, id.TenantID())
|
||||
|
||||
identity := authn.IdentityFromContext(ctx)
|
||||
|
||||
documentFilter := coredata.NewDocumentFilter(nil).WithEmployeeIdentityID(&identity.ID, coredata.EmployeeFilterModeApproval)
|
||||
document, err := prb.Documents.GetWithFilter(ctx, id, documentFilter)
|
||||
if err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get approvable document", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.EmployeeDocument{
|
||||
ID: document.ID,
|
||||
Title: document.Title,
|
||||
DocumentType: document.DocumentType,
|
||||
CreatedAt: document.CreatedAt,
|
||||
UpdatedAt: document.UpdatedAt,
|
||||
FilterMode: types.EmployeeDocumentFilterModeApproval,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Document returns schema.DocumentResolver implementation.
|
||||
func (r *Resolver) Document() schema.DocumentResolver { return &documentResolver{r} }
|
||||
|
||||
|
||||
@@ -8,12 +8,10 @@ package console_v1
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/vikstrous/dataloadgen"
|
||||
"go.gearno.de/kit/log"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"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"
|
||||
@@ -180,11 +178,6 @@ func (r *mutationResolver) UploadMeasureEvidence(ctx context.Context, input type
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Evidences is the resolver for the evidences field.
|
||||
func (r *organizationResolver) Evidences(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.EvidenceOrderBy) (*types.EvidenceConnection, error) {
|
||||
panic(fmt.Errorf("not implemented: Evidences - evidences"))
|
||||
}
|
||||
|
||||
// Evidence returns schema.EvidenceResolver implementation.
|
||||
func (r *Resolver) Evidence() schema.EvidenceResolver { return &evidenceResolver{r} }
|
||||
|
||||
|
||||
@@ -259,36 +259,6 @@ func (r *mutationResolver) ExportFramework(ctx context.Context, input types.Expo
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Frameworks is the resolver for the frameworks field.
|
||||
func (r *organizationResolver) Frameworks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.FrameworkOrderBy) (*types.FrameworkConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionFrameworkList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.FrameworkOrderField]{
|
||||
Field: coredata.FrameworkOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.FrameworkOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := prb.Frameworks.ListForOrganizationID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization frameworks", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewFrameworkConnection(page, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// Framework returns schema.FrameworkResolver implementation.
|
||||
func (r *Resolver) Framework() schema.FrameworkResolver { return &frameworkResolver{r} }
|
||||
|
||||
|
||||
@@ -1,21 +1,3 @@
|
||||
extend type Organization {
|
||||
accessSources(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: AccessSourceOrder
|
||||
): AccessSourceConnection! @goField(forceResolver: true)
|
||||
|
||||
accessReviewCampaigns(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: AccessReviewCampaignOrder
|
||||
): AccessReviewCampaignConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum AccessReviewCampaignStatus
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.AccessReviewCampaignStatus"
|
||||
|
||||
@@ -1,23 +1,3 @@
|
||||
extend type Organization {
|
||||
assets(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: AssetOrder
|
||||
filter: AssetFilter = { snapshotId: null }
|
||||
): AssetConnection! @goField(forceResolver: true)
|
||||
|
||||
data(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: DatumOrder
|
||||
filter: DatumFilter = { snapshotId: null }
|
||||
): DatumConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum AssetType @goModel(model: "go.probo.inc/probo/pkg/coredata.AssetType") {
|
||||
PHYSICAL @goEnum(value: "go.probo.inc/probo/pkg/coredata.AssetTypePhysical")
|
||||
VIRTUAL @goEnum(value: "go.probo.inc/probo/pkg/coredata.AssetTypeVirtual")
|
||||
|
||||
@@ -1,22 +1,3 @@
|
||||
extend type Organization {
|
||||
audits(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: AuditOrder
|
||||
): AuditConnection! @goField(forceResolver: true)
|
||||
|
||||
findings(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: FindingOrder
|
||||
filter: FindingFilter = { snapshotId: null }
|
||||
): FindingConnection @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum AuditState @goModel(model: "go.probo.inc/probo/pkg/coredata.AuditState") {
|
||||
NOT_STARTED
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.AuditStateNotStarted")
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
extend type Organization {
|
||||
auditLogEntries(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: AuditLogEntryOrder
|
||||
filter: AuditLogEntryFilter
|
||||
): AuditLogEntryConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum AuditLogActorType
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.AuditLogActorType"
|
||||
|
||||
@@ -311,35 +311,28 @@ type Query {
|
||||
|
||||
type Viewer {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
type Organization implements Node {
|
||||
id: ID!
|
||||
name: String!
|
||||
logoUrl: String @goField(forceResolver: true)
|
||||
horizontalLogoUrl: String @goField(forceResolver: true)
|
||||
|
||||
description: String
|
||||
websiteUrl: String
|
||||
email: String
|
||||
headquarterAddress: String
|
||||
context: OrganizationContext @goField(forceResolver: true)
|
||||
|
||||
profiles(
|
||||
signableDocuments(
|
||||
organizationId: ID!
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: ProfileOrder
|
||||
filter: ProfileFilter
|
||||
): ProfileConnection! @goField(forceResolver: true)
|
||||
orderBy: DocumentOrder
|
||||
): EmployeeDocumentConnection! @goField(forceResolver: true)
|
||||
|
||||
measureCategories: [String!]! @goField(forceResolver: true)
|
||||
signableDocument(id: ID!): EmployeeDocument @goField(forceResolver: true)
|
||||
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
approvableDocuments(
|
||||
organizationId: ID!
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: DocumentOrder
|
||||
): EmployeeDocumentConnection! @goField(forceResolver: true)
|
||||
|
||||
permission(action: String!): Boolean! @goField(forceResolver: true)
|
||||
approvableDocument(id: ID!): EmployeeDocument @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
|
||||
@@ -1,15 +1,3 @@
|
||||
extend type Organization {
|
||||
slackConnections(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): SlackConnectionConnection! @goField(forceResolver: true)
|
||||
slackOAuth2Scopes: [String!]! @goField(forceResolver: true)
|
||||
connectors(filter: ConnectorFilter): [Connector!]! @goField(forceResolver: true)
|
||||
connectorProviderInfos: [ConnectorProviderInfo!]! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum ConnectorProvider
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.ConnectorProvider") {
|
||||
SLACK @goEnum(value: "go.probo.inc/probo/pkg/coredata.ConnectorProviderSlack")
|
||||
|
||||
@@ -1,23 +1,3 @@
|
||||
extend type Organization {
|
||||
controls(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: ControlOrder
|
||||
filter: ControlFilter
|
||||
): ControlConnection! @goField(forceResolver: true)
|
||||
|
||||
statementsOfApplicability(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: StatementOfApplicabilityOrder
|
||||
filter: StatementOfApplicabilityFilter = { snapshotId: null }
|
||||
): StatementOfApplicabilityConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum ControlImplementationState
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.ControlImplementationState"
|
||||
|
||||
@@ -1,23 +1,3 @@
|
||||
extend type Organization {
|
||||
dataProtectionImpactAssessments(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: DataProtectionImpactAssessmentOrder
|
||||
filter: DataProtectionImpactAssessmentFilter = { snapshotId: null }
|
||||
): DataProtectionImpactAssessmentConnection! @goField(forceResolver: true)
|
||||
|
||||
transferImpactAssessments(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: TransferImpactAssessmentOrder
|
||||
filter: TransferImpactAssessmentFilter = { snapshotId: null }
|
||||
): TransferImpactAssessmentConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum DataProtectionImpactAssessmentResidualRisk
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.DataProtectionImpactAssessmentResidualRisk"
|
||||
|
||||
@@ -1,38 +1,3 @@
|
||||
extend type Organization {
|
||||
documents(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: DocumentOrder
|
||||
filter: DocumentFilter
|
||||
): DocumentConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
extend type Viewer {
|
||||
signableDocuments(
|
||||
organizationId: ID!
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: DocumentOrder
|
||||
): EmployeeDocumentConnection! @goField(forceResolver: true)
|
||||
|
||||
signableDocument(id: ID!): EmployeeDocument @goField(forceResolver: true)
|
||||
|
||||
approvableDocuments(
|
||||
organizationId: ID!
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: DocumentOrder
|
||||
): EmployeeDocumentConnection! @goField(forceResolver: true)
|
||||
|
||||
approvableDocument(id: ID!): EmployeeDocument @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum DocumentVersionStatus
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.DocumentVersionStatus") {
|
||||
DRAFT
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
extend type Organization {
|
||||
evidences(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: EvidenceOrder
|
||||
): EvidenceConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum EvidenceState
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.EvidenceState") {
|
||||
FULFILLED
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
extend type Organization {
|
||||
frameworks(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: FrameworkOrder
|
||||
): FrameworkConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum FrameworkOrderField
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.FrameworkOrderField") {
|
||||
CREATED_AT
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
extend type Organization {
|
||||
measures(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: MeasureOrder
|
||||
filter: MeasureFilter
|
||||
): MeasureConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum MeasureState
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.MeasureState") {
|
||||
NOT_STARTED
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
extend type Organization {
|
||||
meetings(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: MeetingOrder
|
||||
): MeetingConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum MeetingOrderField
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.MeetingOrderField") {
|
||||
DATE @goEnum(value: "go.probo.inc/probo/pkg/coredata.MeetingOrderFieldDate")
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
extend type Organization {
|
||||
obligations(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: ObligationOrder
|
||||
filter: ObligationFilter = { snapshotId: null }
|
||||
): ObligationConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum ObligationStatus
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.ObligationStatus") {
|
||||
NON_COMPLIANT
|
||||
|
||||
@@ -81,3 +81,258 @@ input UpdateOrganizationContextInput {
|
||||
type UpdateOrganizationContextPayload {
|
||||
context: OrganizationContext!
|
||||
}
|
||||
|
||||
type Organization implements Node {
|
||||
id: ID!
|
||||
name: String!
|
||||
logoUrl: String @goField(forceResolver: true)
|
||||
horizontalLogoUrl: String @goField(forceResolver: true)
|
||||
|
||||
description: String
|
||||
websiteUrl: String
|
||||
email: String
|
||||
headquarterAddress: String
|
||||
context: OrganizationContext @goField(forceResolver: true)
|
||||
|
||||
profiles(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: ProfileOrder
|
||||
filter: ProfileFilter
|
||||
): ProfileConnection! @goField(forceResolver: true)
|
||||
|
||||
measureCategories: [String!]! @goField(forceResolver: true)
|
||||
|
||||
accessSources(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: AccessSourceOrder
|
||||
): AccessSourceConnection! @goField(forceResolver: true)
|
||||
|
||||
accessReviewCampaigns(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: AccessReviewCampaignOrder
|
||||
): AccessReviewCampaignConnection! @goField(forceResolver: true)
|
||||
|
||||
assets(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: AssetOrder
|
||||
filter: AssetFilter = { snapshotId: null }
|
||||
): AssetConnection! @goField(forceResolver: true)
|
||||
|
||||
data(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: DatumOrder
|
||||
filter: DatumFilter = { snapshotId: null }
|
||||
): DatumConnection! @goField(forceResolver: true)
|
||||
|
||||
audits(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: AuditOrder
|
||||
): AuditConnection! @goField(forceResolver: true)
|
||||
|
||||
findings(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: FindingOrder
|
||||
filter: FindingFilter = { snapshotId: null }
|
||||
): FindingConnection @goField(forceResolver: true)
|
||||
|
||||
auditLogEntries(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: AuditLogEntryOrder
|
||||
filter: AuditLogEntryFilter
|
||||
): AuditLogEntryConnection! @goField(forceResolver: true)
|
||||
|
||||
slackConnections(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): SlackConnectionConnection! @goField(forceResolver: true)
|
||||
slackOAuth2Scopes: [String!]! @goField(forceResolver: true)
|
||||
connectors(filter: ConnectorFilter): [Connector!]! @goField(forceResolver: true)
|
||||
connectorProviderInfos: [ConnectorProviderInfo!]! @goField(forceResolver: true)
|
||||
|
||||
controls(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: ControlOrder
|
||||
filter: ControlFilter
|
||||
): ControlConnection! @goField(forceResolver: true)
|
||||
|
||||
statementsOfApplicability(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: StatementOfApplicabilityOrder
|
||||
filter: StatementOfApplicabilityFilter = { snapshotId: null }
|
||||
): StatementOfApplicabilityConnection! @goField(forceResolver: true)
|
||||
|
||||
dataProtectionImpactAssessments(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: DataProtectionImpactAssessmentOrder
|
||||
filter: DataProtectionImpactAssessmentFilter = { snapshotId: null }
|
||||
): DataProtectionImpactAssessmentConnection! @goField(forceResolver: true)
|
||||
|
||||
transferImpactAssessments(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: TransferImpactAssessmentOrder
|
||||
filter: TransferImpactAssessmentFilter = { snapshotId: null }
|
||||
): TransferImpactAssessmentConnection! @goField(forceResolver: true)
|
||||
|
||||
documents(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: DocumentOrder
|
||||
filter: DocumentFilter
|
||||
): DocumentConnection! @goField(forceResolver: true)
|
||||
|
||||
evidences(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: EvidenceOrder
|
||||
): EvidenceConnection! @goField(forceResolver: true)
|
||||
|
||||
frameworks(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: FrameworkOrder
|
||||
): FrameworkConnection! @goField(forceResolver: true)
|
||||
|
||||
measures(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: MeasureOrder
|
||||
filter: MeasureFilter
|
||||
): MeasureConnection! @goField(forceResolver: true)
|
||||
|
||||
meetings(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: MeetingOrder
|
||||
): MeetingConnection! @goField(forceResolver: true)
|
||||
|
||||
obligations(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: ObligationOrder
|
||||
filter: ObligationFilter = { snapshotId: null }
|
||||
): ObligationConnection! @goField(forceResolver: true)
|
||||
|
||||
processingActivities(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: ProcessingActivityOrder
|
||||
filter: ProcessingActivityFilter = { snapshotId: null }
|
||||
): ProcessingActivityConnection! @goField(forceResolver: true)
|
||||
|
||||
rightsRequests(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: RightsRequestOrder
|
||||
): RightsRequestConnection! @goField(forceResolver: true)
|
||||
|
||||
risks(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: RiskOrder
|
||||
filter: RiskFilter = { snapshotId: null }
|
||||
): RiskConnection! @goField(forceResolver: true)
|
||||
|
||||
snapshots(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: SnapshotOrder
|
||||
): SnapshotConnection! @goField(forceResolver: true)
|
||||
|
||||
tasks(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: TaskOrder
|
||||
): TaskConnection! @goField(forceResolver: true)
|
||||
|
||||
trustCenter: TrustCenter @goField(forceResolver: true)
|
||||
customDomain: CustomDomain @goField(forceResolver: true)
|
||||
trustCenterFiles(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: TrustCenterFileOrder
|
||||
): TrustCenterFileConnection! @goField(forceResolver: true)
|
||||
|
||||
vendors(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: VendorOrder
|
||||
filter: VendorFilter = { snapshotId: null }
|
||||
): VendorConnection! @goField(forceResolver: true)
|
||||
|
||||
webhookSubscriptions(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: WebhookSubscriptionOrder
|
||||
): WebhookSubscriptionConnection! @goField(forceResolver: true)
|
||||
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
permission(action: String!): Boolean! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
extend type Organization {
|
||||
processingActivities(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: ProcessingActivityOrder
|
||||
filter: ProcessingActivityFilter = { snapshotId: null }
|
||||
): ProcessingActivityConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum ProcessingActivitySpecialOrCriminalDatum
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.ProcessingActivitySpecialOrCriminalDatum"
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
extend type Organization {
|
||||
rightsRequests(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: RightsRequestOrder
|
||||
): RightsRequestConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum RightsRequestType
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.RightsRequestType") {
|
||||
ACCESS
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
extend type Organization {
|
||||
risks(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: RiskOrder
|
||||
filter: RiskFilter = { snapshotId: null }
|
||||
): RiskConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum RiskTreatment
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.RiskTreatment") {
|
||||
MITIGATED
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
extend type Organization {
|
||||
snapshots(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: SnapshotOrder
|
||||
): SnapshotConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum SnapshotsType
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.SnapshotsType") {
|
||||
RISKS @goEnum(value: "go.probo.inc/probo/pkg/coredata.SnapshotsTypeRisks")
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
extend type Organization {
|
||||
tasks(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: TaskOrder
|
||||
): TaskConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum TaskState @goModel(model: "go.probo.inc/probo/pkg/coredata.TaskState") {
|
||||
TODO @goEnum(value: "go.probo.inc/probo/pkg/coredata.TaskStateTodo")
|
||||
IN_PROGRESS @goEnum(value: "go.probo.inc/probo/pkg/coredata.TaskStateInProgress")
|
||||
|
||||
@@ -1,15 +1,3 @@
|
||||
extend type Organization {
|
||||
trustCenter: TrustCenter @goField(forceResolver: true)
|
||||
customDomain: CustomDomain @goField(forceResolver: true)
|
||||
trustCenterFiles(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: TrustCenterFileOrder
|
||||
): TrustCenterFileConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum TrustCenterVisibility
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.TrustCenterVisibility") {
|
||||
NONE
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
extend type Organization {
|
||||
vendors(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: VendorOrder
|
||||
filter: VendorFilter = { snapshotId: null }
|
||||
): VendorConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum VendorCategory
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.VendorCategory") {
|
||||
ANALYTICS
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
extend type Organization {
|
||||
webhookSubscriptions(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: WebhookSubscriptionOrder
|
||||
): WebhookSubscriptionConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum WebhookEventType
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.WebhookEventType") {
|
||||
MEETING_CREATED
|
||||
|
||||
@@ -386,41 +386,6 @@ func (r *mutationResolver) DeleteMeasureDocumentMapping(ctx context.Context, inp
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Measures is the resolver for the measures field.
|
||||
func (r *organizationResolver) Measures(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) (*types.MeasureConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionMeasureList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.MeasureOrderField]{
|
||||
Field: coredata.MeasureOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.MeasureOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
var measureFilter = coredata.NewMeasureFilter(nil, nil, nil)
|
||||
if filter != nil {
|
||||
measureFilter = coredata.NewMeasureFilter(filter.Query, filter.State, filter.Category)
|
||||
}
|
||||
|
||||
page, err := prb.Measures.ListForOrganizationID(ctx, obj.ID, cursor, measureFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization measures", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewMeasureConnection(page, r, obj.ID, measureFilter), nil
|
||||
}
|
||||
|
||||
// Measure returns schema.MeasureResolver implementation.
|
||||
func (r *Resolver) Measure() schema.MeasureResolver { return &measureResolver{r} }
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"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"
|
||||
@@ -185,36 +184,6 @@ func (r *mutationResolver) DeleteMeeting(ctx context.Context, input types.Delete
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Meetings is the resolver for the meetings field.
|
||||
func (r *organizationResolver) Meetings(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeetingOrderBy) (*types.MeetingConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionMeetingList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.MeetingOrderField]{
|
||||
Field: coredata.MeetingOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.MeetingOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := prb.Meetings.ListForOrganizationID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization meetings", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewMeetingConnection(page, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// Meeting returns schema.MeetingResolver implementation.
|
||||
func (r *Resolver) Meeting() schema.MeetingResolver { return &meetingResolver{r} }
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"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"
|
||||
@@ -199,42 +198,6 @@ func (r *obligationConnectionResolver) TotalCount(ctx context.Context, obj *type
|
||||
return 0, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
// Obligations is the resolver for the obligations field.
|
||||
func (r *organizationResolver) Obligations(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ObligationOrderBy, filter *types.ObligationFilter) (*types.ObligationConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionObligationList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.ObligationOrderField]{
|
||||
Field: coredata.ObligationOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.ObligationOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
obligationFilter := coredata.NewObligationFilter(nil)
|
||||
if filter != nil {
|
||||
obligationFilter = coredata.NewObligationFilter(&filter.SnapshotID)
|
||||
}
|
||||
|
||||
page, err := prb.Obligations.ListForOrganizationID(ctx, obj.ID, cursor, obligationFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization obligations", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewObligationConnection(page, r, obj.ID, filter), nil
|
||||
}
|
||||
|
||||
// Obligation returns schema.ObligationResolver implementation.
|
||||
func (r *Resolver) Obligation() schema.ObligationResolver { return &obligationResolver{r} }
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -155,42 +155,6 @@ func (r *mutationResolver) ExportProcessingActivitiesPDF(ctx context.Context, in
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ProcessingActivities is the resolver for the processingActivities field.
|
||||
func (r *organizationResolver) ProcessingActivities(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProcessingActivityOrderBy, filter *types.ProcessingActivityFilter) (*types.ProcessingActivityConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionProcessingActivityList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.ProcessingActivityOrderField]{
|
||||
Field: coredata.ProcessingActivityOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.ProcessingActivityOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
processingActivityFilter := coredata.NewProcessingActivityFilter(nil)
|
||||
if filter != nil {
|
||||
processingActivityFilter = coredata.NewProcessingActivityFilter(&filter.SnapshotID)
|
||||
}
|
||||
|
||||
page, err := prb.ProcessingActivities.ListForOrganizationID(ctx, obj.ID, cursor, processingActivityFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization processing activities", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewProcessingActivityConnection(page, r, obj.ID, filter), nil
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *processingActivityResolver) Organization(ctx context.Context, obj *types.ProcessingActivity) (*types.Organization, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil {
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"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/schema"
|
||||
"go.probo.inc/probo/pkg/server/api/console/v1/types"
|
||||
@@ -105,37 +104,6 @@ func (r *mutationResolver) DeleteRightsRequest(ctx context.Context, input types.
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RightsRequests is the resolver for the rightsRequests field.
|
||||
func (r *organizationResolver) RightsRequests(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.RightsRequestOrderBy) (*types.RightsRequestConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionRightsRequestList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.RightsRequestOrderField]{
|
||||
Field: coredata.RightsRequestOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.RightsRequestOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := prb.RightsRequests.ListForOrganizationID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization rights requests", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewRightsRequestConnection(page, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *rightsRequestResolver) Organization(ctx context.Context, obj *types.RightsRequest) (*types.Organization, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionOrganizationGet); err != nil {
|
||||
|
||||
@@ -239,41 +239,6 @@ func (r *mutationResolver) DeleteRiskObligationMapping(ctx context.Context, inpu
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Risks is the resolver for the risks field.
|
||||
func (r *organizationResolver) Risks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.RiskOrderBy, filter *types.RiskFilter) (*types.RiskConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionRiskList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.RiskOrderField]{
|
||||
Field: coredata.RiskOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.RiskOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
var riskFilter = coredata.NewRiskFilter(nil, nil)
|
||||
if filter != nil {
|
||||
riskFilter = coredata.NewRiskFilter(filter.Query, &filter.SnapshotID)
|
||||
}
|
||||
|
||||
page, err := prb.Risks.ListForOrganizationID(ctx, obj.ID, cursor, riskFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization risks", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewRiskConnection(page, r, obj.ID, riskFilter), nil
|
||||
}
|
||||
|
||||
// Owner is the resolver for the owner field.
|
||||
func (r *riskResolver) Owner(ctx context.Context, obj *types.Risk) (*types.Profile, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil {
|
||||
|
||||
@@ -64,36 +64,6 @@ func (r *mutationResolver) DeleteSnapshot(ctx context.Context, input types.Delet
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Snapshots is the resolver for the snapshots field.
|
||||
func (r *organizationResolver) Snapshots(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SnapshotOrderBy) (*types.SnapshotConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionSnapshotList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.SnapshotOrderField]{
|
||||
Field: coredata.SnapshotOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.SnapshotOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := prb.Snapshots.ListForOrganizationID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization snapshots", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewSnapshotConnection(page, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *snapshotResolver) Organization(ctx context.Context, obj *types.Snapshot) (*types.Organization, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil {
|
||||
|
||||
@@ -115,36 +115,6 @@ func (r *mutationResolver) DeleteTask(ctx context.Context, input types.DeleteTas
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Tasks is the resolver for the tasks field.
|
||||
func (r *organizationResolver) Tasks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TaskOrderBy) (*types.TaskConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionTaskList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.TaskOrderField]{
|
||||
Field: coredata.TaskOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.TaskOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := prb.Tasks.ListForOrganizationID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization tasks", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewTaskConnection(page, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// AssignedTo is the resolver for the assignedTo field.
|
||||
func (r *taskResolver) AssignedTo(ctx context.Context, obj *types.Task) (*types.Profile, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil {
|
||||
|
||||
@@ -675,83 +675,6 @@ func (r *mutationResolver) DeleteCustomDomain(ctx context.Context, input types.D
|
||||
}, nil
|
||||
}
|
||||
|
||||
// TrustCenter is the resolver for the trustCenter field.
|
||||
func (r *organizationResolver) TrustCenter(ctx context.Context, obj *types.Organization) (*types.TrustCenter, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterGet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
trustCenter, err := prb.TrustCenters.GetByOrganizationID(ctx, obj.ID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot get trust center", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
var file *coredata.File
|
||||
if trustCenter.NonDisclosureAgreementFileID != nil {
|
||||
file, err = prb.Files.Get(ctx, *trustCenter.NonDisclosureAgreementFileID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot get NDA file", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
return types.NewTrustCenter(trustCenter, file), nil
|
||||
}
|
||||
|
||||
// CustomDomain is the resolver for the customDomain field.
|
||||
func (r *organizationResolver) CustomDomain(ctx context.Context, obj *types.Organization) (*types.CustomDomain, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionCustomDomainGet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
domain, err := prb.CustomDomains.GetOrganizationCustomDomain(ctx, obj.ID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot get custom domain", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
if domain == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return types.NewCustomDomain(domain, r.customDomainCname), nil
|
||||
}
|
||||
|
||||
// TrustCenterFiles is the resolver for the trustCenterFiles field.
|
||||
func (r *organizationResolver) TrustCenterFiles(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterFileOrderField]) (*types.TrustCenterFileConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterFileList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.TrustCenterFileOrderField]{
|
||||
Field: coredata.TrustCenterFileOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.TrustCenterFileOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
pageResult, err := prb.TrustCenterFiles.ListForOrganizationID(ctx, obj.ID, cursor, &coredata.TrustCenterFileFilter{})
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization trust center files", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewTrustCenterFileConnection(pageResult, obj.ID), nil
|
||||
}
|
||||
|
||||
// LogoFileURL is the resolver for the logoFileUrl field.
|
||||
func (r *trustCenterResolver) LogoFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterGet); err != nil {
|
||||
|
||||
@@ -558,41 +558,6 @@ func (r *mutationResolver) AssessVendor(ctx context.Context, input types.AssessV
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Vendors is the resolver for the vendors field.
|
||||
func (r *organizationResolver) Vendors(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy, filter *types.VendorFilter) (*types.VendorConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionVendorList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.VendorOrderField]{
|
||||
Field: coredata.VendorOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.VendorOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
var vendorFilter = coredata.NewVendorFilter(nil, nil)
|
||||
if filter != nil {
|
||||
vendorFilter = coredata.NewVendorFilter(&filter.SnapshotID, nil)
|
||||
}
|
||||
|
||||
page, err := prb.Vendors.ListForOrganizationID(ctx, obj.ID, cursor, vendorFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization vendors", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewVendorConnection(page, r, obj.ID), 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 {
|
||||
|
||||
@@ -99,36 +99,6 @@ func (r *mutationResolver) DeleteWebhookSubscription(ctx context.Context, input
|
||||
}, nil
|
||||
}
|
||||
|
||||
// WebhookSubscriptions is the resolver for the webhookSubscriptions field.
|
||||
func (r *organizationResolver) WebhookSubscriptions(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.WebhookSubscriptionOrderBy) (*types.WebhookSubscriptionConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionWebhookSubscriptionList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.WebhookSubscriptionOrderField]{
|
||||
Field: coredata.WebhookSubscriptionOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.WebhookSubscriptionOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := prb.WebhookSubscriptions.ListForOrganizationID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list organization webhook subscriptions", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewWebhookSubscriptionConnection(page, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// TotalCount is the resolver for the totalCount field.
|
||||
func (r *webhookEventConnectionResolver) TotalCount(ctx context.Context, obj *types.WebhookEventConnection) (int, error) {
|
||||
if err := r.authorize(ctx, obj.ParentID, probo.ActionWebhookSubscriptionGet); err != nil {
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
"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/saferedirect"
|
||||
"go.probo.inc/probo/pkg/server/api/authn"
|
||||
"go.probo.inc/probo/pkg/server/api/compliancepage"
|
||||
@@ -350,164 +349,6 @@ func (r *queryResolver) OidcProviders(ctx context.Context) ([]*types.OIDCProvide
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// Mutation returns schema.MutationResolver implementation.
|
||||
func (r *Resolver) Mutation() schema.MutationResolver { return &mutationResolver{r} }
|
||||
|
||||
@@ -517,10 +358,6 @@ func (r *Resolver) Organization() schema.OrganizationResolver { return &organiza
|
||||
// Query returns schema.QueryResolver implementation.
|
||||
func (r *Resolver) Query() schema.QueryResolver { return &queryResolver{r} }
|
||||
|
||||
// TrustCenter returns schema.TrustCenterResolver implementation.
|
||||
func (r *Resolver) TrustCenter() schema.TrustCenterResolver { return &trustCenterResolver{r} }
|
||||
|
||||
type mutationResolver struct{ *Resolver }
|
||||
type organizationResolver struct{ *Resolver }
|
||||
type queryResolver struct{ *Resolver }
|
||||
type trustCenterResolver struct{ *Resolver }
|
||||
|
||||
@@ -315,65 +315,6 @@ type Query {
|
||||
@session(required: OPTIONAL)
|
||||
}
|
||||
|
||||
type TrustCenter implements Node {
|
||||
id: ID!
|
||||
active: Boolean!
|
||||
slug: String!
|
||||
logoFileUrl: String @goField(forceResolver: true)
|
||||
darkLogoFileUrl: String @goField(forceResolver: true)
|
||||
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
|
||||
documents(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): DocumentConnection! @goField(forceResolver: true)
|
||||
|
||||
audits(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): AuditConnection! @goField(forceResolver: true)
|
||||
|
||||
subprocessors(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): SubprocessorConnection! @goField(forceResolver: true)
|
||||
|
||||
references(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): TrustCenterReferenceConnection! @goField(forceResolver: true)
|
||||
|
||||
trustCenterFiles(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): TrustCenterFileConnection! @goField(forceResolver: true)
|
||||
|
||||
complianceFrameworks(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): ComplianceFrameworkConnection! @goField(forceResolver: true)
|
||||
|
||||
externalUrls(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): ComplianceExternalURLConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
sendMagicLink(input: SendMagicLinkInput!): SendMagicLinkPayload
|
||||
@session(required: OPTIONAL)
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
extend type TrustCenter {
|
||||
viewerSubscription: MailingListSubscriber @goField(forceResolver: true)
|
||||
|
||||
updates(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): MailingListUpdateConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type MailingListUpdate implements Node {
|
||||
id: ID!
|
||||
title: String!
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
extend type TrustCenter {
|
||||
nonDisclosureAgreement: NonDisclosureAgreement @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type NonDisclosureAgreement {
|
||||
fileName: String!
|
||||
fileUrl: String! @goField(forceResolver: true)
|
||||
|
||||
@@ -1,3 +1,73 @@
|
||||
type TrustCenter implements Node {
|
||||
id: ID!
|
||||
active: Boolean!
|
||||
slug: String!
|
||||
logoFileUrl: String @goField(forceResolver: true)
|
||||
darkLogoFileUrl: String @goField(forceResolver: true)
|
||||
|
||||
nonDisclosureAgreement: NonDisclosureAgreement @goField(forceResolver: true)
|
||||
|
||||
viewerSubscription: MailingListSubscriber @goField(forceResolver: true)
|
||||
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
|
||||
documents(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): DocumentConnection! @goField(forceResolver: true)
|
||||
|
||||
audits(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): AuditConnection! @goField(forceResolver: true)
|
||||
|
||||
subprocessors(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): SubprocessorConnection! @goField(forceResolver: true)
|
||||
|
||||
references(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): TrustCenterReferenceConnection! @goField(forceResolver: true)
|
||||
|
||||
trustCenterFiles(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): TrustCenterFileConnection! @goField(forceResolver: true)
|
||||
|
||||
complianceFrameworks(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): ComplianceFrameworkConnection! @goField(forceResolver: true)
|
||||
|
||||
externalUrls(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): ComplianceExternalURLConnection! @goField(forceResolver: true)
|
||||
|
||||
updates(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): MailingListUpdateConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
enum DocumentType
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.DocumentType") {
|
||||
OTHER @goEnum(value: "go.probo.inc/probo/pkg/coredata.DocumentTypeOther")
|
||||
|
||||
@@ -10,9 +10,7 @@ import (
|
||||
"errors"
|
||||
|
||||
"go.gearno.de/kit/log"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/mailman"
|
||||
"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/types"
|
||||
@@ -81,57 +79,3 @@ func (r *mutationResolver) UnsubscribeFromMailingList(ctx context.Context) (*typ
|
||||
|
||||
return &types.UnsubscribeFromMailingListPayload{DeletedMailingListSubscriberID: &subscriber.ID}, 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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -137,27 +137,6 @@ func (r *nonDisclosureAgreementResolver) ViewerSignature(ctx context.Context, ob
|
||||
return types.NewElectronicSignature(sig), nil
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// NonDisclosureAgreement returns schema.NonDisclosureAgreementResolver implementation.
|
||||
func (r *Resolver) NonDisclosureAgreement() schema.NonDisclosureAgreementResolver {
|
||||
return &nonDisclosureAgreementResolver{r}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"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"
|
||||
@@ -609,6 +610,239 @@ func (r *subprocessorConnectionResolver) TotalCount(ctx context.Context, obj *ty
|
||||
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())
|
||||
@@ -725,6 +959,9 @@ func (r *Resolver) SubprocessorConnection() schema.SubprocessorConnectionResolve
|
||||
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}
|
||||
@@ -741,5 +978,6 @@ 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 }
|
||||
|
||||
Reference in New Issue
Block a user