diff --git a/pkg/cmd/trust-center/update/update.go b/pkg/cmd/trust-center/update/update.go index a97e514bf..117e4be48 100644 --- a/pkg/cmd/trust-center/update/update.go +++ b/pkg/cmd/trust-center/update/update.go @@ -49,6 +49,10 @@ mutation($input: UpdateTrustCenterInput!) { id active searchEngineIndexing + description + websiteUrl + email + headquarterAddress } } } @@ -66,9 +70,13 @@ type trustCenterQueryResponse struct { type updateResponse struct { UpdateTrustCenter struct { TrustCenter struct { - ID string `json:"id"` - Active bool `json:"active"` - SearchEngineIndexing string `json:"searchEngineIndexing"` + ID string `json:"id"` + Active bool `json:"active"` + SearchEngineIndexing string `json:"searchEngineIndexing"` + Description *string `json:"description"` + WebsiteURL *string `json:"websiteUrl"` + Email *string `json:"email"` + HeadquarterAddress *string `json:"headquarterAddress"` } `json:"trustCenter"` } `json:"updateTrustCenter"` } @@ -78,6 +86,10 @@ func NewCmdUpdate(f *cmdutil.Factory) *cobra.Command { flagOrg string flagActive bool flagSearchEngineIndexing string + flagDescription string + flagWebsiteURL string + flagEmail string + flagHeadquarterAddress string ) cmd := &cobra.Command{ @@ -158,6 +170,22 @@ func NewCmdUpdate(f *cmdutil.Factory) *cobra.Command { input["searchEngineIndexing"] = flagSearchEngineIndexing } + if cmd.Flags().Changed("description") { + input["description"] = flagDescription + } + + if cmd.Flags().Changed("website-url") { + input["websiteUrl"] = flagWebsiteURL + } + + if cmd.Flags().Changed("email") { + input["email"] = flagEmail + } + + if cmd.Flags().Changed("headquarter-address") { + input["headquarterAddress"] = flagHeadquarterAddress + } + if len(input) == 1 { return fmt.Errorf("at least one field must be specified for update") } @@ -189,6 +217,10 @@ func NewCmdUpdate(f *cmdutil.Factory) *cobra.Command { cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID") cmd.Flags().BoolVar(&flagActive, "active", false, "Enable or disable the trust center") cmd.Flags().StringVar(&flagSearchEngineIndexing, "search-engine-indexing", "", "Search engine indexing: INDEXABLE, NOT_INDEXABLE") + cmd.Flags().StringVar(&flagDescription, "description", "", "Compliance page description") + cmd.Flags().StringVar(&flagWebsiteURL, "website-url", "", "Compliance page website URL") + cmd.Flags().StringVar(&flagEmail, "email", "", "Compliance page contact email") + cmd.Flags().StringVar(&flagHeadquarterAddress, "headquarter-address", "", "Compliance page headquarter address") return cmd } diff --git a/pkg/complianceportal/visitor/compliance_page_service.go b/pkg/complianceportal/visitor/compliance_page_service.go index e5c69076b..9ae2debb0 100644 --- a/pkg/complianceportal/visitor/compliance_page_service.go +++ b/pkg/complianceportal/visitor/compliance_page_service.go @@ -584,7 +584,7 @@ func (s *Service) fetchThirdParties( }, ) - result, err := s.ListThirdPartiesForOrganizationID(ctx, scope, orgID, cursor) + result, err := s.ListThirdPartiesForOrganizationID(ctx, scope, orgID, cursor, nil) if err != nil { return nil, fmt.Errorf("cannot list thirdParties: %w", err) } diff --git a/pkg/complianceportal/visitor/third_party_service.go b/pkg/complianceportal/visitor/third_party_service.go index 327c1e297..1c9fc73e8 100644 --- a/pkg/complianceportal/visitor/third_party_service.go +++ b/pkg/complianceportal/visitor/third_party_service.go @@ -60,15 +60,18 @@ func (s *Service) ListThirdPartiesForOrganizationID( scope coredata.Scoper, organizationID gid.GID, cursor *page.Cursor[coredata.ThirdPartyOrderField], + filter *coredata.ThirdPartyFilter, ) (*page.Page[*coredata.ThirdParty, coredata.ThirdPartyOrderField], error) { + if filter == nil { + showOnTrustCenter := true + filter = coredata.NewThirdPartyFilter(&showOnTrustCenter, nil, nil, nil, nil) + } + var thirdParties coredata.ThirdParties err := s.pg.WithConn( ctx, func(ctx context.Context, conn pg.Querier) error { - showOnTrustCenter := true - filter := coredata.NewThirdPartyFilter(&showOnTrustCenter, nil, nil, nil, nil) - err := thirdParties.LoadByOrganizationID(ctx, conn, scope, organizationID, cursor, filter) if err != nil { return fmt.Errorf("cannot load thirdParties: %w", err) @@ -146,7 +149,13 @@ func (s *Service) CountThirdPartiesForPortalID( ctx context.Context, scope coredata.Scoper, trustCenterID gid.GID, + filter *coredata.ThirdPartyFilter, ) (int, error) { + if filter == nil { + showOnTrustCenter := true + filter = coredata.NewThirdPartyFilter(&showOnTrustCenter, nil, nil, nil, nil) + } + var count int err := s.pg.WithConn( @@ -158,8 +167,6 @@ func (s *Service) CountThirdPartiesForPortalID( } thirdParties := &coredata.ThirdParties{} - showOnTrustCenter := true - filter := coredata.NewThirdPartyFilter(&showOnTrustCenter, nil, nil, nil, nil) count, err = thirdParties.CountByOrganizationID(ctx, conn, scope, trustCenter.OrganizationID, filter) if err != nil { diff --git a/pkg/server/api/connect/v1/graphql/organization.graphql b/pkg/server/api/connect/v1/graphql/organization.graphql index 5622b6d03..7fecf35ff 100644 --- a/pkg/server/api/connect/v1/graphql/organization.graphql +++ b/pkg/server/api/connect/v1/graphql/organization.graphql @@ -3,10 +3,6 @@ type Organization implements Node { name: String! logo: File @goField(forceResolver: true) horizontalLogo: File @goField(forceResolver: true) - email: String - description: String - websiteUrl: String - headquarterAddress: String createdAt: Datetime! updatedAt: Datetime! @@ -70,10 +66,6 @@ input UpdateOrganizationInput { name: String logoFile: Upload horizontalLogoFile: Upload - description: String @goField(omittable: true) - websiteUrl: String @goField(omittable: true) - email: String @goField(omittable: true) - headquarterAddress: String @goField(omittable: true) } input DeleteOrganizationInput { diff --git a/pkg/server/api/connect/v1/organization_resolvers.go b/pkg/server/api/connect/v1/organization_resolvers.go index b638d2556..f31c9a842 100644 --- a/pkg/server/api/connect/v1/organization_resolvers.go +++ b/pkg/server/api/connect/v1/organization_resolvers.go @@ -87,11 +87,7 @@ func (r *mutationResolver) UpdateOrganization(ctx context.Context, input types.U } req := &iam.UpdateOrganizationRequest{ - Name: input.Name, - Description: gqlutils.UnwrapOmittable(input.Description), - WebsiteURL: gqlutils.UnwrapOmittable(input.WebsiteURL), - Email: gqlutils.UnwrapOmittable(input.Email), - HeadquarterAddress: gqlutils.UnwrapOmittable(input.HeadquarterAddress), + Name: input.Name, } if input.LogoFile != nil { @@ -124,14 +120,10 @@ func (r *mutationResolver) UpdateOrganization(ctx context.Context, input types.U return &types.UpdateOrganizationPayload{ Organization: &types.Organization{ - ID: organization.ID, - Name: organization.Name, - Description: organization.Description, - WebsiteURL: organization.WebsiteURL, - Email: organization.Email, - HeadquarterAddress: organization.HeadquarterAddress, - CreatedAt: organization.CreatedAt, - UpdatedAt: organization.UpdatedAt, + ID: organization.ID, + Name: organization.Name, + CreatedAt: organization.CreatedAt, + UpdatedAt: organization.UpdatedAt, }, }, nil } diff --git a/pkg/server/api/connect/v1/types/organization.go b/pkg/server/api/connect/v1/types/organization.go index cb4046c36..321a82cb0 100644 --- a/pkg/server/api/connect/v1/types/organization.go +++ b/pkg/server/api/connect/v1/types/organization.go @@ -30,14 +30,10 @@ type ( func NewOrganization(organization *coredata.Organization) *Organization { org := &Organization{ - ID: organization.ID, - Name: organization.Name, - Email: organization.Email, - Description: organization.Description, - WebsiteURL: organization.WebsiteURL, - HeadquarterAddress: organization.HeadquarterAddress, - CreatedAt: organization.CreatedAt, - UpdatedAt: organization.UpdatedAt, + ID: organization.ID, + Name: organization.Name, + CreatedAt: organization.CreatedAt, + UpdatedAt: organization.UpdatedAt, } if organization.LogoFileID != nil { diff --git a/pkg/server/api/console/v1/base_resolvers.go b/pkg/server/api/console/v1/base_resolvers.go index 73275f912..066d3c825 100644 --- a/pkg/server/api/console/v1/base_resolvers.go +++ b/pkg/server/api/console/v1/base_resolvers.go @@ -14,6 +14,7 @@ import ( "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/accessreview" "go.probo.inc/probo/pkg/agentrun" + "go.probo.inc/probo/pkg/complianceportal" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/gid" "go.probo.inc/probo/pkg/probo" @@ -334,9 +335,9 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error return types.NewTransferImpactAssessment(tia), nil } case coredata.TrustCenterEntityType: - action = probo.ActionTrustCenterGet + action = complianceportal.ActionCompliancePortalGet loadNode = func(ctx context.Context, scope *coredata.Scope, id gid.GID) (types.Node, error) { - trustCenter, err := r.probo.TrustCenters.Get(ctx, scope, id) + trustCenter, err := r.management.Get(ctx, scope, id) if err != nil { return nil, err } @@ -344,9 +345,9 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error return types.NewTrustCenter(trustCenter), nil } case coredata.TrustCenterAccessEntityType: - action = probo.ActionTrustCenterAccessGet + action = complianceportal.ActionCompliancePortalAccessGet loadNode = func(ctx context.Context, scope *coredata.Scope, id gid.GID) (types.Node, error) { - trustCenterAccess, err := r.probo.TrustCenterAccesses.Get(ctx, scope, id) + trustCenterAccess, err := r.management.GetAccess(ctx, scope, id) if err != nil { return nil, err } diff --git a/pkg/server/api/console/v1/graphql/organization.graphql b/pkg/server/api/console/v1/graphql/organization.graphql index 4f57bd8a4..c1ab5261f 100644 --- a/pkg/server/api/console/v1/graphql/organization.graphql +++ b/pkg/server/api/console/v1/graphql/organization.graphql @@ -93,10 +93,6 @@ type Organization implements Node { logo: File @goField(forceResolver: true) horizontalLogo: File @goField(forceResolver: true) - description: String - websiteUrl: String - email: String - headquarterAddress: String context: OrganizationContext @goField(forceResolver: true) profiles( @@ -319,7 +315,6 @@ type Organization implements Node { ): AgentRunConnection! @goField(forceResolver: true) trustCenter: TrustCenter @goField(forceResolver: true) - customDomain: CustomDomain @goField(forceResolver: true) trustCenterFiles( first: Int after: CursorKey diff --git a/pkg/server/api/console/v1/graphql/trust_center.graphql b/pkg/server/api/console/v1/graphql/trust_center.graphql index c3fb32c8b..2307d88e5 100644 --- a/pkg/server/api/console/v1/graphql/trust_center.graphql +++ b/pkg/server/api/console/v1/graphql/trust_center.graphql @@ -106,99 +106,17 @@ enum TrustCenterReferenceOrderField ) } -enum CompliancePortalCommitmentGroupOrderField +enum ComplianceCustomLinkOrderField @goModel( - model: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentGroupOrderField" - ) { - RANK - @goEnum( - value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentGroupOrderFieldRank" - ) - CREATED_AT - @goEnum( - value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentGroupOrderFieldCreatedAt" - ) - UPDATED_AT - @goEnum( - value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentGroupOrderFieldUpdatedAt" - ) -} - -enum CompliancePortalCommitmentOrderField - @goModel( - model: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentOrderField" - ) { - RANK - @goEnum( - value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentOrderFieldRank" - ) - CREATED_AT - @goEnum( - value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentOrderFieldCreatedAt" - ) - UPDATED_AT - @goEnum( - value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentOrderFieldUpdatedAt" - ) -} - -enum CompliancePortalCommitmentIcon - @goModel( - model: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIcon" - ) { - LOCK_KEY - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconLockKey") - EYE_SLASH - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconEyeSlash") - FINGERPRINT - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconFingerprint") - SHIELD_WARNING - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconShieldWarning") - SHIELD_CHECK - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconShieldCheck") - SIREN - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconSiren") - KEY - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconKey") - LOCK - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconLock") - CLOUD - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconCloud") - DATABASE - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconDatabase") - GLOBE - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconGlobe") - EYE - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconEye") - USERS - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconUsers") - CERTIFICATE - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconCertificate") - GAVEL - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconGavel") - HEARTBEAT - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconHeartbeat") - BELL - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconBell") - BUG - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconBug") - CODE - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconCode") - SERVER - @goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconServer") -} - -enum ComplianceExternalURLOrderField - @goModel( - model: "go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderField" + model: "go.probo.inc/probo/pkg/coredata.ComplianceCustomLinkOrderField" ) { CREATED_AT @goEnum( - value: "go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderFieldCreatedAt" + value: "go.probo.inc/probo/pkg/coredata.ComplianceCustomLinkOrderFieldCreatedAt" ) RANK @goEnum( - value: "go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderFieldRank" + value: "go.probo.inc/probo/pkg/coredata.ComplianceCustomLinkOrderFieldRank" ) } @@ -300,22 +218,6 @@ input TrustCenterReferenceOrder field: TrustCenterReferenceOrderField! } -input CompliancePortalCommitmentGroupOrder - @goModel( - model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CompliancePortalCommitmentGroupOrderBy" - ) { - direction: OrderDirection! - field: CompliancePortalCommitmentGroupOrderField! -} - -input CompliancePortalCommitmentOrder - @goModel( - model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CompliancePortalCommitmentOrderBy" - ) { - direction: OrderDirection! - field: CompliancePortalCommitmentOrderField! -} - input TrustCenterFileOrder @goModel( model: "go.probo.inc/probo/pkg/server/api/console/v1/types.TrustCenterFileOrderBy" @@ -324,12 +226,12 @@ input TrustCenterFileOrder field: TrustCenterFileOrderField! } -input ComplianceExternalURLOrder +input ComplianceCustomLinkOrder @goModel( - model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceExternalURLOrderBy" + model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceCustomLinkOrderBy" ) { direction: OrderDirection! - field: ComplianceExternalURLOrderField! + field: ComplianceCustomLinkOrderField! } input ComplianceFrameworkOrder @@ -350,6 +252,10 @@ type TrustCenter implements Node logo: File @goField(forceResolver: true) darkLogo: File @goField(forceResolver: true) nda: File @goField(forceResolver: true) + description: String + websiteUrl: String + email: String + headquarterAddress: String createdAt: Datetime! updatedAt: Datetime! organization: Organization! @goField(forceResolver: true) @@ -370,14 +276,6 @@ type TrustCenter implements Node orderBy: TrustCenterReferenceOrder ): TrustCenterReferenceConnection! @goField(forceResolver: true) - commitmentGroups( - first: Int - after: CursorKey - last: Int - before: CursorKey - orderBy: CompliancePortalCommitmentGroupOrder - ): CompliancePortalCommitmentGroupConnection! @goField(forceResolver: true) - complianceFrameworks( first: Int after: CursorKey @@ -386,16 +284,22 @@ type TrustCenter implements Node orderBy: ComplianceFrameworkOrder ): ComplianceFrameworkConnection! @goField(forceResolver: true) - externalUrls( + customLinks( first: Int after: CursorKey last: Int before: CursorKey - orderBy: ComplianceExternalURLOrder - ): ComplianceExternalURLConnection! @goField(forceResolver: true) + orderBy: ComplianceCustomLinkOrder + ): ComplianceCustomLinkConnection! @goField(forceResolver: true) mailingList: MailingList @goField(forceResolver: true) + defaultDomain: CustomDomain @goField(forceResolver: true) + + customDomain: CustomDomain @goField(forceResolver: true) + + publicUrl: String! @goField(forceResolver: true) + permission(action: String!): Boolean! @goField(forceResolver: true) } @@ -495,66 +399,6 @@ type TrustCenterReferenceEdge { node: TrustCenterReference! } -type CompliancePortalCommitmentGroup implements Node { - id: ID! - title: String! - description: String! - rank: Int! - createdAt: Datetime! - updatedAt: Datetime! - - commitments( - first: Int - after: CursorKey - last: Int - before: CursorKey - orderBy: CompliancePortalCommitmentOrder - ): CompliancePortalCommitmentConnection! @goField(forceResolver: true) - - permission(action: String!): Boolean! @goField(forceResolver: true) -} - -type CompliancePortalCommitmentGroupConnection - @goModel( - model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CompliancePortalCommitmentGroupConnection" - ) { - totalCount: Int! @goField(forceResolver: true) - edges: [CompliancePortalCommitmentGroupEdge!]! - pageInfo: PageInfo! -} - -type CompliancePortalCommitmentGroupEdge { - cursor: CursorKey! - node: CompliancePortalCommitmentGroup! -} - -type CompliancePortalCommitment implements Node { - id: ID! - icon: CompliancePortalCommitmentIcon! - eyebrow: String! - title: String! - description: String! - rank: Int! - createdAt: Datetime! - updatedAt: Datetime! - - permission(action: String!): Boolean! @goField(forceResolver: true) -} - -type CompliancePortalCommitmentConnection - @goModel( - model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CompliancePortalCommitmentConnection" - ) { - totalCount: Int! @goField(forceResolver: true) - edges: [CompliancePortalCommitmentEdge!]! - pageInfo: PageInfo! -} - -type CompliancePortalCommitmentEdge { - cursor: CursorKey! - node: CompliancePortalCommitment! -} - type ComplianceFramework implements Node @goModel( model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFramework" @@ -580,7 +424,7 @@ type ComplianceFrameworkEdge { node: ComplianceFramework! } -type ComplianceExternalURL implements Node { +type ComplianceCustomLink implements Node { id: ID! name: String! url: String! @@ -591,17 +435,17 @@ type ComplianceExternalURL implements Node { permission(action: String!): Boolean! @goField(forceResolver: true) } -type ComplianceExternalURLConnection +type ComplianceCustomLinkConnection @goModel( - model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceExternalURLConnection" + model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceCustomLinkConnection" ) { - edges: [ComplianceExternalURLEdge!]! + edges: [ComplianceCustomLinkEdge!]! pageInfo: PageInfo! } -type ComplianceExternalURLEdge { +type ComplianceCustomLinkEdge { cursor: CursorKey! - node: ComplianceExternalURL! + node: ComplianceCustomLink! } type TrustCenterFile implements Node { @@ -636,6 +480,7 @@ type CustomDomain implements Node { id: ID! organization: Organization! domain: String! + managed: Boolean! sslStatus: SSLStatus! sslExpiresAt: Datetime provisioningError: String @@ -680,24 +525,6 @@ extend type Mutation { deleteTrustCenterReference( input: DeleteTrustCenterReferenceInput! ): DeleteTrustCenterReferencePayload! - createCompliancePortalCommitmentGroup( - input: CreateCompliancePortalCommitmentGroupInput! - ): CreateCompliancePortalCommitmentGroupPayload! - updateCompliancePortalCommitmentGroup( - input: UpdateCompliancePortalCommitmentGroupInput! - ): UpdateCompliancePortalCommitmentGroupPayload! - deleteCompliancePortalCommitmentGroup( - input: DeleteCompliancePortalCommitmentGroupInput! - ): DeleteCompliancePortalCommitmentGroupPayload! - createCompliancePortalCommitment( - input: CreateCompliancePortalCommitmentInput! - ): CreateCompliancePortalCommitmentPayload! - updateCompliancePortalCommitment( - input: UpdateCompliancePortalCommitmentInput! - ): UpdateCompliancePortalCommitmentPayload! - deleteCompliancePortalCommitment( - input: DeleteCompliancePortalCommitmentInput! - ): DeleteCompliancePortalCommitmentPayload! createComplianceFramework( input: CreateComplianceFrameworkInput! ): CreateComplianceFrameworkPayload! @@ -707,15 +534,15 @@ extend type Mutation { deleteComplianceFramework( input: DeleteComplianceFrameworkInput! ): DeleteComplianceFrameworkPayload! - createComplianceExternalURL( - input: CreateComplianceExternalURLInput! - ): CreateComplianceExternalURLPayload! - updateComplianceExternalURL( - input: UpdateComplianceExternalURLInput! - ): UpdateComplianceExternalURLPayload! - deleteComplianceExternalURL( - input: DeleteComplianceExternalURLInput! - ): DeleteComplianceExternalURLPayload! + createComplianceCustomLink( + input: CreateComplianceCustomLinkInput! + ): CreateComplianceCustomLinkPayload! + updateComplianceCustomLink( + input: UpdateComplianceCustomLinkInput! + ): UpdateComplianceCustomLinkPayload! + deleteComplianceCustomLink( + input: DeleteComplianceCustomLinkInput! + ): DeleteComplianceCustomLinkPayload! createTrustCenterFile( input: CreateTrustCenterFileInput! ): CreateTrustCenterFilePayload! @@ -740,6 +567,10 @@ input UpdateTrustCenterInput { trustCenterId: ID! active: Boolean searchEngineIndexing: SearchEngineIndexing + description: String @goField(omittable: true) + websiteUrl: String @goField(omittable: true) + email: String @goField(omittable: true) + headquarterAddress: String @goField(omittable: true) } input UploadTrustCenterNDAInput { @@ -797,44 +628,6 @@ input DeleteTrustCenterReferenceInput { id: ID! } -input CreateCompliancePortalCommitmentGroupInput { - trustCenterId: ID! - title: String! - description: String! -} - -input UpdateCompliancePortalCommitmentGroupInput { - id: ID! - title: String - description: String - rank: Int -} - -input DeleteCompliancePortalCommitmentGroupInput { - id: ID! -} - -input CreateCompliancePortalCommitmentInput { - groupId: ID! - icon: CompliancePortalCommitmentIcon! - eyebrow: String! - title: String! - description: String! -} - -input UpdateCompliancePortalCommitmentInput { - id: ID! - icon: CompliancePortalCommitmentIcon - eyebrow: String - title: String - description: String - rank: Int -} - -input DeleteCompliancePortalCommitmentInput { - id: ID! -} - input CreateComplianceFrameworkInput { trustCenterId: ID! frameworkId: ID! @@ -849,20 +642,20 @@ input DeleteComplianceFrameworkInput { id: ID! } -input CreateComplianceExternalURLInput { +input CreateComplianceCustomLinkInput { trustCenterId: ID! name: String! url: String! } -input UpdateComplianceExternalURLInput { +input UpdateComplianceCustomLinkInput { id: ID! name: String! url: String! rank: Int } -input DeleteComplianceExternalURLInput { +input DeleteComplianceCustomLinkInput { id: ID! } @@ -890,12 +683,12 @@ input DeleteTrustCenterFileInput { } input CreateCustomDomainInput { - organizationId: ID! + trustCenterId: ID! domain: String! } input DeleteCustomDomainInput { - organizationId: ID! + customDomainId: ID! } type UpdateTrustCenterPayload { @@ -934,30 +727,6 @@ type DeleteTrustCenterReferencePayload { deletedTrustCenterReferenceId: ID! } -type CreateCompliancePortalCommitmentGroupPayload { - compliancePortalCommitmentGroupEdge: CompliancePortalCommitmentGroupEdge! -} - -type UpdateCompliancePortalCommitmentGroupPayload { - compliancePortalCommitmentGroup: CompliancePortalCommitmentGroup! -} - -type DeleteCompliancePortalCommitmentGroupPayload { - deletedCompliancePortalCommitmentGroupId: ID! -} - -type CreateCompliancePortalCommitmentPayload { - compliancePortalCommitmentEdge: CompliancePortalCommitmentEdge! -} - -type UpdateCompliancePortalCommitmentPayload { - compliancePortalCommitment: CompliancePortalCommitment! -} - -type DeleteCompliancePortalCommitmentPayload { - deletedCompliancePortalCommitmentId: ID! -} - type CreateComplianceFrameworkPayload { complianceFrameworkEdge: ComplianceFrameworkEdge! } @@ -970,16 +739,16 @@ type DeleteComplianceFrameworkPayload { deletedComplianceFrameworkId: ID! } -type CreateComplianceExternalURLPayload { - complianceExternalUrlEdge: ComplianceExternalURLEdge! +type CreateComplianceCustomLinkPayload { + complianceCustomLinkEdge: ComplianceCustomLinkEdge! } -type UpdateComplianceExternalURLPayload { - complianceExternalUrl: ComplianceExternalURL! +type UpdateComplianceCustomLinkPayload { + complianceCustomLink: ComplianceCustomLink! } -type DeleteComplianceExternalURLPayload { - deletedComplianceExternalUrlId: ID! +type DeleteComplianceCustomLinkPayload { + deletedComplianceCustomLinkId: ID! } type CreateTrustCenterFilePayload { diff --git a/pkg/server/api/console/v1/graphql_handler.go b/pkg/server/api/console/v1/graphql_handler.go index c44bba3c0..334e7201d 100644 --- a/pkg/server/api/console/v1/graphql_handler.go +++ b/pkg/server/api/console/v1/graphql_handler.go @@ -27,6 +27,7 @@ import ( "go.probo.inc/probo/pkg/accessreview" "go.probo.inc/probo/pkg/agentrun" "go.probo.inc/probo/pkg/baseurl" + "go.probo.inc/probo/pkg/complianceportal/management" "go.probo.inc/probo/pkg/connector" "go.probo.inc/probo/pkg/connector/provider" "go.probo.inc/probo/pkg/cookiebanner" @@ -49,6 +50,7 @@ func NewGraphQLHandler( proboSvc *probo.Service, resourceAliasSvc *resourcealias.Service, esignSvc *esign.Service, + managementSvc *management.Service, accessReviewSvc *accessreview.Service, agentRunSvc *agentrun.Service, mailmanSvc *mailman.Service, @@ -72,6 +74,7 @@ func NewGraphQLHandler( resourceAlias: resourceAliasSvc, iam: iamSvc, esign: esignSvc, + management: managementSvc, accessReview: accessReviewSvc, agentRun: agentRunSvc, mailman: mailmanSvc, diff --git a/pkg/server/api/console/v1/mailing_list_resolvers.go b/pkg/server/api/console/v1/mailing_list_resolvers.go index e1089e65c..4c3af4132 100644 --- a/pkg/server/api/console/v1/mailing_list_resolvers.go +++ b/pkg/server/api/console/v1/mailing_list_resolvers.go @@ -11,10 +11,10 @@ import ( "fmt" "go.gearno.de/kit/log" + "go.probo.inc/probo/pkg/complianceportal" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/mailman" "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" @@ -23,7 +23,7 @@ import ( // Subscribers is the resolver for the subscribers field on MailingList. func (r *mailingListResolver) Subscribers(ctx context.Context, obj *types.MailingList, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.MailingListSubscriberConnection, error) { - if _, err := r.authorize(ctx, obj.ID, probo.ActionMailingListSubscriberList); err != nil { + if _, err := r.authorize(ctx, obj.ID, complianceportal.ActionMailingListSubscriberList); err != nil { return nil, err } @@ -45,7 +45,7 @@ func (r *mailingListResolver) Subscribers(ctx context.Context, obj *types.Mailin // Updates is the resolver for the updates field on MailingList. func (r *mailingListResolver) Updates(ctx context.Context, obj *types.MailingList, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.MailingListUpdateConnection, error) { - if _, err := r.authorize(ctx, obj.ID, probo.ActionMailingListUpdateList); err != nil { + if _, err := r.authorize(ctx, obj.ID, complianceportal.ActionMailingListUpdateList); err != nil { return nil, err } @@ -67,7 +67,7 @@ func (r *mailingListResolver) Updates(ctx context.Context, obj *types.MailingLis // TotalCount is the resolver for the totalCount field. func (r *mailingListSubscriberConnectionResolver) TotalCount(ctx context.Context, obj *types.MailingListSubscriberConnection) (int, error) { - if _, err := r.authorize(ctx, obj.ParentID, probo.ActionMailingListSubscriberList); err != nil { + if _, err := r.authorize(ctx, obj.ParentID, complianceportal.ActionMailingListSubscriberList); err != nil { return 0, err } @@ -89,7 +89,7 @@ func (r *mailingListSubscriberConnectionResolver) TotalCount(ctx context.Context // TotalCount is the resolver for the totalCount field on MailingListUpdateConnection. func (r *mailingListUpdateConnectionResolver) TotalCount(ctx context.Context, obj *types.MailingListUpdateConnection) (int, error) { - if _, err := r.authorize(ctx, obj.ParentID, probo.ActionMailingListUpdateList); err != nil { + if _, err := r.authorize(ctx, obj.ParentID, complianceportal.ActionMailingListUpdateList); err != nil { return 0, err } @@ -104,7 +104,7 @@ func (r *mailingListUpdateConnectionResolver) TotalCount(ctx context.Context, ob // CreateMailingListUpdate is the resolver for the createMailingListUpdate field. func (r *mutationResolver) CreateMailingListUpdate(ctx context.Context, input types.CreateMailingListUpdateInput) (*types.CreateMailingListUpdatePayload, error) { - if _, err := r.authorize(ctx, input.MailingListID, probo.ActionMailingListUpdateCreate); err != nil { + if _, err := r.authorize(ctx, input.MailingListID, complianceportal.ActionMailingListUpdateCreate); err != nil { return nil, err } @@ -133,7 +133,7 @@ func (r *mutationResolver) CreateMailingListUpdate(ctx context.Context, input ty // UpdateMailingListUpdate is the resolver for the updateMailingListUpdate field. func (r *mutationResolver) UpdateMailingListUpdate(ctx context.Context, input types.UpdateMailingListUpdateInput) (*types.UpdateMailingListUpdatePayload, error) { - if _, err := r.authorize(ctx, input.ID, probo.ActionMailingListUpdateUpdate); err != nil { + if _, err := r.authorize(ctx, input.ID, complianceportal.ActionMailingListUpdateUpdate); err != nil { return nil, err } @@ -170,7 +170,7 @@ func (r *mutationResolver) UpdateMailingListUpdate(ctx context.Context, input ty // SendMailingListUpdate is the resolver for the sendMailingListUpdate field. func (r *mutationResolver) SendMailingListUpdate(ctx context.Context, input types.SendMailingListUpdateInput) (*types.SendMailingListUpdatePayload, error) { - if _, err := r.authorize(ctx, input.ID, probo.ActionMailingListUpdateUpdate); err != nil { + if _, err := r.authorize(ctx, input.ID, complianceportal.ActionMailingListUpdateUpdate); err != nil { return nil, err } @@ -196,7 +196,7 @@ func (r *mutationResolver) SendMailingListUpdate(ctx context.Context, input type // DeleteMailingListUpdate is the resolver for the deleteMailingListUpdate field. func (r *mutationResolver) DeleteMailingListUpdate(ctx context.Context, input types.DeleteMailingListUpdateInput) (*types.DeleteMailingListUpdatePayload, error) { - if _, err := r.authorize(ctx, input.ID, probo.ActionMailingListUpdateDelete); err != nil { + if _, err := r.authorize(ctx, input.ID, complianceportal.ActionMailingListUpdateDelete); err != nil { return nil, err } @@ -217,7 +217,7 @@ func (r *mutationResolver) DeleteMailingListUpdate(ctx context.Context, input ty // UpdateMailingList is the resolver for the updateMailingList field. func (r *mutationResolver) UpdateMailingList(ctx context.Context, input types.UpdateMailingListInput) (*types.UpdateMailingListPayload, error) { - if _, err := r.authorize(ctx, input.ID, probo.ActionMailingListUpdate); err != nil { + if _, err := r.authorize(ctx, input.ID, complianceportal.ActionMailingListUpdate); err != nil { return nil, err } @@ -234,7 +234,7 @@ func (r *mutationResolver) UpdateMailingList(ctx context.Context, input types.Up // CreateMailingListSubscriber is the resolver for the createMailingListSubscriber field. func (r *mutationResolver) CreateMailingListSubscriber(ctx context.Context, input types.CreateMailingListSubscriberInput) (*types.CreateMailingListSubscriberPayload, error) { - if _, err := r.authorize(ctx, input.MailingListID, probo.ActionMailingListSubscriberCreate); err != nil { + if _, err := r.authorize(ctx, input.MailingListID, complianceportal.ActionMailingListSubscriberCreate); err != nil { return nil, err } @@ -268,7 +268,7 @@ func (r *mutationResolver) CreateMailingListSubscriber(ctx context.Context, inpu // DeleteMailingListSubscriber is the resolver for the deleteMailingListSubscriber field. func (r *mutationResolver) DeleteMailingListSubscriber(ctx context.Context, input types.DeleteMailingListSubscriberInput) (*types.DeleteMailingListSubscriberPayload, error) { - if _, err := r.authorize(ctx, input.ID, probo.ActionMailingListSubscriberDelete); err != nil { + if _, err := r.authorize(ctx, input.ID, complianceportal.ActionMailingListSubscriberDelete); err != nil { return nil, err } diff --git a/pkg/server/api/console/v1/organization_resolvers.go b/pkg/server/api/console/v1/organization_resolvers.go index 9da86d57c..9626327fa 100644 --- a/pkg/server/api/console/v1/organization_resolvers.go +++ b/pkg/server/api/console/v1/organization_resolvers.go @@ -13,6 +13,7 @@ import ( "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/accessreview" "go.probo.inc/probo/pkg/agentrun" + "go.probo.inc/probo/pkg/complianceportal" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/gid" "go.probo.inc/probo/pkg/iam" @@ -1158,12 +1159,12 @@ func (r *organizationResolver) AgentRuns(ctx context.Context, obj *types.Organiz // TrustCenter is the resolver for the trustCenter field. func (r *organizationResolver) TrustCenter(ctx context.Context, obj *types.Organization) (*types.TrustCenter, error) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterGet) + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalGet) if err != nil { return nil, err } - trustCenter, err := r.probo.TrustCenters.GetByOrganizationID(ctx, scope, obj.ID) + trustCenter, err := r.management.GetByOrganizationID(ctx, scope, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get trust center", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -1172,29 +1173,9 @@ func (r *organizationResolver) TrustCenter(ctx context.Context, obj *types.Organ return types.NewTrustCenter(trustCenter), nil } -// CustomDomain is the resolver for the customDomain field. -func (r *organizationResolver) CustomDomain(ctx context.Context, obj *types.Organization) (*types.CustomDomain, error) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionCustomDomainGet) - if err != nil { - return nil, err - } - - domain, err := r.probo.CustomDomains.GetOrganizationCustomDomain(ctx, scope, 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) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterFileList) + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalFileList) if err != nil { return nil, err } @@ -1213,7 +1194,7 @@ func (r *organizationResolver) TrustCenterFiles(ctx context.Context, obj *types. cursor := types.NewCursor(first, after, last, before, pageOrderBy) - pageResult, err := r.probo.TrustCenterFiles.ListForOrganizationID(ctx, scope, obj.ID, cursor, &coredata.TrustCenterFileFilter{}) + pageResult, err := r.management.ListFilesForOrganizationID(ctx, scope, 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) diff --git a/pkg/server/api/console/v1/resolver.go b/pkg/server/api/console/v1/resolver.go index add94b5d1..b1f5f2e39 100644 --- a/pkg/server/api/console/v1/resolver.go +++ b/pkg/server/api/console/v1/resolver.go @@ -35,6 +35,7 @@ import ( "go.probo.inc/probo/pkg/accessreview" "go.probo.inc/probo/pkg/agentrun" "go.probo.inc/probo/pkg/baseurl" + "go.probo.inc/probo/pkg/complianceportal/management" "go.probo.inc/probo/pkg/connector" "go.probo.inc/probo/pkg/connector/provider" "go.probo.inc/probo/pkg/cookiebanner" @@ -65,6 +66,7 @@ type ( resourceAlias *resourcealias.Service iam *iam.Service esign *esign.Service + management *management.Service accessReview *accessreview.Service agentRun *agentrun.Service mailman *mailman.Service @@ -81,12 +83,29 @@ type ( } ) +// newCustomDomainType loads the domain's certificate (when present) and builds +// the GraphQL CustomDomain type with its certificate-backed SSL fields. +func (r *Resolver) newCustomDomainType( + ctx context.Context, + scope coredata.Scoper, + domain *coredata.CustomDomain, +) (*types.CustomDomain, error) { + cert, err := r.management.GetCertificate(ctx, scope, domain) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot load certificate", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + return types.NewCustomDomain(domain, cert, r.customDomainCname), nil +} + func NewMux( logger *log.Logger, proboSvc *probo.Service, resourceAliasSvc *resourcealias.Service, iamSvc *iam.Service, esignSvc *esign.Service, + managementSvc *management.Service, accessReviewSvc *accessreview.Service, agentRunSvc *agentrun.Service, mailmanSvc *mailman.Service, @@ -111,6 +130,7 @@ func NewMux( proboSvc, resourceAliasSvc, esignSvc, + managementSvc, accessReviewSvc, agentRunSvc, mailmanSvc, diff --git a/pkg/server/api/console/v1/trust_center_resolvers.go b/pkg/server/api/console/v1/trust_center_resolvers.go index b5eadcd06..ada61465f 100644 --- a/pkg/server/api/console/v1/trust_center_resolvers.go +++ b/pkg/server/api/console/v1/trust_center_resolvers.go @@ -12,6 +12,8 @@ import ( "github.com/vikstrous/dataloadgen" "go.gearno.de/kit/log" + "go.probo.inc/probo/pkg/complianceportal" + "go.probo.inc/probo/pkg/complianceportal/management" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/iam" "go.probo.inc/probo/pkg/page" @@ -25,7 +27,7 @@ import ( ) // Permission is the resolver for the permission field. -func (r *complianceExternalURLResolver) Permission(ctx context.Context, obj *types.ComplianceExternalURL, action string) (bool, error) { +func (r *complianceCustomLinkResolver) Permission(ctx context.Context, obj *types.ComplianceCustomLink, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } @@ -51,78 +53,6 @@ func (r *complianceFrameworkResolver) Framework(ctx context.Context, obj *types. return types.NewFramework(framework), nil } -// Permission is the resolver for the permission field. -func (r *compliancePortalCommitmentResolver) Permission(ctx context.Context, obj *types.CompliancePortalCommitment, action string) (bool, error) { - return r.Resolver.Permission(ctx, obj, action) -} - -// TotalCount is the resolver for the totalCount field. -func (r *compliancePortalCommitmentConnectionResolver) TotalCount(ctx context.Context, obj *types.CompliancePortalCommitmentConnection) (int, error) { - scope, err := r.authorize(ctx, obj.ParentID, probo.ActionCompliancePortalCommitmentList) - if err != nil { - return 0, err - } - - count, err := r.probo.CompliancePortalCommitments.CountForGroupID(ctx, scope, obj.ParentID) - if err != nil { - r.logger.ErrorCtx(ctx, "cannot count compliance portal commitments", log.Error(err)) - return 0, gqlutils.Internal(ctx) - } - - return count, nil -} - -// Commitments is the resolver for the commitments field. -func (r *compliancePortalCommitmentGroupResolver) Commitments(ctx context.Context, obj *types.CompliancePortalCommitmentGroup, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.CompliancePortalCommitmentOrderField]) (*types.CompliancePortalCommitmentConnection, error) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionCompliancePortalCommitmentList) - if err != nil { - return nil, err - } - - pageOrderBy := page.OrderBy[coredata.CompliancePortalCommitmentOrderField]{ - Field: coredata.CompliancePortalCommitmentOrderFieldRank, - Direction: page.OrderDirectionAsc, - } - - if orderBy != nil { - pageOrderBy = page.OrderBy[coredata.CompliancePortalCommitmentOrderField]{ - Field: orderBy.Field, - Direction: orderBy.Direction, - } - } - - cursor := types.NewCursor(first, after, last, before, pageOrderBy) - - result, err := r.probo.CompliancePortalCommitments.ListForGroupID(ctx, scope, obj.ID, cursor) - if err != nil { - r.logger.ErrorCtx(ctx, "cannot list compliance portal commitments", log.Error(err)) - return nil, gqlutils.Internal(ctx) - } - - return types.NewCompliancePortalCommitmentConnection(result, obj.ID), nil -} - -// Permission is the resolver for the permission field. -func (r *compliancePortalCommitmentGroupResolver) Permission(ctx context.Context, obj *types.CompliancePortalCommitmentGroup, action string) (bool, error) { - return r.Resolver.Permission(ctx, obj, action) -} - -// TotalCount is the resolver for the totalCount field. -func (r *compliancePortalCommitmentGroupConnectionResolver) TotalCount(ctx context.Context, obj *types.CompliancePortalCommitmentGroupConnection) (int, error) { - scope, err := r.authorize(ctx, obj.ParentID, probo.ActionCompliancePortalCommitmentGroupList) - if err != nil { - return 0, err - } - - count, err := r.probo.CompliancePortalCommitmentGroups.CountForTrustCenterID(ctx, scope, obj.ParentID) - if err != nil { - r.logger.ErrorCtx(ctx, "cannot count compliance portal commitment groups", log.Error(err)) - return 0, gqlutils.Internal(ctx) - } - - return count, nil -} - // Permission is the resolver for the permission field. func (r *customDomainResolver) Permission(ctx context.Context, obj *types.CustomDomain, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) @@ -130,17 +60,21 @@ func (r *customDomainResolver) Permission(ctx context.Context, obj *types.Custom // UpdateTrustCenter is the resolver for the updateTrustCenter field. func (r *mutationResolver) UpdateTrustCenter(ctx context.Context, input types.UpdateTrustCenterInput) (*types.UpdateTrustCenterPayload, error) { - scope, err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterUpdate) + scope, err := r.authorize(ctx, input.TrustCenterID, complianceportal.ActionCompliancePortalUpdate) if err != nil { return nil, err } - trustCenter, _, err := r.probo.TrustCenters.Update( + trustCenter, _, err := r.management.Update( ctx, scope, - &probo.UpdateTrustCenterRequest{ + &management.UpdateRequest{ ID: input.TrustCenterID, Active: input.Active, SearchEngineIndexing: input.SearchEngineIndexing, + Description: gqlutils.UnwrapOmittable(input.Description), + WebsiteURL: gqlutils.UnwrapOmittable(input.WebsiteURL), + Email: gqlutils.UnwrapOmittable(input.Email), + HeadquarterAddress: gqlutils.UnwrapOmittable(input.HeadquarterAddress), }, ) if err != nil { @@ -160,14 +94,14 @@ func (r *mutationResolver) UpdateTrustCenter(ctx context.Context, input types.Up // UploadTrustCenterNda is the resolver for the uploadTrustCenterNDA field. func (r *mutationResolver) UploadTrustCenterNda(ctx context.Context, input types.UploadTrustCenterNDAInput) (*types.UploadTrustCenterNDAPayload, error) { - scope, err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterNonDisclosureAgreementUpload) + scope, err := r.authorize(ctx, input.TrustCenterID, complianceportal.ActionCompliancePortalNonDisclosureAgreementUpload) if err != nil { return nil, err } - trustCenter, _, err := r.probo.TrustCenters.UploadNDA( + trustCenter, _, err := r.management.UploadNDA( ctx, scope, - &probo.UploadTrustCenterNDARequest{ + &management.UploadNDARequest{ TrustCenterID: input.TrustCenterID, File: input.File.File, FileName: input.FileName, @@ -190,12 +124,12 @@ func (r *mutationResolver) UploadTrustCenterNda(ctx context.Context, input types // DeleteTrustCenterNda is the resolver for the deleteTrustCenterNDA field. func (r *mutationResolver) DeleteTrustCenterNda(ctx context.Context, input types.DeleteTrustCenterNDAInput) (*types.DeleteTrustCenterNDAPayload, error) { - scope, err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterNonDisclosureAgreementDelete) + scope, err := r.authorize(ctx, input.TrustCenterID, complianceportal.ActionCompliancePortalNonDisclosureAgreementDelete) if err != nil { return nil, err } - trustCenter, _, err := r.probo.TrustCenters.DeleteNDA(ctx, scope, input.TrustCenterID) + trustCenter, _, err := r.management.DeleteNDA(ctx, scope, input.TrustCenterID) if err != nil { r.logger.ErrorCtx(ctx, "cannot delete trust center NDA", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -208,23 +142,23 @@ func (r *mutationResolver) DeleteTrustCenterNda(ctx context.Context, input types // UpdateTrustCenterBrand is the resolver for the updateTrustCenterBrand field. func (r *mutationResolver) UpdateTrustCenterBrand(ctx context.Context, input types.UpdateTrustCenterBrandInput) (*types.UpdateTrustCenterBrandPayload, error) { - scope, err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterUpdate) + scope, err := r.authorize(ctx, input.TrustCenterID, complianceportal.ActionCompliancePortalUpdate) if err != nil { return nil, err } - req := &probo.UpdateTrustCenterBrandRequest{ + req := &management.UpdateBrandRequest{ TrustCenterID: input.TrustCenterID, } if input.LogoFile.IsSet() { logoFile := input.LogoFile.Value() if logoFile == nil { - var nilFile *probo.FileUpload + var nilFile *management.FileUpload req.LogoFile = &nilFile } else { - fileUpload := &probo.FileUpload{ + fileUpload := &management.FileUpload{ Content: logoFile.File, Filename: logoFile.Filename, Size: logoFile.Size, @@ -237,11 +171,11 @@ func (r *mutationResolver) UpdateTrustCenterBrand(ctx context.Context, input typ if input.DarkLogoFile.IsSet() { darkLogoFile := input.DarkLogoFile.Value() if darkLogoFile == nil { - var nilFile *probo.FileUpload + var nilFile *management.FileUpload req.DarkLogoFile = &nilFile } else { - fileUpload := &probo.FileUpload{ + fileUpload := &management.FileUpload{ Content: darkLogoFile.File, Filename: darkLogoFile.Filename, Size: darkLogoFile.Size, @@ -251,7 +185,7 @@ func (r *mutationResolver) UpdateTrustCenterBrand(ctx context.Context, input typ } } - trustCenter, _, err := r.probo.TrustCenters.UpdateTrustCenterBrand(ctx, scope, req) + trustCenter, _, err := r.management.UpdateBrand(ctx, scope, req) if err != nil { if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) @@ -269,41 +203,41 @@ func (r *mutationResolver) UpdateTrustCenterBrand(ctx context.Context, input typ // UpdateTrustCenterAccess is the resolver for the updateTrustCenterAccess field. func (r *mutationResolver) UpdateTrustCenterAccess(ctx context.Context, input types.UpdateTrustCenterAccessInput) (*types.UpdateTrustCenterAccessPayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionTrustCenterAccessUpdate) + scope, err := r.authorize(ctx, input.ID, complianceportal.ActionCompliancePortalAccessUpdate) if err != nil { return nil, err } var ( - documentAccesses []probo.UpdateTrustCenterDocumentAccessRequest - reportAccesses []probo.UpdateTrustCenterDocumentAccessRequest - fileAccesses []probo.UpdateTrustCenterDocumentAccessRequest + documentAccesses []management.UpdateDocumentAccessRequest + reportAccesses []management.UpdateDocumentAccessRequest + fileAccesses []management.UpdateDocumentAccessRequest ) for _, documentAccess := range input.Documents { - documentAccesses = append(documentAccesses, probo.UpdateTrustCenterDocumentAccessRequest{ + documentAccesses = append(documentAccesses, management.UpdateDocumentAccessRequest{ ID: documentAccess.ID, Status: documentAccess.Status, }) } for _, reportAccess := range input.Reports { - reportAccesses = append(reportAccesses, probo.UpdateTrustCenterDocumentAccessRequest{ + reportAccesses = append(reportAccesses, management.UpdateDocumentAccessRequest{ ID: reportAccess.ID, Status: reportAccess.Status, }) } for _, fileAccess := range input.TrustCenterFiles { - fileAccesses = append(fileAccesses, probo.UpdateTrustCenterDocumentAccessRequest{ + fileAccesses = append(fileAccesses, management.UpdateDocumentAccessRequest{ ID: fileAccess.ID, Status: fileAccess.Status, }) } - access, err := r.probo.TrustCenterAccesses.Update( + access, err := r.management.UpdateAccess( ctx, scope, - &probo.UpdateTrustCenterAccessRequest{ + &management.UpdateAccessRequest{ ID: input.ID, DocumentAccesses: documentAccesses, ReportAccesses: reportAccesses, @@ -327,12 +261,12 @@ func (r *mutationResolver) UpdateTrustCenterAccess(ctx context.Context, input ty // DeleteTrustCenterAccess is the resolver for the deleteTrustCenterAccess field. func (r *mutationResolver) DeleteTrustCenterAccess(ctx context.Context, input types.DeleteTrustCenterAccessInput) (*types.DeleteTrustCenterAccessPayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionTrustCenterAccessDelete) + scope, err := r.authorize(ctx, input.ID, complianceportal.ActionCompliancePortalAccessDelete) if err != nil { return nil, err } - if err := r.probo.TrustCenterAccesses.Delete(ctx, scope, input.ID); err != nil { + if err := r.management.DeleteAccess(ctx, scope, input.ID); err != nil { r.logger.ErrorCtx(ctx, "cannot delete trust center access", log.Error(err)) return nil, gqlutils.Internal(ctx) } @@ -344,19 +278,19 @@ func (r *mutationResolver) DeleteTrustCenterAccess(ctx context.Context, input ty // CreateTrustCenterReference is the resolver for the createTrustCenterReference field. func (r *mutationResolver) CreateTrustCenterReference(ctx context.Context, input types.CreateTrustCenterReferenceInput) (*types.CreateTrustCenterReferencePayload, error) { - scope, err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterReferenceCreate) + scope, err := r.authorize(ctx, input.TrustCenterID, complianceportal.ActionCompliancePortalReferenceCreate) if err != nil { return nil, err } - reference, err := r.probo.TrustCenterReferences.Create( + reference, err := r.management.CreateReference( ctx, scope, - &probo.CreateTrustCenterReferenceRequest{ + &management.CreateReferenceRequest{ TrustCenterID: input.TrustCenterID, Name: input.Name, Description: input.Description, WebsiteURL: input.WebsiteURL, - LogoFile: probo.File{ + LogoFile: management.File{ Content: input.LogoFile.File, Filename: input.LogoFile.Filename, Size: input.LogoFile.Size, @@ -381,12 +315,12 @@ func (r *mutationResolver) CreateTrustCenterReference(ctx context.Context, input // UpdateTrustCenterReference is the resolver for the updateTrustCenterReference field. func (r *mutationResolver) UpdateTrustCenterReference(ctx context.Context, input types.UpdateTrustCenterReferenceInput) (*types.UpdateTrustCenterReferencePayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionTrustCenterReferenceUpdate) + scope, err := r.authorize(ctx, input.ID, complianceportal.ActionCompliancePortalReferenceUpdate) if err != nil { return nil, err } - req := &probo.UpdateTrustCenterReferenceRequest{ + req := &management.UpdateReferenceRequest{ ID: input.ID, Name: input.Name, Description: gqlutils.UnwrapOmittable(input.Description), @@ -395,7 +329,7 @@ func (r *mutationResolver) UpdateTrustCenterReference(ctx context.Context, input } if input.LogoFile != nil { - req.LogoFile = &probo.File{ + req.LogoFile = &management.File{ Content: input.LogoFile.File, Filename: input.LogoFile.Filename, Size: input.LogoFile.Size, @@ -403,7 +337,7 @@ func (r *mutationResolver) UpdateTrustCenterReference(ctx context.Context, input } } - reference, err := r.probo.TrustCenterReferences.Update(ctx, scope, req) + reference, err := r.management.UpdateReference(ctx, scope, req) if err != nil { if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) @@ -421,12 +355,12 @@ func (r *mutationResolver) UpdateTrustCenterReference(ctx context.Context, input // DeleteTrustCenterReference is the resolver for the deleteTrustCenterReference field. func (r *mutationResolver) DeleteTrustCenterReference(ctx context.Context, input types.DeleteTrustCenterReferenceInput) (*types.DeleteTrustCenterReferencePayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionTrustCenterReferenceDelete) + scope, err := r.authorize(ctx, input.ID, complianceportal.ActionCompliancePortalReferenceDelete) if err != nil { return nil, err } - if err := r.probo.TrustCenterReferences.Delete(ctx, scope, input.ID); err != nil { + if err := r.management.DeleteReference(ctx, scope, input.ID); err != nil { r.logger.ErrorCtx(ctx, "cannot delete trust center reference", log.Error(err)) return nil, gqlutils.Internal(ctx) } @@ -436,176 +370,16 @@ func (r *mutationResolver) DeleteTrustCenterReference(ctx context.Context, input }, nil } -// CreateCompliancePortalCommitmentGroup is the resolver for the createCompliancePortalCommitmentGroup field. -func (r *mutationResolver) CreateCompliancePortalCommitmentGroup(ctx context.Context, input types.CreateCompliancePortalCommitmentGroupInput) (*types.CreateCompliancePortalCommitmentGroupPayload, error) { - scope, err := r.authorize(ctx, input.TrustCenterID, probo.ActionCompliancePortalCommitmentGroupCreate) - if err != nil { - return nil, err - } - - group, err := r.probo.CompliancePortalCommitmentGroups.Create( - ctx, scope, - &probo.CreateCompliancePortalCommitmentGroupRequest{ - TrustCenterID: input.TrustCenterID, - Title: input.Title, - Description: input.Description, - }, - ) - if err != nil { - if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { - return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) - } - - r.logger.ErrorCtx(ctx, "cannot create compliance portal commitment group", log.Error(err)) - - return nil, gqlutils.Internal(ctx) - } - - return &types.CreateCompliancePortalCommitmentGroupPayload{ - CompliancePortalCommitmentGroupEdge: types.NewCompliancePortalCommitmentGroupEdge(group, coredata.CompliancePortalCommitmentGroupOrderFieldRank), - }, nil -} - -// UpdateCompliancePortalCommitmentGroup is the resolver for the updateCompliancePortalCommitmentGroup field. -func (r *mutationResolver) UpdateCompliancePortalCommitmentGroup(ctx context.Context, input types.UpdateCompliancePortalCommitmentGroupInput) (*types.UpdateCompliancePortalCommitmentGroupPayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionCompliancePortalCommitmentGroupUpdate) - if err != nil { - return nil, err - } - - group, err := r.probo.CompliancePortalCommitmentGroups.Update( - ctx, scope, - &probo.UpdateCompliancePortalCommitmentGroupRequest{ - ID: input.ID, - Title: input.Title, - Description: input.Description, - Rank: input.Rank, - }, - ) - if err != nil { - if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { - return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) - } - - r.logger.ErrorCtx(ctx, "cannot update compliance portal commitment group", log.Error(err)) - - return nil, gqlutils.Internal(ctx) - } - - return &types.UpdateCompliancePortalCommitmentGroupPayload{ - CompliancePortalCommitmentGroup: types.NewCompliancePortalCommitmentGroup(group), - }, nil -} - -// DeleteCompliancePortalCommitmentGroup is the resolver for the deleteCompliancePortalCommitmentGroup field. -func (r *mutationResolver) DeleteCompliancePortalCommitmentGroup(ctx context.Context, input types.DeleteCompliancePortalCommitmentGroupInput) (*types.DeleteCompliancePortalCommitmentGroupPayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionCompliancePortalCommitmentGroupDelete) - if err != nil { - return nil, err - } - - if err := r.probo.CompliancePortalCommitmentGroups.Delete(ctx, scope, input.ID); err != nil { - r.logger.ErrorCtx(ctx, "cannot delete compliance portal commitment group", log.Error(err)) - return nil, gqlutils.Internal(ctx) - } - - return &types.DeleteCompliancePortalCommitmentGroupPayload{ - DeletedCompliancePortalCommitmentGroupID: input.ID, - }, nil -} - -// CreateCompliancePortalCommitment is the resolver for the createCompliancePortalCommitment field. -func (r *mutationResolver) CreateCompliancePortalCommitment(ctx context.Context, input types.CreateCompliancePortalCommitmentInput) (*types.CreateCompliancePortalCommitmentPayload, error) { - scope, err := r.authorize(ctx, input.GroupID, probo.ActionCompliancePortalCommitmentCreate) - if err != nil { - return nil, err - } - - commitment, err := r.probo.CompliancePortalCommitments.Create( - ctx, scope, - &probo.CreateCompliancePortalCommitmentRequest{ - GroupID: input.GroupID, - Icon: input.Icon, - Eyebrow: input.Eyebrow, - Title: input.Title, - Description: input.Description, - }, - ) - if err != nil { - if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { - return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) - } - - r.logger.ErrorCtx(ctx, "cannot create compliance portal commitment", log.Error(err)) - - return nil, gqlutils.Internal(ctx) - } - - return &types.CreateCompliancePortalCommitmentPayload{ - CompliancePortalCommitmentEdge: types.NewCompliancePortalCommitmentEdge(commitment, coredata.CompliancePortalCommitmentOrderFieldRank), - }, nil -} - -// UpdateCompliancePortalCommitment is the resolver for the updateCompliancePortalCommitment field. -func (r *mutationResolver) UpdateCompliancePortalCommitment(ctx context.Context, input types.UpdateCompliancePortalCommitmentInput) (*types.UpdateCompliancePortalCommitmentPayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionCompliancePortalCommitmentUpdate) - if err != nil { - return nil, err - } - - commitment, err := r.probo.CompliancePortalCommitments.Update( - ctx, scope, - &probo.UpdateCompliancePortalCommitmentRequest{ - ID: input.ID, - Icon: input.Icon, - Eyebrow: input.Eyebrow, - Title: input.Title, - Description: input.Description, - Rank: input.Rank, - }, - ) - if err != nil { - if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { - return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) - } - - r.logger.ErrorCtx(ctx, "cannot update compliance portal commitment", log.Error(err)) - - return nil, gqlutils.Internal(ctx) - } - - return &types.UpdateCompliancePortalCommitmentPayload{ - CompliancePortalCommitment: types.NewCompliancePortalCommitment(commitment), - }, nil -} - -// DeleteCompliancePortalCommitment is the resolver for the deleteCompliancePortalCommitment field. -func (r *mutationResolver) DeleteCompliancePortalCommitment(ctx context.Context, input types.DeleteCompliancePortalCommitmentInput) (*types.DeleteCompliancePortalCommitmentPayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionCompliancePortalCommitmentDelete) - if err != nil { - return nil, err - } - - if err := r.probo.CompliancePortalCommitments.Delete(ctx, scope, input.ID); err != nil { - r.logger.ErrorCtx(ctx, "cannot delete compliance portal commitment", log.Error(err)) - return nil, gqlutils.Internal(ctx) - } - - return &types.DeleteCompliancePortalCommitmentPayload{ - DeletedCompliancePortalCommitmentID: input.ID, - }, nil -} - // CreateComplianceFramework is the resolver for the createComplianceFramework field. func (r *mutationResolver) CreateComplianceFramework(ctx context.Context, input types.CreateComplianceFrameworkInput) (*types.CreateComplianceFrameworkPayload, error) { - scope, err := r.authorize(ctx, input.TrustCenterID, probo.ActionComplianceFrameworkCreate) + scope, err := r.authorize(ctx, input.TrustCenterID, complianceportal.ActionComplianceFrameworkCreate) if err != nil { return nil, err } - cf, err := r.probo.ComplianceFrameworks.Create( + cf, err := r.management.CreateFramework( ctx, scope, - &probo.CreateComplianceFrameworkRequest{ + &management.CreateFrameworkRequest{ TrustCenterID: input.TrustCenterID, FrameworkID: input.FrameworkID, }, @@ -627,12 +401,12 @@ func (r *mutationResolver) CreateComplianceFramework(ctx context.Context, input // UpdateComplianceFramework is the resolver for the updateComplianceFramework field. func (r *mutationResolver) UpdateComplianceFramework(ctx context.Context, input types.UpdateComplianceFrameworkInput) (*types.UpdateComplianceFrameworkPayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionComplianceFrameworkUpdateRank) + scope, err := r.authorize(ctx, input.ID, complianceportal.ActionComplianceFrameworkUpdateRank) if err != nil { return nil, err } - cf, err := r.probo.ComplianceFrameworks.Update(ctx, scope, &probo.UpdateComplianceFrameworkRequest{ + cf, err := r.management.UpdateFramework(ctx, scope, &management.UpdateFrameworkRequest{ ID: input.ID, Rank: input.Rank, }) @@ -653,14 +427,14 @@ func (r *mutationResolver) UpdateComplianceFramework(ctx context.Context, input // DeleteComplianceFramework is the resolver for the deleteComplianceFramework field. func (r *mutationResolver) DeleteComplianceFramework(ctx context.Context, input types.DeleteComplianceFrameworkInput) (*types.DeleteComplianceFrameworkPayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionComplianceFrameworkDelete) + scope, err := r.authorize(ctx, input.ID, complianceportal.ActionComplianceFrameworkDelete) if err != nil { return nil, err } - if err := r.probo.ComplianceFrameworks.Delete( + if err := r.management.DeleteFramework( ctx, scope, - &probo.DeleteComplianceFrameworkRequest{ + &management.DeleteFrameworkRequest{ ID: input.ID, }, ); err != nil { @@ -678,16 +452,16 @@ func (r *mutationResolver) DeleteComplianceFramework(ctx context.Context, input }, nil } -// CreateComplianceExternalURL is the resolver for the createComplianceExternalURL field. -func (r *mutationResolver) CreateComplianceExternalURL(ctx context.Context, input types.CreateComplianceExternalURLInput) (*types.CreateComplianceExternalURLPayload, error) { - scope, err := r.authorize(ctx, input.TrustCenterID, probo.ActionComplianceExternalURLCreate) +// CreateComplianceCustomLink is the resolver for the createComplianceCustomLink field. +func (r *mutationResolver) CreateComplianceCustomLink(ctx context.Context, input types.CreateComplianceCustomLinkInput) (*types.CreateComplianceCustomLinkPayload, error) { + scope, err := r.authorize(ctx, input.TrustCenterID, complianceportal.ActionComplianceCustomLinkCreate) if err != nil { return nil, err } - item, err := r.probo.ComplianceExternalURLs.Create( + item, err := r.management.CreateCustomLink( ctx, scope, - &probo.CreateComplianceExternalURLRequest{ + &management.CreateCustomLinkRequest{ TrustCenterID: input.TrustCenterID, Name: input.Name, URL: input.URL, @@ -698,24 +472,24 @@ func (r *mutationResolver) CreateComplianceExternalURL(ctx context.Context, inpu return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } - r.logger.ErrorCtx(ctx, "cannot create compliance external URL", log.Error(err)) + r.logger.ErrorCtx(ctx, "cannot create compliance custom link", log.Error(err)) return nil, gqlutils.Internal(ctx) } - return &types.CreateComplianceExternalURLPayload{ - ComplianceExternalURLEdge: types.NewComplianceExternalURLEdge(item, coredata.ComplianceExternalURLOrderFieldRank), + return &types.CreateComplianceCustomLinkPayload{ + ComplianceCustomLinkEdge: types.NewComplianceCustomLinkEdge(item, coredata.ComplianceCustomLinkOrderFieldRank), }, nil } -// UpdateComplianceExternalURL is the resolver for the updateComplianceExternalURL field. -func (r *mutationResolver) UpdateComplianceExternalURL(ctx context.Context, input types.UpdateComplianceExternalURLInput) (*types.UpdateComplianceExternalURLPayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionComplianceExternalURLUpdate) +// UpdateComplianceCustomLink is the resolver for the updateComplianceCustomLink field. +func (r *mutationResolver) UpdateComplianceCustomLink(ctx context.Context, input types.UpdateComplianceCustomLinkInput) (*types.UpdateComplianceCustomLinkPayload, error) { + scope, err := r.authorize(ctx, input.ID, complianceportal.ActionComplianceCustomLinkUpdate) if err != nil { return nil, err } - item, err := r.probo.ComplianceExternalURLs.Update(ctx, scope, &probo.UpdateComplianceExternalURLRequest{ + item, err := r.management.UpdateCustomLink(ctx, scope, &management.UpdateCustomLinkRequest{ ID: input.ID, Name: input.Name, URL: input.URL, @@ -726,52 +500,52 @@ func (r *mutationResolver) UpdateComplianceExternalURL(ctx context.Context, inpu return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } - r.logger.ErrorCtx(ctx, "cannot update compliance external URL", log.Error(err)) + r.logger.ErrorCtx(ctx, "cannot update compliance custom link", log.Error(err)) return nil, gqlutils.Internal(ctx) } - return &types.UpdateComplianceExternalURLPayload{ - ComplianceExternalURL: types.NewComplianceExternalURL(item), + return &types.UpdateComplianceCustomLinkPayload{ + ComplianceCustomLink: types.NewComplianceCustomLink(item), }, nil } -// DeleteComplianceExternalURL is the resolver for the deleteComplianceExternalURL field. -func (r *mutationResolver) DeleteComplianceExternalURL(ctx context.Context, input types.DeleteComplianceExternalURLInput) (*types.DeleteComplianceExternalURLPayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionComplianceExternalURLDelete) +// DeleteComplianceCustomLink is the resolver for the deleteComplianceCustomLink field. +func (r *mutationResolver) DeleteComplianceCustomLink(ctx context.Context, input types.DeleteComplianceCustomLinkInput) (*types.DeleteComplianceCustomLinkPayload, error) { + scope, err := r.authorize(ctx, input.ID, complianceportal.ActionComplianceCustomLinkDelete) if err != nil { return nil, err } - if err := r.probo.ComplianceExternalURLs.Delete(ctx, scope, &probo.DeleteComplianceExternalURLRequest{ID: input.ID}); err != nil { + if err := r.management.DeleteCustomLink(ctx, scope, &management.DeleteCustomLinkRequest{ID: input.ID}); err != nil { if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } - r.logger.ErrorCtx(ctx, "cannot delete compliance external URL", log.Error(err)) + r.logger.ErrorCtx(ctx, "cannot delete compliance custom link", log.Error(err)) return nil, gqlutils.Internal(ctx) } - return &types.DeleteComplianceExternalURLPayload{ - DeletedComplianceExternalURLID: input.ID, + return &types.DeleteComplianceCustomLinkPayload{ + DeletedComplianceCustomLinkID: input.ID, }, nil } // CreateTrustCenterFile is the resolver for the createTrustCenterFile field. func (r *mutationResolver) CreateTrustCenterFile(ctx context.Context, input types.CreateTrustCenterFileInput) (*types.CreateTrustCenterFilePayload, error) { - scope, err := r.authorize(ctx, input.OrganizationID, probo.ActionTrustCenterFileCreate) + scope, err := r.authorize(ctx, input.OrganizationID, complianceportal.ActionCompliancePortalFileCreate) if err != nil { return nil, err } - file, err := r.probo.TrustCenterFiles.Create( + file, err := r.management.CreateFile( ctx, scope, - &probo.CreateTrustCenterFileRequest{ + &management.CreateFileRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Category: input.Category, - File: probo.File{ + File: management.File{ Content: input.File.File, Filename: input.File.Filename, Size: input.File.Size, @@ -797,14 +571,14 @@ func (r *mutationResolver) CreateTrustCenterFile(ctx context.Context, input type // UpdateTrustCenterFile is the resolver for the updateTrustCenterFile field. func (r *mutationResolver) UpdateTrustCenterFile(ctx context.Context, input types.UpdateTrustCenterFileInput) (*types.UpdateTrustCenterFilePayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionTrustCenterFileUpdate) + scope, err := r.authorize(ctx, input.ID, complianceportal.ActionCompliancePortalFileUpdate) if err != nil { return nil, err } - file, err := r.probo.TrustCenterFiles.Update( + file, err := r.management.UpdateFile( ctx, scope, - &probo.UpdateTrustCenterFileRequest{ + &management.UpdateFileRequest{ ID: input.ID, Name: input.Name, Category: input.Category, @@ -828,12 +602,12 @@ func (r *mutationResolver) UpdateTrustCenterFile(ctx context.Context, input type // GetTrustCenterFile is the resolver for the getTrustCenterFile field. func (r *mutationResolver) GetTrustCenterFile(ctx context.Context, input types.GetTrustCenterFileInput) (*types.GetTrustCenterFilePayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionTrustCenterFileGet) + scope, err := r.authorize(ctx, input.ID, complianceportal.ActionCompliancePortalFileGet) if err != nil { return nil, err } - file, err := r.probo.TrustCenterFiles.Get(ctx, scope, input.ID) + file, err := r.management.GetFile(ctx, scope, input.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get trust center file", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -846,12 +620,12 @@ func (r *mutationResolver) GetTrustCenterFile(ctx context.Context, input types.G // DeleteTrustCenterFile is the resolver for the deleteTrustCenterFile field. func (r *mutationResolver) DeleteTrustCenterFile(ctx context.Context, input types.DeleteTrustCenterFileInput) (*types.DeleteTrustCenterFilePayload, error) { - scope, err := r.authorize(ctx, input.ID, probo.ActionTrustCenterFileDelete) + scope, err := r.authorize(ctx, input.ID, complianceportal.ActionCompliancePortalFileDelete) if err != nil { return nil, err } - if err := r.probo.TrustCenterFiles.Delete(ctx, scope, input.ID); err != nil { + if err := r.management.DeleteFile(ctx, scope, input.ID); err != nil { r.logger.ErrorCtx(ctx, "cannot delete trust center file", log.Error(err)) return nil, gqlutils.Internal(ctx) } @@ -863,67 +637,65 @@ func (r *mutationResolver) DeleteTrustCenterFile(ctx context.Context, input type // CreateCustomDomain is the resolver for the createCustomDomain field. func (r *mutationResolver) CreateCustomDomain(ctx context.Context, input types.CreateCustomDomainInput) (*types.CreateCustomDomainPayload, error) { - scope, err := r.authorize(ctx, input.OrganizationID, probo.ActionCustomDomainCreate) + scope, err := r.authorize(ctx, input.TrustCenterID, complianceportal.ActionCustomDomainCreate) if err != nil { return nil, err } - domain, err := r.probo.CustomDomains.CreateCustomDomain( + domain, err := r.management.AddCustomDomain( ctx, scope, - probo.CreateCustomDomainRequest{ - OrganizationID: input.OrganizationID, - Domain: input.Domain, - }, + input.TrustCenterID, + input.Domain, ) if err != nil { if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok { return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors) } + if errors.Is(err, management.ErrCustomDomainSlotTaken) { + return nil, gqlutils.Conflictf(ctx, "compliance page already has a custom domain") + } + r.logger.ErrorCtx(ctx, "cannot create custom domain", log.Error(err)) return nil, gqlutils.Internal(ctx) } + customDomain, err := r.newCustomDomainType(ctx, scope, domain) + if err != nil { + return nil, err + } + return &types.CreateCustomDomainPayload{ - CustomDomain: types.NewCustomDomain(domain, r.customDomainCname), + CustomDomain: customDomain, }, nil } // DeleteCustomDomain is the resolver for the deleteCustomDomain field. func (r *mutationResolver) DeleteCustomDomain(ctx context.Context, input types.DeleteCustomDomainInput) (*types.DeleteCustomDomainPayload, error) { - scope, err := r.authorize(ctx, input.OrganizationID, probo.ActionCustomDomainDelete) + scope, err := r.authorize(ctx, input.CustomDomainID, complianceportal.ActionCustomDomainDelete) if err != nil { return nil, err } - // TODO Drop this wierd logic - // Get the current custom domain ID before deleting - domain, err := r.probo.CustomDomains.GetOrganizationCustomDomain(ctx, scope, input.OrganizationID) - if err != nil { - r.logger.ErrorCtx(ctx, "cannot get custom domain", log.Error(err)) - return nil, gqlutils.Internal(ctx) - } + if err := r.management.RemoveCustomDomain(ctx, scope, input.CustomDomainID); err != nil { + if errors.Is(err, complianceportal.ErrCustomDomainManaged) { + return nil, gqlutils.Conflictf(ctx, "managed domain cannot be deleted") + } - if domain == nil { - return nil, fmt.Errorf("organization has no custom domain") - } - - deletedDomainID := domain.ID - - if err := r.probo.CustomDomains.DeleteCustomDomain(ctx, scope, input.OrganizationID); err != nil { r.logger.ErrorCtx(ctx, "cannot delete custom domain", log.Error(err)) + return nil, gqlutils.Internal(ctx) } return &types.DeleteCustomDomainPayload{ - DeletedCustomDomainID: deletedDomainID, + DeletedCustomDomainID: input.CustomDomainID, }, nil } // Logo is the resolver for the logo field. func (r *trustCenterResolver) Logo(ctx context.Context, obj *types.TrustCenter) (*types.File, error) { - if _, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterGet); err != nil { + if _, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalGet); err != nil { return nil, err } @@ -936,7 +708,7 @@ func (r *trustCenterResolver) Logo(ctx context.Context, obj *types.TrustCenter) // DarkLogo is the resolver for the darkLogo field. func (r *trustCenterResolver) DarkLogo(ctx context.Context, obj *types.TrustCenter) (*types.File, error) { - if _, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterGet); err != nil { + if _, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalGet); err != nil { return nil, err } @@ -949,7 +721,7 @@ func (r *trustCenterResolver) DarkLogo(ctx context.Context, obj *types.TrustCent // Nda is the resolver for the nda field. func (r *trustCenterResolver) Nda(ctx context.Context, obj *types.TrustCenter) (*types.File, error) { - hasPermission, err := r.Resolver.Permission(ctx, obj, probo.ActionTrustCenterGetNda) + hasPermission, err := r.Resolver.Permission(ctx, obj, complianceportal.ActionCompliancePortalGetNda) if err != nil { r.logger.ErrorCtx(ctx, "cannot authorize", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -969,7 +741,7 @@ func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.Trust return nil, err } - trustCenter, err := r.probo.TrustCenters.Get(ctx, scope, obj.ID) + trustCenter, err := r.management.Get(ctx, scope, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get trust center", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -991,7 +763,7 @@ func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.Trust // Accesses is the resolver for the accesses field. func (r *trustCenterResolver) Accesses(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterAccessOrderField]) (*types.TrustCenterAccessConnection, error) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterAccessList) + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalAccessList) if err != nil { return nil, err } @@ -1010,7 +782,7 @@ func (r *trustCenterResolver) Accesses(ctx context.Context, obj *types.TrustCent cursor := types.NewCursor(first, after, last, before, pageOrderBy) - result, err := r.probo.TrustCenterAccesses.ListForTrustCenterID(ctx, scope, obj.ID, cursor) + result, err := r.management.ListAccesses(ctx, scope, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list trust center accesses", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -1021,7 +793,7 @@ func (r *trustCenterResolver) Accesses(ctx context.Context, obj *types.TrustCent // 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, orderBy *types.OrderBy[coredata.TrustCenterReferenceOrderField]) (*types.TrustCenterReferenceConnection, error) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterReferenceList) + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalReferenceList) if err != nil { return nil, err } @@ -1040,7 +812,7 @@ func (r *trustCenterResolver) References(ctx context.Context, obj *types.TrustCe cursor := types.NewCursor(first, after, last, before, pageOrderBy) - result, err := r.probo.TrustCenterReferences.ListForTrustCenterID(ctx, scope, obj.ID, cursor) + result, err := r.management.ListReferences(ctx, scope, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list trust center references", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -1049,39 +821,9 @@ func (r *trustCenterResolver) References(ctx context.Context, obj *types.TrustCe return types.NewTrustCenterReferenceConnection(result, obj.ID), nil } -// CommitmentGroups is the resolver for the commitmentGroups field. -func (r *trustCenterResolver) CommitmentGroups(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.CompliancePortalCommitmentGroupOrderField]) (*types.CompliancePortalCommitmentGroupConnection, error) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionCompliancePortalCommitmentGroupList) - if err != nil { - return nil, err - } - - pageOrderBy := page.OrderBy[coredata.CompliancePortalCommitmentGroupOrderField]{ - Field: coredata.CompliancePortalCommitmentGroupOrderFieldRank, - Direction: page.OrderDirectionAsc, - } - - if orderBy != nil { - pageOrderBy = page.OrderBy[coredata.CompliancePortalCommitmentGroupOrderField]{ - Field: orderBy.Field, - Direction: orderBy.Direction, - } - } - - cursor := types.NewCursor(first, after, last, before, pageOrderBy) - - result, err := r.probo.CompliancePortalCommitmentGroups.ListForTrustCenterID(ctx, scope, obj.ID, cursor) - if err != nil { - r.logger.ErrorCtx(ctx, "cannot list compliance portal commitment groups", log.Error(err)) - return nil, gqlutils.Internal(ctx) - } - - return types.NewCompliancePortalCommitmentGroupConnection(result, obj.ID), 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, orderBy *types.OrderBy[coredata.ComplianceFrameworkOrderField]) (*types.ComplianceFrameworkConnection, error) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionComplianceFrameworkList) + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionComplianceFrameworkList) if err != nil { return nil, err } @@ -1100,7 +842,7 @@ func (r *trustCenterResolver) ComplianceFrameworks(ctx context.Context, obj *typ cursor := types.NewCursor(first, after, last, before, pageOrderBy) - result, err := r.probo.ComplianceFrameworks.ListWithHiddenForTrustCenterID(ctx, scope, obj.ID, cursor) + result, err := r.management.ListFrameworksWithHidden(ctx, scope, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list compliance frameworks", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -1109,20 +851,20 @@ func (r *trustCenterResolver) ComplianceFrameworks(ctx context.Context, obj *typ return types.NewComplianceFrameworkConnection(result), 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, orderBy *types.OrderBy[coredata.ComplianceExternalURLOrderField]) (*types.ComplianceExternalURLConnection, error) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionComplianceExternalURLList) +// CustomLinks is the resolver for the customLinks field. +func (r *trustCenterResolver) CustomLinks(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.ComplianceCustomLinkOrderField]) (*types.ComplianceCustomLinkConnection, error) { + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionComplianceCustomLinkList) if err != nil { return nil, err } - pageOrderBy := page.OrderBy[coredata.ComplianceExternalURLOrderField]{ - Field: coredata.ComplianceExternalURLOrderFieldRank, + pageOrderBy := page.OrderBy[coredata.ComplianceCustomLinkOrderField]{ + Field: coredata.ComplianceCustomLinkOrderFieldRank, Direction: page.OrderDirectionAsc, } if orderBy != nil { - pageOrderBy = page.OrderBy[coredata.ComplianceExternalURLOrderField]{ + pageOrderBy = page.OrderBy[coredata.ComplianceCustomLinkOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } @@ -1130,18 +872,18 @@ func (r *trustCenterResolver) ExternalUrls(ctx context.Context, obj *types.Trust cursor := types.NewCursor(first, after, last, before, pageOrderBy) - result, err := r.probo.ComplianceExternalURLs.List(ctx, scope, obj.ID, cursor) + result, err := r.management.ListCustomLinks(ctx, scope, obj.ID, cursor) if err != nil { - r.logger.ErrorCtx(ctx, "cannot list compliance external URLs", log.Error(err)) + r.logger.ErrorCtx(ctx, "cannot list compliance custom links", log.Error(err)) return nil, gqlutils.Internal(ctx) } - return types.NewComplianceExternalURLConnection(result), nil + return types.NewComplianceCustomLinkConnection(result), nil } // MailingList is the resolver for the mailingList field. func (r *trustCenterResolver) MailingList(ctx context.Context, obj *types.TrustCenter) (*types.MailingList, error) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionMailingListSubscriberList) + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionMailingListSubscriberList) if err != nil { return nil, err } @@ -1150,7 +892,7 @@ func (r *trustCenterResolver) MailingList(ctx context.Context, obj *types.TrustC return obj.MailingList, nil } - ml, err := r.probo.TrustCenters.GetMailingList(ctx, scope, obj.ID) + ml, err := r.management.GetMailingList(ctx, scope, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get mailing list for trust center", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -1163,6 +905,62 @@ func (r *trustCenterResolver) MailingList(ctx context.Context, obj *types.TrustC return types.NewMailingList(ml), nil } +// DefaultDomain is the resolver for the defaultDomain field. +func (r *trustCenterResolver) DefaultDomain(ctx context.Context, obj *types.TrustCenter) (*types.CustomDomain, error) { + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionCustomDomainGet) + if err != nil { + return nil, err + } + + domain, err := r.management.GetDefaultDomain(ctx, scope, obj.ID) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot load default domain", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + if domain == nil { + return nil, nil + } + + return r.newCustomDomainType(ctx, scope, domain) +} + +// CustomDomain is the resolver for the customDomain field. +func (r *trustCenterResolver) CustomDomain(ctx context.Context, obj *types.TrustCenter) (*types.CustomDomain, error) { + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionCustomDomainGet) + if err != nil { + return nil, err + } + + domain, err := r.management.GetCustomDomain(ctx, scope, obj.ID) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot load custom domain", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + if domain == nil { + return nil, nil + } + + return r.newCustomDomainType(ctx, scope, domain) +} + +// PublicURL is the resolver for the publicUrl field. +func (r *trustCenterResolver) PublicURL(ctx context.Context, obj *types.TrustCenter) (string, error) { + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalGet) + if err != nil { + return "", err + } + + publicURL, err := r.management.PublicURL(ctx, scope, obj.ID) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot resolve trust center public url", log.Error(err)) + return "", gqlutils.Internal(ctx) + } + + return publicURL, nil +} + // Permission is the resolver for the permission field. func (r *trustCenterResolver) Permission(ctx context.Context, obj *types.TrustCenter, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) @@ -1170,12 +968,12 @@ func (r *trustCenterResolver) Permission(ctx context.Context, obj *types.TrustCe // NdaSignature is the resolver for the ndaSignature field. func (r *trustCenterAccessResolver) NdaSignature(ctx context.Context, obj *types.TrustCenterAccess) (*types.ElectronicSignature, error) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterAccessGet) + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalAccessGet) if err != nil { return nil, err } - access, err := r.probo.TrustCenterAccesses.Get(ctx, scope, obj.ID) + access, err := r.management.GetAccess(ctx, scope, obj.ID) if err != nil { return nil, fmt.Errorf("cannot load trust center access: %w", err) } @@ -1194,12 +992,12 @@ func (r *trustCenterAccessResolver) NdaSignature(ctx context.Context, obj *types // PendingRequestCount is the resolver for the pendingRequestCount field. func (r *trustCenterAccessResolver) PendingRequestCount(ctx context.Context, obj *types.TrustCenterAccess) (int, error) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterAccessGet) + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalAccessGet) if err != nil { return 0, err } - count, err := r.probo.TrustCenterAccesses.CountPendingRequestDocumentAccesses(ctx, scope, obj.ID) + count, err := r.management.CountPendingRequestDocumentAccesses(ctx, scope, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count pending request document accesses", log.Error(err)) return 0, gqlutils.Internal(ctx) @@ -1210,12 +1008,12 @@ func (r *trustCenterAccessResolver) PendingRequestCount(ctx context.Context, obj // ActiveCount is the resolver for the activeCount field. func (r *trustCenterAccessResolver) ActiveCount(ctx context.Context, obj *types.TrustCenterAccess) (int, error) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterAccessGet) + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalAccessGet) if err != nil { return 0, err } - count, err := r.probo.TrustCenterAccesses.CountActiveDocumentAccesses(ctx, scope, obj.ID) + count, err := r.management.CountActiveDocumentAccesses(ctx, scope, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count active document accesses", log.Error(err)) return 0, gqlutils.Internal(ctx) @@ -1246,7 +1044,7 @@ func (r *trustCenterAccessResolver) Profile(ctx context.Context, obj *types.Trus // AvailableDocumentAccesses is the resolver for the availableDocumentAccesses field. func (r *trustCenterAccessResolver) AvailableDocumentAccesses(ctx context.Context, obj *types.TrustCenterAccess, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterDocumentAccessOrderField]) (*types.TrustCenterDocumentAccessConnection, error) { - scope, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterAccessGet) + scope, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalAccessGet) if err != nil { return nil, err } @@ -1265,7 +1063,7 @@ func (r *trustCenterAccessResolver) AvailableDocumentAccesses(ctx context.Contex cursor := types.NewCursor(first, after, last, before, pageOrderBy) - result, err := r.probo.TrustCenterAccesses.ListAvailableDocumentAccesses(ctx, scope, obj.ID, cursor) + result, err := r.management.ListAvailableDocumentAccesses(ctx, scope, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list trust center document accesses", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -1357,7 +1155,7 @@ func (r *trustCenterDocumentAccessResolver) Audit(ctx context.Context, obj *type // TrustCenterFile is the resolver for the trustCenterFile field. func (r *trustCenterDocumentAccessResolver) TrustCenterFile(ctx context.Context, obj *types.TrustCenterDocumentAccess) (*types.TrustCenterFile, error) { - scope, err := r.authorize(ctx, obj.TrustCenterAccessID, probo.ActionTrustCenterFileGet) + scope, err := r.authorize(ctx, obj.TrustCenterAccessID, complianceportal.ActionCompliancePortalFileGet) if err != nil { return nil, err } @@ -1366,7 +1164,7 @@ func (r *trustCenterDocumentAccessResolver) TrustCenterFile(ctx context.Context, return nil, nil } - trustCenterFile, err := r.probo.TrustCenterFiles.Get(ctx, scope, *obj.TrustCenterFileID) + trustCenterFile, err := r.management.GetFile(ctx, scope, *obj.TrustCenterFileID) if err != nil { r.logger.ErrorCtx(ctx, "cannot load trust center file", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -1377,12 +1175,12 @@ func (r *trustCenterDocumentAccessResolver) TrustCenterFile(ctx context.Context, // TotalCount is the resolver for the totalCount field. func (r *trustCenterDocumentAccessConnectionResolver) TotalCount(ctx context.Context, obj *types.TrustCenterDocumentAccessConnection) (int, error) { - scope, err := r.authorize(ctx, obj.ParentID, probo.ActionTrustCenterDocumentAccessList) + scope, err := r.authorize(ctx, obj.ParentID, complianceportal.ActionCompliancePortalDocumentAccessList) if err != nil { return 0, err } - count, err := r.probo.TrustCenterAccesses.CountDocumentAccesses(ctx, scope, obj.ParentID) + count, err := r.management.CountDocumentAccesses(ctx, scope, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count trust center document accesses", log.Error(err)) return 0, gqlutils.Internal(ctx) @@ -1393,7 +1191,7 @@ func (r *trustCenterDocumentAccessConnectionResolver) TotalCount(ctx context.Con // File is the resolver for the file field. func (r *trustCenterFileResolver) File(ctx context.Context, obj *types.TrustCenterFile) (*types.File, error) { - if _, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterFileGetFileUrl); err != nil { + if _, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalFileGetFileUrl); err != nil { return nil, err } @@ -1417,7 +1215,7 @@ func (r *trustCenterFileResolver) Organization(ctx context.Context, obj *types.T return nil, err } - trustCenterFile, err := r.probo.TrustCenterFiles.Get(ctx, scope, obj.ID) + trustCenterFile, err := r.management.GetFile(ctx, scope, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get trust center file", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -1444,12 +1242,12 @@ func (r *trustCenterFileResolver) Permission(ctx context.Context, obj *types.Tru // TotalCount is the resolver for the totalCount field. func (r *trustCenterFileConnectionResolver) TotalCount(ctx context.Context, obj *types.TrustCenterFileConnection) (int, error) { - scope, err := r.authorize(ctx, obj.ParentID, probo.ActionTrustCenterFileList) + scope, err := r.authorize(ctx, obj.ParentID, complianceportal.ActionCompliancePortalFileList) if err != nil { return 0, err } - count, err := r.probo.TrustCenterFiles.CountForOrganizationID(ctx, scope, obj.ParentID) + count, err := r.management.CountFilesForOrganizationID(ctx, scope, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count trust center files", log.Error(err)) return 0, gqlutils.Internal(ctx) @@ -1460,7 +1258,7 @@ func (r *trustCenterFileConnectionResolver) TotalCount(ctx context.Context, obj // Logo is the resolver for the logo field. func (r *trustCenterReferenceResolver) Logo(ctx context.Context, obj *types.TrustCenterReference) (*types.File, error) { - if _, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterReferenceGetLogoUrl); err != nil { + if _, err := r.authorize(ctx, obj.ID, complianceportal.ActionCompliancePortalReferenceGetLogoUrl); err != nil { return nil, err } @@ -1474,12 +1272,12 @@ func (r *trustCenterReferenceResolver) Permission(ctx context.Context, obj *type // TotalCount is the resolver for the totalCount field. func (r *trustCenterReferenceConnectionResolver) TotalCount(ctx context.Context, obj *types.TrustCenterReferenceConnection) (int, error) { - scope, err := r.authorize(ctx, obj.ParentID, probo.ActionTrustCenterReferenceList) + scope, err := r.authorize(ctx, obj.ParentID, complianceportal.ActionCompliancePortalReferenceList) if err != nil { return 0, err } - count, err := r.probo.TrustCenterReferences.CountForTrustCenterID(ctx, scope, obj.ParentID) + count, err := r.management.CountReferences(ctx, scope, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count trust center references", log.Error(err)) return 0, gqlutils.Internal(ctx) @@ -1488,9 +1286,9 @@ func (r *trustCenterReferenceConnectionResolver) TotalCount(ctx context.Context, return count, nil } -// ComplianceExternalURL returns schema.ComplianceExternalURLResolver implementation. -func (r *Resolver) ComplianceExternalURL() schema.ComplianceExternalURLResolver { - return &complianceExternalURLResolver{r} +// ComplianceCustomLink returns schema.ComplianceCustomLinkResolver implementation. +func (r *Resolver) ComplianceCustomLink() schema.ComplianceCustomLinkResolver { + return &complianceCustomLinkResolver{r} } // ComplianceFramework returns schema.ComplianceFrameworkResolver implementation. @@ -1498,26 +1296,6 @@ func (r *Resolver) ComplianceFramework() schema.ComplianceFrameworkResolver { return &complianceFrameworkResolver{r} } -// CompliancePortalCommitment returns schema.CompliancePortalCommitmentResolver implementation. -func (r *Resolver) CompliancePortalCommitment() schema.CompliancePortalCommitmentResolver { - return &compliancePortalCommitmentResolver{r} -} - -// CompliancePortalCommitmentConnection returns schema.CompliancePortalCommitmentConnectionResolver implementation. -func (r *Resolver) CompliancePortalCommitmentConnection() schema.CompliancePortalCommitmentConnectionResolver { - return &compliancePortalCommitmentConnectionResolver{r} -} - -// CompliancePortalCommitmentGroup returns schema.CompliancePortalCommitmentGroupResolver implementation. -func (r *Resolver) CompliancePortalCommitmentGroup() schema.CompliancePortalCommitmentGroupResolver { - return &compliancePortalCommitmentGroupResolver{r} -} - -// CompliancePortalCommitmentGroupConnection returns schema.CompliancePortalCommitmentGroupConnectionResolver implementation. -func (r *Resolver) CompliancePortalCommitmentGroupConnection() schema.CompliancePortalCommitmentGroupConnectionResolver { - return &compliancePortalCommitmentGroupConnectionResolver{r} -} - // CustomDomain returns schema.CustomDomainResolver implementation. func (r *Resolver) CustomDomain() schema.CustomDomainResolver { return &customDomainResolver{r} } @@ -1560,19 +1338,15 @@ func (r *Resolver) TrustCenterReferenceConnection() schema.TrustCenterReferenceC } type ( - complianceExternalURLResolver struct{ *Resolver } - complianceFrameworkResolver struct{ *Resolver } - compliancePortalCommitmentResolver struct{ *Resolver } - compliancePortalCommitmentConnectionResolver struct{ *Resolver } - compliancePortalCommitmentGroupResolver struct{ *Resolver } - compliancePortalCommitmentGroupConnectionResolver struct{ *Resolver } - customDomainResolver struct{ *Resolver } - trustCenterResolver struct{ *Resolver } - trustCenterAccessResolver struct{ *Resolver } - trustCenterDocumentAccessResolver struct{ *Resolver } - trustCenterDocumentAccessConnectionResolver struct{ *Resolver } - trustCenterFileResolver struct{ *Resolver } - trustCenterFileConnectionResolver struct{ *Resolver } - trustCenterReferenceResolver struct{ *Resolver } - trustCenterReferenceConnectionResolver struct{ *Resolver } + complianceCustomLinkResolver struct{ *Resolver } + complianceFrameworkResolver struct{ *Resolver } + customDomainResolver struct{ *Resolver } + trustCenterResolver struct{ *Resolver } + trustCenterAccessResolver struct{ *Resolver } + trustCenterDocumentAccessResolver struct{ *Resolver } + trustCenterDocumentAccessConnectionResolver struct{ *Resolver } + trustCenterFileResolver struct{ *Resolver } + trustCenterFileConnectionResolver struct{ *Resolver } + trustCenterReferenceResolver struct{ *Resolver } + trustCenterReferenceConnectionResolver struct{ *Resolver } ) diff --git a/pkg/server/api/console/v1/types/compliance_external_url.go b/pkg/server/api/console/v1/types/compliance_custom_link.go similarity index 61% rename from pkg/server/api/console/v1/types/compliance_external_url.go rename to pkg/server/api/console/v1/types/compliance_custom_link.go index 80fae295c..36ae422c0 100644 --- a/pkg/server/api/console/v1/types/compliance_external_url.go +++ b/pkg/server/api/console/v1/types/compliance_custom_link.go @@ -25,15 +25,15 @@ import ( "go.probo.inc/probo/pkg/page" ) -type ComplianceExternalURLOrderBy = OrderBy[coredata.ComplianceExternalURLOrderField] +type ComplianceCustomLinkOrderBy = OrderBy[coredata.ComplianceCustomLinkOrderField] -type ComplianceExternalURLConnection struct { - Edges []*ComplianceExternalURLEdge `json:"edges"` - PageInfo *PageInfo `json:"pageInfo"` +type ComplianceCustomLinkConnection struct { + Edges []*ComplianceCustomLinkEdge `json:"edges"` + PageInfo *PageInfo `json:"pageInfo"` } -func NewComplianceExternalURL(c *coredata.ComplianceExternalURL) *ComplianceExternalURL { - return &ComplianceExternalURL{ +func NewComplianceCustomLink(c *coredata.ComplianceCustomLink) *ComplianceCustomLink { + return &ComplianceCustomLink{ ID: c.ID, Name: c.Name, URL: c.URL, @@ -43,23 +43,23 @@ func NewComplianceExternalURL(c *coredata.ComplianceExternalURL) *ComplianceExte } } -func NewComplianceExternalURLConnection( - p *page.Page[*coredata.ComplianceExternalURL, coredata.ComplianceExternalURLOrderField], -) *ComplianceExternalURLConnection { - edges := make([]*ComplianceExternalURLEdge, len(p.Data)) +func NewComplianceCustomLinkConnection( + p *page.Page[*coredata.ComplianceCustomLink, coredata.ComplianceCustomLinkOrderField], +) *ComplianceCustomLinkConnection { + edges := make([]*ComplianceCustomLinkEdge, len(p.Data)) for i := range edges { - edges[i] = NewComplianceExternalURLEdge(p.Data[i], p.Cursor.OrderBy.Field) + edges[i] = NewComplianceCustomLinkEdge(p.Data[i], p.Cursor.OrderBy.Field) } - return &ComplianceExternalURLConnection{ + return &ComplianceCustomLinkConnection{ Edges: edges, PageInfo: NewPageInfo(p), } } -func NewComplianceExternalURLEdge(c *coredata.ComplianceExternalURL, orderBy coredata.ComplianceExternalURLOrderField) *ComplianceExternalURLEdge { - return &ComplianceExternalURLEdge{ +func NewComplianceCustomLinkEdge(c *coredata.ComplianceCustomLink, orderBy coredata.ComplianceCustomLinkOrderField) *ComplianceCustomLinkEdge { + return &ComplianceCustomLinkEdge{ Cursor: c.CursorKey(orderBy), - Node: NewComplianceExternalURL(c), + Node: NewComplianceCustomLink(c), } } diff --git a/pkg/server/api/console/v1/types/custom_domain.go b/pkg/server/api/console/v1/types/custom_domain.go index fcdf51ec0..366dc0fe9 100644 --- a/pkg/server/api/console/v1/types/custom_domain.go +++ b/pkg/server/api/console/v1/types/custom_domain.go @@ -24,18 +24,26 @@ import ( "go.probo.inc/probo/pkg/coredata" ) -func NewCustomDomain(d *coredata.CustomDomain, cnameTarget string) *CustomDomain { +// NewCustomDomain builds the GraphQL CustomDomain type. The TLS lifecycle now +// lives on the linked certificate; when cert is nil (certificate not yet +// created) the domain reports a pending SSL status. +func NewCustomDomain(d *coredata.CustomDomain, cert *coredata.Certificate, cnameTarget string) *CustomDomain { result := &CustomDomain{ ID: d.ID, Organization: &Organization{ ID: d.OrganizationID, }, - Domain: d.Domain, - SslStatus: d.SSLStatus, - CreatedAt: d.CreatedAt, - UpdatedAt: d.UpdatedAt, - SslExpiresAt: d.SSLExpiresAt, - ProvisioningError: d.ProvisioningError, + Domain: d.Domain, + Managed: d.Managed, + SslStatus: coredata.CustomDomainSSLStatusPending, + CreatedAt: d.CreatedAt, + UpdatedAt: d.UpdatedAt, + } + + if cert != nil { + result.SslStatus = coredata.CustomDomainSSLStatus(cert.Status) + result.SslExpiresAt = cert.SSLExpiresAt + result.ProvisioningError = cert.ProvisioningError } // Convert DNS records diff --git a/pkg/server/api/console/v1/types/organization.go b/pkg/server/api/console/v1/types/organization.go index e4eb39087..2ee2cd31e 100644 --- a/pkg/server/api/console/v1/types/organization.go +++ b/pkg/server/api/console/v1/types/organization.go @@ -26,18 +26,14 @@ import ( func NewOrganization(o *coredata.Organization) *Organization { org := &Organization{ - ID: o.ID, - Name: o.Name, - Description: o.Description, - WebsiteURL: o.WebsiteURL, - Email: o.Email, + ID: o.ID, + Name: o.Name, Context: &OrganizationContext{ OrganizationID: o.ID, }, - HeadquarterAddress: o.HeadquarterAddress, - CreatedAt: o.CreatedAt, - UpdatedAt: o.UpdatedAt, + CreatedAt: o.CreatedAt, + UpdatedAt: o.UpdatedAt, } if o.LogoFileID != nil { @@ -48,11 +44,5 @@ func NewOrganization(o *coredata.Organization) *Organization { org.HorizontalLogo = &File{ID: *o.HorizontalLogoFileID} } - if o.CustomDomainID != nil { - org.CustomDomain = &CustomDomain{ - ID: *o.CustomDomainID, - } - } - return org } diff --git a/pkg/server/api/console/v1/types/trust_center.go b/pkg/server/api/console/v1/types/trust_center.go index 9c9919c4a..348d788fd 100644 --- a/pkg/server/api/console/v1/types/trust_center.go +++ b/pkg/server/api/console/v1/types/trust_center.go @@ -28,21 +28,25 @@ import ( ) type TrustCenter struct { - ID gid.GID `json:"id"` - Active bool `json:"active"` - SearchEngineIndexing coredata.SearchEngineIndexing `json:"searchEngineIndexing"` - Logo *File `json:"logo,omitempty"` - DarkLogo *File `json:"darkLogo,omitempty"` - Nda *File `json:"nda,omitempty"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - Organization *Organization `json:"organization"` - Accesses *TrustCenterAccessConnection `json:"accesses"` - References *TrustCenterReferenceConnection `json:"references"` - ComplianceFrameworks *ComplianceFrameworkConnection `json:"complianceFrameworks"` - ExternalUrls *ComplianceExternalURLConnection `json:"externalUrls"` - MailingList *MailingList `json:"mailingList,omitempty"` - Permission bool `json:"permission"` + ID gid.GID `json:"id"` + Active bool `json:"active"` + SearchEngineIndexing coredata.SearchEngineIndexing `json:"searchEngineIndexing"` + Logo *File `json:"logo,omitempty"` + DarkLogo *File `json:"darkLogo,omitempty"` + Nda *File `json:"nda,omitempty"` + Description *string `json:"description,omitempty"` + WebsiteURL *string `json:"websiteUrl,omitempty"` + Email *string `json:"email,omitempty"` + HeadquarterAddress *string `json:"headquarterAddress,omitempty"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + Organization *Organization `json:"organization"` + Accesses *TrustCenterAccessConnection `json:"accesses"` + References *TrustCenterReferenceConnection `json:"references"` + ComplianceFrameworks *ComplianceFrameworkConnection `json:"complianceFrameworks"` + CustomLinks *ComplianceCustomLinkConnection `json:"customLinks"` + MailingList *MailingList `json:"mailingList,omitempty"` + Permission bool `json:"permission"` } func (TrustCenter) IsNode() {} @@ -56,6 +60,10 @@ func NewTrustCenter(tc *coredata.TrustCenter) *TrustCenter { }, Active: tc.Active, SearchEngineIndexing: tc.SearchEngineIndexing, + Description: tc.Description, + WebsiteURL: tc.WebsiteURL, + Email: tc.Email, + HeadquarterAddress: tc.HeadquarterAddress, CreatedAt: tc.CreatedAt, UpdatedAt: tc.UpdatedAt, } diff --git a/pkg/server/api/mcp/v1/resolver.go b/pkg/server/api/mcp/v1/resolver.go index 07da1d3cb..34fe074e1 100644 --- a/pkg/server/api/mcp/v1/resolver.go +++ b/pkg/server/api/mcp/v1/resolver.go @@ -31,6 +31,7 @@ import ( "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/accessreview" "go.probo.inc/probo/pkg/baseurl" + "go.probo.inc/probo/pkg/complianceportal/management" "go.probo.inc/probo/pkg/cookiebanner" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/filemanager" @@ -47,6 +48,7 @@ import ( type Resolver struct { proboSvc *probo.Service + management *management.Service resourceAlias *resourcealias.Service thirdPartySvc *thirdparty.Service iamSvc *iam.Service diff --git a/pkg/server/api/mcp/v1/schema.resolvers.go b/pkg/server/api/mcp/v1/schema.resolvers.go index a50877296..7a0c83ac4 100644 --- a/pkg/server/api/mcp/v1/schema.resolvers.go +++ b/pkg/server/api/mcp/v1/schema.resolvers.go @@ -14,6 +14,8 @@ import ( "github.com/modelcontextprotocol/go-sdk/mcp" "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/accessreview" + "go.probo.inc/probo/pkg/complianceportal" + "go.probo.inc/probo/pkg/complianceportal/management" "go.probo.inc/probo/pkg/cookiebanner" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/gid" @@ -4882,14 +4884,14 @@ func (r *Resolver) DeleteRightsRequestTool(ctx context.Context, req *mcp.CallToo // GetTrustCenterTool handles the getTrustCenter tool // Get the trust center for an organization func (r *Resolver) GetTrustCenterTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetTrustCenterInput) (*mcp.CallToolResult, types.GetTrustCenterOutput, error) { - scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionTrustCenterGet) + scope, err := r.Authorize(ctx, input.OrganizationID, complianceportal.ActionCompliancePortalGet) if err != nil { return nil, types.GetTrustCenterOutput{}, err } - prb := r.proboSvc + prb := r.management - trustCenter, err := prb.TrustCenters.GetByOrganizationID(ctx, scope, input.OrganizationID) + trustCenter, err := prb.GetByOrganizationID(ctx, scope, input.OrganizationID) if err != nil { return nil, types.GetTrustCenterOutput{}, fmt.Errorf("cannot get trust center: %w", err) } @@ -4929,14 +4931,14 @@ func (r *Resolver) GetTrustCenterTool(ctx context.Context, req *mcp.CallToolRequ // UpdateTrustCenterTool handles the updateTrustCenter tool // Update the trust center settings func (r *Resolver) UpdateTrustCenterTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateTrustCenterInput) (*mcp.CallToolResult, types.UpdateTrustCenterOutput, error) { - scope, err := r.Authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterUpdate) + scope, err := r.Authorize(ctx, input.TrustCenterID, complianceportal.ActionCompliancePortalUpdate) if err != nil { return nil, types.UpdateTrustCenterOutput{}, err } - prb := r.proboSvc + prb := r.management - updateReq := &probo.UpdateTrustCenterRequest{ + updateReq := &management.UpdateRequest{ ID: input.TrustCenterID, } @@ -4948,7 +4950,12 @@ func (r *Resolver) UpdateTrustCenterTool(ctx context.Context, req *mcp.CallToolR updateReq.SearchEngineIndexing = *sei } - trustCenter, _, err := prb.TrustCenters.Update(ctx, scope, updateReq) + updateReq.Description = UnwrapOmittable(input.Description) + updateReq.WebsiteURL = UnwrapOmittable(input.WebsiteURL) + updateReq.Email = UnwrapOmittable(input.Email) + updateReq.HeadquarterAddress = UnwrapOmittable(input.HeadquarterAddress) + + trustCenter, _, err := prb.Update(ctx, scope, updateReq) if err != nil { return nil, types.UpdateTrustCenterOutput{}, fmt.Errorf("cannot update trust center: %w", err) } @@ -4959,12 +4966,12 @@ func (r *Resolver) UpdateTrustCenterTool(ctx context.Context, req *mcp.CallToolR // ListTrustCenterReferencesTool handles the listTrustCenterReferences tool // List all references for a trust center func (r *Resolver) ListTrustCenterReferencesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListTrustCenterReferencesInput) (*mcp.CallToolResult, types.ListTrustCenterReferencesOutput, error) { - scope, err := r.Authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterReferenceList) + scope, err := r.Authorize(ctx, input.TrustCenterID, complianceportal.ActionCompliancePortalReferenceList) if err != nil { return nil, types.ListTrustCenterReferencesOutput{}, err } - prb := r.proboSvc + prb := r.management pageOrderBy := page.OrderBy[coredata.TrustCenterReferenceOrderField]{ Field: coredata.TrustCenterReferenceOrderFieldRank, @@ -4980,7 +4987,7 @@ func (r *Resolver) ListTrustCenterReferencesTool(ctx context.Context, req *mcp.C cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy) - p, err := prb.TrustCenterReferences.ListForTrustCenterID(ctx, scope, input.TrustCenterID, cursor) + p, err := prb.ListReferences(ctx, scope, input.TrustCenterID, cursor) if err != nil { return nil, types.ListTrustCenterReferencesOutput{}, fmt.Errorf("cannot list trust center references: %w", err) } @@ -5005,21 +5012,21 @@ func (r *Resolver) ListTrustCenterReferencesTool(ctx context.Context, req *mcp.C // AddTrustCenterReferenceTool handles the addTrustCenterReference tool // Add a new reference to the trust center func (r *Resolver) AddTrustCenterReferenceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddTrustCenterReferenceInput) (*mcp.CallToolResult, types.AddTrustCenterReferenceOutput, error) { - scope, err := r.Authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterReferenceCreate) + scope, err := r.Authorize(ctx, input.TrustCenterID, complianceportal.ActionCompliancePortalReferenceCreate) if err != nil { return nil, types.AddTrustCenterReferenceOutput{}, err } - prb := r.proboSvc + prb := r.management var websiteURL string if input.WebsiteURL != nil { websiteURL = *input.WebsiteURL } - reference, err := prb.TrustCenterReferences.Create( + reference, err := prb.CreateReference( ctx, scope, - &probo.CreateTrustCenterReferenceRequest{ + &management.CreateReferenceRequest{ TrustCenterID: input.TrustCenterID, Name: input.Name, Description: input.Description, @@ -5036,14 +5043,14 @@ func (r *Resolver) AddTrustCenterReferenceTool(ctx context.Context, req *mcp.Cal // UpdateTrustCenterReferenceTool handles the updateTrustCenterReference tool // Update a trust center reference func (r *Resolver) UpdateTrustCenterReferenceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateTrustCenterReferenceInput) (*mcp.CallToolResult, types.UpdateTrustCenterReferenceOutput, error) { - scope, err := r.Authorize(ctx, input.ID, probo.ActionTrustCenterReferenceUpdate) + scope, err := r.Authorize(ctx, input.ID, complianceportal.ActionCompliancePortalReferenceUpdate) if err != nil { return nil, types.UpdateTrustCenterReferenceOutput{}, err } - prb := r.proboSvc + prb := r.management - updateRefReq := &probo.UpdateTrustCenterReferenceRequest{ + updateRefReq := &management.UpdateReferenceRequest{ ID: input.ID, Description: UnwrapOmittable(input.Description), } @@ -5060,7 +5067,7 @@ func (r *Resolver) UpdateTrustCenterReferenceTool(ctx context.Context, req *mcp. updateRefReq.Rank = *rank } - reference, err := prb.TrustCenterReferences.Update(ctx, scope, updateRefReq) + reference, err := prb.UpdateReference(ctx, scope, updateRefReq) if err != nil { return nil, types.UpdateTrustCenterReferenceOutput{}, fmt.Errorf("cannot update trust center reference: %w", err) } @@ -5071,14 +5078,14 @@ func (r *Resolver) UpdateTrustCenterReferenceTool(ctx context.Context, req *mcp. // DeleteTrustCenterReferenceTool handles the deleteTrustCenterReference tool // Delete a trust center reference func (r *Resolver) DeleteTrustCenterReferenceTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteTrustCenterReferenceInput) (*mcp.CallToolResult, types.DeleteTrustCenterReferenceOutput, error) { - scope, err := r.Authorize(ctx, input.ID, probo.ActionTrustCenterReferenceDelete) + scope, err := r.Authorize(ctx, input.ID, complianceportal.ActionCompliancePortalReferenceDelete) if err != nil { return nil, types.DeleteTrustCenterReferenceOutput{}, err } - prb := r.proboSvc + prb := r.management - err = prb.TrustCenterReferences.Delete(ctx, scope, input.ID) + err = prb.DeleteReference(ctx, scope, input.ID) if err != nil { return nil, types.DeleteTrustCenterReferenceOutput{}, fmt.Errorf("cannot delete trust center reference: %w", err) } @@ -5089,12 +5096,12 @@ func (r *Resolver) DeleteTrustCenterReferenceTool(ctx context.Context, req *mcp. // ListTrustCenterFilesTool handles the listTrustCenterFiles tool // List all files for the trust center func (r *Resolver) ListTrustCenterFilesTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListTrustCenterFilesInput) (*mcp.CallToolResult, types.ListTrustCenterFilesOutput, error) { - scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionTrustCenterFileList) + scope, err := r.Authorize(ctx, input.OrganizationID, complianceportal.ActionCompliancePortalFileList) if err != nil { return nil, types.ListTrustCenterFilesOutput{}, err } - prb := r.proboSvc + prb := r.management pageOrderBy := page.OrderBy[coredata.TrustCenterFileOrderField]{ Field: coredata.TrustCenterFileOrderFieldCreatedAt, @@ -5111,7 +5118,7 @@ func (r *Resolver) ListTrustCenterFilesTool(ctx context.Context, req *mcp.CallTo cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy) filter := coredata.NewTrustCenterFileFilter() - p, err := prb.TrustCenterFiles.ListForOrganizationID(ctx, scope, input.OrganizationID, cursor, filter) + p, err := prb.ListFilesForOrganizationID(ctx, scope, input.OrganizationID, cursor, filter) if err != nil { return nil, types.ListTrustCenterFilesOutput{}, fmt.Errorf("cannot list trust center files: %w", err) } @@ -5132,14 +5139,14 @@ func (r *Resolver) ListTrustCenterFilesTool(ctx context.Context, req *mcp.CallTo // DeleteTrustCenterFileTool handles the deleteTrustCenterFile tool // Delete a trust center file func (r *Resolver) DeleteTrustCenterFileTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteTrustCenterFileInput) (*mcp.CallToolResult, types.DeleteTrustCenterFileOutput, error) { - scope, err := r.Authorize(ctx, input.ID, probo.ActionTrustCenterFileDelete) + scope, err := r.Authorize(ctx, input.ID, complianceportal.ActionCompliancePortalFileDelete) if err != nil { return nil, types.DeleteTrustCenterFileOutput{}, err } - prb := r.proboSvc + prb := r.management - err = prb.TrustCenterFiles.Delete(ctx, scope, input.ID) + err = prb.DeleteFile(ctx, scope, input.ID) if err != nil { return nil, types.DeleteTrustCenterFileOutput{}, fmt.Errorf("cannot delete trust center file: %w", err) } @@ -5147,23 +5154,23 @@ func (r *Resolver) DeleteTrustCenterFileTool(ctx context.Context, req *mcp.CallT return nil, types.DeleteTrustCenterFileOutput{DeletedTrustCenterFileID: input.ID}, nil } -// ListComplianceExternalURLsTool handles the listComplianceExternalURLs tool -// List all external URLs for a trust center -func (r *Resolver) ListComplianceExternalURLsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListComplianceExternalURLsInput) (*mcp.CallToolResult, types.ListComplianceExternalURLsOutput, error) { - scope, err := r.Authorize(ctx, input.TrustCenterID, probo.ActionComplianceExternalURLList) +// ListComplianceCustomLinksTool handles the listComplianceCustomLinks tool +// List all custom links for a trust center +func (r *Resolver) ListComplianceCustomLinksTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListComplianceCustomLinksInput) (*mcp.CallToolResult, types.ListComplianceCustomLinksOutput, error) { + scope, err := r.Authorize(ctx, input.TrustCenterID, complianceportal.ActionComplianceCustomLinkList) if err != nil { - return nil, types.ListComplianceExternalURLsOutput{}, err + return nil, types.ListComplianceCustomLinksOutput{}, err } - prb := r.proboSvc + prb := r.management - pageOrderBy := page.OrderBy[coredata.ComplianceExternalURLOrderField]{ - Field: coredata.ComplianceExternalURLOrderFieldRank, + pageOrderBy := page.OrderBy[coredata.ComplianceCustomLinkOrderField]{ + Field: coredata.ComplianceCustomLinkOrderFieldRank, Direction: page.OrderDirectionAsc, } if input.OrderBy != nil { - pageOrderBy = page.OrderBy[coredata.ComplianceExternalURLOrderField]{ + pageOrderBy = page.OrderBy[coredata.ComplianceCustomLinkOrderField]{ Field: input.OrderBy.Field, Direction: input.OrderBy.Direction, } @@ -5171,50 +5178,50 @@ func (r *Resolver) ListComplianceExternalURLsTool(ctx context.Context, req *mcp. cursor := types.NewCursor(input.Size, input.Cursor, pageOrderBy) - p, err := prb.ComplianceExternalURLs.List(ctx, scope, input.TrustCenterID, cursor) + p, err := prb.ListCustomLinks(ctx, scope, input.TrustCenterID, cursor) if err != nil { - return nil, types.ListComplianceExternalURLsOutput{}, fmt.Errorf("cannot list compliance external URLs: %w", err) + return nil, types.ListComplianceCustomLinksOutput{}, fmt.Errorf("cannot list compliance custom links: %w", err) } - return nil, types.NewListComplianceExternalURLsOutput(p), nil + return nil, types.NewListComplianceCustomLinksOutput(p), nil } -// AddComplianceExternalURLTool handles the addComplianceExternalURL tool -// Add a new external URL to the trust center -func (r *Resolver) AddComplianceExternalURLTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddComplianceExternalURLInput) (*mcp.CallToolResult, types.AddComplianceExternalURLOutput, error) { - scope, err := r.Authorize(ctx, input.TrustCenterID, probo.ActionComplianceExternalURLCreate) +// AddComplianceCustomLinkTool handles the addComplianceCustomLink tool +// Add a new custom link to the trust center +func (r *Resolver) AddComplianceCustomLinkTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddComplianceCustomLinkInput) (*mcp.CallToolResult, types.AddComplianceCustomLinkOutput, error) { + scope, err := r.Authorize(ctx, input.TrustCenterID, complianceportal.ActionComplianceCustomLinkCreate) if err != nil { - return nil, types.AddComplianceExternalURLOutput{}, err + return nil, types.AddComplianceCustomLinkOutput{}, err } - prb := r.proboSvc + prb := r.management - item, err := prb.ComplianceExternalURLs.Create( + item, err := prb.CreateCustomLink( ctx, scope, - &probo.CreateComplianceExternalURLRequest{ + &management.CreateCustomLinkRequest{ TrustCenterID: input.TrustCenterID, Name: input.Name, URL: input.URL, }, ) if err != nil { - return nil, types.AddComplianceExternalURLOutput{}, fmt.Errorf("cannot add compliance external URL: %w", err) + return nil, types.AddComplianceCustomLinkOutput{}, fmt.Errorf("cannot add compliance custom link: %w", err) } - return nil, types.AddComplianceExternalURLOutput{ComplianceExternalURL: types.NewComplianceExternalURL(item)}, nil + return nil, types.AddComplianceCustomLinkOutput{ComplianceCustomLink: types.NewComplianceCustomLink(item)}, nil } -// UpdateComplianceExternalURLTool handles the updateComplianceExternalURL tool -// Update a compliance external URL -func (r *Resolver) UpdateComplianceExternalURLTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateComplianceExternalURLInput) (*mcp.CallToolResult, types.UpdateComplianceExternalURLOutput, error) { - scope, err := r.Authorize(ctx, input.ID, probo.ActionComplianceExternalURLUpdate) +// UpdateComplianceCustomLinkTool handles the updateComplianceCustomLink tool +// Update a compliance custom link +func (r *Resolver) UpdateComplianceCustomLinkTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateComplianceCustomLinkInput) (*mcp.CallToolResult, types.UpdateComplianceCustomLinkOutput, error) { + scope, err := r.Authorize(ctx, input.ID, complianceportal.ActionComplianceCustomLinkUpdate) if err != nil { - return nil, types.UpdateComplianceExternalURLOutput{}, err + return nil, types.UpdateComplianceCustomLinkOutput{}, err } - prb := r.proboSvc + prb := r.management - updateURLReq := &probo.UpdateComplianceExternalURLRequest{ + updateURLReq := &management.UpdateCustomLinkRequest{ ID: input.ID, } @@ -5230,83 +5237,87 @@ func (r *Resolver) UpdateComplianceExternalURLTool(ctx context.Context, req *mcp updateURLReq.Rank = *rank } - item, err := prb.ComplianceExternalURLs.Update(ctx, scope, updateURLReq) + item, err := prb.UpdateCustomLink(ctx, scope, updateURLReq) if err != nil { - return nil, types.UpdateComplianceExternalURLOutput{}, fmt.Errorf("cannot update compliance external URL: %w", err) + return nil, types.UpdateComplianceCustomLinkOutput{}, fmt.Errorf("cannot update compliance custom link: %w", err) } - return nil, types.UpdateComplianceExternalURLOutput{ComplianceExternalURL: types.NewComplianceExternalURL(item)}, nil + return nil, types.UpdateComplianceCustomLinkOutput{ComplianceCustomLink: types.NewComplianceCustomLink(item)}, nil } -// DeleteComplianceExternalURLTool handles the deleteComplianceExternalURL tool -// Delete a compliance external URL -func (r *Resolver) DeleteComplianceExternalURLTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteComplianceExternalURLInput) (*mcp.CallToolResult, types.DeleteComplianceExternalURLOutput, error) { - scope, err := r.Authorize(ctx, input.ID, probo.ActionComplianceExternalURLDelete) +// DeleteComplianceCustomLinkTool handles the deleteComplianceCustomLink tool +// Delete a compliance custom link +func (r *Resolver) DeleteComplianceCustomLinkTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteComplianceCustomLinkInput) (*mcp.CallToolResult, types.DeleteComplianceCustomLinkOutput, error) { + scope, err := r.Authorize(ctx, input.ID, complianceportal.ActionComplianceCustomLinkDelete) if err != nil { - return nil, types.DeleteComplianceExternalURLOutput{}, err + return nil, types.DeleteComplianceCustomLinkOutput{}, err } - prb := r.proboSvc + prb := r.management - err = prb.ComplianceExternalURLs.Delete( + err = prb.DeleteCustomLink( ctx, scope, - &probo.DeleteComplianceExternalURLRequest{ + &management.DeleteCustomLinkRequest{ ID: input.ID, }, ) if err != nil { - return nil, types.DeleteComplianceExternalURLOutput{}, fmt.Errorf("cannot delete compliance external URL: %w", err) + return nil, types.DeleteComplianceCustomLinkOutput{}, fmt.Errorf("cannot delete compliance custom link: %w", err) } - return nil, types.DeleteComplianceExternalURLOutput{DeletedComplianceExternalURLID: input.ID}, nil + return nil, types.DeleteComplianceCustomLinkOutput{DeletedComplianceCustomLinkID: input.ID}, nil } // CreateCustomDomainTool handles the createCustomDomain tool -// Create a custom domain for the organization +// Create a custom domain for a compliance page func (r *Resolver) CreateCustomDomainTool(ctx context.Context, req *mcp.CallToolRequest, input *types.CreateCustomDomainInput) (*mcp.CallToolResult, types.CreateCustomDomainOutput, error) { - scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionCustomDomainCreate) + scope, err := r.Authorize(ctx, input.TrustCenterID, complianceportal.ActionCustomDomainCreate) if err != nil { return nil, types.CreateCustomDomainOutput{}, err } - prb := r.proboSvc - - domain, err := prb.CustomDomains.CreateCustomDomain( + domain, err := r.management.AddCustomDomain( ctx, scope, - probo.CreateCustomDomainRequest{ - OrganizationID: input.OrganizationID, - Domain: input.Domain, - }, + input.TrustCenterID, + input.Domain, ) if err != nil { return nil, types.CreateCustomDomainOutput{}, fmt.Errorf("cannot create custom domain: %w", err) } - return nil, types.CreateCustomDomainOutput{CustomDomain: types.NewCustomDomain(domain)}, nil + cert, err := r.management.GetCertificate(ctx, scope, domain) + if err != nil { + return nil, types.CreateCustomDomainOutput{}, fmt.Errorf("cannot load certificate: %w", err) + } + + return nil, types.CreateCustomDomainOutput{CustomDomain: types.NewCustomDomain(domain, cert)}, nil } // DeleteCustomDomainTool handles the deleteCustomDomain tool -// Delete the custom domain for the organization +// Delete the custom domain of a compliance page func (r *Resolver) DeleteCustomDomainTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteCustomDomainInput) (*mcp.CallToolResult, types.DeleteCustomDomainOutput, error) { - scope, err := r.Authorize(ctx, input.OrganizationID, probo.ActionCustomDomainDelete) + scope, err := r.Authorize(ctx, input.TrustCenterID, complianceportal.ActionCustomDomainDelete) if err != nil { return nil, types.DeleteCustomDomainOutput{}, err } - prb := r.proboSvc - - domain, err := prb.CustomDomains.GetOrganizationCustomDomain(ctx, scope, input.OrganizationID) + domain, err := r.management.GetCustomDomain(ctx, scope, input.TrustCenterID) if err != nil { return nil, types.DeleteCustomDomainOutput{}, fmt.Errorf("cannot get custom domain: %w", err) } if domain == nil { - return nil, types.DeleteCustomDomainOutput{}, fmt.Errorf("organization has no custom domain") + return nil, types.DeleteCustomDomainOutput{}, fmt.Errorf("compliance page has no custom domain") } - deletedDomain := types.NewCustomDomain(domain) + cert, err := r.management.GetCertificate(ctx, scope, domain) + if err != nil { + return nil, types.DeleteCustomDomainOutput{}, fmt.Errorf("cannot load certificate: %w", err) + } - if err := prb.CustomDomains.DeleteCustomDomain(ctx, scope, input.OrganizationID); err != nil { + deletedDomain := types.NewCustomDomain(domain, cert) + + if err := r.management.RemoveCustomDomain(ctx, scope, domain.ID); err != nil { return nil, types.DeleteCustomDomainOutput{}, fmt.Errorf("cannot delete custom domain: %w", err) } diff --git a/pkg/server/api/mcp/v1/specification.yaml b/pkg/server/api/mcp/v1/specification.yaml index 48f008a06..e91332536 100644 --- a/pkg/server/api/mcp/v1/specification.yaml +++ b/pkg/server/api/mcp/v1/specification.yaml @@ -616,7 +616,6 @@ components: required: - id - name - - description - created_at - updated_at properties: @@ -626,11 +625,6 @@ components: name: type: string description: Organization name - description: - type: - - string - - "null" - description: Organization description created_at: type: string format: date-time @@ -8784,21 +8778,21 @@ components: direction: $ref: "#/components/schemas/OrderDirection" - ComplianceExternalURLOrderField: + ComplianceCustomLinkOrderField: type: string enum: - CREATED_AT - RANK - go.probo.inc/mcpgen/type: go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderField + go.probo.inc/mcpgen/type: go.probo.inc/probo/pkg/coredata.ComplianceCustomLinkOrderField - ComplianceExternalURLOrderBy: + ComplianceCustomLinkOrderBy: type: object required: - field - direction properties: field: - $ref: "#/components/schemas/ComplianceExternalURLOrderField" + $ref: "#/components/schemas/ComplianceCustomLinkOrderField" direction: $ref: "#/components/schemas/OrderDirection" @@ -8855,6 +8849,26 @@ components: $ref: "#/components/schemas/File" nda: $ref: "#/components/schemas/File" + description: + type: + - string + - "null" + description: Compliance page description + website_url: + type: + - string + - "null" + description: Compliance page website URL + email: + type: + - string + - "null" + description: Compliance page contact email + headquarter_address: + type: + - string + - "null" + description: Compliance page headquarter address created_at: type: string format: date-time @@ -8925,7 +8939,7 @@ components: type: string format: date-time - ComplianceExternalURL: + ComplianceCustomLink: type: object required: - id @@ -8956,6 +8970,7 @@ components: - id - organization_id - domain + - managed - ssl_status - created_at - updated_at @@ -8966,6 +8981,9 @@ components: $ref: "#/components/schemas/GID" domain: type: string + managed: + type: boolean + description: Whether this domain is a Probo-managed probopage subdomain ssl_status: $ref: "#/components/schemas/SSLStatus" ssl_expires_at: @@ -9017,6 +9035,30 @@ components: - type: "null" description: Search engine indexing setting go.probo.inc/mcpgen/omittable: true + description: + type: + - string + - "null" + description: Compliance page description + go.probo.inc/mcpgen/omittable: true + website_url: + type: + - string + - "null" + description: Compliance page website URL + go.probo.inc/mcpgen/omittable: true + email: + type: + - string + - "null" + description: Compliance page contact email + go.probo.inc/mcpgen/omittable: true + headquarter_address: + type: + - string + - "null" + description: Compliance page headquarter address + go.probo.inc/mcpgen/omittable: true UpdateTrustCenterOutput: type: object @@ -9604,7 +9646,7 @@ components: $ref: "#/components/schemas/GID" description: Deleted trust center file ID - ListComplianceExternalURLsInput: + ListComplianceCustomLinksInput: type: object required: - trust_center_id @@ -9613,8 +9655,8 @@ components: $ref: "#/components/schemas/GID" description: Trust center ID order_by: - $ref: "#/components/schemas/ComplianceExternalURLOrderBy" - description: Compliance external URL order by + $ref: "#/components/schemas/ComplianceCustomLinkOrderBy" + description: Compliance custom link order by size: type: integer description: Page size @@ -9622,20 +9664,20 @@ components: $ref: "#/components/schemas/CursorKey" description: Page cursor - ListComplianceExternalURLsOutput: + ListComplianceCustomLinksOutput: type: object required: - - compliance_external_urls + - compliance_custom_links properties: next_cursor: $ref: "#/components/schemas/CursorKey" description: Next cursor - compliance_external_urls: + compliance_custom_links: type: array items: - $ref: "#/components/schemas/ComplianceExternalURL" + $ref: "#/components/schemas/ComplianceCustomLink" - AddComplianceExternalURLInput: + AddComplianceCustomLinkInput: type: object required: - trust_center_id @@ -9647,81 +9689,81 @@ components: description: Trust center ID name: type: string - description: External URL name + description: Custom Link name url: type: string - description: External URL + description: Custom Link - AddComplianceExternalURLOutput: + AddComplianceCustomLinkOutput: type: object required: - - compliance_external_url + - compliance_custom_link properties: - compliance_external_url: - $ref: "#/components/schemas/ComplianceExternalURL" + compliance_custom_link: + $ref: "#/components/schemas/ComplianceCustomLink" - UpdateComplianceExternalURLInput: + UpdateComplianceCustomLinkInput: type: object required: - id properties: id: $ref: "#/components/schemas/GID" - description: Compliance external URL ID + description: Compliance custom link ID name: type: - string - "null" - description: External URL name + description: Custom Link name go.probo.inc/mcpgen/omittable: true url: type: - string - "null" - description: External URL + description: Custom Link go.probo.inc/mcpgen/omittable: true rank: type: - integer - "null" - description: External URL rank + description: Custom Link rank go.probo.inc/mcpgen/omittable: true - UpdateComplianceExternalURLOutput: + UpdateComplianceCustomLinkOutput: type: object required: - - compliance_external_url + - compliance_custom_link properties: - compliance_external_url: - $ref: "#/components/schemas/ComplianceExternalURL" + compliance_custom_link: + $ref: "#/components/schemas/ComplianceCustomLink" - DeleteComplianceExternalURLInput: + DeleteComplianceCustomLinkInput: type: object required: - id properties: id: $ref: "#/components/schemas/GID" - description: Compliance external URL ID + description: Compliance custom link ID - DeleteComplianceExternalURLOutput: + DeleteComplianceCustomLinkOutput: type: object required: - - deleted_compliance_external_url_id + - deleted_compliance_custom_link_id properties: - deleted_compliance_external_url_id: + deleted_compliance_custom_link_id: $ref: "#/components/schemas/GID" - description: Deleted compliance external URL ID + description: Deleted compliance custom link ID CreateCustomDomainInput: type: object required: - - organization_id + - trust_center_id - domain properties: - organization_id: + trust_center_id: $ref: "#/components/schemas/GID" - description: Organization ID + description: Compliance page (trust center) ID domain: type: string description: Custom domain name @@ -9737,11 +9779,11 @@ components: DeleteCustomDomainInput: type: object required: - - organization_id + - trust_center_id properties: - organization_id: + trust_center_id: $ref: "#/components/schemas/GID" - description: Organization ID + description: Compliance page (trust center) ID DeleteCustomDomainOutput: type: object @@ -14122,42 +14164,42 @@ tools: $ref: "#/components/schemas/DeleteTrustCenterFileInput" outputSchema: $ref: "#/components/schemas/DeleteTrustCenterFileOutput" - - name: listComplianceExternalURLs - description: List all compliance external URLs for a trust center + - name: listComplianceCustomLinks + description: List all compliance custom links for a trust center hints: readonly: true idempotent: true inputSchema: - $ref: "#/components/schemas/ListComplianceExternalURLsInput" + $ref: "#/components/schemas/ListComplianceCustomLinksInput" outputSchema: - $ref: "#/components/schemas/ListComplianceExternalURLsOutput" - - name: addComplianceExternalURL - description: Add a new compliance external URL to a trust center + $ref: "#/components/schemas/ListComplianceCustomLinksOutput" + - name: addComplianceCustomLink + description: Add a new compliance custom link to a trust center hints: readonly: false inputSchema: - $ref: "#/components/schemas/AddComplianceExternalURLInput" + $ref: "#/components/schemas/AddComplianceCustomLinkInput" outputSchema: - $ref: "#/components/schemas/AddComplianceExternalURLOutput" - - name: updateComplianceExternalURL - description: Update an existing compliance external URL + $ref: "#/components/schemas/AddComplianceCustomLinkOutput" + - name: updateComplianceCustomLink + description: Update an existing compliance custom link hints: readonly: false inputSchema: - $ref: "#/components/schemas/UpdateComplianceExternalURLInput" + $ref: "#/components/schemas/UpdateComplianceCustomLinkInput" outputSchema: - $ref: "#/components/schemas/UpdateComplianceExternalURLOutput" - - name: deleteComplianceExternalURL - description: Delete a compliance external URL + $ref: "#/components/schemas/UpdateComplianceCustomLinkOutput" + - name: deleteComplianceCustomLink + description: Delete a compliance custom link hints: readonly: false destructive: true inputSchema: - $ref: "#/components/schemas/DeleteComplianceExternalURLInput" + $ref: "#/components/schemas/DeleteComplianceCustomLinkInput" outputSchema: - $ref: "#/components/schemas/DeleteComplianceExternalURLOutput" + $ref: "#/components/schemas/DeleteComplianceCustomLinkOutput" - name: createCustomDomain - description: Create a custom domain for an organization + description: Create a custom domain for a compliance page hints: readonly: false inputSchema: @@ -14165,7 +14207,7 @@ tools: outputSchema: $ref: "#/components/schemas/CreateCustomDomainOutput" - name: deleteCustomDomain - description: Delete the custom domain for an organization + description: Delete the custom domain of a compliance page hints: readonly: false destructive: true diff --git a/pkg/server/api/mcp/v1/types/compliance_external_url.go b/pkg/server/api/mcp/v1/types/compliance_custom_link.go similarity index 75% rename from pkg/server/api/mcp/v1/types/compliance_external_url.go rename to pkg/server/api/mcp/v1/types/compliance_custom_link.go index a65100baf..bb2132cac 100644 --- a/pkg/server/api/mcp/v1/types/compliance_external_url.go +++ b/pkg/server/api/mcp/v1/types/compliance_custom_link.go @@ -25,8 +25,8 @@ import ( "go.probo.inc/probo/pkg/page" ) -func NewComplianceExternalURL(c *coredata.ComplianceExternalURL) *ComplianceExternalURL { - return &ComplianceExternalURL{ +func NewComplianceCustomLink(c *coredata.ComplianceCustomLink) *ComplianceCustomLink { + return &ComplianceCustomLink{ ID: c.ID, Name: c.Name, URL: c.URL, @@ -36,10 +36,10 @@ func NewComplianceExternalURL(c *coredata.ComplianceExternalURL) *ComplianceExte } } -func NewListComplianceExternalURLsOutput(p *page.Page[*coredata.ComplianceExternalURL, coredata.ComplianceExternalURLOrderField]) ListComplianceExternalURLsOutput { - urls := make([]*ComplianceExternalURL, 0, len(p.Data)) +func NewListComplianceCustomLinksOutput(p *page.Page[*coredata.ComplianceCustomLink, coredata.ComplianceCustomLinkOrderField]) ListComplianceCustomLinksOutput { + urls := make([]*ComplianceCustomLink, 0, len(p.Data)) for _, c := range p.Data { - urls = append(urls, NewComplianceExternalURL(c)) + urls = append(urls, NewComplianceCustomLink(c)) } var nextCursor *page.CursorKey @@ -49,8 +49,8 @@ func NewListComplianceExternalURLsOutput(p *page.Page[*coredata.ComplianceExtern nextCursor = &cursorKey } - return ListComplianceExternalURLsOutput{ - NextCursor: nextCursor, - ComplianceExternalUrls: urls, + return ListComplianceCustomLinksOutput{ + NextCursor: nextCursor, + ComplianceCustomLinks: urls, } } diff --git a/pkg/server/api/mcp/v1/types/custom_domain.go b/pkg/server/api/mcp/v1/types/custom_domain.go index 82f308b04..a2b9375cf 100644 --- a/pkg/server/api/mcp/v1/types/custom_domain.go +++ b/pkg/server/api/mcp/v1/types/custom_domain.go @@ -24,14 +24,24 @@ import ( "go.probo.inc/probo/pkg/coredata" ) -func NewCustomDomain(d *coredata.CustomDomain) *CustomDomain { - return &CustomDomain{ +// NewCustomDomain builds the MCP CustomDomain type. The TLS lifecycle now lives +// on the linked certificate; when cert is nil (certificate not yet created) the +// domain reports a pending SSL status. +func NewCustomDomain(d *coredata.CustomDomain, cert *coredata.Certificate) *CustomDomain { + result := &CustomDomain{ ID: d.ID, OrganizationID: d.OrganizationID, Domain: d.Domain, - SslStatus: d.SSLStatus, - SslExpiresAt: d.SSLExpiresAt, + Managed: d.Managed, + SslStatus: coredata.CustomDomainSSLStatusPending, CreatedAt: d.CreatedAt, UpdatedAt: d.UpdatedAt, } + + if cert != nil { + result.SslStatus = coredata.CustomDomainSSLStatus(cert.Status) + result.SslExpiresAt = cert.SSLExpiresAt + } + + return result } diff --git a/pkg/server/api/mcp/v1/types/organization.go b/pkg/server/api/mcp/v1/types/organization.go index a72d609e3..32175d401 100644 --- a/pkg/server/api/mcp/v1/types/organization.go +++ b/pkg/server/api/mcp/v1/types/organization.go @@ -24,10 +24,9 @@ import "go.probo.inc/probo/pkg/coredata" func NewOrganization(o *coredata.Organization) *Organization { return &Organization{ - ID: o.ID, - Name: o.Name, - Description: o.Description, - CreatedAt: o.CreatedAt, - UpdatedAt: o.UpdatedAt, + ID: o.ID, + Name: o.Name, + CreatedAt: o.CreatedAt, + UpdatedAt: o.UpdatedAt, } } diff --git a/pkg/server/api/mcp/v1/types/trust_center.go b/pkg/server/api/mcp/v1/types/trust_center.go index 5214839bd..e080ab591 100644 --- a/pkg/server/api/mcp/v1/types/trust_center.go +++ b/pkg/server/api/mcp/v1/types/trust_center.go @@ -31,6 +31,10 @@ func NewTrustCenter(tc *coredata.TrustCenter) *TrustCenter { OrganizationID: tc.OrganizationID, Active: tc.Active, SearchEngineIndexing: tc.SearchEngineIndexing, + Description: tc.Description, + WebsiteURL: tc.WebsiteURL, + Email: tc.Email, + HeadquarterAddress: tc.HeadquarterAddress, CreatedAt: tc.CreatedAt, UpdatedAt: tc.UpdatedAt, } diff --git a/pkg/server/api/mcp/v1/v1_handler.go b/pkg/server/api/mcp/v1/v1_handler.go index 4f1f3ed05..5253d96eb 100644 --- a/pkg/server/api/mcp/v1/v1_handler.go +++ b/pkg/server/api/mcp/v1/v1_handler.go @@ -29,6 +29,7 @@ import ( mcpgenmcp "go.probo.inc/mcpgen/mcp" "go.probo.inc/probo/pkg/accessreview" "go.probo.inc/probo/pkg/baseurl" + "go.probo.inc/probo/pkg/complianceportal/management" "go.probo.inc/probo/pkg/cookiebanner" "go.probo.inc/probo/pkg/filemanager" "go.probo.inc/probo/pkg/iam" @@ -44,6 +45,7 @@ import ( func NewMux( logger *log.Logger, proboSvc *probo.Service, + managementSvc *management.Service, resourceAliasSvc *resourcealias.Service, thirdPartySvc *thirdparty.Service, iamSvc *iam.Service, @@ -60,6 +62,7 @@ func NewMux( resolver := &Resolver{ proboSvc: proboSvc, + management: managementSvc, resourceAlias: resourceAliasSvc, thirdPartySvc: thirdPartySvc, iamSvc: iamSvc, diff --git a/pkg/server/api/slack/v1/resolver.go b/pkg/server/api/slack/v1/resolver.go index d46734b46..fc6f0f69f 100644 --- a/pkg/server/api/slack/v1/resolver.go +++ b/pkg/server/api/slack/v1/resolver.go @@ -23,8 +23,8 @@ package slack_v1 import ( "github.com/go-chi/chi/v5" "go.gearno.de/kit/log" + trust "go.probo.inc/probo/pkg/complianceportal/visitor" "go.probo.inc/probo/pkg/slack" - "go.probo.inc/probo/pkg/trust" ) func NewMux( diff --git a/pkg/server/api/slack/v1/slack_handler.go b/pkg/server/api/slack/v1/slack_handler.go index e374c73a2..b35068f03 100644 --- a/pkg/server/api/slack/v1/slack_handler.go +++ b/pkg/server/api/slack/v1/slack_handler.go @@ -30,10 +30,10 @@ import ( "go.gearno.de/kit/httpserver" "go.gearno.de/kit/log" + trust "go.probo.inc/probo/pkg/complianceportal/visitor" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/gid" "go.probo.inc/probo/pkg/slack" - "go.probo.inc/probo/pkg/trust" ) type ( @@ -247,7 +247,7 @@ func SlackHandler(slackSvc *slack.Service, slackSigningSecret string, logger *lo switch statusAction { case StatusAccept: - if err := trustSvc.TrustCenterAccesses.GrantByIDs( + if err := trustSvc.GrantPortalAccessByIDs( ctx, scope, initialSlackMessage.OrganizationID, @@ -262,7 +262,7 @@ func SlackHandler(slackSvc *slack.Service, slackSigningSecret string, logger *lo return } case StatusReject: - if err := trustSvc.TrustCenterAccesses.RejectOrRevokeByIDs( + if err := trustSvc.RejectOrRevokePortalAccessByIDs( ctx, scope, initialSlackMessage.OrganizationID, diff --git a/pkg/server/api/trust/v1/auth_resolvers.go b/pkg/server/api/trust/v1/auth_resolvers.go index d9f957769..581f9c0d0 100644 --- a/pkg/server/api/trust/v1/auth_resolvers.go +++ b/pkg/server/api/trust/v1/auth_resolvers.go @@ -15,16 +15,16 @@ import ( "go.probo.inc/probo/pkg/iam" "go.probo.inc/probo/pkg/saferedirect" "go.probo.inc/probo/pkg/server/api/authn" - "go.probo.inc/probo/pkg/server/api/compliancepage" + "go.probo.inc/probo/pkg/server/api/complianceportal" "go.probo.inc/probo/pkg/server/api/trust/v1/types" "go.probo.inc/probo/pkg/server/gqlutils" ) // SendMagicLink is the resolver for the sendMagicLink field. func (r *mutationResolver) SendMagicLink(ctx context.Context, input types.SendMagicLinkInput) (*types.SendMagicLinkPayload, error) { - trustCenter := compliancepage.CompliancePageFromContext(ctx) + trustCenter := complianceportal.CompliancePageFromContext(ctx) - baseURL := compliancepage.CompliancePageBaseURLFromContext(ctx) + baseURL := complianceportal.CompliancePageBaseURLFromContext(ctx) safeRedirect := saferedirect.New(saferedirect.StaticHosts(baseurl.MustParse(*baseURL).Host())) @@ -123,9 +123,9 @@ func (r *mutationResolver) VerifyMagicLink(ctx context.Context, input types.Veri } } - trustCenter := compliancepage.CompliancePageFromContext(ctx) + trustCenter := complianceportal.CompliancePageFromContext(ctx) - if _, err := r.trust.ProvisionMember(ctx, trustCenter.ID, identity.ID); err != nil { + if _, err := r.trust.ProvisionPortalMember(ctx, trustCenter.ID, identity.ID); err != nil { r.logger.ErrorCtx(ctx, "cannot provision member", log.Error(err)) return nil, gqlutils.Internal(ctx) } @@ -157,7 +157,7 @@ func (r *mutationResolver) UpdateFullName(ctx context.Context, input types.Updat return nil, gqlutils.Internal(ctx) } - compliancePage := compliancepage.CompliancePageFromContext(ctx) + compliancePage := complianceportal.CompliancePageFromContext(ctx) profile, err := r.iam.OrganizationService.GetProfileForIdentityAndOrganization(ctx, identity.ID, compliancePage.OrganizationID) if err != nil { diff --git a/pkg/server/api/trust/v1/base_resolvers.go b/pkg/server/api/trust/v1/base_resolvers.go index b2636b804..e5f08a16e 100644 --- a/pkg/server/api/trust/v1/base_resolvers.go +++ b/pkg/server/api/trust/v1/base_resolvers.go @@ -11,16 +11,15 @@ import ( "strings" "go.gearno.de/kit/log" + trust "go.probo.inc/probo/pkg/complianceportal/visitor" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/gid" - "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/complianceportal" "go.probo.inc/probo/pkg/server/api/trust/v1/schema" "go.probo.inc/probo/pkg/server/api/trust/v1/types" "go.probo.inc/probo/pkg/server/gqlutils" - "go.probo.inc/probo/pkg/trust" ) // Viewer is the resolver for the viewer field. @@ -43,27 +42,23 @@ func (r *queryResolver) Viewer(ctx context.Context) (*types.Identity, error) { // Node is the resolver for the node field. func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(id) trustService := r.trust switch id.EntityType() { case coredata.OrganizationEntityType: - organization, err := trustService.Organizations.Get(ctx, scope, id) + organization, err := trustService.GetOrganization(ctx, scope, id) if err != nil { - if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) - } - r.logger.ErrorCtx(ctx, "cannot get organization", log.Error(err)) - return nil, gqlutils.Internal(ctx) } return types.NewOrganization(organization), nil case coredata.DocumentEntityType: - document, err := trustService.Documents.Get(ctx, scope, compliancePage.OrganizationID, id) + trustCenter := complianceportal.CompliancePageFromContext(ctx) + + document, err := trustService.GetDocument(ctx, scope, trustCenter.OrganizationID, id) if err != nil { if errors.Is(err, trust.ErrDocumentNotFound) || errors.Is(err, trust.ErrDocumentNotVisible) || errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) @@ -81,21 +76,18 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error return types.NewDocument(document), nil case coredata.FrameworkEntityType: - framework, err := trustService.Frameworks.Get(ctx, scope, id) + framework, err := trustService.GetFramework(ctx, scope, id) if err != nil { - if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) - } - r.logger.ErrorCtx(ctx, "cannot get framework", log.Error(err)) - return nil, gqlutils.Internal(ctx) } return types.NewFramework(framework), nil case coredata.FileEntityType: - file, err := trustService.Reports.Get(ctx, scope, compliancePage.OrganizationID, id) + trustCenter := complianceportal.CompliancePageFromContext(ctx) + + file, err := trustService.GetReport(ctx, scope, trustCenter.OrganizationID, id) if err != nil { if errors.Is(err, trust.ErrReportNotFound) || errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) @@ -106,89 +98,48 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error return nil, gqlutils.Internal(ctx) } - audit, err := trustService.Audits.GetByReportFileID(ctx, scope, id) - if err != nil { - if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) - } - - r.logger.ErrorCtx(ctx, "cannot get audit for report file", log.Error(err)) - - return nil, gqlutils.Internal(ctx) - } - - if audit.TrustCenterVisibility == coredata.TrustCenterVisibilityNone { - return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) - } - return types.NewAuditReport(file), nil case coredata.AuditEntityType: - audit, err := trustService.Audits.Get(ctx, scope, id) + audit, err := trustService.GetAudit(ctx, scope, id) if err != nil { - if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) - } - r.logger.ErrorCtx(ctx, "cannot get audit", log.Error(err)) - return nil, gqlutils.Internal(ctx) } - if audit.TrustCenterVisibility == coredata.TrustCenterVisibilityNone { - return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) - } - return types.NewAudit(audit), nil case coredata.ThirdPartyEntityType: - thirdParty, err := trustService.ThirdParties.Get(ctx, scope, id) + thirdParty, err := trustService.GetThirdParty(ctx, scope, id) if err != nil { - if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) - } - r.logger.ErrorCtx(ctx, "cannot get thirdParty", log.Error(err)) - return nil, gqlutils.Internal(ctx) } - if !thirdParty.ShowOnTrustCenter { - return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) - } - return types.NewSubprocessor(thirdParty), nil case coredata.TrustCenterEntityType: - trustCenter, err := trustService.TrustCenters.Get(ctx, scope, id) + trustCenter, err := trustService.GetPortal(ctx, scope, id) if err != nil { - if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) - } - r.logger.ErrorCtx(ctx, "cannot get trust center", log.Error(err)) - return nil, gqlutils.Internal(ctx) } return types.NewTrustCenter(trustCenter), nil case coredata.TrustCenterReferenceEntityType: - reference, err := trustService.TrustCenterReferences.Get(ctx, scope, id) + reference, err := trustService.GetPortalReference(ctx, scope, id) if err != nil { - if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) - } - r.logger.ErrorCtx(ctx, "cannot get trust center reference", log.Error(err)) - return nil, gqlutils.Internal(ctx) } return types.NewTrustCenterReference(reference), nil case coredata.TrustCenterFileEntityType: - trustCenterFile, err := trustService.TrustCenterFiles.Get(ctx, scope, compliancePage.OrganizationID, id) + trustCenter := complianceportal.CompliancePageFromContext(ctx) + + trustCenterFile, err := trustService.GetPortalFile(ctx, scope, trustCenter.OrganizationID, id) if err != nil { if errors.Is(err, trust.ErrTrustCenterFileNotFound) || errors.Is(err, trust.ErrTrustCenterFileNotVisible) { return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) @@ -201,35 +152,6 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error return types.NewTrustCenterFile(trustCenterFile), nil - case coredata.MailingListUpdateEntityType: - update, err := r.mailman.GetMailingListUpdate(ctx, id) - if err != nil { - if errors.Is(err, mailman.ErrMailingListUpdateNotFound) || errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) - } - - r.logger.ErrorCtx(ctx, "cannot get mailing list update", log.Error(err)) - - return nil, gqlutils.Internal(ctx) - } - - if update.Status != coredata.MailingListUpdateStatusSent { - return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) - } - - trustCenter, err := trustService.TrustCenters.Get(ctx, scope, compliancePage.ID) - if err != nil { - r.logger.ErrorCtx(ctx, "cannot get trust center", log.Error(err)) - - return nil, gqlutils.Internal(ctx) - } - - if trustCenter.MailingListID == nil || *trustCenter.MailingListID != update.MailingListID { - return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) - } - - return types.NewMailingListUpdate(update), nil - default: return nil, gqlutils.NotFoundf(ctx, "node %q not found", id) } @@ -239,8 +161,8 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error func (r *queryResolver) AliasedNode(ctx context.Context, alias string) (types.Node, error) { resourceID, err := gid.ParseGID(alias) if err != nil { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + trustCenter := complianceportal.CompliancePageFromContext(ctx) + scope := coredata.NewScopeFromObjectID(trustCenter.ID) resourceID, err = r.resourceAlias.ResolveAlias( ctx, @@ -263,18 +185,18 @@ func (r *queryResolver) AliasedNode(ctx context.Context, alias string) (types.No // CurrentTrustCenter is the resolver for the currentTrustCenter field. func (r *queryResolver) CurrentTrustCenter(ctx context.Context) (*types.TrustCenter, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) + trustCenter := complianceportal.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(trustCenter.ID) trustService := r.trust - org, err := trustService.Organizations.Get(ctx, scope, compliancePage.OrganizationID) + org, err := trustService.GetOrganization(ctx, scope, trustCenter.OrganizationID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get organization", log.Error(err)) return nil, gqlutils.Internal(ctx) } - trustCenter, err := trustService.TrustCenters.Get(ctx, scope, compliancePage.ID) + trustCenter, err = trustService.GetPortal(ctx, scope, trustCenter.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get trust center", log.Error(err)) return nil, gqlutils.Internal(ctx) diff --git a/pkg/server/api/trust/v1/graphql/organization.graphql b/pkg/server/api/trust/v1/graphql/organization.graphql index b286a0119..38ce26139 100644 --- a/pkg/server/api/trust/v1/graphql/organization.graphql +++ b/pkg/server/api/trust/v1/graphql/organization.graphql @@ -2,9 +2,4 @@ type Organization implements Node { id: ID! name: String! logo: File @goField(forceResolver: true) - - description: String - websiteUrl: String - email: String - headquarterAddress: String } diff --git a/pkg/server/api/trust/v1/graphql/trust_center.graphql b/pkg/server/api/trust/v1/graphql/trust_center.graphql index ff3d46fd2..d1366a4d4 100644 --- a/pkg/server/api/trust/v1/graphql/trust_center.graphql +++ b/pkg/server/api/trust/v1/graphql/trust_center.graphql @@ -5,6 +5,11 @@ type TrustCenter implements Node { logo: File @goField(forceResolver: true) darkLogo: File @goField(forceResolver: true) + description: String + websiteUrl: String + email: String + headquarterAddress: String + nonDisclosureAgreement: NonDisclosureAgreement @goField(forceResolver: true) viewerSubscription: MailingListSubscriber @goField(forceResolver: true) @@ -69,12 +74,12 @@ type TrustCenter implements Node { before: CursorKey ): ComplianceFrameworkConnection! @goField(forceResolver: true) - externalUrls( + customLinks( first: Int after: CursorKey last: Int before: CursorKey - ): ComplianceExternalURLConnection! @goField(forceResolver: true) + ): ComplianceCustomLinkConnection! @goField(forceResolver: true) updates( first: Int @@ -415,21 +420,21 @@ type TrustCenterFileEdge @nda { node: TrustCenterFile! } -type ComplianceExternalURL implements Node { +type ComplianceCustomLink implements Node { id: ID! name: String! url: String! rank: Int! } -type ComplianceExternalURLConnection { - edges: [ComplianceExternalURLEdge!]! +type ComplianceCustomLinkConnection { + edges: [ComplianceCustomLinkEdge!]! pageInfo: PageInfo! } -type ComplianceExternalURLEdge { +type ComplianceCustomLinkEdge { cursor: CursorKey! - node: ComplianceExternalURL! + node: ComplianceCustomLink! } type TrustCenterAccess implements Node { diff --git a/pkg/server/api/trust/v1/graphql_handler.go b/pkg/server/api/trust/v1/graphql_handler.go index 7ec6a6844..697fb5abb 100644 --- a/pkg/server/api/trust/v1/graphql_handler.go +++ b/pkg/server/api/trust/v1/graphql_handler.go @@ -25,6 +25,7 @@ import ( "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/baseurl" + trust "go.probo.inc/probo/pkg/complianceportal/visitor" "go.probo.inc/probo/pkg/esign" "go.probo.inc/probo/pkg/filemanager" "go.probo.inc/probo/pkg/iam" @@ -36,7 +37,6 @@ import ( "go.probo.inc/probo/pkg/server/gqlutils" "go.probo.inc/probo/pkg/server/gqlutils/directives/authentication" "go.probo.inc/probo/pkg/server/gqlutils/directives/session" - "go.probo.inc/probo/pkg/trust" ) func NewGraphQLHandler( diff --git a/pkg/server/api/trust/v1/mailing_list_resolvers.go b/pkg/server/api/trust/v1/mailing_list_resolvers.go index 1b07591be..5990848bf 100644 --- a/pkg/server/api/trust/v1/mailing_list_resolvers.go +++ b/pkg/server/api/trust/v1/mailing_list_resolvers.go @@ -12,7 +12,7 @@ import ( "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/mailman" "go.probo.inc/probo/pkg/server/api/authn" - "go.probo.inc/probo/pkg/server/api/compliancepage" + "go.probo.inc/probo/pkg/server/api/complianceportal" "go.probo.inc/probo/pkg/server/api/trust/v1/types" "go.probo.inc/probo/pkg/server/gqlutils" "go.probo.inc/probo/pkg/validator" @@ -20,7 +20,7 @@ import ( // SubscribeToMailingList is the resolver for the subscribeToMailingList field. func (r *mutationResolver) SubscribeToMailingList(ctx context.Context) (*types.SubscribeToMailingListPayload, error) { - trustCenter := compliancepage.CompliancePageFromContext(ctx) + trustCenter := complianceportal.CompliancePageFromContext(ctx) if trustCenter.MailingListID == nil { return nil, gqlutils.NotFoundf(ctx, "mailing list not found") } @@ -56,7 +56,7 @@ func (r *mutationResolver) SubscribeToMailingList(ctx context.Context) (*types.S // UnsubscribeFromMailingList is the resolver for the unsubscribeFromMailingList field. func (r *mutationResolver) UnsubscribeFromMailingList(ctx context.Context) (*types.UnsubscribeFromMailingListPayload, error) { - trustCenter := compliancepage.CompliancePageFromContext(ctx) + trustCenter := complianceportal.CompliancePageFromContext(ctx) if trustCenter.MailingListID == nil { return nil, gqlutils.NotFoundf(ctx, "mailing list not found") } diff --git a/pkg/server/api/trust/v1/nda_directive.go b/pkg/server/api/trust/v1/nda_directive.go index 41c2179cf..377bb533f 100644 --- a/pkg/server/api/trust/v1/nda_directive.go +++ b/pkg/server/api/trust/v1/nda_directive.go @@ -25,12 +25,12 @@ import ( "github.com/99designs/gqlgen/graphql" "go.gearno.de/kit/log" + trust "go.probo.inc/probo/pkg/complianceportal/visitor" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/esign" "go.probo.inc/probo/pkg/server/api/authn" - "go.probo.inc/probo/pkg/server/api/compliancepage" + "go.probo.inc/probo/pkg/server/api/complianceportal" "go.probo.inc/probo/pkg/server/gqlutils" - "go.probo.inc/probo/pkg/trust" ) func newNDADirective( @@ -44,13 +44,13 @@ func newNDADirective( return next(ctx) } - compliancePage := compliancepage.CompliancePageFromContext(ctx) + compliancePage := complianceportal.CompliancePageFromContext(ctx) if compliancePage == nil { logger.ErrorCtx(ctx, "cannot get compliance page from context") return nil, gqlutils.Internal(ctx) } - membership, err := trustSvc.GetMembershipByCompliancePageIDAndIdentityID(ctx, compliancePage.ID, identity.ID) + membership, err := trustSvc.GetPortalMembership(ctx, compliancePage.ID, identity.ID) if err != nil { logger.ErrorCtx(ctx, "cannot get compliance page membership", log.Error(err)) return nil, gqlutils.Internal(ctx) diff --git a/pkg/server/api/trust/v1/nda_resolvers.go b/pkg/server/api/trust/v1/nda_resolvers.go index 412affcf7..a40698f9d 100644 --- a/pkg/server/api/trust/v1/nda_resolvers.go +++ b/pkg/server/api/trust/v1/nda_resolvers.go @@ -7,15 +7,14 @@ package trust_v1 import ( "context" - "errors" + "net" "time" "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/esign" "go.probo.inc/probo/pkg/server/api/authn" - "go.probo.inc/probo/pkg/server/api/clientip" - "go.probo.inc/probo/pkg/server/api/compliancepage" + "go.probo.inc/probo/pkg/server/api/complianceportal" "go.probo.inc/probo/pkg/server/api/trust/v1/schema" "go.probo.inc/probo/pkg/server/api/trust/v1/types" "go.probo.inc/probo/pkg/server/gqlutils" @@ -24,17 +23,17 @@ import ( // AcceptElectronicSignature is the resolver for the acceptElectronicSignature field. func (r *mutationResolver) AcceptElectronicSignature(ctx context.Context, input types.AcceptElectronicSignatureInput) (*types.AcceptElectronicSignaturePayload, error) { var ( - identity = authn.IdentityFromContext(ctx) - httpReq = gqlutils.HTTPRequestFromContext(ctx) - compliancePage = compliancepage.CompliancePageFromContext(ctx) - scope = coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + identity = authn.IdentityFromContext(ctx) + httpReq = gqlutils.HTTPRequestFromContext(ctx) ) - signerIP := clientip.Extract(httpReq) + signerIP, _, _ := net.SplitHostPort(httpReq.RemoteAddr) + if signerIP == "" { + signerIP = httpReq.RemoteAddr + } signature, err := r.esign.AcceptSignature( ctx, - scope, &esign.AcceptSignatureRequest{ SignatureID: input.SignatureID, SignerFullName: identity.FullName, @@ -44,16 +43,7 @@ func (r *mutationResolver) AcceptElectronicSignature(ctx context.Context, input }, ) if err != nil { - if errors.Is(err, esign.ErrElectronicSignatureNotFound) { - return nil, gqlutils.NotFoundf(ctx, "electronic signature %q not found", input.SignatureID) - } - - if errors.Is(err, esign.ErrSignatureAccessDenied) { - return nil, gqlutils.Forbiddenf(ctx, "cannot accept electronic signature") - } - r.logger.ErrorCtx(ctx, "cannot accept electronic signature", log.Error(err)) - return nil, gqlutils.Internal(ctx) } @@ -65,17 +55,17 @@ func (r *mutationResolver) AcceptElectronicSignature(ctx context.Context, input // RecordSigningEvent is the resolver for the recordSigningEvent field. func (r *mutationResolver) RecordSigningEvent(ctx context.Context, input types.RecordSigningEventInput) (*types.RecordSigningEventPayload, error) { var ( - identity = authn.IdentityFromContext(ctx) - httpReq = gqlutils.HTTPRequestFromContext(ctx) - compliancePage = compliancepage.CompliancePageFromContext(ctx) - scope = coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + identity = authn.IdentityFromContext(ctx) + httpReq = gqlutils.HTTPRequestFromContext(ctx) ) - actorIP := clientip.Extract(httpReq) + actorIP, _, _ := net.SplitHostPort(httpReq.RemoteAddr) + if actorIP == "" { + actorIP = httpReq.RemoteAddr + } if err := r.esign.RecordEvent( ctx, - scope, &esign.RecordEventRequest{ SignatureID: input.SignatureID, EventType: input.EventType, @@ -85,16 +75,7 @@ func (r *mutationResolver) RecordSigningEvent(ctx context.Context, input types.R ActorUA: httpReq.UserAgent(), }, ); err != nil { - if errors.Is(err, esign.ErrElectronicSignatureNotFound) { - return nil, gqlutils.NotFoundf(ctx, "electronic signature %q not found", input.SignatureID) - } - - if errors.Is(err, esign.ErrSignatureAccessDenied) { - return nil, gqlutils.Forbiddenf(ctx, "cannot record signing event") - } - r.logger.ErrorCtx(ctx, "cannot record signing event", log.Error(err)) - return nil, gqlutils.Internal(ctx) } @@ -103,13 +84,13 @@ func (r *mutationResolver) RecordSigningEvent(ctx context.Context, input types.R // FileURL is the resolver for the fileUrl field. func (r *nonDisclosureAgreementResolver) FileURL(ctx context.Context, obj *types.NonDisclosureAgreement) (string, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) + trustCenter := complianceportal.CompliancePageFromContext(ctx) if identity := authn.IdentityFromContext(ctx); identity != nil && r.esign != nil { - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(trustCenter.ID) trustService := r.trust - access, err := trustService.TrustCenterAccesses.GetAccess(ctx, scope, compliancePage.ID, identity.ID) + access, err := trustService.GetPortalAccess(ctx, scope, trustCenter.ID, identity.ID) if err == nil && access.ElectronicSignatureID != nil { fileURL, err := r.esign.GenerateSignatureFileURL(ctx, *access.ElectronicSignatureID, 15*time.Minute) if err == nil { @@ -120,10 +101,10 @@ func (r *nonDisclosureAgreementResolver) FileURL(ctx context.Context, obj *types } } - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(trustCenter.ID) trustService := r.trust - fileURL, err := trustService.TrustCenters.GenerateNDAFileURL(ctx, scope, compliancePage.ID, 15*time.Minute) + fileURL, err := trustService.GeneratePortalNDAFileURL(ctx, scope, trustCenter.ID, 15*time.Minute) if err != nil { return "", gqlutils.Internal(ctx) } @@ -138,11 +119,11 @@ func (r *nonDisclosureAgreementResolver) ViewerSignature(ctx context.Context, ob return nil, nil } - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + trustCenter := complianceportal.CompliancePageFromContext(ctx) + scope := coredata.NewScopeFromObjectID(trustCenter.ID) trustService := r.trust - access, err := trustService.TrustCenterAccesses.GetAccess(ctx, scope, compliancePage.ID, identity.ID) + access, err := trustService.GetPortalAccess(ctx, scope, trustCenter.ID, identity.ID) if err != nil { return nil, nil } @@ -151,7 +132,7 @@ func (r *nonDisclosureAgreementResolver) ViewerSignature(ctx context.Context, ob return nil, nil } - sig, err := r.esign.GetSignatureByID(ctx, scope, *access.ElectronicSignatureID) + sig, err := r.esign.GetSignatureByID(ctx, *access.ElectronicSignatureID) if err != nil { return nil, nil } diff --git a/pkg/server/api/trust/v1/organization_resolvers.go b/pkg/server/api/trust/v1/organization_resolvers.go index 3b5319401..7b6c40087 100644 --- a/pkg/server/api/trust/v1/organization_resolvers.go +++ b/pkg/server/api/trust/v1/organization_resolvers.go @@ -20,7 +20,7 @@ func (r *organizationResolver) Logo(ctx context.Context, obj *types.Organization compliancePage := compliancepage.CompliancePageFromContext(ctx) scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) - organization, err := r.trust.Organizations.Get(ctx, scope, obj.ID) + organization, err := r.trust.GetOrganization(ctx, scope, obj.ID) if err != nil { return nil, gqlutils.NotFoundf(ctx, "organization %q not found", obj.ID) } diff --git a/pkg/server/api/trust/v1/resolver.go b/pkg/server/api/trust/v1/resolver.go index f9591e7c7..5548c5355 100644 --- a/pkg/server/api/trust/v1/resolver.go +++ b/pkg/server/api/trust/v1/resolver.go @@ -50,6 +50,7 @@ import ( "github.com/go-chi/chi/v5" "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/baseurl" + trust "go.probo.inc/probo/pkg/complianceportal/visitor" "go.probo.inc/probo/pkg/esign" "go.probo.inc/probo/pkg/filemanager" "go.probo.inc/probo/pkg/iam" @@ -57,9 +58,8 @@ import ( "go.probo.inc/probo/pkg/resourcealias" "go.probo.inc/probo/pkg/securecookie" "go.probo.inc/probo/pkg/server/api/authn" - "go.probo.inc/probo/pkg/server/api/compliancepage" + "go.probo.inc/probo/pkg/server/api/complianceportal" "go.probo.inc/probo/pkg/server/gqlutils" - "go.probo.inc/probo/pkg/trust" ) type ( @@ -102,13 +102,13 @@ func NewMux( ) *chi.Mux { r := chi.NewMux() - r.Use(compliancepage.NewCompliancePagePresenceMiddleware()) + r.Use(complianceportal.NewCompliancePagePresenceMiddleware()) sessionTransferHandler := NewSessionTransferHandler( iamSvc, cookieConfig, func(ctx context.Context, host string) bool { - _, err := trustSvc.GetByDomainName(ctx, host) + _, err := trustSvc.GetPortalByDomainName(ctx, host) return err == nil }, logger, @@ -132,7 +132,7 @@ func NewMux( r.Group( func(r chi.Router) { r.Use(authn.NewSessionMiddleware(iamSvc, cookieConfig)) - r.Use(compliancepage.NewMemberProvisioningMiddleware(trustSvc, logger)) + r.Use(complianceportal.NewMemberProvisioningMiddleware(trustSvc, logger)) r.Handle("/graphql", graphqlHandler) }, ) diff --git a/pkg/server/api/trust/v1/resource_alias_resolvers.go b/pkg/server/api/trust/v1/resource_alias_resolvers.go index ef82dcae5..a873b6e38 100644 --- a/pkg/server/api/trust/v1/resource_alias_resolvers.go +++ b/pkg/server/api/trust/v1/resource_alias_resolvers.go @@ -26,7 +26,7 @@ import ( "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/gid" - "go.probo.inc/probo/pkg/server/api/compliancepage" + "go.probo.inc/probo/pkg/server/api/complianceportal" "go.probo.inc/probo/pkg/server/gqlutils" ) @@ -34,8 +34,8 @@ func (r *Resolver) ResourceAliasResolver( ctx context.Context, storageResourceID gid.GID, ) (*string, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + trustCenter := complianceportal.CompliancePageFromContext(ctx) + scope := coredata.NewScopeFromObjectID(trustCenter.ID) alias, err := r.resourceAlias.GetByResourceID(ctx, scope, storageResourceID) if err != nil { diff --git a/pkg/server/api/trust/v1/trust_center_resolvers.go b/pkg/server/api/trust/v1/trust_center_resolvers.go index 5489309e9..8e5ad5b5b 100644 --- a/pkg/server/api/trust/v1/trust_center_resolvers.go +++ b/pkg/server/api/trust/v1/trust_center_resolvers.go @@ -12,30 +12,29 @@ import ( "fmt" "go.gearno.de/kit/log" + trust "go.probo.inc/probo/pkg/complianceportal/visitor" "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/complianceportal" "go.probo.inc/probo/pkg/server/api/trust/v1/schema" "go.probo.inc/probo/pkg/server/api/trust/v1/types" "go.probo.inc/probo/pkg/server/gqlutils" - "go.probo.inc/probo/pkg/trust" ) // Framework is the resolver for the framework field. func (r *auditResolver) Framework(ctx context.Context, obj *types.Audit) (*types.Framework, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust - audit, err := trustService.Audits.Get(ctx, scope, obj.ID) + audit, err := trustService.GetAudit(ctx, scope, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot load audit", log.Error(err)) return nil, gqlutils.Internal(ctx) } - framework, err := trustService.Frameworks.Get(ctx, scope, audit.FrameworkID) + framework, err := trustService.GetFramework(ctx, scope, audit.FrameworkID) if err != nil { r.logger.ErrorCtx(ctx, "cannot load framework", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -46,11 +45,10 @@ func (r *auditResolver) Framework(ctx context.Context, obj *types.Audit) (*types // ReportFile is the resolver for the reportFile field. func (r *auditResolver) ReportFile(ctx context.Context, obj *types.Audit) (*types.AuditReport, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust - audit, err := trustService.Audits.Get(ctx, scope, obj.ID) + audit, err := trustService.GetAudit(ctx, scope, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot load audit", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -60,7 +58,9 @@ func (r *auditResolver) ReportFile(ctx context.Context, obj *types.Audit) (*type return nil, nil } - file, err := trustService.Reports.Get(ctx, scope, compliancePage.OrganizationID, *audit.ReportFileID) + trustCenter := complianceportal.CompliancePageFromContext(ctx) + + file, err := trustService.GetReport(ctx, scope, trustCenter.OrganizationID, *audit.ReportFileID) if err != nil { r.logger.ErrorCtx(ctx, "cannot load report file", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -76,11 +76,11 @@ func (r *auditReportResolver) Alias(ctx context.Context, obj *types.AuditReport) // IsUserAuthorized is the resolver for the isUserAuthorized field. func (r *auditReportResolver) IsUserAuthorized(ctx context.Context, obj *types.AuditReport) (bool, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust + trustCenter := complianceportal.CompliancePageFromContext(ctx) - audit, err := trustService.Audits.GetByReportFileID(ctx, scope, obj.ID) + audit, err := trustService.GetAuditByReportFileID(ctx, scope, obj.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { return false, nil @@ -100,8 +100,8 @@ func (r *auditReportResolver) IsUserAuthorized(ctx context.Context, obj *types.A return false, nil } - reportAccess, err := trustService.TrustCenterAccesses.GetReportFileAccess(ctx, scope, - compliancePage.ID, + reportAccess, err := trustService.GetPortalReportFileAccess(ctx, scope, + trustCenter.ID, identity.ID, obj.ID, ) @@ -123,18 +123,18 @@ func (r *auditReportResolver) IsUserAuthorized(ctx context.Context, obj *types.A // Access is the resolver for the access field. func (r *auditReportResolver) Access(ctx context.Context, obj *types.AuditReport) (*types.DocumentAccess, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust + trustCenter := complianceportal.CompliancePageFromContext(ctx) identity := authn.IdentityFromContext(ctx) if identity == nil { return nil, nil } - access, err := trustService.TrustCenterAccesses.GetReportFileAccess( + access, err := trustService.GetPortalReportFileAccess( ctx, scope, - compliancePage.ID, + trustCenter.ID, identity.ID, obj.ID, ) @@ -162,11 +162,10 @@ func (r *auditReportResolver) Access(ctx context.Context, obj *types.AuditReport // Framework is the resolver for the framework field on ComplianceFramework. func (r *complianceFrameworkResolver) Framework(ctx context.Context, obj *types.ComplianceFramework) (*types.Framework, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust - framework, err := trustService.Frameworks.Get(ctx, scope, obj.FrameworkID) + framework, err := trustService.GetFramework(ctx, scope, obj.FrameworkID) if err != nil { r.logger.ErrorCtx(ctx, "cannot load framework", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -175,25 +174,6 @@ func (r *complianceFrameworkResolver) Framework(ctx context.Context, obj *types. return types.NewFramework(framework), nil } -// Commitments is the resolver for the commitments field. -func (r *compliancePortalCommitmentGroupResolver) Commitments(ctx context.Context, obj *types.CompliancePortalCommitmentGroup, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.CompliancePortalCommitmentConnection, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) - pageOrderBy := page.OrderBy[coredata.CompliancePortalCommitmentOrderField]{ - Field: coredata.CompliancePortalCommitmentOrderFieldRank, - Direction: page.OrderDirectionAsc, - } - cursor := types.NewCursor(first, after, last, before, pageOrderBy) - - commitmentPage, err := r.trust.CompliancePortalCommitments.ListForGroupID(ctx, scope, obj.ID, cursor) - if err != nil { - r.logger.ErrorCtx(ctx, "cannot list public compliance portal commitments", log.Error(err)) - return nil, gqlutils.Internal(ctx) - } - - return types.NewCompliancePortalCommitmentConnection(commitmentPage), nil -} - // Alias is the resolver for the alias field. func (r *documentResolver) Alias(ctx context.Context, obj *types.Document) (*string, error) { return r.ResourceAliasResolver(ctx, obj.ID) @@ -201,11 +181,11 @@ func (r *documentResolver) Alias(ctx context.Context, obj *types.Document) (*str // IsUserAuthorized is the resolver for the isUserAuthorized field. func (r *documentResolver) IsUserAuthorized(ctx context.Context, obj *types.Document) (bool, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust + trustCenter := complianceportal.CompliancePageFromContext(ctx) - document, err := trustService.Documents.Get(ctx, scope, compliancePage.OrganizationID, obj.ID) + document, err := trustService.GetDocument(ctx, scope, trustCenter.OrganizationID, obj.ID) if err != nil { if errors.Is(err, trust.ErrDocumentNotFound) || errors.Is(err, trust.ErrDocumentNotVisible) || errors.Is(err, coredata.ErrResourceNotFound) { return false, gqlutils.NotFoundf(ctx, "document %q not found", obj.ID) @@ -229,9 +209,9 @@ func (r *documentResolver) IsUserAuthorized(ctx context.Context, obj *types.Docu return false, nil } - documentAccess, err := trustService.TrustCenterAccesses.GetDocumentAccess( + documentAccess, err := trustService.GetPortalDocumentAccess( ctx, scope, - compliancePage.ID, + trustCenter.ID, identity.ID, obj.ID, ) @@ -253,18 +233,18 @@ func (r *documentResolver) IsUserAuthorized(ctx context.Context, obj *types.Docu // Access is the resolver for the access field. func (r *documentResolver) Access(ctx context.Context, obj *types.Document) (*types.DocumentAccess, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust + trustCenter := complianceportal.CompliancePageFromContext(ctx) identity := authn.IdentityFromContext(ctx) if identity == nil { return nil, nil // User is not authenticated, so no access requested } - access, err := trustService.TrustCenterAccesses.GetDocumentAccess( + access, err := trustService.GetPortalDocumentAccess( ctx, scope, - compliancePage.ID, + trustCenter.ID, identity.ID, obj.ID, ) @@ -292,10 +272,9 @@ func (r *documentResolver) Access(ctx context.Context, obj *types.Document) (*ty // LightLogo is the resolver for the lightLogo field. func (r *frameworkResolver) LightLogo(ctx context.Context, obj *types.Framework) (*types.File, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) - framework, err := r.trust.Frameworks.Get(ctx, scope, obj.ID) + framework, err := r.trust.GetFramework(ctx, scope, obj.ID) if err != nil { return nil, gqlutils.NotFoundf(ctx, "framework %q not found", obj.ID) } @@ -309,10 +288,9 @@ func (r *frameworkResolver) LightLogo(ctx context.Context, obj *types.Framework) // DarkLogo is the resolver for the darkLogo field. func (r *frameworkResolver) DarkLogo(ctx context.Context, obj *types.Framework) (*types.File, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) - framework, err := r.trust.Frameworks.Get(ctx, scope, obj.ID) + framework, err := r.trust.GetFramework(ctx, scope, obj.ID) if err != nil { return nil, gqlutils.NotFoundf(ctx, "framework %q not found", obj.ID) } @@ -326,8 +304,8 @@ func (r *frameworkResolver) DarkLogo(ctx context.Context, obj *types.Framework) // RequestAllAccesses is the resolver for the requestAllAccesses field. func (r *mutationResolver) RequestAllAccesses(ctx context.Context) (*types.RequestAccessesPayload, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + trustCenter := complianceportal.CompliancePageFromContext(ctx) + scope := coredata.NewScopeFromObjectID(trustCenter.ID) trustService := r.trust identity := authn.IdentityFromContext(ctx) @@ -335,10 +313,10 @@ func (r *mutationResolver) RequestAllAccesses(ctx context.Context) (*types.Reque return nil, gqlutils.Unauthenticatedf(ctx, "authentication is required to request access") } - access, err := trustService.TrustCenterAccesses.Request( + access, err := trustService.RequestPortalAccess( ctx, scope, - &trust.TrustCenterAccessRequest{ - TrustCenterID: compliancePage.ID, + &trust.PortalAccessRequest{ + TrustCenterID: trustCenter.ID, IdentityID: identity.ID, DocumentIDs: nil, ReportIDs: nil, @@ -360,11 +338,11 @@ func (r *mutationResolver) RequestAllAccesses(ctx context.Context) (*types.Reque // ExportDocumentPDF is the resolver for the exportDocumentPDF field. func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.ExportDocumentPDFInput) (*types.ExportDocumentPDFPayload, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(input.DocumentID) trustService := r.trust + trustCenter := complianceportal.CompliancePageFromContext(ctx) - document, err := trustService.Documents.Get(ctx, scope, compliancePage.OrganizationID, input.DocumentID) + document, err := trustService.GetDocument(ctx, scope, trustCenter.OrganizationID, input.DocumentID) if err != nil { if errors.Is(err, trust.ErrDocumentNotFound) || errors.Is(err, trust.ErrDocumentNotVisible) || errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFoundf(ctx, "document %q not found", input.DocumentID) @@ -380,7 +358,7 @@ func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.Ex } if document.TrustCenterVisibility == coredata.TrustCenterVisibilityPublic { - pdf, err := trustService.Documents.ExportPDFWithoutWatermark(ctx, scope, input.DocumentID) + pdf, err := trustService.ExportDocumentPDFWithoutWatermark(ctx, scope, input.DocumentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot export document PDF", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -396,9 +374,9 @@ func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.Ex return nil, gqlutils.Unauthenticated(ctx, errors.New("unauthenticated")) } - documentAccess, err := trustService.TrustCenterAccesses.GetDocumentAccess( + documentAccess, err := trustService.GetPortalDocumentAccess( ctx, scope, - compliancePage.ID, + trustCenter.ID, identity.ID, input.DocumentID, ) @@ -410,7 +388,7 @@ func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.Ex return nil, gqlutils.Forbiddenf(ctx, "access denied: no permission to access this document") } - pdf, err := trustService.Documents.ExportPDF(ctx, scope, input.DocumentID, identity.EmailAddress) + pdf, err := trustService.ExportDocumentPDF(ctx, scope, input.DocumentID, identity.EmailAddress) if err != nil { r.logger.ErrorCtx(ctx, "cannot export document PDF", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -423,23 +401,18 @@ func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.Ex // ExportReportPDF is the resolver for the exportReportPDF field. func (r *mutationResolver) ExportReportPDF(ctx context.Context, input types.ExportReportPDFInput) (*types.ExportReportPDFPayload, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(input.ReportID) trustService := r.trust + trustCenter := complianceportal.CompliancePageFromContext(ctx) - audit, err := trustService.Audits.GetByReportFileID(ctx, scope, input.ReportID) + audit, err := trustService.GetAuditByReportFileID(ctx, scope, input.ReportID) if err != nil { - if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFoundf(ctx, "report %q not found", input.ReportID) - } - r.logger.ErrorCtx(ctx, "cannot load audit", log.Error(err)) - return nil, gqlutils.Internal(ctx) } if audit.TrustCenterVisibility == coredata.TrustCenterVisibilityPublic { - pdf, err := trustService.Reports.ExportPDFWithoutWatermark(ctx, scope, input.ReportID) + pdf, err := trustService.ExportReportPDFWithoutWatermark(ctx, scope, input.ReportID) if err != nil { r.logger.ErrorCtx(ctx, "cannot export report PDF", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -455,9 +428,9 @@ func (r *mutationResolver) ExportReportPDF(ctx context.Context, input types.Expo return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated") } - reportAccess, err := trustService.TrustCenterAccesses.GetReportFileAccess( + reportAccess, err := trustService.GetPortalReportFileAccess( ctx, scope, - compliancePage.ID, + trustCenter.ID, identity.ID, input.ReportID, ) @@ -469,7 +442,7 @@ func (r *mutationResolver) ExportReportPDF(ctx context.Context, input types.Expo return nil, gqlutils.Forbiddenf(ctx, "access denied: no permission to access this report") } - pdf, err := trustService.Reports.ExportPDF(ctx, scope, input.ReportID, identity.EmailAddress) + pdf, err := trustService.ExportReportPDF(ctx, scope, input.ReportID, identity.EmailAddress) if err != nil { r.logger.ErrorCtx(ctx, "cannot export report PDF", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -482,11 +455,11 @@ func (r *mutationResolver) ExportReportPDF(ctx context.Context, input types.Expo // ExportTrustCenterFile is the resolver for the exportTrustCenterFile field. func (r *mutationResolver) ExportTrustCenterFile(ctx context.Context, input types.ExportTrustCenterFileInput) (*types.ExportTrustCenterFilePayload, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + trustCenter := complianceportal.CompliancePageFromContext(ctx) + scope := coredata.NewScopeFromObjectID(trustCenter.ID) trustService := r.trust - trustCenterFile, err := trustService.TrustCenterFiles.Get(ctx, scope, compliancePage.OrganizationID, input.TrustCenterFileID) + trustCenterFile, err := trustService.GetPortalFile(ctx, scope, trustCenter.OrganizationID, input.TrustCenterFileID) if err != nil { if errors.Is(err, trust.ErrTrustCenterFileNotFound) || errors.Is(err, trust.ErrTrustCenterFileNotVisible) { return nil, gqlutils.NotFoundf(ctx, "trust center file %q not found", input.TrustCenterFileID) @@ -498,7 +471,7 @@ func (r *mutationResolver) ExportTrustCenterFile(ctx context.Context, input type } if trustCenterFile.TrustCenterVisibility == coredata.TrustCenterVisibilityPublic { - fileData, mimeType, err := trustService.TrustCenterFiles.ExportFileWithoutWatermark(ctx, scope, input.TrustCenterFileID) + fileData, mimeType, err := trustService.ExportPortalFileWithoutWatermark(ctx, scope, input.TrustCenterFileID) if err != nil { r.logger.ErrorCtx(ctx, "cannot export trust center file", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -514,8 +487,8 @@ func (r *mutationResolver) ExportTrustCenterFile(ctx context.Context, input type return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated") } - fileAccess, err := trustService.TrustCenterAccesses.GetTrustCenterFileAccess(ctx, scope, - compliancePage.ID, + fileAccess, err := trustService.GetPortalFileAccess(ctx, scope, + trustCenter.ID, identity.ID, input.TrustCenterFileID, ) @@ -527,7 +500,7 @@ func (r *mutationResolver) ExportTrustCenterFile(ctx context.Context, input type return nil, gqlutils.Forbiddenf(ctx, "access denied: no permission to access this file") } - fileData, mimeType, err := trustService.TrustCenterFiles.ExportFile(ctx, scope, input.TrustCenterFileID, identity.EmailAddress) + fileData, mimeType, err := trustService.ExportPortalFile(ctx, scope, input.TrustCenterFileID, identity.EmailAddress) if err != nil { r.logger.ErrorCtx(ctx, "cannot export trust center file", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -540,11 +513,11 @@ func (r *mutationResolver) ExportTrustCenterFile(ctx context.Context, input type // RequestDocumentAccess is the resolver for the requestDocumentAccess field. func (r *mutationResolver) RequestDocumentAccess(ctx context.Context, input types.RequestDocumentAccessInput) (*types.RequestDocumentAccessPayload, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + trustCenter := complianceportal.CompliancePageFromContext(ctx) + scope := coredata.NewScopeFromObjectID(trustCenter.ID) trustService := r.trust - document, err := trustService.Documents.Get(ctx, scope, compliancePage.OrganizationID, input.DocumentID) + document, err := trustService.GetDocument(ctx, scope, trustCenter.OrganizationID, input.DocumentID) if err != nil { if errors.Is(err, trust.ErrDocumentNotFound) || errors.Is(err, trust.ErrDocumentNotVisible) || errors.Is(err, coredata.ErrResourceNotFound) { return nil, gqlutils.NotFoundf(ctx, "document %q not found", input.DocumentID) @@ -571,10 +544,10 @@ func (r *mutationResolver) RequestDocumentAccess(ctx context.Context, input type return nil, gqlutils.Unauthenticatedf(ctx, "authentication is required to request access") } - if _, err := trustService.TrustCenterAccesses.Request( + if _, err := trustService.RequestPortalAccess( ctx, scope, - &trust.TrustCenterAccessRequest{ - TrustCenterID: compliancePage.ID, + &trust.PortalAccessRequest{ + TrustCenterID: trustCenter.ID, IdentityID: identity.ID, DocumentIDs: []gid.GID{input.DocumentID}, ReportIDs: []gid.GID{}, @@ -592,11 +565,11 @@ func (r *mutationResolver) RequestDocumentAccess(ctx context.Context, input type // RequestReportAccess is the resolver for the requestReportAccess field. func (r *mutationResolver) RequestReportAccess(ctx context.Context, input types.RequestReportAccessInput) (*types.RequestReportAccessPayload, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + trustCenter := complianceportal.CompliancePageFromContext(ctx) + scope := coredata.NewScopeFromObjectID(trustCenter.ID) trustService := r.trust - audit, err := trustService.Audits.GetByReportFileID(ctx, scope, input.ReportID) + audit, err := trustService.GetAuditByReportFileID(ctx, scope, input.ReportID) if err != nil { r.logger.ErrorCtx(ctx, "cannot load audit", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -614,10 +587,10 @@ func (r *mutationResolver) RequestReportAccess(ctx context.Context, input types. return nil, gqlutils.Unauthenticatedf(ctx, "authentication is required to request access") } - if _, err := trustService.TrustCenterAccesses.Request( + if _, err := trustService.RequestPortalAccess( ctx, scope, - &trust.TrustCenterAccessRequest{ - TrustCenterID: compliancePage.ID, + &trust.PortalAccessRequest{ + TrustCenterID: trustCenter.ID, IdentityID: identity.ID, DocumentIDs: []gid.GID{}, ReportIDs: []gid.GID{input.ReportID}, @@ -635,11 +608,11 @@ func (r *mutationResolver) RequestReportAccess(ctx context.Context, input types. // RequestTrustCenterFileAccess is the resolver for the requestTrustCenterFileAccess field. func (r *mutationResolver) RequestTrustCenterFileAccess(ctx context.Context, input types.RequestTrustCenterFileAccessInput) (*types.RequestFileAccessPayload, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + trustCenter := complianceportal.CompliancePageFromContext(ctx) + scope := coredata.NewScopeFromObjectID(trustCenter.ID) trustService := r.trust - trustCenterFile, err := trustService.TrustCenterFiles.Get(ctx, scope, compliancePage.OrganizationID, input.TrustCenterFileID) + trustCenterFile, err := trustService.GetPortalFile(ctx, scope, trustCenter.OrganizationID, input.TrustCenterFileID) if err != nil { if errors.Is(err, trust.ErrTrustCenterFileNotFound) || errors.Is(err, trust.ErrTrustCenterFileNotVisible) { return nil, gqlutils.NotFoundf(ctx, "trust center file %q not found", input.TrustCenterFileID) @@ -662,10 +635,10 @@ func (r *mutationResolver) RequestTrustCenterFileAccess(ctx context.Context, inp return nil, gqlutils.Unauthenticatedf(ctx, "authentication is required to request access") } - if _, err := trustService.TrustCenterAccesses.Request( + if _, err := trustService.RequestPortalAccess( ctx, scope, - &trust.TrustCenterAccessRequest{ - TrustCenterID: compliancePage.ID, + &trust.PortalAccessRequest{ + TrustCenterID: trustCenter.ID, IdentityID: identity.ID, DocumentIDs: []gid.GID{}, ReportIDs: []gid.GID{}, @@ -683,13 +656,12 @@ func (r *mutationResolver) RequestTrustCenterFileAccess(ctx context.Context, inp // TotalCount is the resolver for the totalCount field. func (r *subprocessorConnectionResolver) TotalCount(ctx context.Context, obj *types.SubprocessorConnection) (int, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ParentID) trustService := r.trust switch obj.Resolver.(type) { case *trustCenterResolver: - count, err := trustService.ThirdParties.CountForTrustCenterId(ctx, scope, obj.ParentID, obj.Filter) + count, err := trustService.CountThirdPartiesForPortalID(ctx, scope, obj.ParentID, obj.Filter) if err != nil { r.logger.ErrorCtx(ctx, "cannot count subprocessors", log.Error(err)) return 0, gqlutils.Internal(ctx) @@ -705,35 +677,35 @@ func (r *subprocessorConnectionResolver) TotalCount(ctx context.Context, obj *ty // Logo is the resolver for the logo field. func (r *trustCenterResolver) Logo(ctx context.Context, obj *types.TrustCenter) (*types.File, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - if compliancePage.LogoFileID == nil { + trustCenter := complianceportal.CompliancePageFromContext(ctx) + if trustCenter.LogoFileID == nil { return nil, nil } - return r.loadPublicFile(ctx, *compliancePage.LogoFileID) + return r.loadPublicFile(ctx, *trustCenter.LogoFileID) } // DarkLogo is the resolver for the darkLogo field. func (r *trustCenterResolver) DarkLogo(ctx context.Context, obj *types.TrustCenter) (*types.File, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - if compliancePage.DarkLogoFileID == nil { + trustCenter := complianceportal.CompliancePageFromContext(ctx) + if trustCenter.DarkLogoFileID == nil { return nil, nil } - return r.loadPublicFile(ctx, *compliancePage.DarkLogoFileID) + return r.loadPublicFile(ctx, *trustCenter.DarkLogoFileID) } // NonDisclosureAgreement is the resolver for the nonDisclosureAgreement field. func (r *trustCenterResolver) NonDisclosureAgreement(ctx context.Context, obj *types.TrustCenter) (*types.NonDisclosureAgreement, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - if compliancePage.NonDisclosureAgreementFileID == nil { + trustCenter := complianceportal.CompliancePageFromContext(ctx) + if trustCenter.NonDisclosureAgreementFileID == nil { return nil, nil } - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust - file, err := trustService.TrustCenters.GetNDAFile(ctx, scope, obj.ID) + file, err := trustService.GetPortalNDAFile(ctx, scope, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot load NDA file", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -748,8 +720,8 @@ func (r *trustCenterResolver) NonDisclosureAgreement(ctx context.Context, obj *t // ViewerSubscription is the resolver for the viewerSubscription field. func (r *trustCenterResolver) ViewerSubscription(ctx context.Context, obj *types.TrustCenter) (*types.MailingListSubscriber, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - if compliancePage.MailingListID == nil { + trustCenter := complianceportal.CompliancePageFromContext(ctx) + if trustCenter.MailingListID == nil { return nil, nil } @@ -758,7 +730,7 @@ func (r *trustCenterResolver) ViewerSubscription(ctx context.Context, obj *types return nil, nil } - subscriber, err := r.mailman.GetSubscriber(ctx, *compliancePage.MailingListID, identity.EmailAddress) + 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) @@ -771,15 +743,10 @@ func (r *trustCenterResolver) ViewerSubscription(ctx context.Context, obj *types 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, filter *types.TrustCenterVisibilityFilter) (*types.DocumentConnection, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) +func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.DocumentConnection, error) { + trustCenter := complianceportal.CompliancePageFromContext(ctx) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{ Field: coredata.DocumentOrderFieldTitle, @@ -787,12 +754,7 @@ func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCen } cursor := types.NewCursor(first, after, last, before, pageOrderBy) - documentFilter := coredata.NewDocumentTrustCenterFilter() - if filter != nil && filter.Visibility != nil { - documentFilter = documentFilter.WithTrustCenterVisibilities(*filter.Visibility) - } - - documentPage, err := trustService.Documents.ListForOrganizationId(ctx, scope, obj.Organization.ID, cursor, documentFilter) + documentPage, err := trustService.ListDocumentsForOrganizationID(ctx, scope, trustCenter.OrganizationID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list public documents", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -802,9 +764,9 @@ func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCen } // 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, filter *types.TrustCenterVisibilityFilter) (*types.AuditConnection, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) +func (r *trustCenterResolver) Audits(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.AuditConnection, error) { + trustCenter := complianceportal.CompliancePageFromContext(ctx) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust pageOrderBy := page.OrderBy[coredata.AuditOrderField]{ Field: coredata.AuditOrderFieldValidFrom, @@ -812,12 +774,7 @@ func (r *trustCenterResolver) Audits(ctx context.Context, obj *types.TrustCenter } cursor := types.NewCursor(first, after, last, before, pageOrderBy) - auditFilter := coredata.NewAuditTrustCenterFilter() - if filter != nil && filter.Visibility != nil { - auditFilter = auditFilter.WithTrustCenterVisibilities(*filter.Visibility) - } - - auditPage, err := trustService.Audits.ListForOrganizationId(ctx, scope, obj.Organization.ID, cursor, auditFilter) + auditPage, err := trustService.ListAuditsForOrganizationID(ctx, scope, trustCenter.OrganizationID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list public audits", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -828,8 +785,8 @@ func (r *trustCenterResolver) Audits(ctx context.Context, obj *types.TrustCenter // 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, filter *types.SubprocessorFilter) (*types.SubprocessorConnection, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + trustCenter := complianceportal.CompliancePageFromContext(ctx) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust pageOrderBy := page.OrderBy[coredata.ThirdPartyOrderField]{ Field: coredata.ThirdPartyOrderFieldName, @@ -859,7 +816,7 @@ func (r *trustCenterResolver) Subprocessors(ctx context.Context, obj *types.Trus showOnTrustCenter := true thirdPartyFilter := coredata.NewThirdPartyFilter(&showOnTrustCenter, nil, query, category, country) - thirdPartyPage, err := trustService.ThirdParties.ListForOrganizationId(ctx, scope, obj.Organization.ID, cursor, thirdPartyFilter) + thirdPartyPage, err := trustService.ListThirdPartiesForOrganizationID(ctx, scope, trustCenter.OrganizationID, cursor, thirdPartyFilter) if err != nil { r.logger.ErrorCtx(ctx, "cannot list subprocessors", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -870,10 +827,9 @@ func (r *trustCenterResolver) Subprocessors(ctx context.Context, obj *types.Trus // SubprocessorCategories is the resolver for the subprocessorCategories field. func (r *trustCenterResolver) SubprocessorCategories(ctx context.Context, obj *types.TrustCenter) ([]coredata.ThirdPartyCategory, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) - categories, err := r.trust.ThirdParties.ListDistinctTrustCenterCategoriesForOrganizationID(ctx, scope, obj.Organization.ID) + categories, err := r.trust.ListDistinctTrustCenterCategoriesForOrganizationID(ctx, scope, obj.Organization.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot list subprocessor categories", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -884,10 +840,9 @@ func (r *trustCenterResolver) SubprocessorCategories(ctx context.Context, obj *t // SubprocessorCountries is the resolver for the subprocessorCountries field. func (r *trustCenterResolver) SubprocessorCountries(ctx context.Context, obj *types.TrustCenter) ([]coredata.CountryCode, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) - countries, err := r.trust.ThirdParties.ListDistinctTrustCenterCountriesForOrganizationID(ctx, scope, obj.Organization.ID) + countries, err := r.trust.ListDistinctTrustCenterCountriesForOrganizationID(ctx, scope, obj.Organization.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot list subprocessor countries", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -898,8 +853,7 @@ func (r *trustCenterResolver) SubprocessorCountries(ctx context.Context, obj *ty // 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) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust pageOrderBy := page.OrderBy[coredata.TrustCenterReferenceOrderField]{ Field: coredata.TrustCenterReferenceOrderFieldRank, @@ -907,7 +861,7 @@ func (r *trustCenterResolver) References(ctx context.Context, obj *types.TrustCe } cursor := types.NewCursor(first, after, last, before, pageOrderBy) - referencePage, err := trustService.TrustCenterReferences.ListForTrustCenterID(ctx, scope, obj.ID, cursor) + referencePage, err := trustService.ListPortalReferencesForPortalID(ctx, scope, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list public trust center references", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -916,29 +870,10 @@ func (r *trustCenterResolver) References(ctx context.Context, obj *types.TrustCe return types.NewTrustCenterReferenceConnection(referencePage), nil } -// CommitmentGroups is the resolver for the commitmentGroups field. -func (r *trustCenterResolver) CommitmentGroups(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.CompliancePortalCommitmentGroupConnection, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) - pageOrderBy := page.OrderBy[coredata.CompliancePortalCommitmentGroupOrderField]{ - Field: coredata.CompliancePortalCommitmentGroupOrderFieldRank, - Direction: page.OrderDirectionAsc, - } - cursor := types.NewCursor(first, after, last, before, pageOrderBy) - - groupPage, err := r.trust.CompliancePortalCommitmentGroups.ListForTrustCenterID(ctx, scope, obj.ID, cursor) - if err != nil { - r.logger.ErrorCtx(ctx, "cannot list public compliance portal commitment groups", log.Error(err)) - return nil, gqlutils.Internal(ctx) - } - - return types.NewCompliancePortalCommitmentGroupConnection(groupPage), 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, filter *types.TrustCenterVisibilityFilter) (*types.TrustCenterFileConnection, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) +func (r *trustCenterResolver) TrustCenterFiles(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.TrustCenterFileConnection, error) { + trustCenter := complianceportal.CompliancePageFromContext(ctx) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust pageOrderBy := page.OrderBy[coredata.TrustCenterFileOrderField]{ Field: coredata.TrustCenterFileOrderFieldName, @@ -946,19 +881,14 @@ func (r *trustCenterResolver) TrustCenterFiles(ctx context.Context, obj *types.T } cursor := types.NewCursor(first, after, last, before, pageOrderBy) - visibilities := []coredata.TrustCenterVisibility{ - coredata.TrustCenterVisibilityPublic, - coredata.TrustCenterVisibilityPrivate, - } - if filter != nil && filter.Visibility != nil { - visibilities = []coredata.TrustCenterVisibility{*filter.Visibility} - } - - fileFilter := coredata.NewTrustCenterFileFilter( - coredata.WithTrustCenterFileVisibilities(visibilities...), + filter := coredata.NewTrustCenterFileFilter( + coredata.WithTrustCenterFileVisibilities( + coredata.TrustCenterVisibilityPublic, + coredata.TrustCenterVisibilityPrivate, + ), ) - trustCenterFilePage, err := trustService.TrustCenterFiles.ListForOrganizationId(ctx, scope, obj.Organization.ID, cursor, fileFilter) + trustCenterFilePage, err := trustService.ListPortalFilesForOrganizationID(ctx, scope, trustCenter.OrganizationID, cursor, filter) if err != nil { r.logger.ErrorCtx(ctx, "cannot list public trust center files", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -969,8 +899,7 @@ func (r *trustCenterResolver) TrustCenterFiles(ctx context.Context, obj *types.T // 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) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust pageOrderBy := page.OrderBy[coredata.ComplianceFrameworkOrderField]{ Field: coredata.ComplianceFrameworkOrderFieldRank, @@ -978,7 +907,7 @@ func (r *trustCenterResolver) ComplianceFrameworks(ctx context.Context, obj *typ } cursor := types.NewCursor(first, after, last, before, pageOrderBy) - cfPage, err := trustService.ComplianceFrameworks.ListByTrustCenterID(ctx, scope, obj.ID, cursor) + cfPage, err := trustService.ListComplianceFrameworksByPortalID(ctx, scope, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list compliance frameworks", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -987,33 +916,31 @@ func (r *trustCenterResolver) ComplianceFrameworks(ctx context.Context, obj *typ 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) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) +// CustomLinks is the resolver for the customLinks field. +func (r *trustCenterResolver) CustomLinks(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.ComplianceCustomLinkConnection, error) { + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust - pageOrderBy := page.OrderBy[coredata.ComplianceExternalURLOrderField]{ - Field: coredata.ComplianceExternalURLOrderFieldRank, + pageOrderBy := page.OrderBy[coredata.ComplianceCustomLinkOrderField]{ + Field: coredata.ComplianceCustomLinkOrderFieldRank, Direction: page.OrderDirectionAsc, } cursor := types.NewCursor(first, after, last, before, pageOrderBy) - result, err := trustService.ComplianceExternalURLs.ListForTrustCenterID(ctx, scope, obj.ID, cursor) + result, err := trustService.ListCustomLinksForPortalID(ctx, scope, obj.ID, cursor) if err != nil { - r.logger.ErrorCtx(ctx, "cannot list compliance external URLs", log.Error(err)) + r.logger.ErrorCtx(ctx, "cannot list compliance custom links", log.Error(err)) return nil, gqlutils.Internal(ctx) } - return types.NewComplianceExternalURLConnection(result), nil + return types.NewComplianceCustomLinkConnection(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) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust - tc, err := trustService.TrustCenters.Get(ctx, scope, obj.ID) + tc, err := trustService.GetPortal(ctx, scope, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot load trust center", log.Error(err)) return nil, gqlutils.Internal(ctx) @@ -1045,11 +972,11 @@ func (r *trustCenterFileResolver) Alias(ctx context.Context, obj *types.TrustCen // IsUserAuthorized is the resolver for the isUserAuthorized field. func (r *trustCenterFileResolver) IsUserAuthorized(ctx context.Context, obj *types.TrustCenterFile) (bool, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust + trustCenter := complianceportal.CompliancePageFromContext(ctx) - trustCenterFile, err := trustService.TrustCenterFiles.Get(ctx, scope, compliancePage.OrganizationID, obj.ID) + trustCenterFile, err := trustService.GetPortalFile(ctx, scope, trustCenter.OrganizationID, obj.ID) if err != nil { if errors.Is(err, trust.ErrTrustCenterFileNotFound) || errors.Is(err, trust.ErrTrustCenterFileNotVisible) { return false, gqlutils.NotFoundf(ctx, "trust center file %q not found", obj.ID) @@ -1069,8 +996,8 @@ func (r *trustCenterFileResolver) IsUserAuthorized(ctx context.Context, obj *typ return false, nil } - fileAccess, err := trustService.TrustCenterAccesses.GetTrustCenterFileAccess(ctx, scope, - compliancePage.ID, + fileAccess, err := trustService.GetPortalFileAccess(ctx, scope, + trustCenter.ID, identity.ID, obj.ID, ) @@ -1092,18 +1019,18 @@ func (r *trustCenterFileResolver) IsUserAuthorized(ctx context.Context, obj *typ // Access is the resolver for the access field. func (r *trustCenterFileResolver) Access(ctx context.Context, obj *types.TrustCenterFile) (*types.DocumentAccess, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) trustService := r.trust + trustCenter := complianceportal.CompliancePageFromContext(ctx) identity := authn.IdentityFromContext(ctx) if identity == nil { return nil, nil // User is not authenticated, so no access requested } - access, err := trustService.TrustCenterAccesses.GetTrustCenterFileAccess( + access, err := trustService.GetPortalFileAccess( ctx, scope, - compliancePage.ID, + trustCenter.ID, identity.ID, obj.ID, ) @@ -1131,10 +1058,9 @@ func (r *trustCenterFileResolver) Access(ctx context.Context, obj *types.TrustCe // Logo is the resolver for the logo field. func (r *trustCenterReferenceResolver) Logo(ctx context.Context, obj *types.TrustCenterReference) (*types.File, error) { - compliancePage := compliancepage.CompliancePageFromContext(ctx) - scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID) + scope := coredata.NewScopeFromObjectID(obj.ID) - reference, err := r.trust.TrustCenterReferences.Get(ctx, scope, obj.ID) + reference, err := r.trust.GetPortalReference(ctx, scope, obj.ID) if err != nil { return nil, gqlutils.NotFoundf(ctx, "trust center reference %q not found", obj.ID) } @@ -1153,11 +1079,6 @@ func (r *Resolver) ComplianceFramework() schema.ComplianceFrameworkResolver { return &complianceFrameworkResolver{r} } -// CompliancePortalCommitmentGroup returns schema.CompliancePortalCommitmentGroupResolver implementation. -func (r *Resolver) CompliancePortalCommitmentGroup() schema.CompliancePortalCommitmentGroupResolver { - return &compliancePortalCommitmentGroupResolver{r} -} - // Document returns schema.DocumentResolver implementation. func (r *Resolver) Document() schema.DocumentResolver { return &documentResolver{r} } @@ -1183,14 +1104,13 @@ func (r *Resolver) TrustCenterReference() schema.TrustCenterReferenceResolver { } type ( - auditResolver struct{ *Resolver } - auditReportResolver struct{ *Resolver } - complianceFrameworkResolver struct{ *Resolver } - compliancePortalCommitmentGroupResolver struct{ *Resolver } - documentResolver struct{ *Resolver } - frameworkResolver struct{ *Resolver } - subprocessorConnectionResolver struct{ *Resolver } - trustCenterResolver struct{ *Resolver } - trustCenterFileResolver struct{ *Resolver } - trustCenterReferenceResolver struct{ *Resolver } + auditResolver struct{ *Resolver } + auditReportResolver struct{ *Resolver } + complianceFrameworkResolver struct{ *Resolver } + documentResolver struct{ *Resolver } + frameworkResolver struct{ *Resolver } + subprocessorConnectionResolver struct{ *Resolver } + trustCenterResolver struct{ *Resolver } + trustCenterFileResolver struct{ *Resolver } + trustCenterReferenceResolver struct{ *Resolver } ) diff --git a/pkg/server/api/trust/v1/types/compliance_external_url.go b/pkg/server/api/trust/v1/types/compliance_custom_link.go similarity index 67% rename from pkg/server/api/trust/v1/types/compliance_external_url.go rename to pkg/server/api/trust/v1/types/compliance_custom_link.go index 8b0c234e0..87c8f14c1 100644 --- a/pkg/server/api/trust/v1/types/compliance_external_url.go +++ b/pkg/server/api/trust/v1/types/compliance_custom_link.go @@ -25,8 +25,8 @@ import ( "go.probo.inc/probo/pkg/page" ) -func NewComplianceExternalURL(c *coredata.ComplianceExternalURL) *ComplianceExternalURL { - return &ComplianceExternalURL{ +func NewComplianceCustomLink(c *coredata.ComplianceCustomLink) *ComplianceCustomLink { + return &ComplianceCustomLink{ ID: c.ID, Name: c.Name, URL: c.URL, @@ -34,24 +34,24 @@ func NewComplianceExternalURL(c *coredata.ComplianceExternalURL) *ComplianceExte } } -func NewComplianceExternalURLConnection( - p *page.Page[*coredata.ComplianceExternalURL, coredata.ComplianceExternalURLOrderField], -) *ComplianceExternalURLConnection { - edges := make([]*ComplianceExternalURLEdge, len(p.Data)) +func NewComplianceCustomLinkConnection( + p *page.Page[*coredata.ComplianceCustomLink, coredata.ComplianceCustomLinkOrderField], +) *ComplianceCustomLinkConnection { + edges := make([]*ComplianceCustomLinkEdge, len(p.Data)) for i, item := range p.Data { - edges[i] = NewComplianceExternalURLEdge(item, p.Cursor.OrderBy.Field) + edges[i] = NewComplianceCustomLinkEdge(item, p.Cursor.OrderBy.Field) } - return &ComplianceExternalURLConnection{ + return &ComplianceCustomLinkConnection{ Edges: edges, PageInfo: NewPageInfo(p), } } -func NewComplianceExternalURLEdge(c *coredata.ComplianceExternalURL, orderBy coredata.ComplianceExternalURLOrderField) *ComplianceExternalURLEdge { - return &ComplianceExternalURLEdge{ +func NewComplianceCustomLinkEdge(c *coredata.ComplianceCustomLink, orderBy coredata.ComplianceCustomLinkOrderField) *ComplianceCustomLinkEdge { + return &ComplianceCustomLinkEdge{ Cursor: c.CursorKey(orderBy), - Node: NewComplianceExternalURL(c), + Node: NewComplianceCustomLink(c), } } diff --git a/pkg/server/api/trust/v1/types/organization.go b/pkg/server/api/trust/v1/types/organization.go index 758227a90..d846dceb9 100644 --- a/pkg/server/api/trust/v1/types/organization.go +++ b/pkg/server/api/trust/v1/types/organization.go @@ -26,11 +26,7 @@ import ( func NewOrganization(o *coredata.Organization) *Organization { return &Organization{ - ID: o.ID, - Name: o.Name, - Description: o.Description, - WebsiteURL: o.WebsiteURL, - Email: o.Email, - HeadquarterAddress: o.HeadquarterAddress, + ID: o.ID, + Name: o.Name, } } diff --git a/pkg/server/api/trust/v1/types/trust_center.go b/pkg/server/api/trust/v1/types/trust_center.go index 8bd6ab0c3..d1224fd72 100644 --- a/pkg/server/api/trust/v1/types/trust_center.go +++ b/pkg/server/api/trust/v1/types/trust_center.go @@ -26,9 +26,13 @@ import ( func NewTrustCenter(tc *coredata.TrustCenter) *TrustCenter { return &TrustCenter{ - ID: tc.ID, - Active: tc.Active, - Slug: tc.Slug, + ID: tc.ID, + Active: tc.Active, + Slug: tc.Slug, + Description: tc.Description, + WebsiteURL: tc.WebsiteURL, + Email: tc.Email, + HeadquarterAddress: tc.HeadquarterAddress, } }