Trust center access management - get rid of access token
Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -23,10 +23,16 @@ import (
|
||||
type ctxKey struct{ name string }
|
||||
|
||||
var (
|
||||
compliancePageKey = &ctxKey{name: "compliance_page"}
|
||||
compliancePageKey = &ctxKey{name: "compliance_page"}
|
||||
complianceMembershipKey = &ctxKey{name: "compliance_membership"}
|
||||
)
|
||||
|
||||
func CompliancePageFromContext(ctx context.Context) *coredata.TrustCenter {
|
||||
trustCenter, _ := ctx.Value(compliancePageKey).(*coredata.TrustCenter)
|
||||
return trustCenter
|
||||
}
|
||||
|
||||
func ComplianceMembershipFromContext(ctx context.Context) *coredata.TrustCenterAccess {
|
||||
membership, _ := ctx.Value(complianceMembershipKey).(*coredata.TrustCenterAccess)
|
||||
return membership
|
||||
}
|
||||
|
||||
@@ -16,10 +16,15 @@ package compliancepage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
"go.gearno.de/kit/httpserver"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/trust"
|
||||
)
|
||||
|
||||
@@ -33,7 +38,25 @@ func NewIDMiddleware(trustSvc *trust.Service) func(next http.Handler) http.Handl
|
||||
|
||||
if id, err := gid.ParseGID(value); err == nil {
|
||||
compliancePage, err := trustSvc.Get(ctx, id)
|
||||
if err != nil || !compliancePage.Active {
|
||||
if err != nil {
|
||||
if errors.Is(err, trust.ErrPageNotFound) {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
httpserver.RenderJSON(
|
||||
w,
|
||||
http.StatusInternalServerError,
|
||||
&graphql.Response{
|
||||
Errors: gqlerror.List{
|
||||
gqlutils.Internal(ctx),
|
||||
},
|
||||
},
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if !compliancePage.Active {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
@@ -43,7 +66,26 @@ func NewIDMiddleware(trustSvc *trust.Service) func(next http.Handler) http.Handl
|
||||
return
|
||||
}
|
||||
|
||||
if compliancePage, err := trustSvc.GetBySlug(ctx, value); err == nil && compliancePage.Active {
|
||||
compliancePage, err := trustSvc.GetBySlug(ctx, value)
|
||||
if err != nil {
|
||||
if errors.Is(err, trust.ErrPageNotFound) {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
httpserver.RenderJSON(
|
||||
w,
|
||||
http.StatusInternalServerError,
|
||||
&graphql.Response{
|
||||
Errors: gqlerror.List{
|
||||
gqlutils.Internal(ctx),
|
||||
},
|
||||
},
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if compliancePage.Active {
|
||||
ctx = context.WithValue(ctx, compliancePageKey, compliancePage)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
return
|
||||
|
||||
74
pkg/server/api/compliancepage/membership_middleware.go
Normal file
74
pkg/server/api/compliancepage/membership_middleware.go
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package compliancepage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
"go.gearno.de/kit/httpserver"
|
||||
"go.gearno.de/kit/log"
|
||||
"go.probo.inc/probo/pkg/server/api/authn"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/trust"
|
||||
)
|
||||
|
||||
func NewMembershipMiddleware(trustSvc *trust.Service, logger *log.Logger) func(next http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
identity := authn.IdentityFromContext(r.Context())
|
||||
if identity == nil {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
compliancePage := CompliancePageFromContext(ctx)
|
||||
|
||||
membership, err := trustSvc.GetMembershipByCompliancePageIDAndEmail(ctx, compliancePage.ID, identity.EmailAddress)
|
||||
if err != nil {
|
||||
if errors.Is(err, trust.ErrMembershipNotFound) {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
logger.ErrorCtx(ctx, "cannot get membership by page id and email", log.Error(err))
|
||||
httpserver.RenderJSON(
|
||||
w,
|
||||
http.StatusInternalServerError,
|
||||
&graphql.Response{
|
||||
Errors: gqlerror.List{
|
||||
gqlutils.Internal(ctx),
|
||||
},
|
||||
},
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if membership.Active {
|
||||
ctx = context.WithValue(ctx, complianceMembershipKey, membership)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,13 @@ package compliancepage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
"go.gearno.de/kit/httpserver"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/trust"
|
||||
)
|
||||
|
||||
@@ -32,13 +37,31 @@ func NewSNIMiddleware(trustSvc *trust.Service) func(next http.Handler) http.Hand
|
||||
}
|
||||
|
||||
compliancePage, err := trustSvc.GetByDomainName(ctx, r.TLS.ServerName)
|
||||
if err != nil || !compliancePage.Active {
|
||||
next.ServeHTTP(w, r)
|
||||
if err != nil {
|
||||
if errors.Is(err, trust.ErrPageNotFound) {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
httpserver.RenderJSON(
|
||||
w,
|
||||
http.StatusInternalServerError,
|
||||
&graphql.Response{
|
||||
Errors: gqlerror.List{
|
||||
gqlutils.Internal(ctx),
|
||||
},
|
||||
},
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
ctx = context.WithValue(ctx, compliancePageKey, compliancePage)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
if compliancePage.Active {
|
||||
ctx = context.WithValue(ctx, compliancePageKey, compliancePage)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6169,7 +6169,7 @@ func (r *organizationResolver) TrustCenterFiles(ctx context.Context, obj *types.
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
pageResult, err := prb.TrustCenterFiles.ListForOrganizationID(ctx, obj.ID, cursor)
|
||||
pageResult, err := prb.TrustCenterFiles.ListForOrganizationID(ctx, obj.ID, cursor, &coredata.TrustCenterFileFilter{})
|
||||
if err != nil {
|
||||
// TODO no panic use gqlutils.InternalError
|
||||
panic(fmt.Errorf("cannot list organization trust center files: %w", err))
|
||||
|
||||
63
pkg/server/api/trust/v1/graphql_handler.go
Normal file
63
pkg/server/api/trust/v1/graphql_handler.go
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package trust_v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"go.gearno.de/kit/log"
|
||||
"go.probo.inc/probo/pkg/baseurl"
|
||||
"go.probo.inc/probo/pkg/iam"
|
||||
"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/trust/v1/schema"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils/directives/session"
|
||||
"go.probo.inc/probo/pkg/trust"
|
||||
)
|
||||
|
||||
func MembersOnlyDirective(ctx context.Context, obj any, next graphql.Resolver) (any, error) {
|
||||
membership := compliancepage.ComplianceMembershipFromContext(ctx)
|
||||
|
||||
if membership == nil {
|
||||
return nil, gqlutils.Forbiddenf(ctx, "insufficient permission to access this resource")
|
||||
}
|
||||
|
||||
return next(ctx)
|
||||
}
|
||||
|
||||
func NewGraphQLHandler(iamSvc *iam.Service, trustSvc *trust.Service, logger *log.Logger, baseURL *baseurl.BaseURL, cookieConfig securecookie.Config) http.Handler {
|
||||
config := schema.Config{
|
||||
Resolvers: &Resolver{
|
||||
iam: iamSvc,
|
||||
trust: trustSvc,
|
||||
logger: logger,
|
||||
baseURL: baseURL,
|
||||
sessionCookie: authn.NewCookie(&cookieConfig),
|
||||
},
|
||||
Directives: schema.DirectiveRoot{
|
||||
Session: session.Directive,
|
||||
MembersOnly: MembersOnlyDirective,
|
||||
},
|
||||
}
|
||||
|
||||
es := schema.NewExecutableSchema(config)
|
||||
gqlh := gqlutils.NewHandler(es, logger)
|
||||
|
||||
return gqlh
|
||||
}
|
||||
@@ -28,9 +28,6 @@ import (
|
||||
"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/trust/v1/schema"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils/directives/session"
|
||||
"go.probo.inc/probo/pkg/trust"
|
||||
)
|
||||
|
||||
@@ -85,21 +82,9 @@ func NewMux(
|
||||
|
||||
r.Use(compliancepage.NewCompliancePagePresenceMiddleware())
|
||||
r.Use(authn.NewSessionMiddleware(iamSvc, cookieConfig))
|
||||
r.Use(compliancepage.NewMembershipMiddleware(trustSvc, logger))
|
||||
|
||||
config := schema.Config{
|
||||
Resolvers: &Resolver{
|
||||
iam: iamSvc,
|
||||
trust: trustSvc,
|
||||
logger: logger,
|
||||
sessionCookie: authn.NewCookie(&cookieConfig),
|
||||
baseURL: baseURL,
|
||||
},
|
||||
Directives: schema.DirectiveRoot{
|
||||
Session: session.Directive,
|
||||
},
|
||||
}
|
||||
es := schema.NewExecutableSchema(config)
|
||||
graphqlHandler := gqlutils.NewHandler(es, logger)
|
||||
graphqlHandler := NewGraphQLHandler(iamSvc, trustSvc, logger, baseURL, cookieConfig)
|
||||
|
||||
r.Handle("/graphql", graphqlHandler)
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ directive @goModel(
|
||||
|
||||
directive @goEnum(value: String) on ENUM_VALUE
|
||||
|
||||
directive @membersOnly on FIELD_DEFINITION
|
||||
|
||||
enum Role {
|
||||
NONE
|
||||
USER
|
||||
@@ -495,7 +497,7 @@ type TrustCenter implements Node {
|
||||
ndaFileName: String
|
||||
ndaFileUrl: String @goField(forceResolver: true)
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
isUserAuthenticated: Boolean! @goField(forceResolver: true)
|
||||
isViewerMember: Boolean! @goField(forceResolver: true)
|
||||
hasAcceptedNonDisclosureAgreement: Boolean! @goField(forceResolver: true)
|
||||
|
||||
documents(
|
||||
@@ -610,30 +612,37 @@ type Query {
|
||||
|
||||
type Mutation {
|
||||
sendMagicLink(input: SendMagicLinkInput!): SendMagicLinkPayload
|
||||
@session(required: OPTIONAL)
|
||||
verifyMagicLink(input: VerifyMagicLinkInput!): VerifyMagicLinkPayload
|
||||
@session(required: OPTIONAL)
|
||||
|
||||
requestAllAccesses: RequestAccessesPayload!
|
||||
requestAllAccesses: RequestAccessesPayload! @session(required: PRESENT)
|
||||
|
||||
exportDocumentPDF(input: ExportDocumentPDFInput!): ExportDocumentPDFPayload!
|
||||
@session(required: NONE)
|
||||
@session(required: PRESENT)
|
||||
@membersOnly
|
||||
|
||||
exportReportPDF(input: ExportReportPDFInput!): ExportReportPDFPayload!
|
||||
@session(required: NONE)
|
||||
@session(required: PRESENT)
|
||||
@membersOnly
|
||||
|
||||
acceptNonDisclosureAgreement: AcceptNonDisclosureAgreementPayload!
|
||||
@session(required: PRESENT)
|
||||
@membersOnly
|
||||
|
||||
requestDocumentAccess(
|
||||
input: RequestDocumentAccessInput!
|
||||
): RequestAccessesPayload!
|
||||
): RequestAccessesPayload! @session(required: PRESENT)
|
||||
|
||||
requestReportAccess(input: RequestReportAccessInput!): RequestAccessesPayload!
|
||||
requestReportAccess(
|
||||
input: RequestReportAccessInput!
|
||||
): RequestAccessesPayload! @session(required: PRESENT)
|
||||
|
||||
requestTrustCenterFileAccess(
|
||||
input: RequestTrustCenterFileAccessInput!
|
||||
): RequestAccessesPayload!
|
||||
): RequestAccessesPayload! @session(required: PRESENT)
|
||||
|
||||
exportTrustCenterFile(
|
||||
input: ExportTrustCenterFileInput!
|
||||
): ExportTrustCenterFilePayload!
|
||||
): ExportTrustCenterFilePayload! @session(required: PRESENT) @membersOnly
|
||||
}
|
||||
|
||||
@@ -60,7 +60,8 @@ type ResolverRoot interface {
|
||||
}
|
||||
|
||||
type DirectiveRoot struct {
|
||||
Session func(ctx context.Context, obj any, next graphql.Resolver, required session.SessionRequirement) (res any, err error)
|
||||
MembersOnly func(ctx context.Context, obj any, next graphql.Resolver) (res any, err error)
|
||||
Session func(ctx context.Context, obj any, next graphql.Resolver, required session.SessionRequirement) (res any, err error)
|
||||
}
|
||||
|
||||
type ComplexityRoot struct {
|
||||
@@ -187,7 +188,7 @@ type ComplexityRoot struct {
|
||||
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
|
||||
IsViewerMember func(childComplexity int) int
|
||||
NdaFileName func(childComplexity int) int
|
||||
NdaFileURL func(childComplexity int) int
|
||||
Organization func(childComplexity int) int
|
||||
@@ -304,7 +305,7 @@ type ReportResolver interface {
|
||||
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)
|
||||
IsViewerMember(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)
|
||||
@@ -803,12 +804,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
}
|
||||
|
||||
return e.complexity.TrustCenter.ID(childComplexity), true
|
||||
case "TrustCenter.isUserAuthenticated":
|
||||
if e.complexity.TrustCenter.IsUserAuthenticated == nil {
|
||||
case "TrustCenter.isViewerMember":
|
||||
if e.complexity.TrustCenter.IsViewerMember == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.TrustCenter.IsUserAuthenticated(childComplexity), true
|
||||
return e.complexity.TrustCenter.IsViewerMember(childComplexity), true
|
||||
case "TrustCenter.ndaFileName":
|
||||
if e.complexity.TrustCenter.NdaFileName == nil {
|
||||
break
|
||||
@@ -1209,6 +1210,8 @@ directive @goModel(
|
||||
|
||||
directive @goEnum(value: String) on ENUM_VALUE
|
||||
|
||||
directive @membersOnly on FIELD_DEFINITION
|
||||
|
||||
enum Role {
|
||||
NONE
|
||||
USER
|
||||
@@ -1692,7 +1695,7 @@ type TrustCenter implements Node {
|
||||
ndaFileName: String
|
||||
ndaFileUrl: String @goField(forceResolver: true)
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
isUserAuthenticated: Boolean! @goField(forceResolver: true)
|
||||
isViewerMember: Boolean! @goField(forceResolver: true)
|
||||
hasAcceptedNonDisclosureAgreement: Boolean! @goField(forceResolver: true)
|
||||
|
||||
documents(
|
||||
@@ -1807,32 +1810,39 @@ type Query {
|
||||
|
||||
type Mutation {
|
||||
sendMagicLink(input: SendMagicLinkInput!): SendMagicLinkPayload
|
||||
@session(required: OPTIONAL)
|
||||
verifyMagicLink(input: VerifyMagicLinkInput!): VerifyMagicLinkPayload
|
||||
@session(required: OPTIONAL)
|
||||
|
||||
requestAllAccesses: RequestAccessesPayload!
|
||||
requestAllAccesses: RequestAccessesPayload! @session(required: PRESENT)
|
||||
|
||||
exportDocumentPDF(input: ExportDocumentPDFInput!): ExportDocumentPDFPayload!
|
||||
@session(required: NONE)
|
||||
@session(required: PRESENT)
|
||||
@membersOnly
|
||||
|
||||
exportReportPDF(input: ExportReportPDFInput!): ExportReportPDFPayload!
|
||||
@session(required: NONE)
|
||||
@session(required: PRESENT)
|
||||
@membersOnly
|
||||
|
||||
acceptNonDisclosureAgreement: AcceptNonDisclosureAgreementPayload!
|
||||
@session(required: PRESENT)
|
||||
@membersOnly
|
||||
|
||||
requestDocumentAccess(
|
||||
input: RequestDocumentAccessInput!
|
||||
): RequestAccessesPayload!
|
||||
): RequestAccessesPayload! @session(required: PRESENT)
|
||||
|
||||
requestReportAccess(input: RequestReportAccessInput!): RequestAccessesPayload!
|
||||
requestReportAccess(
|
||||
input: RequestReportAccessInput!
|
||||
): RequestAccessesPayload! @session(required: PRESENT)
|
||||
|
||||
requestTrustCenterFileAccess(
|
||||
input: RequestTrustCenterFileAccessInput!
|
||||
): RequestAccessesPayload!
|
||||
): RequestAccessesPayload! @session(required: PRESENT)
|
||||
|
||||
exportTrustCenterFile(
|
||||
input: ExportTrustCenterFileInput!
|
||||
): ExportTrustCenterFilePayload!
|
||||
): ExportTrustCenterFilePayload! @session(required: PRESENT) @membersOnly
|
||||
}
|
||||
`, BuiltIn: false},
|
||||
{Name: "../../../../gqlutils/directives/session/schema.graphql", Input: `# Session directive for GraphQL APIs
|
||||
@@ -3136,7 +3146,25 @@ func (ec *executionContext) _Mutation_sendMagicLink(ctx context.Context, field g
|
||||
fc := graphql.GetFieldContext(ctx)
|
||||
return ec.resolvers.Mutation().SendMagicLink(ctx, fc.Args["input"].(types.SendMagicLinkInput))
|
||||
},
|
||||
nil,
|
||||
func(ctx context.Context, next graphql.Resolver) graphql.Resolver {
|
||||
directive0 := next
|
||||
|
||||
directive1 := func(ctx context.Context) (any, error) {
|
||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "OPTIONAL")
|
||||
if err != nil {
|
||||
var zeroVal *types.SendMagicLinkPayload
|
||||
return zeroVal, err
|
||||
}
|
||||
if ec.directives.Session == nil {
|
||||
var zeroVal *types.SendMagicLinkPayload
|
||||
return zeroVal, errors.New("directive session is not implemented")
|
||||
}
|
||||
return ec.directives.Session(ctx, nil, directive0, required)
|
||||
}
|
||||
|
||||
next = directive1
|
||||
return next
|
||||
},
|
||||
ec.marshalOSendMagicLinkPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐSendMagicLinkPayload,
|
||||
true,
|
||||
false,
|
||||
@@ -3181,7 +3209,25 @@ func (ec *executionContext) _Mutation_verifyMagicLink(ctx context.Context, field
|
||||
fc := graphql.GetFieldContext(ctx)
|
||||
return ec.resolvers.Mutation().VerifyMagicLink(ctx, fc.Args["input"].(types.VerifyMagicLinkInput))
|
||||
},
|
||||
nil,
|
||||
func(ctx context.Context, next graphql.Resolver) graphql.Resolver {
|
||||
directive0 := next
|
||||
|
||||
directive1 := func(ctx context.Context) (any, error) {
|
||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "OPTIONAL")
|
||||
if err != nil {
|
||||
var zeroVal *types.VerifyMagicLinkPayload
|
||||
return zeroVal, err
|
||||
}
|
||||
if ec.directives.Session == nil {
|
||||
var zeroVal *types.VerifyMagicLinkPayload
|
||||
return zeroVal, errors.New("directive session is not implemented")
|
||||
}
|
||||
return ec.directives.Session(ctx, nil, directive0, required)
|
||||
}
|
||||
|
||||
next = directive1
|
||||
return next
|
||||
},
|
||||
ec.marshalOVerifyMagicLinkPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐVerifyMagicLinkPayload,
|
||||
true,
|
||||
false,
|
||||
@@ -3225,7 +3271,25 @@ func (ec *executionContext) _Mutation_requestAllAccesses(ctx context.Context, fi
|
||||
func(ctx context.Context) (any, error) {
|
||||
return ec.resolvers.Mutation().RequestAllAccesses(ctx)
|
||||
},
|
||||
nil,
|
||||
func(ctx context.Context, next graphql.Resolver) graphql.Resolver {
|
||||
directive0 := next
|
||||
|
||||
directive1 := func(ctx context.Context) (any, error) {
|
||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "PRESENT")
|
||||
if err != nil {
|
||||
var zeroVal *types.RequestAccessesPayload
|
||||
return zeroVal, err
|
||||
}
|
||||
if ec.directives.Session == nil {
|
||||
var zeroVal *types.RequestAccessesPayload
|
||||
return zeroVal, errors.New("directive session is not implemented")
|
||||
}
|
||||
return ec.directives.Session(ctx, nil, directive0, required)
|
||||
}
|
||||
|
||||
next = directive1
|
||||
return next
|
||||
},
|
||||
ec.marshalNRequestAccessesPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAccessesPayload,
|
||||
true,
|
||||
true,
|
||||
@@ -3263,7 +3327,7 @@ func (ec *executionContext) _Mutation_exportDocumentPDF(ctx context.Context, fie
|
||||
directive0 := next
|
||||
|
||||
directive1 := func(ctx context.Context) (any, error) {
|
||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "NONE")
|
||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "PRESENT")
|
||||
if err != nil {
|
||||
var zeroVal *types.ExportDocumentPDFPayload
|
||||
return zeroVal, err
|
||||
@@ -3274,8 +3338,15 @@ func (ec *executionContext) _Mutation_exportDocumentPDF(ctx context.Context, fie
|
||||
}
|
||||
return ec.directives.Session(ctx, nil, directive0, required)
|
||||
}
|
||||
directive2 := func(ctx context.Context) (any, error) {
|
||||
if ec.directives.MembersOnly == nil {
|
||||
var zeroVal *types.ExportDocumentPDFPayload
|
||||
return zeroVal, errors.New("directive membersOnly is not implemented")
|
||||
}
|
||||
return ec.directives.MembersOnly(ctx, nil, directive1)
|
||||
}
|
||||
|
||||
next = directive1
|
||||
next = directive2
|
||||
return next
|
||||
},
|
||||
ec.marshalNExportDocumentPDFPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐExportDocumentPDFPayload,
|
||||
@@ -3326,7 +3397,7 @@ func (ec *executionContext) _Mutation_exportReportPDF(ctx context.Context, field
|
||||
directive0 := next
|
||||
|
||||
directive1 := func(ctx context.Context) (any, error) {
|
||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "NONE")
|
||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "PRESENT")
|
||||
if err != nil {
|
||||
var zeroVal *types.ExportReportPDFPayload
|
||||
return zeroVal, err
|
||||
@@ -3337,8 +3408,15 @@ func (ec *executionContext) _Mutation_exportReportPDF(ctx context.Context, field
|
||||
}
|
||||
return ec.directives.Session(ctx, nil, directive0, required)
|
||||
}
|
||||
directive2 := func(ctx context.Context) (any, error) {
|
||||
if ec.directives.MembersOnly == nil {
|
||||
var zeroVal *types.ExportReportPDFPayload
|
||||
return zeroVal, errors.New("directive membersOnly is not implemented")
|
||||
}
|
||||
return ec.directives.MembersOnly(ctx, nil, directive1)
|
||||
}
|
||||
|
||||
next = directive1
|
||||
next = directive2
|
||||
return next
|
||||
},
|
||||
ec.marshalNExportReportPDFPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐExportReportPDFPayload,
|
||||
@@ -3399,8 +3477,15 @@ func (ec *executionContext) _Mutation_acceptNonDisclosureAgreement(ctx context.C
|
||||
}
|
||||
return ec.directives.Session(ctx, nil, directive0, required)
|
||||
}
|
||||
directive2 := func(ctx context.Context) (any, error) {
|
||||
if ec.directives.MembersOnly == nil {
|
||||
var zeroVal *types.AcceptNonDisclosureAgreementPayload
|
||||
return zeroVal, errors.New("directive membersOnly is not implemented")
|
||||
}
|
||||
return ec.directives.MembersOnly(ctx, nil, directive1)
|
||||
}
|
||||
|
||||
next = directive1
|
||||
next = directive2
|
||||
return next
|
||||
},
|
||||
ec.marshalNAcceptNonDisclosureAgreementPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAcceptNonDisclosureAgreementPayload,
|
||||
@@ -3436,7 +3521,25 @@ func (ec *executionContext) _Mutation_requestDocumentAccess(ctx context.Context,
|
||||
fc := graphql.GetFieldContext(ctx)
|
||||
return ec.resolvers.Mutation().RequestDocumentAccess(ctx, fc.Args["input"].(types.RequestDocumentAccessInput))
|
||||
},
|
||||
nil,
|
||||
func(ctx context.Context, next graphql.Resolver) graphql.Resolver {
|
||||
directive0 := next
|
||||
|
||||
directive1 := func(ctx context.Context) (any, error) {
|
||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "PRESENT")
|
||||
if err != nil {
|
||||
var zeroVal *types.RequestAccessesPayload
|
||||
return zeroVal, err
|
||||
}
|
||||
if ec.directives.Session == nil {
|
||||
var zeroVal *types.RequestAccessesPayload
|
||||
return zeroVal, errors.New("directive session is not implemented")
|
||||
}
|
||||
return ec.directives.Session(ctx, nil, directive0, required)
|
||||
}
|
||||
|
||||
next = directive1
|
||||
return next
|
||||
},
|
||||
ec.marshalNRequestAccessesPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAccessesPayload,
|
||||
true,
|
||||
true,
|
||||
@@ -3481,7 +3584,25 @@ func (ec *executionContext) _Mutation_requestReportAccess(ctx context.Context, f
|
||||
fc := graphql.GetFieldContext(ctx)
|
||||
return ec.resolvers.Mutation().RequestReportAccess(ctx, fc.Args["input"].(types.RequestReportAccessInput))
|
||||
},
|
||||
nil,
|
||||
func(ctx context.Context, next graphql.Resolver) graphql.Resolver {
|
||||
directive0 := next
|
||||
|
||||
directive1 := func(ctx context.Context) (any, error) {
|
||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "PRESENT")
|
||||
if err != nil {
|
||||
var zeroVal *types.RequestAccessesPayload
|
||||
return zeroVal, err
|
||||
}
|
||||
if ec.directives.Session == nil {
|
||||
var zeroVal *types.RequestAccessesPayload
|
||||
return zeroVal, errors.New("directive session is not implemented")
|
||||
}
|
||||
return ec.directives.Session(ctx, nil, directive0, required)
|
||||
}
|
||||
|
||||
next = directive1
|
||||
return next
|
||||
},
|
||||
ec.marshalNRequestAccessesPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAccessesPayload,
|
||||
true,
|
||||
true,
|
||||
@@ -3526,7 +3647,25 @@ func (ec *executionContext) _Mutation_requestTrustCenterFileAccess(ctx context.C
|
||||
fc := graphql.GetFieldContext(ctx)
|
||||
return ec.resolvers.Mutation().RequestTrustCenterFileAccess(ctx, fc.Args["input"].(types.RequestTrustCenterFileAccessInput))
|
||||
},
|
||||
nil,
|
||||
func(ctx context.Context, next graphql.Resolver) graphql.Resolver {
|
||||
directive0 := next
|
||||
|
||||
directive1 := func(ctx context.Context) (any, error) {
|
||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "PRESENT")
|
||||
if err != nil {
|
||||
var zeroVal *types.RequestAccessesPayload
|
||||
return zeroVal, err
|
||||
}
|
||||
if ec.directives.Session == nil {
|
||||
var zeroVal *types.RequestAccessesPayload
|
||||
return zeroVal, errors.New("directive session is not implemented")
|
||||
}
|
||||
return ec.directives.Session(ctx, nil, directive0, required)
|
||||
}
|
||||
|
||||
next = directive1
|
||||
return next
|
||||
},
|
||||
ec.marshalNRequestAccessesPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAccessesPayload,
|
||||
true,
|
||||
true,
|
||||
@@ -3571,7 +3710,32 @@ func (ec *executionContext) _Mutation_exportTrustCenterFile(ctx context.Context,
|
||||
fc := graphql.GetFieldContext(ctx)
|
||||
return ec.resolvers.Mutation().ExportTrustCenterFile(ctx, fc.Args["input"].(types.ExportTrustCenterFileInput))
|
||||
},
|
||||
nil,
|
||||
func(ctx context.Context, next graphql.Resolver) graphql.Resolver {
|
||||
directive0 := next
|
||||
|
||||
directive1 := func(ctx context.Context) (any, error) {
|
||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "PRESENT")
|
||||
if err != nil {
|
||||
var zeroVal *types.ExportTrustCenterFilePayload
|
||||
return zeroVal, err
|
||||
}
|
||||
if ec.directives.Session == nil {
|
||||
var zeroVal *types.ExportTrustCenterFilePayload
|
||||
return zeroVal, errors.New("directive session is not implemented")
|
||||
}
|
||||
return ec.directives.Session(ctx, nil, directive0, required)
|
||||
}
|
||||
directive2 := func(ctx context.Context) (any, error) {
|
||||
if ec.directives.MembersOnly == nil {
|
||||
var zeroVal *types.ExportTrustCenterFilePayload
|
||||
return zeroVal, errors.New("directive membersOnly is not implemented")
|
||||
}
|
||||
return ec.directives.MembersOnly(ctx, nil, directive1)
|
||||
}
|
||||
|
||||
next = directive2
|
||||
return next
|
||||
},
|
||||
ec.marshalNExportTrustCenterFilePayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐExportTrustCenterFilePayload,
|
||||
true,
|
||||
true,
|
||||
@@ -4045,8 +4209,8 @@ func (ec *executionContext) fieldContext_Query_currentTrustCenter(_ context.Cont
|
||||
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 "isViewerMember":
|
||||
return ec.fieldContext_TrustCenter_isViewerMember(ctx, field)
|
||||
case "hasAcceptedNonDisclosureAgreement":
|
||||
return ec.fieldContext_TrustCenter_hasAcceptedNonDisclosureAgreement(ctx, field)
|
||||
case "documents":
|
||||
@@ -4550,14 +4714,14 @@ func (ec *executionContext) fieldContext_TrustCenter_organization(_ context.Cont
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _TrustCenter_isUserAuthenticated(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
|
||||
func (ec *executionContext) _TrustCenter_isViewerMember(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
ec.OperationContext,
|
||||
field,
|
||||
ec.fieldContext_TrustCenter_isUserAuthenticated,
|
||||
ec.fieldContext_TrustCenter_isViewerMember,
|
||||
func(ctx context.Context) (any, error) {
|
||||
return ec.resolvers.TrustCenter().IsUserAuthenticated(ctx, obj)
|
||||
return ec.resolvers.TrustCenter().IsViewerMember(ctx, obj)
|
||||
},
|
||||
nil,
|
||||
ec.marshalNBoolean2bool,
|
||||
@@ -4566,7 +4730,7 @@ func (ec *executionContext) _TrustCenter_isUserAuthenticated(ctx context.Context
|
||||
)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_TrustCenter_isUserAuthenticated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
func (ec *executionContext) fieldContext_TrustCenter_isViewerMember(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "TrustCenter",
|
||||
Field: field,
|
||||
@@ -9046,7 +9210,7 @@ func (ec *executionContext) _TrustCenter(ctx context.Context, sel ast.SelectionS
|
||||
}
|
||||
|
||||
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
|
||||
case "isUserAuthenticated":
|
||||
case "isViewerMember":
|
||||
field := field
|
||||
|
||||
innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) {
|
||||
@@ -9055,7 +9219,7 @@ func (ec *executionContext) _TrustCenter(ctx context.Context, sel ast.SelectionS
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
}
|
||||
}()
|
||||
res = ec._TrustCenter_isUserAuthenticated(ctx, field, obj)
|
||||
res = ec._TrustCenter_isViewerMember(ctx, field, obj)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&fs.Invalids, 1)
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ type TrustCenter struct {
|
||||
NdaFileName *string `json:"ndaFileName,omitempty"`
|
||||
NdaFileURL *string `json:"ndaFileUrl,omitempty"`
|
||||
Organization *Organization `json:"organization"`
|
||||
IsUserAuthenticated bool `json:"isUserAuthenticated"`
|
||||
IsViewerMember bool `json:"isViewerMember"`
|
||||
HasAcceptedNonDisclosureAgreement bool `json:"hasAcceptedNonDisclosureAgreement"`
|
||||
Documents *DocumentConnection `json:"documents"`
|
||||
Audits *AuditConnection `json:"audits"`
|
||||
|
||||
@@ -166,11 +166,12 @@ func (r *mutationResolver) SendMagicLink(ctx context.Context, input types.SendMa
|
||||
|
||||
customDomain, err := r.trust.GetCustomDomainByOrganizationID(ctx, organization.ID)
|
||||
if err != nil {
|
||||
var errNotFound *iam.ErrOrganizationNotFound
|
||||
if !errors.As(err, &errNotFound) {
|
||||
r.logger.ErrorCtx(ctx, "cannot get custom domain", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
if errors.Is(err, trust.ErrCustomDomainNotFound) {
|
||||
return nil, gqlutils.NotFoundf(ctx, "custom domain not found")
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get custom domain", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
req := &iam.SendMagicLinkRequest{
|
||||
@@ -874,11 +875,11 @@ func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.Trust
|
||||
return obj.Organization, nil
|
||||
}
|
||||
|
||||
// IsUserAuthenticated is the resolver for the isUserAuthenticated field.
|
||||
func (r *trustCenterResolver) IsUserAuthenticated(ctx context.Context, obj *types.TrustCenter) (bool, error) {
|
||||
identity := authn.IdentityFromContext(ctx)
|
||||
// IsViewerMember is the resolver for the isViewerMember field.
|
||||
func (r *trustCenterResolver) IsViewerMember(ctx context.Context, obj *types.TrustCenter) (bool, error) {
|
||||
membership := compliancepage.ComplianceMembershipFromContext(ctx)
|
||||
|
||||
return identity != nil, nil
|
||||
return membership != nil, nil
|
||||
}
|
||||
|
||||
// HasAcceptedNonDisclosureAgreement is the resolver for the hasAcceptedNonDisclosureAgreement field.
|
||||
@@ -985,7 +986,13 @@ func (r *trustCenterResolver) TrustCenterFiles(ctx context.Context, obj *types.T
|
||||
}
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
trustCenterFilePage, err := trustService.TrustCenterFiles.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
|
||||
filter := coredata.NewTrustCenterFileFilter(
|
||||
coredata.WithTrustCenterFileVisibilities(
|
||||
coredata.TrustCenterVisibilityPublic,
|
||||
coredata.TrustCenterVisibilityPrivate,
|
||||
),
|
||||
)
|
||||
trustCenterFilePage, err := trustService.TrustCenterFiles.ListForOrganizationId(ctx, obj.Organization.ID, cursor, filter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list public trust center files", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
|
||||
Reference in New Issue
Block a user