Add nda to trust center

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-09-09 16:17:24 +02:00
parent 28c41fa4ae
commit b06bd113f3
37 changed files with 2921 additions and 259 deletions

View File

@@ -1144,6 +1144,8 @@ type TrustCenter implements Node {
id: ID!
active: Boolean!
slug: String!
ndaFileName: String
ndaFileUrl: String @goField(forceResolver: true)
createdAt: Datetime!
updatedAt: Datetime!
organization: Organization! @goField(forceResolver: true)
@@ -1889,6 +1891,7 @@ type TrustCenterAccess implements Node {
email: String!
name: String!
active: Boolean!
hasAcceptedNonDisclosureAgreement: Boolean!
createdAt: Datetime!
updatedAt: Datetime!
}
@@ -2218,6 +2221,14 @@ type Mutation {
input: UpdateTrustCenterInput!
): UpdateTrustCenterPayload!
uploadTrustCenterNDA(
input: UploadTrustCenterNDAInput!
): UploadTrustCenterNDAPayload!
deleteTrustCenterNDA(
input: DeleteTrustCenterNDAInput!
): DeleteTrustCenterNDAPayload!
# Trust Center Access CRUD mutations
createTrustCenterAccess(
input: CreateTrustCenterAccessInput!
@@ -2503,6 +2514,16 @@ input UpdateTrustCenterInput {
slug: String
}
input UploadTrustCenterNDAInput {
trustCenterId: ID!
fileName: String!
file: Upload!
}
input DeleteTrustCenterNDAInput {
trustCenterId: ID!
}
input CreateTrustCenterAccessInput {
trustCenterId: ID!
email: String!
@@ -3135,6 +3156,14 @@ type UpdateTrustCenterPayload {
trustCenter: TrustCenter!
}
type UploadTrustCenterNDAPayload {
trustCenter: TrustCenter!
}
type DeleteTrustCenterNDAPayload {
trustCenter: TrustCenter!
}
type CreateTrustCenterAccessPayload {
trustCenterAccessEdge: TrustCenterAccessEdge!
}

File diff suppressed because it is too large Load Diff

View File

@@ -18,12 +18,18 @@ import (
"github.com/getprobo/probo/pkg/coredata"
)
func NewTrustCenter(tc *coredata.TrustCenter) *TrustCenter {
func NewTrustCenter(tc *coredata.TrustCenter, file *coredata.File) *TrustCenter {
var ndaFileName *string
if file != nil {
ndaFileName = &file.FileName
}
return &TrustCenter{
ID: tc.ID,
Active: tc.Active,
Slug: tc.Slug,
CreatedAt: tc.CreatedAt,
UpdatedAt: tc.UpdatedAt,
ID: tc.ID,
Active: tc.Active,
Slug: tc.Slug,
NdaFileName: ndaFileName,
CreatedAt: tc.CreatedAt,
UpdatedAt: tc.UpdatedAt,
}
}

View File

@@ -23,12 +23,13 @@ type TrustCenterAccessOrderBy = OrderBy[coredata.TrustCenterAccessOrderField]
func NewTrustCenterAccess(tca *coredata.TrustCenterAccess) *TrustCenterAccess {
return &TrustCenterAccess{
ID: tca.ID,
Email: tca.Email,
Name: tca.Name,
Active: tca.Active,
CreatedAt: tca.CreatedAt,
UpdatedAt: tca.UpdatedAt,
ID: tca.ID,
Email: tca.Email,
Name: tca.Name,
Active: tca.Active,
HasAcceptedNonDisclosureAgreement: tca.HasAcceptedNonDisclosureAgreement,
CreatedAt: tca.CreatedAt,
UpdatedAt: tca.UpdatedAt,
}
}

View File

@@ -828,6 +828,14 @@ type DeleteTrustCenterAccessPayload struct {
DeletedTrustCenterAccessID gid.GID `json:"deletedTrustCenterAccessId"`
}
type DeleteTrustCenterNDAInput struct {
TrustCenterID gid.GID `json:"trustCenterId"`
}
type DeleteTrustCenterNDAPayload struct {
TrustCenter *TrustCenter `json:"trustCenter"`
}
type DeleteVendorBusinessAssociateAgreementInput struct {
VendorID gid.GID `json:"vendorId"`
}
@@ -1436,6 +1444,8 @@ type TrustCenter struct {
ID gid.GID `json:"id"`
Active bool `json:"active"`
Slug string `json:"slug"`
NdaFileName *string `json:"ndaFileName,omitempty"`
NdaFileURL *string `json:"ndaFileUrl,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Organization *Organization `json:"organization"`
@@ -1446,12 +1456,13 @@ func (TrustCenter) IsNode() {}
func (this TrustCenter) GetID() gid.GID { return this.ID }
type TrustCenterAccess struct {
ID gid.GID `json:"id"`
Email string `json:"email"`
Name string `json:"name"`
Active bool `json:"active"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
ID gid.GID `json:"id"`
Email string `json:"email"`
Name string `json:"name"`
Active bool `json:"active"`
HasAcceptedNonDisclosureAgreement bool `json:"hasAcceptedNonDisclosureAgreement"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
func (TrustCenterAccess) IsNode() {}
@@ -1831,6 +1842,16 @@ type UploadTaskEvidencePayload struct {
EvidenceEdge *EvidenceEdge `json:"evidenceEdge"`
}
type UploadTrustCenterNDAInput struct {
TrustCenterID gid.GID `json:"trustCenterId"`
FileName string `json:"fileName"`
File graphql.Upload `json:"file"`
}
type UploadTrustCenterNDAPayload struct {
TrustCenter *TrustCenter `json:"trustCenter"`
}
type UploadVendorBusinessAssociateAgreementInput struct {
VendorID gid.GID `json:"vendorId"`
ValidFrom *time.Time `json:"validFrom,omitempty"`

View File

@@ -1145,7 +1145,7 @@ func (r *mutationResolver) DeleteOrganization(ctx context.Context, input types.D
func (r *mutationResolver) UpdateTrustCenter(ctx context.Context, input types.UpdateTrustCenterInput) (*types.UpdateTrustCenterPayload, error) {
prb := r.ProboService(ctx, input.TrustCenterID.TenantID())
trustCenter, err := prb.TrustCenters.Update(ctx, &probo.UpdateTrustCenterRequest{
trustCenter, file, err := prb.TrustCenters.Update(ctx, &probo.UpdateTrustCenterRequest{
ID: input.TrustCenterID,
Active: input.Active,
Slug: input.Slug,
@@ -1155,7 +1155,41 @@ func (r *mutationResolver) UpdateTrustCenter(ctx context.Context, input types.Up
}
return &types.UpdateTrustCenterPayload{
TrustCenter: types.NewTrustCenter(trustCenter),
TrustCenter: types.NewTrustCenter(trustCenter, file),
}, nil
}
// UploadTrustCenterNda is the resolver for the uploadTrustCenterNDA field.
func (r *mutationResolver) UploadTrustCenterNda(ctx context.Context, input types.UploadTrustCenterNDAInput) (*types.UploadTrustCenterNDAPayload, error) {
prb := r.ProboService(ctx, input.TrustCenterID.TenantID())
trustCenter, file, err := prb.TrustCenters.UploadNDA(ctx, &probo.UploadTrustCenterNDARequest{
TrustCenterID: input.TrustCenterID,
File: input.File.File,
FileName: input.FileName,
})
if err != nil {
return nil, fmt.Errorf("cannot upload trust center NDA: %w", err)
}
return &types.UploadTrustCenterNDAPayload{
TrustCenter: types.NewTrustCenter(trustCenter, file),
}, nil
}
// DeleteTrustCenterNda is the resolver for the deleteTrustCenterNDA field.
func (r *mutationResolver) DeleteTrustCenterNda(ctx context.Context, input types.DeleteTrustCenterNDAInput) (*types.DeleteTrustCenterNDAPayload, error) {
prb := r.ProboService(ctx, input.TrustCenterID.TenantID())
trustCenter, file, err := prb.TrustCenters.DeleteNDA(ctx, &probo.DeleteTrustCenterNDARequest{
TrustCenterID: input.TrustCenterID,
})
if err != nil {
return nil, fmt.Errorf("cannot delete trust center NDA: %w", err)
}
return &types.DeleteTrustCenterNDAPayload{
TrustCenter: types.NewTrustCenter(trustCenter, file),
}, nil
}
@@ -3895,12 +3929,12 @@ func (r *organizationResolver) Snapshots(ctx context.Context, obj *types.Organiz
func (r *organizationResolver) TrustCenter(ctx context.Context, obj *types.Organization) (*types.TrustCenter, error) {
prb := r.ProboService(ctx, obj.ID.TenantID())
trustCenter, err := prb.TrustCenters.GetByOrganizationID(ctx, obj.ID)
trustCenter, file, err := prb.TrustCenters.GetByOrganizationID(ctx, obj.ID)
if err != nil {
return nil, fmt.Errorf("cannot get trust center: %w", err)
}
return types.NewTrustCenter(trustCenter), nil
return types.NewTrustCenter(trustCenter, file), nil
}
// TotalCount is the resolver for the totalCount field.
@@ -4115,11 +4149,12 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
}
return types.NewSnapshot(snapshot), nil
case coredata.TrustCenterEntityType:
trustCenter, err := prb.TrustCenters.Get(ctx, id)
trustCenter, file, err := prb.TrustCenters.Get(ctx, id)
if err != nil {
panic(fmt.Errorf("cannot get trust center: %w", err))
panic(fmt.Errorf("cannot get trust center with file: %w", err))
}
return types.NewTrustCenter(trustCenter), nil
return types.NewTrustCenter(trustCenter, file), nil
default:
}
@@ -4462,6 +4497,18 @@ func (r *taskConnectionResolver) TotalCount(ctx context.Context, obj *types.Task
panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver))
}
// NdaFileURL is the resolver for the ndaFileUrl field.
func (r *trustCenterResolver) NdaFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) {
prb := r.ProboService(ctx, obj.ID.TenantID())
fileURL, err := prb.TrustCenters.GenerateNDAFileURL(ctx, obj.ID, 15*time.Minute)
if err != nil {
panic(fmt.Errorf("failed to generate NDA file URL: %w", err))
}
return fileURL, nil
}
// Organization is the resolver for the organization field.
func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error) {
prb := r.ProboService(ctx, obj.ID.TenantID())

View File

@@ -31,6 +31,10 @@ type TokenAccessData struct {
Scope string
}
func (t *TokenAccessData) GetEmail() string {
return t.Email
}
type ContextAccessor interface {
UserFromContext(ctx context.Context) *coredata.User
TokenAccessFromContext(ctx context.Context) *TokenAccessData

View File

@@ -20,6 +20,7 @@ import (
"context"
"fmt"
"net/http"
"strings"
"time"
"github.com/99designs/gqlgen/graphql/handler"
@@ -138,20 +139,29 @@ func graphqlHandler(logger *log.Logger, usrmgrSvc *usrmgr.Service, trustSvc *tru
return WithSession(usrmgrSvc, trustSvc, authCfg, trustAuthCfg, srv.ServeHTTP)
}
// TrustService returns a trust service scoped to the given tenant
func (r *Resolver) TrustService(ctx context.Context, tenantID gid.TenantID) *trust.TenantService {
func (r *Resolver) RootTrustService(ctx context.Context) *trust.TenantService {
return r.trustCenterSvc.WithTenant(gid.NewTenantID())
}
func (r *Resolver) PublicTrustService(ctx context.Context, tenantID gid.TenantID) *trust.TenantService {
return r.trustCenterSvc.WithTenant(tenantID)
}
// GetTenantService returns a tenant service for the given tenant ID
func (r *Resolver) GetTenantService(ctx context.Context, tenantID gid.TenantID) *trust.TenantService {
return r.trustCenterSvc.WithTenant(tenantID)
func (r *Resolver) PrivateTrustService(ctx context.Context, tenantID gid.TenantID) (*trust.TenantService, error) {
if err := auth.ValidateTenantAccess(ctx, r, userTenantContextKey, tenantID); err != nil {
return nil, fmt.Errorf("cannot access trust center: %w", err)
}
return r.trustCenterSvc.WithTenant(tenantID), nil
}
func WithSession(usrmgrSvc *usrmgr.Service, trustSvc *trust.Service, authCfg console_v1.AuthConfig, trustAuthCfg TrustAuthConfig, next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ip := extractIPAddress(r)
ctx = context.WithValue(ctx, coredata.ContextKeyIPAddress, ip)
if authCtx := tryTokenAuth(ctx, w, r, trustSvc, trustAuthCfg); authCtx != nil {
next(w, r.WithContext(authCtx))
return
@@ -219,15 +229,14 @@ func tryTokenAuth(ctx context.Context, w http.ResponseWriter, r *http.Request, t
tenantID := basicPayload.Data.TrustCenterID.TenantID()
tenantSvc := trustSvc.WithTenant(tenantID)
payload, err := tenantSvc.TrustCenterAccesses.ValidateToken(ctx, cookie.Value)
if err != nil {
if err := tenantSvc.TrustCenterAccesses.ValidateToken(ctx, basicPayload.Data.TrustCenterID, basicPayload.Data.Email); err != nil {
clearTokenCookie(w, trustAuthCfg)
return nil
}
tokenAccess := &auth.TokenAccessData{
TrustCenterID: payload.TrustCenterID,
Email: payload.Email,
TrustCenterID: basicPayload.Data.TrustCenterID,
Email: basicPayload.Data.Email,
TenantID: tenantID,
Scope: trustAuthCfg.Scope,
}
@@ -256,3 +265,21 @@ func updateSessionIfNeeded(ctx context.Context, usrmgrSvc *usrmgr.Service) {
}
}
}
func extractIPAddress(r *http.Request) string {
if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
if ip := strings.Split(xff, ",")[0]; ip != "" {
return strings.TrimSpace(ip)
}
}
if xri := r.Header.Get("X-Real-IP"); xri != "" {
return strings.TrimSpace(xri)
}
if ip := strings.Split(r.RemoteAddr, ":")[0]; ip != "" {
return ip
}
return "unknown"
}

View File

@@ -199,8 +199,11 @@ type TrustCenter implements Node {
id: ID!
active: Boolean!
slug: String!
ndaFileName: String
ndaFileUrl: String @goField(forceResolver: true)
organization: Organization! @goField(forceResolver: true)
isUserAuthenticated: Boolean! @goField(forceResolver: true)
hasAcceptedNonDisclosureAgreement: Boolean! @goField(forceResolver: true)
documents(
first: Int
@@ -246,10 +249,18 @@ input ExportDocumentPDFInput {
documentId: ID!
}
input AcceptNonDisclosureAgreementInput {
trustCenterId: ID!
}
type ExportDocumentPDFPayload {
data: String!
}
type AcceptNonDisclosureAgreementPayload{
success: Boolean!
}
type Query {
trustCenterBySlug(slug: String!): TrustCenter @mustBeAuthenticated(role: NONE)
}
@@ -262,4 +273,8 @@ type Mutation {
exportDocumentPDF(
input: ExportDocumentPDFInput!
): ExportDocumentPDFPayload! @mustBeAuthenticated(role: USER)
acceptNonDisclosureAgreement(
input: AcceptNonDisclosureAgreementInput!
): AcceptNonDisclosureAgreementPayload! @mustBeAuthenticated(role: USER)
}

View File

@@ -57,6 +57,10 @@ type DirectiveRoot struct {
}
type ComplexityRoot struct {
AcceptNonDisclosureAgreementPayload struct {
Success func(childComplexity int) int
}
Audit struct {
Framework func(childComplexity int) int
ID func(childComplexity int) int
@@ -103,8 +107,9 @@ type ComplexityRoot struct {
}
Mutation struct {
CreateTrustCenterAccess func(childComplexity int, input types.CreateTrustCenterAccessInput) int
ExportDocumentPDF func(childComplexity int, input types.ExportDocumentPDFInput) int
AcceptNonDisclosureAgreement func(childComplexity int, input types.AcceptNonDisclosureAgreementInput) int
CreateTrustCenterAccess func(childComplexity int, input types.CreateTrustCenterAccessInput) int
ExportDocumentPDF func(childComplexity int, input types.ExportDocumentPDFInput) int
}
Organization struct {
@@ -131,14 +136,17 @@ type ComplexityRoot struct {
}
TrustCenter struct {
Active func(childComplexity int) int
Audits func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int
Documents func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int
ID func(childComplexity int) int
IsUserAuthenticated func(childComplexity int) int
Organization func(childComplexity int) int
Slug func(childComplexity int) int
Vendors func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int
Active func(childComplexity int) int
Audits func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int
Documents func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int
HasAcceptedNonDisclosureAgreement func(childComplexity int) int
ID func(childComplexity int) int
IsUserAuthenticated func(childComplexity int) int
NdaFileName func(childComplexity int) int
NdaFileURL func(childComplexity int) int
Organization func(childComplexity int) int
Slug func(childComplexity int) int
Vendors func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int
}
TrustCenterAccess struct {
@@ -175,6 +183,7 @@ type AuditResolver interface {
type MutationResolver interface {
CreateTrustCenterAccess(ctx context.Context, input types.CreateTrustCenterAccessInput) (*types.CreateTrustCenterAccessPayload, error)
ExportDocumentPDF(ctx context.Context, input types.ExportDocumentPDFInput) (*types.ExportDocumentPDFPayload, error)
AcceptNonDisclosureAgreement(ctx context.Context, input types.AcceptNonDisclosureAgreementInput) (*types.AcceptNonDisclosureAgreementPayload, error)
}
type OrganizationResolver interface {
LogoURL(ctx context.Context, obj *types.Organization) (*string, error)
@@ -186,8 +195,10 @@ type ReportResolver interface {
DownloadURL(ctx context.Context, obj *types.Report) (*string, error)
}
type TrustCenterResolver interface {
NdaFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error)
Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error)
IsUserAuthenticated(ctx context.Context, obj *types.TrustCenter) (bool, error)
HasAcceptedNonDisclosureAgreement(ctx context.Context, obj *types.TrustCenter) (bool, error)
Documents(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.DocumentConnection, error)
Audits(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.AuditConnection, error)
Vendors(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.VendorConnection, error)
@@ -212,6 +223,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
_ = ec
switch typeName + "." + field {
case "AcceptNonDisclosureAgreementPayload.success":
if e.complexity.AcceptNonDisclosureAgreementPayload.Success == nil {
break
}
return e.complexity.AcceptNonDisclosureAgreementPayload.Success(childComplexity), true
case "Audit.framework":
if e.complexity.Audit.Framework == nil {
break
@@ -338,6 +356,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.Framework.Name(childComplexity), true
case "Mutation.acceptNonDisclosureAgreement":
if e.complexity.Mutation.AcceptNonDisclosureAgreement == nil {
break
}
args, err := ec.field_Mutation_acceptNonDisclosureAgreement_args(ctx, rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.AcceptNonDisclosureAgreement(childComplexity, args["input"].(types.AcceptNonDisclosureAgreementInput)), true
case "Mutation.createTrustCenterAccess":
if e.complexity.Mutation.CreateTrustCenterAccess == nil {
break
@@ -475,6 +505,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.TrustCenter.Documents(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey)), true
case "TrustCenter.hasAcceptedNonDisclosureAgreement":
if e.complexity.TrustCenter.HasAcceptedNonDisclosureAgreement == nil {
break
}
return e.complexity.TrustCenter.HasAcceptedNonDisclosureAgreement(childComplexity), true
case "TrustCenter.id":
if e.complexity.TrustCenter.ID == nil {
break
@@ -489,6 +526,20 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.TrustCenter.IsUserAuthenticated(childComplexity), true
case "TrustCenter.ndaFileName":
if e.complexity.TrustCenter.NdaFileName == nil {
break
}
return e.complexity.TrustCenter.NdaFileName(childComplexity), true
case "TrustCenter.ndaFileUrl":
if e.complexity.TrustCenter.NdaFileURL == nil {
break
}
return e.complexity.TrustCenter.NdaFileURL(childComplexity), true
case "TrustCenter.organization":
if e.complexity.TrustCenter.Organization == nil {
break
@@ -621,6 +672,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
opCtx := graphql.GetOperationContext(ctx)
ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)}
inputUnmarshalMap := graphql.BuildUnmarshalerMap(
ec.unmarshalInputAcceptNonDisclosureAgreementInput,
ec.unmarshalInputCreateTrustCenterAccessInput,
ec.unmarshalInputExportDocumentPDFInput,
)
@@ -921,8 +973,11 @@ type TrustCenter implements Node {
id: ID!
active: Boolean!
slug: String!
ndaFileName: String
ndaFileUrl: String @goField(forceResolver: true)
organization: Organization! @goField(forceResolver: true)
isUserAuthenticated: Boolean! @goField(forceResolver: true)
hasAcceptedNonDisclosureAgreement: Boolean! @goField(forceResolver: true)
documents(
first: Int
@@ -968,10 +1023,18 @@ input ExportDocumentPDFInput {
documentId: ID!
}
input AcceptNonDisclosureAgreementInput {
trustCenterId: ID!
}
type ExportDocumentPDFPayload {
data: String!
}
type AcceptNonDisclosureAgreementPayload{
success: Boolean!
}
type Query {
trustCenterBySlug(slug: String!): TrustCenter @mustBeAuthenticated(role: NONE)
}
@@ -984,6 +1047,10 @@ type Mutation {
exportDocumentPDF(
input: ExportDocumentPDFInput!
): ExportDocumentPDFPayload! @mustBeAuthenticated(role: USER)
acceptNonDisclosureAgreement(
input: AcceptNonDisclosureAgreementInput!
): AcceptNonDisclosureAgreementPayload! @mustBeAuthenticated(role: USER)
}
`, BuiltIn: false},
}
@@ -1021,6 +1088,29 @@ func (ec *executionContext) dir_mustBeAuthenticated_argsRole(
return zeroVal, nil
}
func (ec *executionContext) field_Mutation_acceptNonDisclosureAgreement_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
args := map[string]any{}
arg0, err := ec.field_Mutation_acceptNonDisclosureAgreement_argsInput(ctx, rawArgs)
if err != nil {
return nil, err
}
args["input"] = arg0
return args, nil
}
func (ec *executionContext) field_Mutation_acceptNonDisclosureAgreement_argsInput(
ctx context.Context,
rawArgs map[string]any,
) (types.AcceptNonDisclosureAgreementInput, error) {
ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input"))
if tmp, ok := rawArgs["input"]; ok {
return ec.unmarshalNAcceptNonDisclosureAgreementInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAcceptNonDisclosureAgreementInput(ctx, tmp)
}
var zeroVal types.AcceptNonDisclosureAgreementInput
return zeroVal, nil
}
func (ec *executionContext) field_Mutation_createTrustCenterAccess_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
args := map[string]any{}
@@ -1444,6 +1534,50 @@ func (ec *executionContext) field___Type_fields_argsIncludeDeprecated(
// region **************************** field.gotpl *****************************
func (ec *executionContext) _AcceptNonDisclosureAgreementPayload_success(ctx context.Context, field graphql.CollectedField, obj *types.AcceptNonDisclosureAgreementPayload) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_AcceptNonDisclosureAgreementPayload_success(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Success, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(bool)
fc.Result = res
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_AcceptNonDisclosureAgreementPayload_success(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AcceptNonDisclosureAgreementPayload",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Boolean does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Audit_id(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Audit_id(ctx, field)
if err != nil {
@@ -2479,6 +2613,92 @@ func (ec *executionContext) fieldContext_Mutation_exportDocumentPDF(ctx context.
return fc, nil
}
func (ec *executionContext) _Mutation_acceptNonDisclosureAgreement(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Mutation_acceptNonDisclosureAgreement(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
directive0 := func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().AcceptNonDisclosureAgreement(rctx, fc.Args["input"].(types.AcceptNonDisclosureAgreementInput))
}
directive1 := func(ctx context.Context) (any, error) {
role, err := ec.unmarshalORole2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRole(ctx, "USER")
if err != nil {
var zeroVal *types.AcceptNonDisclosureAgreementPayload
return zeroVal, err
}
if ec.directives.MustBeAuthenticated == nil {
var zeroVal *types.AcceptNonDisclosureAgreementPayload
return zeroVal, errors.New("directive mustBeAuthenticated is not implemented")
}
return ec.directives.MustBeAuthenticated(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
if err != nil {
return nil, graphql.ErrorOnPath(ctx, err)
}
if tmp == nil {
return nil, nil
}
if data, ok := tmp.(*types.AcceptNonDisclosureAgreementPayload); ok {
return data, nil
}
return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/getprobo/probo/pkg/server/api/trust/v1/types.AcceptNonDisclosureAgreementPayload`, tmp)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*types.AcceptNonDisclosureAgreementPayload)
fc.Result = res
return ec.marshalNAcceptNonDisclosureAgreementPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAcceptNonDisclosureAgreementPayload(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_acceptNonDisclosureAgreement(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Mutation",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "success":
return ec.fieldContext_AcceptNonDisclosureAgreementPayload_success(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type AcceptNonDisclosureAgreementPayload", field.Name)
},
}
defer func() {
if r := recover(); r != nil {
err = ec.Recover(ctx, r)
ec.Error(ctx, err)
}
}()
ctx = graphql.WithFieldContext(ctx, fc)
if fc.Args, err = ec.field_Mutation_acceptNonDisclosureAgreement_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
ec.Error(ctx, err)
return fc, err
}
return fc, nil
}
func (ec *executionContext) _Organization_id(ctx context.Context, field graphql.CollectedField, obj *types.Organization) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Organization_id(ctx, field)
if err != nil {
@@ -2847,10 +3067,16 @@ func (ec *executionContext) fieldContext_Query_trustCenterBySlug(ctx context.Con
return ec.fieldContext_TrustCenter_active(ctx, field)
case "slug":
return ec.fieldContext_TrustCenter_slug(ctx, field)
case "ndaFileName":
return ec.fieldContext_TrustCenter_ndaFileName(ctx, field)
case "ndaFileUrl":
return ec.fieldContext_TrustCenter_ndaFileUrl(ctx, field)
case "organization":
return ec.fieldContext_TrustCenter_organization(ctx, field)
case "isUserAuthenticated":
return ec.fieldContext_TrustCenter_isUserAuthenticated(ctx, field)
case "hasAcceptedNonDisclosureAgreement":
return ec.fieldContext_TrustCenter_hasAcceptedNonDisclosureAgreement(ctx, field)
case "documents":
return ec.fieldContext_TrustCenter_documents(ctx, field)
case "audits":
@@ -3294,6 +3520,88 @@ func (ec *executionContext) fieldContext_TrustCenter_slug(_ context.Context, fie
return fc, nil
}
func (ec *executionContext) _TrustCenter_ndaFileName(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_TrustCenter_ndaFileName(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.NdaFileName, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_TrustCenter_ndaFileName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "TrustCenter",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _TrustCenter_ndaFileUrl(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_TrustCenter_ndaFileUrl(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.TrustCenter().NdaFileURL(rctx, obj)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_TrustCenter_ndaFileUrl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "TrustCenter",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _TrustCenter_organization(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_TrustCenter_organization(ctx, field)
if err != nil {
@@ -3390,6 +3698,50 @@ func (ec *executionContext) fieldContext_TrustCenter_isUserAuthenticated(_ conte
return fc, nil
}
func (ec *executionContext) _TrustCenter_hasAcceptedNonDisclosureAgreement(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_TrustCenter_hasAcceptedNonDisclosureAgreement(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.TrustCenter().HasAcceptedNonDisclosureAgreement(rctx, obj)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(bool)
fc.Result = res
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_TrustCenter_hasAcceptedNonDisclosureAgreement(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "TrustCenter",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Boolean does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _TrustCenter_documents(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_TrustCenter_documents(ctx, field)
if err != nil {
@@ -6162,6 +6514,33 @@ func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field
// region **************************** input.gotpl *****************************
func (ec *executionContext) unmarshalInputAcceptNonDisclosureAgreementInput(ctx context.Context, obj any) (types.AcceptNonDisclosureAgreementInput, error) {
var it types.AcceptNonDisclosureAgreementInput
asMap := map[string]any{}
for k, v := range obj.(map[string]any) {
asMap[k] = v
}
fieldsInOrder := [...]string{"trustCenterId"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
continue
}
switch k {
case "trustCenterId":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("trustCenterId"))
data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v)
if err != nil {
return it, err
}
it.TrustCenterID = data
}
}
return it, nil
}
func (ec *executionContext) unmarshalInputCreateTrustCenterAccessInput(ctx context.Context, obj any) (types.CreateTrustCenterAccessInput, error) {
var it types.CreateTrustCenterAccessInput
asMap := map[string]any{}
@@ -6303,6 +6682,45 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj
// region **************************** object.gotpl ****************************
var acceptNonDisclosureAgreementPayloadImplementors = []string{"AcceptNonDisclosureAgreementPayload"}
func (ec *executionContext) _AcceptNonDisclosureAgreementPayload(ctx context.Context, sel ast.SelectionSet, obj *types.AcceptNonDisclosureAgreementPayload) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, acceptNonDisclosureAgreementPayloadImplementors)
out := graphql.NewFieldSet(fields)
deferred := make(map[string]*graphql.FieldSet)
for i, field := range fields {
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("AcceptNonDisclosureAgreementPayload")
case "success":
out.Values[i] = ec._AcceptNonDisclosureAgreementPayload_success(ctx, field, obj)
if out.Values[i] == graphql.Null {
out.Invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
}
out.Dispatch(ctx)
if out.Invalids > 0 {
return graphql.Null
}
atomic.AddInt32(&ec.deferred, int32(len(deferred)))
for label, dfs := range deferred {
ec.processDeferredGroup(graphql.DeferredGroup{
Label: label,
Path: graphql.GetPath(ctx),
FieldSet: dfs,
Context: ctx,
})
}
return out
}
var auditImplementors = []string{"Audit", "Node"}
func (ec *executionContext) _Audit(ctx context.Context, sel ast.SelectionSet, obj *types.Audit) graphql.Marshaler {
@@ -6791,6 +7209,13 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
if out.Values[i] == graphql.Null {
out.Invalids++
}
case "acceptNonDisclosureAgreement":
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
return ec._Mutation_acceptNonDisclosureAgreement(ctx, field)
})
if out.Values[i] == graphql.Null {
out.Invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
@@ -7111,6 +7536,41 @@ func (ec *executionContext) _TrustCenter(ctx context.Context, sel ast.SelectionS
if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1)
}
case "ndaFileName":
out.Values[i] = ec._TrustCenter_ndaFileName(ctx, field, obj)
case "ndaFileUrl":
field := field
innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._TrustCenter_ndaFileUrl(ctx, field, obj)
return res
}
if field.Deferrable != nil {
dfs, ok := deferred[field.Deferrable.Label]
di := 0
if ok {
dfs.AddField(field)
di = len(dfs.Values) - 1
} else {
dfs = graphql.NewFieldSet([]graphql.CollectedField{field})
deferred[field.Deferrable.Label] = dfs
}
dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler {
return innerFunc(ctx, dfs)
})
// don't run the out.Concurrently() call below
out.Values[i] = graphql.Null
continue
}
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
case "organization":
field := field
@@ -7182,6 +7642,42 @@ func (ec *executionContext) _TrustCenter(ctx context.Context, sel ast.SelectionS
continue
}
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
case "hasAcceptedNonDisclosureAgreement":
field := field
innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._TrustCenter_hasAcceptedNonDisclosureAgreement(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&fs.Invalids, 1)
}
return res
}
if field.Deferrable != nil {
dfs, ok := deferred[field.Deferrable.Label]
di := 0
if ok {
dfs.AddField(field)
di = len(dfs.Values) - 1
} else {
dfs = graphql.NewFieldSet([]graphql.CollectedField{field})
deferred[field.Deferrable.Label] = dfs
}
dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler {
return innerFunc(ctx, dfs)
})
// don't run the out.Concurrently() call below
out.Values[i] = graphql.Null
continue
}
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
case "documents":
field := field
@@ -7849,6 +8345,25 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o
// region ***************************** type.gotpl *****************************
func (ec *executionContext) unmarshalNAcceptNonDisclosureAgreementInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAcceptNonDisclosureAgreementInput(ctx context.Context, v any) (types.AcceptNonDisclosureAgreementInput, error) {
res, err := ec.unmarshalInputAcceptNonDisclosureAgreementInput(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNAcceptNonDisclosureAgreementPayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAcceptNonDisclosureAgreementPayload(ctx context.Context, sel ast.SelectionSet, v types.AcceptNonDisclosureAgreementPayload) graphql.Marshaler {
return ec._AcceptNonDisclosureAgreementPayload(ctx, sel, &v)
}
func (ec *executionContext) marshalNAcceptNonDisclosureAgreementPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAcceptNonDisclosureAgreementPayload(ctx context.Context, sel ast.SelectionSet, v *types.AcceptNonDisclosureAgreementPayload) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
}
return graphql.Null
}
return ec._AcceptNonDisclosureAgreementPayload(ctx, sel, v)
}
func (ec *executionContext) marshalNAudit2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAudit(ctx context.Context, sel ast.SelectionSet, v *types.Audit) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {

View File

@@ -109,15 +109,12 @@ func validateTrustCenterAccessToken(ctx context.Context, trustSvc *trust.Service
return nil, fmt.Errorf("cannot validate trust center access token: %w", err)
}
tenantID := token.Data.TrustCenterID.TenantID()
tenantSvc := trustSvc.WithTenant(tenantID)
accessData, err := tenantSvc.TrustCenterAccesses.ValidateToken(ctx, tokenString)
if err != nil {
tenantSvc := trustSvc.WithTenant(token.Data.TrustCenterID.TenantID())
if err := tenantSvc.TrustCenterAccesses.ValidateToken(ctx, token.Data.TrustCenterID, token.Data.Email); err != nil {
return nil, fmt.Errorf("cannot validate trust center access token: %w", err)
}
return accessData, nil
return &token.Data, nil
}
func trustCenterLogoutHandler(authCfg console_v1.AuthConfig, trustAuthCfg TrustAuthConfig) http.HandlerFunc {

View File

@@ -18,10 +18,16 @@ import (
"github.com/getprobo/probo/pkg/coredata"
)
func NewTrustCenter(tc *coredata.TrustCenter) *TrustCenter {
func NewTrustCenter(tc *coredata.TrustCenter, file *coredata.File) *TrustCenter {
var ndaFileName *string
if file != nil {
ndaFileName = &file.FileName
}
return &TrustCenter{
ID: tc.ID,
Active: tc.Active,
Slug: tc.Slug,
ID: tc.ID,
Active: tc.Active,
Slug: tc.Slug,
NdaFileName: ndaFileName,
}
}

View File

@@ -19,6 +19,14 @@ type Node interface {
GetID() gid.GID
}
type AcceptNonDisclosureAgreementInput struct {
TrustCenterID gid.GID `json:"trustCenterId"`
}
type AcceptNonDisclosureAgreementPayload struct {
Success bool `json:"success"`
}
type Audit struct {
ID gid.GID `json:"id"`
Framework *Framework `json:"framework"`
@@ -115,14 +123,17 @@ func (Report) IsNode() {}
func (this Report) GetID() gid.GID { return this.ID }
type TrustCenter struct {
ID gid.GID `json:"id"`
Active bool `json:"active"`
Slug string `json:"slug"`
Organization *Organization `json:"organization"`
IsUserAuthenticated bool `json:"isUserAuthenticated"`
Documents *DocumentConnection `json:"documents"`
Audits *AuditConnection `json:"audits"`
Vendors *VendorConnection `json:"vendors"`
ID gid.GID `json:"id"`
Active bool `json:"active"`
Slug string `json:"slug"`
NdaFileName *string `json:"ndaFileName,omitempty"`
NdaFileURL *string `json:"ndaFileUrl,omitempty"`
Organization *Organization `json:"organization"`
IsUserAuthenticated bool `json:"isUserAuthenticated"`
HasAcceptedNonDisclosureAgreement bool `json:"hasAcceptedNonDisclosureAgreement"`
Documents *DocumentConnection `json:"documents"`
Audits *AuditConnection `json:"audits"`
Vendors *VendorConnection `json:"vendors"`
}
func (TrustCenter) IsNode() {}

View File

@@ -11,9 +11,7 @@ import (
"time"
"github.com/getprobo/probo/pkg/coredata"
"github.com/getprobo/probo/pkg/gid"
"github.com/getprobo/probo/pkg/page"
"github.com/getprobo/probo/pkg/server/api/trust/v1/auth"
"github.com/getprobo/probo/pkg/server/api/trust/v1/schema"
"github.com/getprobo/probo/pkg/server/api/trust/v1/types"
"github.com/getprobo/probo/pkg/trust"
@@ -21,14 +19,14 @@ import (
// Framework is the resolver for the framework field.
func (r *auditResolver) Framework(ctx context.Context, obj *types.Audit) (*types.Framework, error) {
trust := r.TrustService(ctx, obj.ID.TenantID())
publicTrustService := r.PublicTrustService(ctx, obj.ID.TenantID())
audit, err := trust.Audits.Get(ctx, obj.ID)
audit, err := publicTrustService.Audits.Get(ctx, obj.ID)
if err != nil {
panic(fmt.Errorf("cannot load audit: %w", err))
}
framework, err := trust.Frameworks.Get(ctx, audit.FrameworkID)
framework, err := publicTrustService.Frameworks.Get(ctx, audit.FrameworkID)
if err != nil {
panic(fmt.Errorf("cannot load framework: %w", err))
}
@@ -38,9 +36,9 @@ func (r *auditResolver) Framework(ctx context.Context, obj *types.Audit) (*types
// Report is the resolver for the report field.
func (r *auditResolver) Report(ctx context.Context, obj *types.Audit) (*types.Report, error) {
trust := r.TrustService(ctx, obj.ID.TenantID())
publicTrustService := r.PublicTrustService(ctx, obj.ID.TenantID())
audit, err := trust.Audits.Get(ctx, obj.ID)
audit, err := publicTrustService.Audits.Get(ctx, obj.ID)
if err != nil {
panic(fmt.Errorf("cannot load audit: %w", err))
}
@@ -49,7 +47,7 @@ func (r *auditResolver) Report(ctx context.Context, obj *types.Audit) (*types.Re
return nil, nil
}
report, err := trust.Reports.Get(ctx, *audit.ReportID)
report, err := publicTrustService.Reports.Get(ctx, *audit.ReportID)
if err != nil {
panic(fmt.Errorf("cannot load report: %w", err))
}
@@ -59,9 +57,9 @@ func (r *auditResolver) Report(ctx context.Context, obj *types.Audit) (*types.Re
// CreateTrustCenterAccess is the resolver for the createTrustCenterAccess field.
func (r *mutationResolver) CreateTrustCenterAccess(ctx context.Context, input types.CreateTrustCenterAccessInput) (*types.CreateTrustCenterAccessPayload, error) {
trustSvc := r.trustCenterSvc.WithTenant(input.TrustCenterID.TenantID())
publicTrustService := r.PublicTrustService(ctx, input.TrustCenterID.TenantID())
access, err := trustSvc.TrustCenterAccesses.Create(ctx, &trust.CreateTrustCenterAccessRequest{
access, err := publicTrustService.TrustCenterAccesses.Create(ctx, &trust.CreateTrustCenterAccessRequest{
TrustCenterID: input.TrustCenterID,
Email: input.Email,
Name: input.Name,
@@ -83,34 +81,72 @@ func (r *mutationResolver) CreateTrustCenterAccess(ctx context.Context, input ty
// ExportDocumentPDF is the resolver for the exportDocumentPDF field.
func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.ExportDocumentPDFInput) (*types.ExportDocumentPDFPayload, error) {
if err := auth.ValidateTenantAccess(ctx, r, userTenantContextKey, input.DocumentID.TenantID()); err != nil {
return nil, err
}
trust := r.trustCenterSvc.WithTenant(input.DocumentID.TenantID())
pdf, err := trust.Documents.ExportPDF(ctx, input.DocumentID)
privateTrustService, err := r.PrivateTrustService(ctx, input.DocumentID.TenantID())
if err != nil {
return nil, fmt.Errorf("cannot export document PDF: %w", err)
}
hasAcceptedNDA := false
userData := UserFromContext(ctx)
if userData != nil {
hasAcceptedNDA = true
}
tokenData := TokenAccessFromContext(ctx)
if tokenData != nil {
tokenData := TokenAccessFromContext(ctx)
hasAcceptedNDA, err = privateTrustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(ctx, tokenData.TrustCenterID, tokenData.GetEmail())
if err != nil {
panic(fmt.Errorf("cannot check if user has accepted NDA: %w", err))
}
}
if !hasAcceptedNDA {
return nil, fmt.Errorf("user has not accepted NDA")
}
pdf, err := privateTrustService.Documents.ExportPDF(ctx, input.DocumentID)
if err != nil {
panic(fmt.Errorf("cannot export document PDF: %w", err))
}
return &types.ExportDocumentPDFPayload{
Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)),
}, nil
}
// AcceptNonDisclosureAgreement is the resolver for the acceptNonDisclosureAgreement field.
func (r *mutationResolver) AcceptNonDisclosureAgreement(ctx context.Context, input types.AcceptNonDisclosureAgreementInput) (*types.AcceptNonDisclosureAgreementPayload, error) {
privateTrustService, err := r.PrivateTrustService(ctx, input.TrustCenterID.TenantID())
if err != nil {
return nil, fmt.Errorf("cannot accept NDA: %w", err)
}
tokenData := TokenAccessFromContext(ctx)
if tokenData == nil {
return nil, fmt.Errorf("token not found")
}
err = privateTrustService.TrustCenterAccesses.AcceptNonDisclosureAgreement(ctx, input.TrustCenterID, tokenData.GetEmail())
if err != nil {
return nil, fmt.Errorf("cannot accept NDA: %w", err)
}
return &types.AcceptNonDisclosureAgreementPayload{Success: true}, nil
}
// LogoURL is the resolver for the logoUrl field.
func (r *organizationResolver) LogoURL(ctx context.Context, obj *types.Organization) (*string, error) {
trust := r.TrustService(ctx, obj.ID.TenantID())
publicTrustService := r.PublicTrustService(ctx, obj.ID.TenantID())
return trust.Organizations.GenerateLogoURL(ctx, obj.ID, 1*time.Hour)
return publicTrustService.Organizations.GenerateLogoURL(ctx, obj.ID, 1*time.Hour)
}
// TrustCenterBySlug is the resolver for the trustCenterBySlug field.
func (r *queryResolver) TrustCenterBySlug(ctx context.Context, slug string) (*types.TrustCenter, error) {
publicTrust := r.trustCenterSvc.WithTenant(gid.NewTenantID())
rootTrustService := r.RootTrustService(ctx)
trustCenter, err := publicTrust.TrustCenters.GetBySlug(ctx, slug)
trustCenter, err := rootTrustService.TrustCenters.GetBySlug(ctx, slug)
if err != nil {
return nil, nil
}
@@ -119,28 +155,48 @@ func (r *queryResolver) TrustCenterBySlug(ctx context.Context, slug string) (*ty
return nil, nil
}
result := types.NewTrustCenter(trustCenter)
publicTrustService := r.PublicTrustService(ctx, trustCenter.TenantID)
trustCenter, file, err := publicTrustService.TrustCenters.Get(ctx, trustCenter.ID)
if err != nil {
panic(fmt.Errorf("cannot get trust center: %w", err))
}
orgTrust := r.trustCenterSvc.WithTenant(trustCenter.TenantID)
org, err := orgTrust.Organizations.Get(ctx, trustCenter.OrganizationID)
org, err := publicTrustService.Organizations.Get(ctx, trustCenter.OrganizationID)
if err != nil {
panic(fmt.Errorf("cannot get organization: %w", err))
}
response := types.NewTrustCenter(trustCenter, file)
response.Organization = types.NewOrganization(org)
result.Organization = types.NewOrganization(org)
return result, nil
return response, nil
}
// DownloadURL is the resolver for the downloadUrl field.
func (r *reportResolver) DownloadURL(ctx context.Context, obj *types.Report) (*string, error) {
if err := auth.ValidateTenantAccess(ctx, r, userTenantContextKey, obj.ID.TenantID()); err != nil {
return nil, err
privateTrustService, err := r.PrivateTrustService(ctx, obj.ID.TenantID())
if err != nil {
return nil, fmt.Errorf("cannot generate download URL: %w", err)
}
trust := r.TrustService(ctx, obj.ID.TenantID())
hasAcceptedNDA := false
userData := UserFromContext(ctx)
if userData != nil {
hasAcceptedNDA = true
}
url, err := trust.Reports.GenerateDownloadURL(ctx, obj.ID, r.trustAuthCfg.ReportURLDuration)
tokenData := TokenAccessFromContext(ctx)
if tokenData != nil {
hasAcceptedNDA, err = privateTrustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(ctx, tokenData.TrustCenterID, tokenData.GetEmail())
if err != nil {
panic(fmt.Errorf("cannot check if user has accepted NDA: %w", err))
}
}
if !hasAcceptedNDA {
return nil, fmt.Errorf("user has not accepted NDA")
}
url, err := privateTrustService.Reports.GenerateDownloadURL(ctx, obj.ID, r.trustAuthCfg.ReportURLDuration)
if err != nil {
panic(fmt.Errorf("cannot generate download URL: %w", err))
}
@@ -148,6 +204,21 @@ func (r *reportResolver) DownloadURL(ctx context.Context, obj *types.Report) (*s
return url, nil
}
// NdaFileURL is the resolver for the ndaFileUrl field.
func (r *trustCenterResolver) NdaFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) {
privateTrustService, err := r.PrivateTrustService(ctx, obj.ID.TenantID())
if err != nil {
return nil, fmt.Errorf("failed to get private trust service: %w", err)
}
fileURL, err := privateTrustService.TrustCenters.GenerateNDAFileURL(ctx, obj.ID, 15*time.Minute)
if err != nil {
return nil, fmt.Errorf("failed to generate NDA file URL: %w", err)
}
return &fileURL, 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
@@ -155,15 +226,41 @@ func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.Trust
// IsUserAuthenticated is the resolver for the isUserAuthenticated field.
func (r *trustCenterResolver) IsUserAuthenticated(ctx context.Context, obj *types.TrustCenter) (bool, error) {
if err := auth.ValidateTenantAccess(ctx, r, userTenantContextKey, obj.Organization.ID.TenantID()); err != nil {
_, err := r.PrivateTrustService(ctx, obj.ID.TenantID())
if err != nil {
return false, nil
}
return true, nil
}
// HasAcceptedNonDisclosureAgreement is the resolver for the hasAcceptedNonDisclosureAgreement field.
func (r *trustCenterResolver) HasAcceptedNonDisclosureAgreement(ctx context.Context, obj *types.TrustCenter) (bool, error) {
privateTrustService, err := r.PrivateTrustService(ctx, obj.ID.TenantID())
if err != nil {
return false, nil
}
userData := UserFromContext(ctx)
if userData != nil {
return true, nil
}
tokenData := TokenAccessFromContext(ctx)
if tokenData != nil {
hasAcceptedNDA, err := privateTrustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(ctx, obj.ID, tokenData.GetEmail())
if err != nil {
panic(fmt.Errorf("cannot check if user has accepted NDA: %w", err))
}
return hasAcceptedNDA, nil
}
panic(fmt.Errorf("no user or token data found"))
}
// Documents is the resolver for the documents field.
func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.DocumentConnection, error) {
trust := r.trustCenterSvc.WithTenant(obj.Organization.ID.TenantID())
publicTrustService := r.PublicTrustService(ctx, obj.ID.TenantID())
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
Field: coredata.DocumentOrderFieldTitle,
@@ -171,7 +268,7 @@ func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCen
}
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
documentPage, err := trust.Documents.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
documentPage, err := publicTrustService.Documents.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
if err != nil {
panic(fmt.Errorf("cannot list public documents: %w", err))
}
@@ -181,7 +278,7 @@ 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) (*types.AuditConnection, error) {
trust := r.trustCenterSvc.WithTenant(obj.Organization.ID.TenantID())
publicTrustService := r.PublicTrustService(ctx, obj.ID.TenantID())
pageOrderBy := page.OrderBy[coredata.AuditOrderField]{
Field: coredata.AuditOrderFieldValidFrom,
@@ -189,7 +286,7 @@ func (r *trustCenterResolver) Audits(ctx context.Context, obj *types.TrustCenter
}
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
auditPage, err := trust.Audits.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
auditPage, err := publicTrustService.Audits.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
if err != nil {
panic(fmt.Errorf("cannot list public audits: %w", err))
}
@@ -199,7 +296,7 @@ func (r *trustCenterResolver) Audits(ctx context.Context, obj *types.TrustCenter
// Vendors is the resolver for the vendors field.
func (r *trustCenterResolver) Vendors(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.VendorConnection, error) {
trust := r.trustCenterSvc.WithTenant(obj.Organization.ID.TenantID())
publicTrustService := r.PublicTrustService(ctx, obj.ID.TenantID())
pageOrderBy := page.OrderBy[coredata.VendorOrderField]{
Field: coredata.VendorOrderFieldName,
@@ -207,7 +304,7 @@ func (r *trustCenterResolver) Vendors(ctx context.Context, obj *types.TrustCente
}
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
vendorPage, err := trust.Vendors.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
vendorPage, err := publicTrustService.Vendors.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
if err != nil {
panic(fmt.Errorf("cannot list public vendors: %w", err))
}