diff --git a/apps/console/src/pages/iam/organizations/ViewerMembershipLayout.tsx b/apps/console/src/pages/iam/organizations/ViewerMembershipLayout.tsx index 914003ac1..19e0d00e4 100644 --- a/apps/console/src/pages/iam/organizations/ViewerMembershipLayout.tsx +++ b/apps/console/src/pages/iam/organizations/ViewerMembershipLayout.tsx @@ -1,8 +1,8 @@ import { graphql, usePreloadedQuery, type PreloadedQuery } from "react-relay"; import { Link, Outlet } from "react-router"; import { Badge, Button, IconPeopleAdd, Layout, Skeleton } from "@probo/ui"; -import { Sidebar } from "../memberships/_components/Sidebar"; -import { MembershipsDropdown } from "../memberships/MembershipsDropdown"; +import { Sidebar } from "./_components/Sidebar"; +import { MembershipsDropdown } from "./_components/MembershipsDropdown"; import type { ViewerMembershipLayoutQuery } from "/__generated__/iam/ViewerMembershipLayoutQuery.graphql"; import { ViewerMembershipDropdown } from "./_components/ViewerMembershipDropdown"; import { Suspense } from "react"; diff --git a/apps/console/src/pages/iam/memberships/MembershipsDropdown.tsx b/apps/console/src/pages/iam/organizations/_components/MembershipsDropdown.tsx similarity index 100% rename from apps/console/src/pages/iam/memberships/MembershipsDropdown.tsx rename to apps/console/src/pages/iam/organizations/_components/MembershipsDropdown.tsx index 9aef91c08..fab18398f 100644 --- a/apps/console/src/pages/iam/memberships/MembershipsDropdown.tsx +++ b/apps/console/src/pages/iam/organizations/_components/MembershipsDropdown.tsx @@ -14,14 +14,14 @@ import { } from "@probo/ui"; import { Suspense, useCallback, useState } from "react"; import { useTranslate } from "@probo/i18n"; -import { - MembershipsDropdownMenu, - membershipsDropdownMenuQuery, -} from "./MembershipsDropdownMenu"; import type { MembershipsDropdownMenuQuery } from "/__generated__/iam/MembershipsDropdownMenuQuery.graphql"; import { Link } from "react-router"; import type { MembershipsDropdown_organizationFragment$key } from "/__generated__/iam/MembershipsDropdown_organizationFragment.graphql"; import type { MembershipsDropdown_viewerFragment$key } from "/__generated__/iam/MembershipsDropdown_viewerFragment.graphql"; +import { + MembershipsDropdownMenu, + membershipsDropdownMenuQuery, +} from "./MembershipsDropdownMenu"; const organizationFragment = graphql` fragment MembershipsDropdown_organizationFragment on Organization { diff --git a/apps/console/src/pages/iam/memberships/MembershipsDropdownMenu.tsx b/apps/console/src/pages/iam/organizations/_components/MembershipsDropdownMenu.tsx similarity index 100% rename from apps/console/src/pages/iam/memberships/MembershipsDropdownMenu.tsx rename to apps/console/src/pages/iam/organizations/_components/MembershipsDropdownMenu.tsx diff --git a/apps/console/src/pages/iam/memberships/MembershipsDropdownMenuItem.tsx b/apps/console/src/pages/iam/organizations/_components/MembershipsDropdownMenuItem.tsx similarity index 100% rename from apps/console/src/pages/iam/memberships/MembershipsDropdownMenuItem.tsx rename to apps/console/src/pages/iam/organizations/_components/MembershipsDropdownMenuItem.tsx diff --git a/apps/console/src/pages/iam/memberships/_components/Sidebar.tsx b/apps/console/src/pages/iam/organizations/_components/Sidebar.tsx similarity index 100% rename from apps/console/src/pages/iam/memberships/_components/Sidebar.tsx rename to apps/console/src/pages/iam/organizations/_components/Sidebar.tsx diff --git a/pkg/coredata/session.go b/pkg/coredata/session.go index cdbebbc7c..8e0439c18 100644 --- a/pkg/coredata/session.go +++ b/pkg/coredata/session.go @@ -341,7 +341,12 @@ WHERE return result.RowsAffected(), nil } -func (s *Session) LoadByRootSessionIDAndMembershipID(ctx context.Context, conn pg.Conn, rootSessionID gid.GID, membershipID gid.GID) error { +func (s *Session) LoadByRootSessionIDAndMembershipID( + ctx context.Context, + conn pg.Conn, + rootSessionID gid.GID, + membershipID gid.GID, +) error { q := ` SELECT id, @@ -390,3 +395,58 @@ LIMIT 1 return nil } + +func (s *Session) LoadByRootSessionIDAndOrganizationID( + ctx context.Context, + conn pg.Conn, + rootSessionID gid.GID, + organizationID gid.GID, +) error { + q := ` +SELECT + id, + identity_id, + tenant_id, + membership_id, + data, + parent_session_id, + auth_method, + authenticated_at, + expire_reason, + user_agent, + ip_address, + expired_at, + created_at, + updated_at +FROM + iam_sessions +WHERE + parent_session_id = @root_session_id + AND organization_id = @organization_id +ORDER BY created_at DESC +LIMIT 1 +` + + args := pgx.StrictNamedArgs{ + "root_session_id": rootSessionID, + "organization_id": organizationID, + } + + rows, err := conn.Query(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot query session: %w", err) + } + + session, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[Session]) + if err != nil { + if err == pgx.ErrNoRows { + return ErrResourceNotFound + } + + return fmt.Errorf("cannot collect session: %w", err) + } + + *s = session + + return nil +} diff --git a/pkg/iam/authorizer.go b/pkg/iam/authorizer.go index 2ebad204e..1fd12383b 100644 --- a/pkg/iam/authorizer.go +++ b/pkg/iam/authorizer.go @@ -16,8 +16,10 @@ package iam import ( "context" + "errors" "fmt" "maps" + "time" "go.gearno.de/kit/pg" "go.probo.inc/probo/pkg/coredata" @@ -35,6 +37,7 @@ type AuthorizationAttributer interface { type AuthorizeParams struct { Principal gid.GID Resource gid.GID + Session *gid.GID Action string ResourceAttributes map[string]string } @@ -70,29 +73,52 @@ func (a *Authorizer) Authorize(ctx context.Context, params AuthorizeParams) erro } func (a *Authorizer) authorize(ctx context.Context, conn pg.Conn, params AuthorizeParams) error { - memberships, err := a.loadMemberships(ctx, conn, params.Principal) - if err != nil { - return err - } - resourceAttrs, err := a.buildResourceAttributes(ctx, conn, params) if err != nil { - return err + return fmt.Errorf("cannot build resource attributes: %w", err) } - // Find role for resource's organization resourceOrgID := resourceAttrs["organization_id"] - role := findRoleForOrg(memberships, resourceOrgID) + + // Find role for resource's organization + memberships, err := a.loadMemberships(ctx, conn, params.Principal) + if err != nil { + return fmt.Errorf("cannot load memberships for principal: %w", err) + } + membership := findMembershipForOrg(memberships, resourceOrgID) + + if membership != nil && params.Session != nil { + if _, err := a.getActiveChildSessionForMembership( + ctx, + conn, + *params.Session, + membership.ID, + ); err != nil { + var errSessionNotFound *ErrSessionNotFound + var errSessionExpired *ErrSessionExpired + + if errors.As(err, &errSessionNotFound) || errors.As(err, &errSessionExpired) { + return NewInsufficientPermissionsError(params.Principal, params.Resource, params.Action) + } + + return fmt.Errorf("cannot get active child session for membership: %w", err) + } + } + + var role string + if membership != nil { + role = membership.Role.String() + } // Only set principal.organization_id if they have a role in this org var principalOrgID string - if role != "" { - principalOrgID = resourceOrgID + if membership != nil && role != "" { + principalOrgID = membership.OrganizationID.String() } principalAttrs, err := a.buildPrincipalAttributes(ctx, conn, params.Principal, principalOrgID) if err != nil { - return err + return fmt.Errorf("cannot build principal attributes: %w", err) } policies := a.buildPoliciesForRole(role) @@ -122,6 +148,29 @@ func (a *Authorizer) loadMemberships(ctx context.Context, conn pg.Conn, principa return memberships, nil } +func (a *Authorizer) getActiveChildSessionForMembership( + ctx context.Context, + conn pg.Conn, + rootSessionID gid.GID, + membershipID gid.GID, +) (*coredata.Session, error) { + childSession := &coredata.Session{} + + if err := childSession.LoadByRootSessionIDAndMembershipID(ctx, conn, rootSessionID, membershipID); err != nil { + if err == coredata.ErrResourceNotFound { + return nil, NewSessionNotFoundError(gid.Nil) + } + + return nil, fmt.Errorf("cannot load child session: %w", err) + } + + if childSession.ExpireReason != nil || time.Now().After(childSession.ExpiredAt) { + return nil, NewSessionExpiredError(childSession.ID) + } + + return childSession, nil +} + func (a *Authorizer) buildPrincipalAttributes( ctx context.Context, conn pg.Conn, @@ -188,11 +237,12 @@ func (a *Authorizer) buildPoliciesForRole(role string) []*policy.Policy { return policies } -func findRoleForOrg(memberships coredata.Memberships, orgID string) string { +func findMembershipForOrg(memberships coredata.Memberships, orgID string) *coredata.Membership { for _, m := range memberships { if m.OrganizationID.String() == orgID && m.State == coredata.MembershipStateActive { - return string(m.Role) + return m } } - return "" + + return nil } diff --git a/pkg/iam/errors.go b/pkg/iam/errors.go index 437876434..3e553df47 100644 --- a/pkg/iam/errors.go +++ b/pkg/iam/errors.go @@ -190,6 +190,10 @@ func NewSessionNotFoundError(sessionID gid.GID) error { } func (e ErrSessionNotFound) Error() string { + if e.SessionID == gid.Nil { + return "session not found" + } + return fmt.Sprintf("session %q not found", e.SessionID) } @@ -353,18 +357,3 @@ func NewNoSCIMConfigurationFoundError(organizationID gid.GID) error { func (e ErrNoSCIMConfigurationFound) Error() string { return fmt.Sprintf("SCIM configuration not found for organization %q", e.OrganizationID) } - -// TenantAccessError is used by API recovery middleware to translate authorization/tenant failures -// into a consistent client-facing error response. -// -// NOTE: This is intentionally generic to avoid leaking resource existence. -type TenantAccessError struct { - Message string -} - -func (e *TenantAccessError) Error() string { - if e == nil || e.Message == "" { - return "tenant access denied" - } - return e.Message -} diff --git a/pkg/probo/actions.go b/pkg/probo/actions.go index 48ecb6eb4..30070963d 100644 --- a/pkg/probo/actions.go +++ b/pkg/probo/actions.go @@ -297,9 +297,6 @@ const ( // TrustCenterDocumentAccess actions ActionTrustCenterDocumentAccessList = "core:trust-center-document-access:list" - // DataProtectionOfficer actions - ActionDataProtectionOfficerList = "core:data-protection-officer:list" - // RightsRequest actions ActionRightsRequestList = "core:rights-request:list" ActionRightsRequestGet = "core:rights-request:get" diff --git a/pkg/server/api/connect/v1/api_key_middleware.go b/pkg/server/api/connect/v1/api_key_middleware.go index 87f09c9ba..c5eaff471 100644 --- a/pkg/server/api/connect/v1/api_key_middleware.go +++ b/pkg/server/api/connect/v1/api_key_middleware.go @@ -20,11 +20,14 @@ import ( "fmt" "net/http" + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/gqlerror" "go.gearno.de/kit/httpserver" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/gid" "go.probo.inc/probo/pkg/iam" "go.probo.inc/probo/pkg/securetoken" + "go.probo.inc/probo/pkg/server/gqlutils" ) var ( @@ -56,7 +59,15 @@ func NewAPIKeyMiddleware(svc *iam.Service, tokenSecret string) func(next http.Ha session := SessionFromContext(ctx) if keyID != gid.Nil && session != nil { - httpserver.RenderError(w, http.StatusBadRequest, errors.New("api key authentication cannot be used with session authentication")) + httpserver.RenderJSON( + w, + http.StatusUnauthorized, + &graphql.Response{ + Errors: gqlerror.List{ + gqlutils.Conflictf(ctx, "API key authentication cannot be used with session authentication"), + }, + }, + ) return } diff --git a/pkg/server/api/connect/v1/authorization.go b/pkg/server/api/connect/v1/authorization.go new file mode 100644 index 000000000..8f3f4fe90 --- /dev/null +++ b/pkg/server/api/connect/v1/authorization.go @@ -0,0 +1,83 @@ +// Copyright (c) 2025 Probo Inc . +// +// 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 connect_v1 + +import ( + "context" + "errors" + + "go.gearno.de/kit/log" + "go.probo.inc/probo/pkg/gid" + "go.probo.inc/probo/pkg/iam" + "go.probo.inc/probo/pkg/server/gqlutils" +) + +type ( + AuthorizeFuncOption func(*iam.AuthorizeParams) + AuthorizeFunc func(context.Context, gid.GID, string, ...AuthorizeFuncOption) error +) + +func WithAttr(key, value string) AuthorizeFuncOption { + return func(params *iam.AuthorizeParams) { + params.ResourceAttributes[key] = value + } +} + +func WithSession(sessionID *gid.GID) AuthorizeFuncOption { + return func(params *iam.AuthorizeParams) { + params.Session = sessionID + } +} + +func NewAuthorizeFunc( + svc *iam.Service, + logger *log.Logger, +) AuthorizeFunc { + return func( + ctx context.Context, + objectID gid.GID, + action string, + options ...AuthorizeFuncOption, + ) error { + identity := IdentityFromContext(ctx) + session := SessionFromContext(ctx) + + params := iam.AuthorizeParams{ + Principal: identity.ID, + Resource: objectID, + Action: action, + ResourceAttributes: make(map[string]string), + } + if session != nil { + params.Session = &session.ID + } + + for _, option := range options { + option(¶ms) + } + + if err := svc.Authorizer.Authorize(ctx, params); err != nil { + var errInsufficientPermissions *iam.ErrInsufficientPermissions + if errors.As(err, &errInsufficientPermissions) { + return gqlutils.Forbidden(ctx, err) + } + + logger.ErrorCtx(ctx, "cannot authorize", log.Error(err)) + return gqlutils.Internal(ctx) + } + + return nil + } +} diff --git a/pkg/server/api/connect/v1/graphql_handler.go b/pkg/server/api/connect/v1/graphql_handler.go index 860d5bd0f..559d69d30 100644 --- a/pkg/server/api/connect/v1/graphql_handler.go +++ b/pkg/server/api/connect/v1/graphql_handler.go @@ -19,7 +19,6 @@ import ( "net/http" "github.com/99designs/gqlgen/graphql" - "github.com/vektah/gqlparser/v2/gqlerror" "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/baseurl" "go.probo.inc/probo/pkg/iam" @@ -29,29 +28,6 @@ import ( "go.probo.inc/probo/pkg/server/gqlutils" ) -var ( - ErrForbidden = &gqlerror.Error{ - Message: "You are not authorized to access this resource", - Extensions: map[string]any{ - "code": "FORBIDDEN", - }, - } - - ErrUnauthenticated = &gqlerror.Error{ - Message: "You must be authenticated to access this resouce", - Extensions: map[string]any{ - "code": "UNAUTHENTICATED", - }, - } - - ErrAlreadyAuthenticated = &gqlerror.Error{ - Message: "authentication not allowed for this resource/action", - Extensions: map[string]any{ - "code": "ALREADY_AUTHENTICATED", - }, - } -) - func SessionDirective(ctx context.Context, obj any, next graphql.Resolver, required types.SessionRequirement) (any, error) { session := SessionFromContext(ctx) apiKey := APIKeyFromContext(ctx) @@ -60,50 +36,34 @@ func SessionDirective(ctx context.Context, obj any, next graphql.Resolver, requi case types.SessionRequirementOptional: case types.SessionRequirementPresent: if session == nil && apiKey == nil { - return nil, ErrUnauthenticated + return nil, gqlutils.Unauthenticatedf( + ctx, + "authentication is required to access this resouce", + ) } case types.SessionRequirementNone: if session != nil && apiKey != nil { - return nil, ErrAlreadyAuthenticated + return nil, gqlutils.Invalidf( + ctx, + "authentication not allowed for this resource/action", + ) } } return next(ctx) } -func IsViewerDirective(ctx context.Context, obj any, next graphql.Resolver) (any, error) { - identity := IdentityFromContext(ctx) - - switch node := obj.(type) { - case *types.Identity: - if identity.ID != node.ID { - return nil, ErrForbidden - } - case *types.Membership: - if identity.ID != node.Identity.ID { - return nil, ErrForbidden - } - case *types.Session: - if identity.ID != node.Identity.ID { - return nil, ErrForbidden - } - default: - } - - return next(ctx) -} - func NewGraphQLHandler(svc *iam.Service, logger *log.Logger, baseURL *baseurl.BaseURL, cookieConfig securecookie.Config) http.Handler { config := schema.Config{ Resolvers: &Resolver{ + authorize: NewAuthorizeFunc(svc, logger), logger: logger, iam: svc, baseURL: baseURL, cookieConfig: cookieConfig, }, Directives: schema.DirectiveRoot{ - Session: SessionDirective, - IsViewer: IsViewerDirective, + Session: SessionDirective, }, } diff --git a/pkg/server/api/connect/v1/identity_presence_middleware.go b/pkg/server/api/connect/v1/identity_presence_middleware.go new file mode 100644 index 000000000..3b8555c9b --- /dev/null +++ b/pkg/server/api/connect/v1/identity_presence_middleware.go @@ -0,0 +1,52 @@ +// Copyright (c) 2025 Probo Inc . +// +// 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 connect_v1 + +import ( + "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" +) + +func NewIdentityPresenceMiddleware() func(next http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + identity := IdentityFromContext(r.Context()) + + if identity == nil { + httpserver.RenderJSON( + w, + http.StatusUnauthorized, + &graphql.Response{ + Errors: gqlerror.List{ + gqlutils.Unauthenticatedf( + r.Context(), + "authentication is required to access this resouce", + ), + }, + }, + ) + return + } + + next.ServeHTTP(w, r) + }, + ) + } +} diff --git a/pkg/server/api/connect/v1/resolver.go b/pkg/server/api/connect/v1/resolver.go index 30559fcd0..824d65b1b 100644 --- a/pkg/server/api/connect/v1/resolver.go +++ b/pkg/server/api/connect/v1/resolver.go @@ -18,23 +18,20 @@ package connect_v1 import ( "context" - "errors" "net/http" "time" - "github.com/99designs/gqlgen/graphql" "github.com/go-chi/chi/v5" "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/baseurl" - "go.probo.inc/probo/pkg/gid" "go.probo.inc/probo/pkg/iam" "go.probo.inc/probo/pkg/securecookie" "go.probo.inc/probo/pkg/server/api/connect/v1/types" - "go.probo.inc/probo/pkg/server/gqlutils" ) type ( Resolver struct { + authorize AuthorizeFunc logger *log.Logger iam *iam.Service baseURL *baseurl.BaseURL @@ -81,54 +78,5 @@ func NewMux(logger *log.Logger, svc *iam.Service, cookieConfig securecookie.Conf } func (r *Resolver) Permission(ctx context.Context, obj types.Node, action string) (bool, error) { - identity := IdentityFromContext(ctx) - - err := r.iam.Authorizer.Authorize( - ctx, - iam.AuthorizeParams{ - Principal: identity.ID, - Resource: obj.GetID(), - Action: action, - }, - ) - - if err != nil { - var errInsufficientPermissions *iam.ErrInsufficientPermissions - if errors.As(err, &errInsufficientPermissions) { - return false, nil - } - - r.logger.ErrorCtx(ctx, "cannot authorize", log.Error(err)) - return false, gqlutils.InternalServerError(ctx) - } - - return true, nil -} - -func (r *Resolver) Authorize(ctx context.Context, objectID gid.GID, action string, attrs map[string]string) bool { - identity := IdentityFromContext(ctx) - - err := r.iam.Authorizer.Authorize( - ctx, - iam.AuthorizeParams{ - Principal: identity.ID, - Resource: objectID, - Action: action, - ResourceAttributes: attrs, - }, - ) - - if err != nil { - var errInsufficientPermissions *iam.ErrInsufficientPermissions - if errors.As(err, &errInsufficientPermissions) { - graphql.AddError(ctx, err) - return false - } - - r.logger.ErrorCtx(ctx, "cannot authorize", log.Error(err)) - graphql.AddError(ctx, gqlutils.InternalServerError(ctx)) - return false - } - - return true + return r.authorize(ctx, obj.GetID(), action) == nil, nil } diff --git a/pkg/server/api/connect/v1/saml_handler.go b/pkg/server/api/connect/v1/saml_handler.go index f52628d64..234a7c869 100644 --- a/pkg/server/api/connect/v1/saml_handler.go +++ b/pkg/server/api/connect/v1/saml_handler.go @@ -37,7 +37,7 @@ func (h *SAMLHandler) MetadataHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/samlmetadata+xml") w.WriteHeader(http.StatusOK) - w.Write(metadataXML) + _, _ = w.Write(metadataXML) } func (h *SAMLHandler) ConsumeHandler(w http.ResponseWriter, r *http.Request) { @@ -97,7 +97,11 @@ func (h *SAMLHandler) ConsumeHandler(w http.ResponseWriter, r *http.Request) { return } - securecookie.Set(w, h.cookieConfig, rootSession.ID.String()) + if err := securecookie.Set(w, h.cookieConfig, rootSession.ID.String()); err != nil { + h.logger.ErrorCtx(ctx, "cannot set cookie", log.Error(err)) + h.renderInternalServerError(w, r) + return + } redirectURL := h.baseURL.WithPath("/organizations/" + membership.OrganizationID.String()).MustString() http.Redirect(w, r, redirectURL, http.StatusFound) } diff --git a/pkg/server/api/connect/v1/schema.graphql b/pkg/server/api/connect/v1/schema.graphql index 89e86a38c..0de8d2daa 100644 --- a/pkg/server/api/connect/v1/schema.graphql +++ b/pkg/server/api/connect/v1/schema.graphql @@ -13,8 +13,6 @@ directive @goEnum(value: String) on ENUM_VALUE directive @session(required: SessionRequirement!) on FIELD_DEFINITION -directive @isViewer on FIELD_DEFINITION - scalar CursorKey scalar Datetime scalar Upload @@ -150,7 +148,7 @@ type Identity implements Node { last: Int before: CursorKey orderBy: MembershipOrder - ): MembershipConnection @goField(forceResolver: true) @isViewer + ): MembershipConnection @goField(forceResolver: true) pendingInvitations( first: Int @@ -158,7 +156,7 @@ type Identity implements Node { last: Int before: CursorKey orderBy: InvitationOrder - ): InvitationConnection @goField(forceResolver: true) @isViewer + ): InvitationConnection @goField(forceResolver: true) sessions( first: Int @@ -166,14 +164,14 @@ type Identity implements Node { last: Int before: CursorKey orderBy: SessionOrder - ): SessionConnection @goField(forceResolver: true) @isViewer + ): SessionConnection @goField(forceResolver: true) personalAPIKeys( first: Int after: CursorKey last: Int before: CursorKey - ): PersonalAPIKeyConnection @goField(forceResolver: true) @isViewer + ): PersonalAPIKeyConnection @goField(forceResolver: true) permission(action: String!): Boolean! @goField(forceResolver: true) @@ -272,7 +270,7 @@ type Membership implements Node { source: MembershipSource! state: MembershipState! - lastSession: Session @goField(forceResolver: true) @isViewer + lastSession: Session @goField(forceResolver: true) permission(action: String!): Boolean! @goField(forceResolver: true) @@ -297,7 +295,7 @@ type Invitation implements Node { type Session implements Node { id: ID! - identity: Identity @goField(forceResolver: true) @isViewer + identity: Identity @goField(forceResolver: true) ipAddress: String! userAgent: String! updatedAt: Datetime! diff --git a/pkg/server/api/connect/v1/schema/schema.go b/pkg/server/api/connect/v1/schema/schema.go index 7e064cd30..b331bf9f6 100644 --- a/pkg/server/api/connect/v1/schema/schema.go +++ b/pkg/server/api/connect/v1/schema/schema.go @@ -67,8 +67,7 @@ type ResolverRoot interface { } type DirectiveRoot struct { - IsViewer func(ctx context.Context, obj any, next graphql.Resolver) (res any, err error) - Session func(ctx context.Context, obj any, next graphql.Resolver, required types.SessionRequirement) (res any, err error) + Session func(ctx context.Context, obj any, next graphql.Resolver, required types.SessionRequirement) (res any, err error) } type ComplexityRoot struct { @@ -2281,8 +2280,6 @@ directive @goEnum(value: String) on ENUM_VALUE directive @session(required: SessionRequirement!) on FIELD_DEFINITION -directive @isViewer on FIELD_DEFINITION - scalar CursorKey scalar Datetime scalar Upload @@ -2418,7 +2415,7 @@ type Identity implements Node { last: Int before: CursorKey orderBy: MembershipOrder - ): MembershipConnection @goField(forceResolver: true) @isViewer + ): MembershipConnection @goField(forceResolver: true) pendingInvitations( first: Int @@ -2426,7 +2423,7 @@ type Identity implements Node { last: Int before: CursorKey orderBy: InvitationOrder - ): InvitationConnection @goField(forceResolver: true) @isViewer + ): InvitationConnection @goField(forceResolver: true) sessions( first: Int @@ -2434,14 +2431,14 @@ type Identity implements Node { last: Int before: CursorKey orderBy: SessionOrder - ): SessionConnection @goField(forceResolver: true) @isViewer + ): SessionConnection @goField(forceResolver: true) personalAPIKeys( first: Int after: CursorKey last: Int before: CursorKey - ): PersonalAPIKeyConnection @goField(forceResolver: true) @isViewer + ): PersonalAPIKeyConnection @goField(forceResolver: true) permission(action: String!): Boolean! @goField(forceResolver: true) @@ -2540,7 +2537,7 @@ type Membership implements Node { source: MembershipSource! state: MembershipState! - lastSession: Session @goField(forceResolver: true) @isViewer + lastSession: Session @goField(forceResolver: true) permission(action: String!): Boolean! @goField(forceResolver: true) @@ -2565,7 +2562,7 @@ type Invitation implements Node { type Session implements Node { id: ID! - identity: Identity @goField(forceResolver: true) @isViewer + identity: Identity @goField(forceResolver: true) ipAddress: String! userAgent: String! updatedAt: Datetime! @@ -4683,20 +4680,7 @@ func (ec *executionContext) _Identity_memberships(ctx context.Context, field gra fc := graphql.GetFieldContext(ctx) return ec.resolvers.Identity().Memberships(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey), fc.Args["orderBy"].(*types.MembershipOrderBy)) }, - func(ctx context.Context, next graphql.Resolver) graphql.Resolver { - directive0 := next - - directive1 := func(ctx context.Context) (any, error) { - if ec.directives.IsViewer == nil { - var zeroVal *types.MembershipConnection - return zeroVal, errors.New("directive isViewer is not implemented") - } - return ec.directives.IsViewer(ctx, obj, directive0) - } - - next = directive1 - return next - }, + nil, ec.marshalOMembershipConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconnectᚋv1ᚋtypesᚐMembershipConnection, true, false, @@ -4745,20 +4729,7 @@ func (ec *executionContext) _Identity_pendingInvitations(ctx context.Context, fi fc := graphql.GetFieldContext(ctx) return ec.resolvers.Identity().PendingInvitations(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey), fc.Args["orderBy"].(*types.InvitationOrderBy)) }, - func(ctx context.Context, next graphql.Resolver) graphql.Resolver { - directive0 := next - - directive1 := func(ctx context.Context) (any, error) { - if ec.directives.IsViewer == nil { - var zeroVal *types.InvitationConnection - return zeroVal, errors.New("directive isViewer is not implemented") - } - return ec.directives.IsViewer(ctx, obj, directive0) - } - - next = directive1 - return next - }, + nil, ec.marshalOInvitationConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconnectᚋv1ᚋtypesᚐInvitationConnection, true, false, @@ -4807,20 +4778,7 @@ func (ec *executionContext) _Identity_sessions(ctx context.Context, field graphq fc := graphql.GetFieldContext(ctx) return ec.resolvers.Identity().Sessions(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey), fc.Args["orderBy"].(*types.SessionOrder)) }, - func(ctx context.Context, next graphql.Resolver) graphql.Resolver { - directive0 := next - - directive1 := func(ctx context.Context) (any, error) { - if ec.directives.IsViewer == nil { - var zeroVal *types.SessionConnection - return zeroVal, errors.New("directive isViewer is not implemented") - } - return ec.directives.IsViewer(ctx, obj, directive0) - } - - next = directive1 - return next - }, + nil, ec.marshalOSessionConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconnectᚋv1ᚋtypesᚐSessionConnection, true, false, @@ -4869,20 +4827,7 @@ func (ec *executionContext) _Identity_personalAPIKeys(ctx context.Context, field fc := graphql.GetFieldContext(ctx) return ec.resolvers.Identity().PersonalAPIKeys(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey)) }, - func(ctx context.Context, next graphql.Resolver) graphql.Resolver { - directive0 := next - - directive1 := func(ctx context.Context) (any, error) { - if ec.directives.IsViewer == nil { - var zeroVal *types.PersonalAPIKeyConnection - return zeroVal, errors.New("directive isViewer is not implemented") - } - return ec.directives.IsViewer(ctx, obj, directive0) - } - - next = directive1 - return next - }, + nil, ec.marshalOPersonalAPIKeyConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconnectᚋv1ᚋtypesᚐPersonalAPIKeyConnection, true, false, @@ -5863,20 +5808,7 @@ func (ec *executionContext) _Membership_lastSession(ctx context.Context, field g func(ctx context.Context) (any, error) { return ec.resolvers.Membership().LastSession(ctx, obj) }, - func(ctx context.Context, next graphql.Resolver) graphql.Resolver { - directive0 := next - - directive1 := func(ctx context.Context) (any, error) { - if ec.directives.IsViewer == nil { - var zeroVal *types.Session - return zeroVal, errors.New("directive isViewer is not implemented") - } - return ec.directives.IsViewer(ctx, obj, directive0) - } - - next = directive1 - return next - }, + nil, ec.marshalOSession2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconnectᚋv1ᚋtypesᚐSession, true, false, @@ -11579,20 +11511,7 @@ func (ec *executionContext) _Session_identity(ctx context.Context, field graphql func(ctx context.Context) (any, error) { return ec.resolvers.Session().Identity(ctx, obj) }, - func(ctx context.Context, next graphql.Resolver) graphql.Resolver { - directive0 := next - - directive1 := func(ctx context.Context) (any, error) { - if ec.directives.IsViewer == nil { - var zeroVal *types.Identity - return zeroVal, errors.New("directive isViewer is not implemented") - } - return ec.directives.IsViewer(ctx, obj, directive0) - } - - next = directive1 - return next - }, + nil, ec.marshalOIdentity2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconnectᚋv1ᚋtypesᚐIdentity, true, false, diff --git a/pkg/server/api/connect/v1/session_middleware.go b/pkg/server/api/connect/v1/session_middleware.go index 61a84f357..5a57eaa21 100644 --- a/pkg/server/api/connect/v1/session_middleware.go +++ b/pkg/server/api/connect/v1/session_middleware.go @@ -21,11 +21,14 @@ import ( "net" "net/http" + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/gqlerror" "go.gearno.de/kit/httpserver" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/gid" "go.probo.inc/probo/pkg/iam" "go.probo.inc/probo/pkg/securecookie" + "go.probo.inc/probo/pkg/server/gqlutils" ) var ( @@ -64,7 +67,15 @@ func NewSessionMiddleware(svc *iam.Service, cookieConfig securecookie.Config) fu apiKey := APIKeyFromContext(ctx) if sessionID != gid.Nil && apiKey != nil { - httpserver.RenderError(w, http.StatusBadRequest, errors.New("session authentication cannot be used with API key authentication")) + httpserver.RenderJSON( + w, + http.StatusUnauthorized, + &graphql.Response{ + Errors: gqlerror.List{ + gqlutils.Conflictf(ctx, "session authentication cannot be used with API key authentication"), + }, + }, + ) return } diff --git a/pkg/server/api/connect/v1/v1_resolver.go b/pkg/server/api/connect/v1/v1_resolver.go index 419844cfa..31b20027c 100644 --- a/pkg/server/api/connect/v1/v1_resolver.go +++ b/pkg/server/api/connect/v1/v1_resolver.go @@ -28,8 +28,8 @@ import ( // Memberships is the resolver for the memberships field. func (r *identityResolver) Memberships(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MembershipOrderBy) (*types.MembershipConnection, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionMembershipList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionMembershipList); err != nil { + return nil, err } if gqlutils.OnlyTotalCountSelected(ctx) { @@ -55,7 +55,7 @@ func (r *identityResolver) Memberships(ctx context.Context, obj *types.Identity, page, err := r.iam.AccountService.ListMemberships(ctx, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list memberships", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewMembershipConnection(page, r, obj.ID), nil @@ -63,8 +63,8 @@ func (r *identityResolver) Memberships(ctx context.Context, obj *types.Identity, // PendingInvitations is the resolver for the pendingInvitations field. func (r *identityResolver) PendingInvitations(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.InvitationOrderBy) (*types.InvitationConnection, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionInvitationList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionInvitationList); err != nil { + return nil, err } if gqlutils.OnlyTotalCountSelected(ctx) { @@ -84,7 +84,7 @@ func (r *identityResolver) PendingInvitations(ctx context.Context, obj *types.Id page, err := r.iam.AccountService.ListPendingInvitations(ctx, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list pending invitations", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewInvitationConnection(page, r, obj.ID, nil), nil @@ -92,8 +92,8 @@ func (r *identityResolver) PendingInvitations(ctx context.Context, obj *types.Id // Sessions is the resolver for the sessions field. func (r *identityResolver) Sessions(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SessionOrder) (*types.SessionConnection, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionSessionList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionSessionList); err != nil { + return nil, err } if gqlutils.OnlyTotalCountSelected(ctx) { @@ -119,7 +119,7 @@ func (r *identityResolver) Sessions(ctx context.Context, obj *types.Identity, fi page, err := r.iam.AccountService.ListSessions(ctx, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list sessions", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewSessionConnection(page, r, obj.ID), nil @@ -127,8 +127,8 @@ func (r *identityResolver) Sessions(ctx context.Context, obj *types.Identity, fi // PersonalAPIKeys is the resolver for the personalAPIKeys field. func (r *identityResolver) PersonalAPIKeys(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.PersonalAPIKeyConnection, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionPersonalAPIKeyList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionPersonalAPIKeyList); err != nil { + return nil, err } if gqlutils.OnlyTotalCountSelected(ctx) { @@ -148,7 +148,7 @@ func (r *identityResolver) PersonalAPIKeys(ctx context.Context, obj *types.Ident page, err := r.iam.AccountService.ListPersonalAPIKeys(ctx, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list personal api keys", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewPersonalAPIKeyConnection(page, r, obj.ID), nil @@ -161,8 +161,8 @@ func (r *identityResolver) Permission(ctx context.Context, obj *types.Identity, // Organization is the resolver for the organization field. func (r *invitationResolver) Organization(ctx context.Context, obj *types.Invitation) (*types.Organization, error) { - if ok := r.Authorize(ctx, obj.Organization.ID, iam.ActionOrganizationGet, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.Organization.ID, iam.ActionOrganizationGet); err != nil { + return nil, err } if gqlutils.OnlyIDSelected(ctx) { @@ -174,7 +174,7 @@ func (r *invitationResolver) Organization(ctx context.Context, obj *types.Invita organization, err := r.iam.OrganizationService.GetOrganizationForInvitation(ctx, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get organization for invitation", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewOrganization(organization), nil @@ -189,41 +189,43 @@ func (r *invitationResolver) Permission(ctx context.Context, obj *types.Invitati func (r *invitationConnectionResolver) TotalCount(ctx context.Context, obj *types.InvitationConnection) (*int, error) { switch obj.Resolver.(type) { case *organizationResolver: - if ok := r.Authorize(ctx, obj.ParentID, iam.ActionInvitationList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ParentID, iam.ActionInvitationList); err != nil { + return nil, err } count, err := r.iam.OrganizationService.CountInvitations(ctx, obj.ParentID, obj.Filters) if err != nil { r.logger.ErrorCtx(ctx, "cannot count invitations", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &count, nil case *identityResolver: - if ok := r.Authorize(ctx, obj.ParentID, iam.ActionInvitationList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ParentID, iam.ActionInvitationList); err != nil { + return nil, err } count, err := r.iam.AccountService.CountPendingInvitations(ctx, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count invitations", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &count, nil } r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } // Identity is the resolver for the identity field. func (r *membershipResolver) Identity(ctx context.Context, obj *types.Membership) (*types.Identity, error) { - resourceAttrs := map[string]string{ - "organization_id": obj.Organization.ID.String(), - } - if ok := r.Authorize(ctx, obj.Identity.ID, iam.ActionIdentityGet, resourceAttrs); !ok { - return nil, nil + if err := r.authorize( + ctx, + obj.Identity.ID, + iam.ActionIdentityGet, + WithAttr("organization_id", obj.Organization.ID.String()), + ); err != nil { + return nil, err } if gqlutils.OnlyIDSelected(ctx) { @@ -235,7 +237,7 @@ func (r *membershipResolver) Identity(ctx context.Context, obj *types.Membership identity, err := r.iam.AccountService.GetIdentityForMembership(ctx, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get identity for membership", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewIdentity(identity), nil @@ -243,8 +245,8 @@ func (r *membershipResolver) Identity(ctx context.Context, obj *types.Membership // Profile is the resolver for the profile field. func (r *membershipResolver) Profile(ctx context.Context, obj *types.Membership) (*types.MembershipProfile, error) { - if ok := r.Authorize(ctx, obj.Profile.ID, iam.ActionMembershipProfileGet, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.Profile.ID, iam.ActionMembershipProfileGet); err != nil { + return nil, err } if gqlutils.OnlyIDSelected(ctx) { @@ -261,7 +263,7 @@ func (r *membershipResolver) Profile(ctx context.Context, obj *types.Membership) } r.logger.ErrorCtx(ctx, "cannot get profile for membership", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewMembershipProfile(profile), nil @@ -269,8 +271,8 @@ func (r *membershipResolver) Profile(ctx context.Context, obj *types.Membership) // Organization is the resolver for the organization field. func (r *membershipResolver) Organization(ctx context.Context, obj *types.Membership) (*types.Organization, error) { - if ok := r.Authorize(ctx, obj.Organization.ID, iam.ActionOrganizationGet, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.Organization.ID, iam.ActionOrganizationGet, WithSession(nil)); err != nil { + return nil, err } if gqlutils.OnlyIDSelected(ctx) { @@ -282,7 +284,7 @@ func (r *membershipResolver) Organization(ctx context.Context, obj *types.Member organization, err := r.iam.OrganizationService.GetOrganizationForMembership(ctx, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get organization for membership", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewOrganization(organization), nil @@ -290,8 +292,8 @@ func (r *membershipResolver) Organization(ctx context.Context, obj *types.Member // LastSession is the resolver for the lastSession field. func (r *membershipResolver) LastSession(ctx context.Context, obj *types.Membership) (*types.Session, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionMembershipGet, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionMembershipGet, WithSession(nil)); err != nil { + return nil, err } session := SessionFromContext(ctx) @@ -307,7 +309,7 @@ func (r *membershipResolver) LastSession(ctx context.Context, obj *types.Members } r.logger.ErrorCtx(ctx, "cannot get active session for membership", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewSession(childSession), nil @@ -320,8 +322,8 @@ func (r *membershipResolver) Permission(ctx context.Context, obj *types.Membersh // TotalCount is the resolver for the totalCount field. func (r *membershipConnectionResolver) TotalCount(ctx context.Context, obj *types.MembershipConnection) (*int, error) { - if ok := r.Authorize(ctx, obj.ParentID, iam.ActionMembershipList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ParentID, iam.ActionMembershipList); err != nil { + return nil, err } switch obj.Resolver.(type) { @@ -329,7 +331,7 @@ func (r *membershipConnectionResolver) TotalCount(ctx context.Context, obj *type count, err := r.iam.AccountService.CountMemberships(ctx, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count memberships", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &count, nil @@ -337,14 +339,14 @@ func (r *membershipConnectionResolver) TotalCount(ctx context.Context, obj *type count, err := r.iam.OrganizationService.CountMemberships(ctx, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count memberships", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &count, nil } r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } // Permission is the resolver for the permission field. @@ -374,7 +376,7 @@ func (r *mutationResolver) SignIn(ctx context.Context, input types.SignInInput) } r.logger.ErrorCtx(ctx, "cannot sign in", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } w := HTTPResponseWriterFromContext(ctx) @@ -403,11 +405,11 @@ func (r *mutationResolver) SignUp(ctx context.Context, input types.SignUpInput) if err != nil { var errIdentityAlreadyExists *iam.ErrIdentityAlreadyExists if errors.As(err, &errIdentityAlreadyExists) { - return nil, gqlutils.Invalid(err, nil) + return nil, gqlutils.Invalid(ctx, err) } r.logger.ErrorCtx(ctx, "cannot create identity with password", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } w := HTTPResponseWriterFromContext(ctx) @@ -434,7 +436,7 @@ func (r *mutationResolver) SignOut(ctx context.Context) (*types.SignOutPayload, } r.logger.ErrorCtx(ctx, "cannot close session", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.SignOutPayload{Success: true}, nil @@ -465,15 +467,15 @@ func (r *mutationResolver) SignUpFromInvitation(ctx context.Context, input types ) if isInvalidErr { - return nil, gqlutils.Invalid(err, nil) + return nil, gqlutils.Invalid(ctx, err) } if errors.As(err, &errIdentityAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } r.logger.ErrorCtx(ctx, "cannot create identity from invitation", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } w := HTTPResponseWriterFromContext(ctx) @@ -502,7 +504,7 @@ func (r *mutationResolver) ForgotPassword(ctx context.Context, input types.Forgo ) if err != nil { r.logger.ErrorCtx(ctx, "cannot send password reset instruction by email", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.ForgotPasswordPayload{ @@ -522,11 +524,11 @@ func (r *mutationResolver) ResetPassword(ctx context.Context, input types.ResetP if err != nil { var errInvalidToken *iam.ErrInvalidToken if errors.As(err, &errInvalidToken) { - return nil, gqlutils.Invalid(err, nil) + return nil, gqlutils.Invalid(ctx, err) } r.logger.ErrorCtx(ctx, "cannot reset password", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.ResetPasswordPayload{ @@ -549,19 +551,19 @@ func (r *mutationResolver) VerifyEmail(ctx context.Context, input types.VerifyEm ) if isInvalidErr { - return nil, gqlutils.Invalid(err, nil) + return nil, gqlutils.Invalid(ctx, err) } if errors.As(err, &errEmailAlreadyVerified) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } if errors.As(err, &errIdentityNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot verify email", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.VerifyEmailPayload{ @@ -588,15 +590,15 @@ func (r *mutationResolver) ChangePassword(ctx context.Context, input types.Chang ) if errors.As(err, &errInvalidPassword) { - return nil, gqlutils.Invalid(err, nil) + return nil, gqlutils.Invalid(ctx, err) } if errors.As(err, &errIdentityNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot change password", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.ChangePasswordPayload{ @@ -623,15 +625,15 @@ func (r *mutationResolver) ChangeEmail(ctx context.Context, input types.ChangeEm ) if errors.As(err, &errInvalidPassword) { - return nil, gqlutils.Invalid(err, nil) + return nil, gqlutils.Invalid(ctx, err) } if errors.As(err, &errIdentityNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot change email", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.ChangeEmailPayload{ @@ -653,7 +655,7 @@ func (r *mutationResolver) AssumeOrganizationSession(ctx context.Context, input switch { case errors.As(err, &errMembershipNotFound): - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) case errors.As(err, &errPasswordRequired): return &types.AssumeOrganizationSessionPayload{ @@ -672,7 +674,7 @@ func (r *mutationResolver) AssumeOrganizationSession(ctx context.Context, input default: r.logger.ErrorCtx(ctx, "cannot assume organization session", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } } @@ -686,8 +688,8 @@ func (r *mutationResolver) AssumeOrganizationSession(ctx context.Context, input // RevokeSession is the resolver for the revokeSession field. func (r *mutationResolver) RevokeSession(ctx context.Context, input types.RevokeSessionInput) (*types.RevokeSessionPayload, error) { - if ok := r.Authorize(ctx, input.SessionID, iam.ActionSessionRevoke, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.SessionID, iam.ActionSessionRevoke); err != nil { + return nil, err } identity := IdentityFromContext(ctx) @@ -700,7 +702,7 @@ func (r *mutationResolver) RevokeSession(ctx context.Context, input types.Revoke } r.logger.ErrorCtx(ctx, "cannot revoke session", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.RevokeSessionPayload{Success: true}, nil @@ -708,8 +710,8 @@ func (r *mutationResolver) RevokeSession(ctx context.Context, input types.Revoke // RevokeAllSessions is the resolver for the revokeAllSessions field. func (r *mutationResolver) RevokeAllSessions(ctx context.Context) (*types.RevokeAllSessionsPayload, error) { - if ok := r.Authorize(ctx, SessionFromContext(ctx).ID, iam.ActionSessionRevokeAll, nil); !ok { - return nil, nil + if err := r.authorize(ctx, SessionFromContext(ctx).ID, iam.ActionSessionRevokeAll); err != nil { + return nil, err } session := SessionFromContext(ctx) @@ -717,7 +719,7 @@ func (r *mutationResolver) RevokeAllSessions(ctx context.Context) (*types.Revoke revokedCount, err := r.iam.SessionService.RevokeAllSessions(ctx, session.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot revoke all sessions", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.RevokeAllSessionsPayload{RevokedCount: int(revokedCount)}, nil @@ -727,8 +729,8 @@ func (r *mutationResolver) RevokeAllSessions(ctx context.Context) (*types.Revoke func (r *mutationResolver) CreatePersonalAPIKey(ctx context.Context, input types.CreatePersonalAPIKeyInput) (*types.CreatePersonalAPIKeyPayload, error) { identity := IdentityFromContext(ctx) - if ok := r.Authorize(ctx, identity.ID, iam.ActionPersonalAPIKeyCreate, nil); !ok { - return nil, nil + if err := r.authorize(ctx, identity.ID, iam.ActionPersonalAPIKeyCreate); err != nil { + return nil, err } userAPIKey, token, err := r.iam.AccountService.CreatePersonalAPIKey( @@ -739,7 +741,7 @@ func (r *mutationResolver) CreatePersonalAPIKey(ctx context.Context, input types ) if err != nil { r.logger.ErrorCtx(ctx, "cannot create personal api key", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.CreatePersonalAPIKeyPayload{ @@ -750,8 +752,8 @@ func (r *mutationResolver) CreatePersonalAPIKey(ctx context.Context, input types // RevokePersonalAPIKey is the resolver for the revokePersonalAPIKey field. func (r *mutationResolver) RevokePersonalAPIKey(ctx context.Context, input types.RevokePersonalAPIKeyInput) (*types.RevokePersonalAPIKeyPayload, error) { - if ok := r.Authorize(ctx, input.PersonalAPIKeyID, iam.ActionPersonalAPIKeyDelete, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.PersonalAPIKeyID, iam.ActionPersonalAPIKeyDelete); err != nil { + return nil, err } identity := IdentityFromContext(ctx) @@ -759,7 +761,7 @@ func (r *mutationResolver) RevokePersonalAPIKey(ctx context.Context, input types err := r.iam.AccountService.DeletePersonalAPIKey(ctx, identity.ID, input.PersonalAPIKeyID) if err != nil { r.logger.ErrorCtx(ctx, "cannot delete personal api key", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.RevokePersonalAPIKeyPayload{PersonalAPIKeyID: input.PersonalAPIKeyID}, nil @@ -770,7 +772,7 @@ func (r *mutationResolver) CreateOrganization(ctx context.Context, input types.C identity := IdentityFromContext(ctx) // FIXME check email domain and related IDP config - // if ok := r.Authorize(ctx, identity.ID, iam.ActionOrganizationCreate,nil); !ok { + // if ok := r.authorize(ctx, identity.ID, iam.ActionOrganizationCreate); !ok { // return nil, nil // } @@ -807,7 +809,7 @@ func (r *mutationResolver) CreateOrganization(ctx context.Context, input types.C ) if err != nil { r.logger.ErrorCtx(ctx, "cannot create organization", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.CreateOrganizationPayload{ @@ -817,8 +819,8 @@ func (r *mutationResolver) CreateOrganization(ctx context.Context, input types.C // UpdateOrganization is the resolver for the updateOrganization field. func (r *mutationResolver) UpdateOrganization(ctx context.Context, input types.UpdateOrganizationInput) (*types.UpdateOrganizationPayload, error) { - if ok := r.Authorize(ctx, input.OrganizationID, iam.ActionOrganizationUpdate, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.OrganizationID, iam.ActionOrganizationUpdate); err != nil { + return nil, err } req := &iam.UpdateOrganizationRequest{ @@ -854,7 +856,7 @@ func (r *mutationResolver) UpdateOrganization(ctx context.Context, input types.U ) if err != nil { r.logger.ErrorCtx(ctx, "cannot update organization", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.UpdateOrganizationPayload{ @@ -873,14 +875,14 @@ func (r *mutationResolver) UpdateOrganization(ctx context.Context, input types.U // DeleteOrganization is the resolver for the deleteOrganization field. func (r *mutationResolver) DeleteOrganization(ctx context.Context, input types.DeleteOrganizationInput) (*types.DeleteOrganizationPayload, error) { - if ok := r.Authorize(ctx, input.OrganizationID, iam.ActionOrganizationDelete, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.OrganizationID, iam.ActionOrganizationDelete); err != nil { + return nil, err } err := r.iam.OrganizationService.DeleteOrganization(ctx, input.OrganizationID) if err != nil { r.logger.ErrorCtx(ctx, "cannot delete organization", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.DeleteOrganizationPayload{DeletedOrganizationID: input.OrganizationID}, nil @@ -893,8 +895,8 @@ func (r *mutationResolver) DeleteOrganizationHorizontalLogo(ctx context.Context, // InviteMember is the resolver for the inviteMember field. func (r *mutationResolver) InviteMember(ctx context.Context, input types.InviteMemberInput) (*types.InviteMemberPayload, error) { - if ok := r.Authorize(ctx, input.OrganizationID, iam.ActionInvitationCreate, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.OrganizationID, iam.ActionInvitationCreate); err != nil { + return nil, err } invitation, err := r.iam.OrganizationService.InviteMember( @@ -911,15 +913,15 @@ func (r *mutationResolver) InviteMember(ctx context.Context, input types.InviteM var errMembershipAlreadyExists *iam.ErrMembershipAlreadyExists if errors.As(err, &errOrganizationNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } if errors.As(err, &errMembershipAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } r.logger.ErrorCtx(ctx, "cannot add member to organization", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.InviteMemberPayload{ @@ -929,8 +931,8 @@ func (r *mutationResolver) InviteMember(ctx context.Context, input types.InviteM // DeleteInvitation is the resolver for the deleteInvitation field. func (r *mutationResolver) DeleteInvitation(ctx context.Context, input types.DeleteInvitationInput) (*types.DeleteInvitationPayload, error) { - if ok := r.Authorize(ctx, input.OrganizationID, iam.ActionInvitationDelete, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.OrganizationID, iam.ActionInvitationDelete); err != nil { + return nil, err } err := r.iam.OrganizationService.DeleteInvitation(ctx, input.OrganizationID, input.InvitationID) @@ -939,15 +941,15 @@ func (r *mutationResolver) DeleteInvitation(ctx context.Context, input types.Del var errInvitationNotDeleted *iam.ErrInvitationNotDeleted if errors.As(err, &errInvitationNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } if errors.As(err, &errInvitationNotDeleted) { - return nil, gqlutils.Invalid(err, nil) + return nil, gqlutils.Invalid(ctx, err) } r.logger.ErrorCtx(ctx, "cannot delete invitation", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.DeleteInvitationPayload{DeletedInvitationID: input.InvitationID}, nil @@ -955,14 +957,14 @@ func (r *mutationResolver) DeleteInvitation(ctx context.Context, input types.Del // UpdateMembership is the resolver for the updateMembership field. func (r *mutationResolver) UpdateMembership(ctx context.Context, input types.UpdateMembershipInput) (*types.UpdateMembershipPayload, error) { - if ok := r.Authorize(ctx, input.MembershipID, iam.ActionMembershipUpdate, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.MembershipID, iam.ActionMembershipUpdate); err != nil { + return nil, err } membership, err := r.iam.OrganizationService.UpdateMempership(ctx, input.OrganizationID, input.MembershipID, input.Role) if err != nil { r.logger.ErrorCtx(ctx, "cannot update membership", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.UpdateMembershipPayload{ @@ -972,8 +974,8 @@ func (r *mutationResolver) UpdateMembership(ctx context.Context, input types.Upd // RemoveMember is the resolver for the removeMember field. func (r *mutationResolver) RemoveMember(ctx context.Context, input types.RemoveMemberInput) (*types.RemoveMemberPayload, error) { - if ok := r.Authorize(ctx, input.MembershipID, iam.ActionMembershipDelete, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.MembershipID, iam.ActionMembershipDelete); err != nil { + return nil, err } err := r.iam.OrganizationService.RemoveMember(ctx, input.OrganizationID, input.MembershipID) @@ -982,15 +984,15 @@ func (r *mutationResolver) RemoveMember(ctx context.Context, input types.RemoveM var errLastActiveOwner *iam.ErrLastActiveOwner if errors.As(err, &errManagedBySCIM) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } if errors.As(err, &errLastActiveOwner) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } r.logger.ErrorCtx(ctx, "cannot remove member from organization", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.RemoveMemberPayload{DeletedMembershipID: input.MembershipID}, nil @@ -998,8 +1000,8 @@ func (r *mutationResolver) RemoveMember(ctx context.Context, input types.RemoveM // AcceptInvitation is the resolver for the acceptInvitation field. func (r *mutationResolver) AcceptInvitation(ctx context.Context, input types.AcceptInvitationInput) (*types.AcceptInvitationPayload, error) { - if ok := r.Authorize(ctx, input.InvitationID, iam.ActionInvitationAccept, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.InvitationID, iam.ActionInvitationAccept); err != nil { + return nil, err } identity := IdentityFromContext(ctx) @@ -1007,7 +1009,7 @@ func (r *mutationResolver) AcceptInvitation(ctx context.Context, input types.Acc membership, err := r.iam.AccountService.AcceptInvitation(ctx, identity.ID, input.InvitationID) if err != nil { r.logger.ErrorCtx(ctx, "cannot accept invitation", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.AcceptInvitationPayload{ @@ -1017,8 +1019,8 @@ func (r *mutationResolver) AcceptInvitation(ctx context.Context, input types.Acc // CreateSAMLConfiguration is the resolver for the createSAMLConfiguration field. func (r *mutationResolver) CreateSAMLConfiguration(ctx context.Context, input types.CreateSAMLConfigurationInput) (*types.CreateSAMLConfigurationPayload, error) { - if ok := r.Authorize(ctx, input.OrganizationID, iam.ActionSAMLConfigurationCreate, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.OrganizationID, iam.ActionSAMLConfigurationCreate); err != nil { + return nil, err } req := &iam.CreateSAMLConfigurationRequest{ @@ -1045,11 +1047,11 @@ func (r *mutationResolver) CreateSAMLConfiguration(ctx context.Context, input ty if err != nil { var errSAMLConfigurationEmailDomainAlreadyExists *iam.ErrSAMLConfigurationEmailDomainAlreadyExists if errors.As(err, &errSAMLConfigurationEmailDomainAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } r.logger.ErrorCtx(ctx, "cannot create saml configuration", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.CreateSAMLConfigurationPayload{ @@ -1062,8 +1064,8 @@ func (r *mutationResolver) CreateSAMLConfiguration(ctx context.Context, input ty // UpdateSAMLConfiguration is the resolver for the updateSAMLConfiguration field. func (r *mutationResolver) UpdateSAMLConfiguration(ctx context.Context, input types.UpdateSAMLConfigurationInput) (*types.UpdateSAMLConfigurationPayload, error) { - if ok := r.Authorize(ctx, input.SamlConfigurationID, iam.ActionSAMLConfigurationUpdate, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.SamlConfigurationID, iam.ActionSAMLConfigurationUpdate); err != nil { + return nil, err } req := &iam.UpdateSAMLConfigurationRequest{ @@ -1089,7 +1091,7 @@ func (r *mutationResolver) UpdateSAMLConfiguration(ctx context.Context, input ty ) if err != nil { r.logger.ErrorCtx(ctx, "cannot update saml configuration", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.UpdateSAMLConfigurationPayload{ @@ -1099,14 +1101,14 @@ func (r *mutationResolver) UpdateSAMLConfiguration(ctx context.Context, input ty // DeleteSAMLConfiguration is the resolver for the deleteSAMLConfiguration field. func (r *mutationResolver) DeleteSAMLConfiguration(ctx context.Context, input types.DeleteSAMLConfigurationInput) (*types.DeleteSAMLConfigurationPayload, error) { - if ok := r.Authorize(ctx, input.OrganizationID, iam.ActionSAMLConfigurationDelete, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.OrganizationID, iam.ActionSAMLConfigurationDelete); err != nil { + return nil, err } err := r.iam.OrganizationService.DeleteSAMLConfiguration(ctx, input.OrganizationID, input.SamlConfigurationID) if err != nil { r.logger.ErrorCtx(ctx, "cannot delete saml configuration", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.DeleteSAMLConfigurationPayload{DeletedSamlConfigurationID: input.SamlConfigurationID}, nil @@ -1114,14 +1116,14 @@ func (r *mutationResolver) DeleteSAMLConfiguration(ctx context.Context, input ty // CreateSCIMConfiguration is the resolver for the createSCIMConfiguration field. func (r *mutationResolver) CreateSCIMConfiguration(ctx context.Context, input types.CreateSCIMConfigurationInput) (*types.CreateSCIMConfigurationPayload, error) { - if ok := r.Authorize(ctx, input.OrganizationID, iam.ActionSCIMConfigurationCreate, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.OrganizationID, iam.ActionSCIMConfigurationCreate); err != nil { + return nil, err } config, token, err := r.iam.OrganizationService.CreateSCIMConfiguration(ctx, input.OrganizationID) if err != nil { r.logger.ErrorCtx(ctx, "cannot create scim configuration", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.CreateSCIMConfigurationPayload{ @@ -1132,14 +1134,14 @@ func (r *mutationResolver) CreateSCIMConfiguration(ctx context.Context, input ty // DeleteSCIMConfiguration is the resolver for the deleteSCIMConfiguration field. func (r *mutationResolver) DeleteSCIMConfiguration(ctx context.Context, input types.DeleteSCIMConfigurationInput) (*types.DeleteSCIMConfigurationPayload, error) { - if ok := r.Authorize(ctx, input.OrganizationID, iam.ActionSCIMConfigurationDelete, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.OrganizationID, iam.ActionSCIMConfigurationDelete); err != nil { + return nil, err } err := r.iam.OrganizationService.DeleteSCIMConfiguration(ctx, input.OrganizationID, input.ScimConfigurationID) if err != nil { r.logger.ErrorCtx(ctx, "cannot delete scim configuration", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.DeleteSCIMConfigurationPayload{DeletedScimConfigurationID: input.ScimConfigurationID}, nil @@ -1147,14 +1149,14 @@ func (r *mutationResolver) DeleteSCIMConfiguration(ctx context.Context, input ty // RegenerateSCIMToken is the resolver for the regenerateSCIMToken field. func (r *mutationResolver) RegenerateSCIMToken(ctx context.Context, input types.RegenerateSCIMTokenInput) (*types.RegenerateSCIMTokenPayload, error) { - if ok := r.Authorize(ctx, input.ScimConfigurationID, iam.ActionSCIMConfigurationUpdate, nil); !ok { - return nil, nil + if err := r.authorize(ctx, input.ScimConfigurationID, iam.ActionSCIMConfigurationUpdate); err != nil { + return nil, err } config, token, err := r.iam.OrganizationService.RegenerateSCIMToken(ctx, input.OrganizationID, input.ScimConfigurationID) if err != nil { r.logger.ErrorCtx(ctx, "cannot regenerate scim token", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &types.RegenerateSCIMTokenPayload{ @@ -1165,14 +1167,14 @@ func (r *mutationResolver) RegenerateSCIMToken(ctx context.Context, input types. // LogoURL is the resolver for the logoUrl field. func (r *organizationResolver) LogoURL(ctx context.Context, obj *types.Organization) (*string, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionOrganizationGet, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionOrganizationGet, WithSession(nil)); err != nil { + return nil, err } presignedURL, err := r.iam.OrganizationService.GenerateLogoURL(ctx, obj.ID, 1*time.Hour) if err != nil { r.logger.ErrorCtx(ctx, "cannot generate logo URL", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return presignedURL, nil @@ -1180,14 +1182,14 @@ func (r *organizationResolver) LogoURL(ctx context.Context, obj *types.Organizat // HorizontalLogoURL is the resolver for the horizontalLogoUrl field. func (r *organizationResolver) HorizontalLogoURL(ctx context.Context, obj *types.Organization) (*string, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionOrganizationGet, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionOrganizationGet); err != nil { + return nil, err } presignedURL, err := r.iam.OrganizationService.GenerateHorizontalLogoURL(ctx, obj.ID, 1*time.Hour) if err != nil { r.logger.ErrorCtx(ctx, "cannot generate horizontal logo URL", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return presignedURL, nil @@ -1195,8 +1197,8 @@ func (r *organizationResolver) HorizontalLogoURL(ctx context.Context, obj *types // Members is the resolver for the members field. func (r *organizationResolver) Members(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MembershipOrderBy) (*types.MembershipConnection, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionMembershipList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionMembershipList); err != nil { + return nil, err } if gqlutils.OnlyTotalCountSelected(ctx) { @@ -1220,7 +1222,7 @@ func (r *organizationResolver) Members(ctx context.Context, obj *types.Organizat page, err := r.iam.OrganizationService.ListMembers(ctx, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list memberships", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewMembershipConnection(page, r, obj.ID), nil @@ -1228,8 +1230,8 @@ func (r *organizationResolver) Members(ctx context.Context, obj *types.Organizat // Invitations is the resolver for the invitations field. func (r *organizationResolver) Invitations(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, status *coredata.InvitationStatus, orderBy *types.InvitationOrderBy) (*types.InvitationConnection, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionInvitationList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionInvitationList); err != nil { + return nil, err } filters := coredata.NewInvitationFilter(nil) @@ -1261,7 +1263,7 @@ func (r *organizationResolver) Invitations(ctx context.Context, obj *types.Organ page, err := r.iam.OrganizationService.ListInvitations(ctx, obj.ID, cursor, filters) if err != nil { r.logger.ErrorCtx(ctx, "cannot list invitations", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewInvitationConnection(page, r, obj.ID, filters), nil @@ -1269,8 +1271,8 @@ func (r *organizationResolver) Invitations(ctx context.Context, obj *types.Organ // SamlConfigurations is the resolver for the samlConfigurations field. func (r *organizationResolver) SamlConfigurations(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.SAMLConfigurationConnection, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionSAMLConfigurationList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionSAMLConfigurationList); err != nil { + return nil, err } if gqlutils.OnlyTotalCountSelected(ctx) { @@ -1290,7 +1292,7 @@ func (r *organizationResolver) SamlConfigurations(ctx context.Context, obj *type page, err := r.iam.OrganizationService.ListSAMLConfigurations(ctx, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list saml configurations", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewSAMLConfigurationConnection(page, r, obj.ID), nil @@ -1298,8 +1300,8 @@ func (r *organizationResolver) SamlConfigurations(ctx context.Context, obj *type // ScimConfiguration is the resolver for the scimConfiguration field. func (r *organizationResolver) ScimConfiguration(ctx context.Context, obj *types.Organization) (*types.SCIMConfiguration, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionSCIMConfigurationGet, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionSCIMConfigurationGet); err != nil { + return nil, err } config, err := r.iam.OrganizationService.GetSCIMConfiguration(ctx, obj.ID) @@ -1310,7 +1312,7 @@ func (r *organizationResolver) ScimConfiguration(ctx context.Context, obj *types } r.logger.ErrorCtx(ctx, "cannot get scim configuration", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewSCIMConfiguration(config), nil @@ -1318,8 +1320,8 @@ func (r *organizationResolver) ScimConfiguration(ctx context.Context, obj *types // ViewerMembership is the resolver for the viewerMembership field. func (r *organizationResolver) ViewerMembership(ctx context.Context, obj *types.Organization) (*types.Membership, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionMembershipList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionMembershipGet, WithSession(nil)); err != nil { + return nil, err } identity := IdentityFromContext(ctx) @@ -1327,7 +1329,7 @@ func (r *organizationResolver) ViewerMembership(ctx context.Context, obj *types. membership, err := r.iam.AccountService.GetMembershipForOrganization(ctx, identity.ID, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get membership for organization", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewMembership(membership), nil @@ -1340,8 +1342,8 @@ func (r *organizationResolver) Permission(ctx context.Context, obj *types.Organi // Token is the resolver for the token field. func (r *personalAPIKeyResolver) Token(ctx context.Context, obj *types.PersonalAPIKey) (*string, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionPersonalAPIKeyGet, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionPersonalAPIKeyGet); err != nil { + return nil, err } identity := IdentityFromContext(ctx) @@ -1349,7 +1351,7 @@ func (r *personalAPIKeyResolver) Token(ctx context.Context, obj *types.PersonalA token, err := r.iam.AccountService.RevealPersonalAPIKeyToken(ctx, identity.ID, obj.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot reveal personal api key token", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &token, nil @@ -1364,28 +1366,27 @@ func (r *personalAPIKeyResolver) Permission(ctx context.Context, obj *types.Pers func (r *personalAPIKeyConnectionResolver) TotalCount(ctx context.Context, obj *types.PersonalAPIKeyConnection) (*int, error) { switch obj.Resolver.(type) { case *identityResolver: - if ok := r.Authorize(ctx, obj.ParentID, iam.ActionPersonalAPIKeyList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ParentID, iam.ActionPersonalAPIKeyList); err != nil { + return nil, err } count, err := r.iam.AccountService.CountPersonalAPIKeys(ctx, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count personal api keys", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &count, nil } r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } // Node is the resolver for the node field. func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error) { var ( loadNode func(ctx context.Context, id gid.GID) (types.Node, error) - user = IdentityFromContext(ctx) action string ) @@ -1480,23 +1481,8 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error return nil, fmt.Errorf("unsupported entity type: %d", id.EntityType()) } - err := r.iam.Authorizer.Authorize( - ctx, - iam.AuthorizeParams{ - Principal: user.ID, - Resource: id, - Action: action, - ResourceAttributes: map[string]string{}, - }, - ) - if err != nil { - var errInsufficientPermissions *iam.ErrInsufficientPermissions - if errors.As(err, &errInsufficientPermissions) { - return nil, gqlutils.Forbidden(err) - } - - r.logger.ErrorCtx(ctx, "cannot authorize", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + if err := r.authorize(ctx, id, action); err != nil { + return nil, err } node, err := loadNode(ctx, id) @@ -1516,11 +1502,11 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error ) if isNotFoundErr { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot load node", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return node, nil @@ -1545,33 +1531,27 @@ func (r *queryResolver) SsoLoginURL(ctx context.Context, email mail.Addr) (*stri count, err := r.iam.AccountService.CountSAMLConfigurationsForEmail(ctx, email) if err != nil { r.logger.ErrorCtx(ctx, "cannot count SAML configurations for email", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } if count != 1 { if count == 0 { - graphql.AddError(ctx, graphql.ErrorOnPath( + return nil, graphql.ErrorOnPath( ctx, fmt.Errorf("no SAML configuration for email"), - )) - - return nil, nil + ) } - graphql.AddError( + return nil, graphql.ErrorOnPath( ctx, - graphql.ErrorOnPath( - ctx, - fmt.Errorf("multiple SSO configurations found for this domain. Please use your organization-specific SSO login URL"), - ), + fmt.Errorf("multiple SSO configurations found for this domain. Please use your organization-specific SSO login URL"), ) - return nil, nil } samlConfigs, err := r.iam.AccountService.ListSAMLConfigurationsForEmail(ctx, email) if err != nil { r.logger.ErrorCtx(ctx, "cannot list SAML configurations for email", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } samlConfig := samlConfigs[0] @@ -1596,13 +1576,13 @@ func (r *sAMLConfigurationConnectionResolver) TotalCount(ctx context.Context, ob count, err := r.iam.OrganizationService.CountSAMLConfigurations(ctx, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count saml configurations", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &count, nil } r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } // EndpointURL is the resolver for the endpointUrl field. @@ -1612,8 +1592,8 @@ func (r *sCIMConfigurationResolver) EndpointURL(ctx context.Context, obj *types. // Organization is the resolver for the organization field. func (r *sCIMConfigurationResolver) Organization(ctx context.Context, obj *types.SCIMConfiguration) (*types.Organization, error) { - if ok := r.Authorize(ctx, obj.Organization.ID, iam.ActionOrganizationGet, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.Organization.ID, iam.ActionOrganizationGet); err != nil { + return nil, err } if gqlutils.OnlyIDSelected(ctx) { @@ -1630,7 +1610,7 @@ func (r *sCIMConfigurationResolver) Organization(ctx context.Context, obj *types } r.logger.ErrorCtx(ctx, "cannot get organization for scim configuration", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewOrganization(organization), nil @@ -1638,8 +1618,8 @@ func (r *sCIMConfigurationResolver) Organization(ctx context.Context, obj *types // Events is the resolver for the events field. func (r *sCIMConfigurationResolver) Events(ctx context.Context, obj *types.SCIMConfiguration, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SCIMEventOrderBy) (*types.SCIMEventConnection, error) { - if ok := r.Authorize(ctx, obj.ID, iam.ActionSCIMEventList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ID, iam.ActionSCIMEventList); err != nil { + return nil, err } pageOrderBy := page.OrderBy[coredata.SCIMEventOrderField]{ @@ -1656,7 +1636,7 @@ func (r *sCIMConfigurationResolver) Events(ctx context.Context, obj *types.SCIMC events, err := r.iam.OrganizationService.ListSCIMEventsByConfigID(ctx, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list scim events", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewSCIMEventConnection(events, r, obj.ID), nil @@ -1673,8 +1653,8 @@ func (r *sCIMEventResolver) Membership(ctx context.Context, obj *types.SCIMEvent return nil, nil } - if ok := r.Authorize(ctx, obj.Membership.ID, iam.ActionMembershipGet, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.Membership.ID, iam.ActionMembershipGet); err != nil { + return nil, err } if gqlutils.OnlyIDSelected(ctx) { @@ -1691,7 +1671,7 @@ func (r *sCIMEventResolver) Membership(ctx context.Context, obj *types.SCIMEvent } r.logger.ErrorCtx(ctx, "cannot get membership for scim event", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewMembership(membership), nil @@ -1704,8 +1684,8 @@ func (r *sCIMEventResolver) Permission(ctx context.Context, obj *types.SCIMEvent // TotalCount is the resolver for the totalCount field. func (r *sCIMEventConnectionResolver) TotalCount(ctx context.Context, obj *types.SCIMEventConnection) (*int, error) { - if ok := r.Authorize(ctx, obj.ParentID, iam.ActionSCIMEventList, nil); !ok { - return nil, nil + if err := r.authorize(ctx, obj.ParentID, iam.ActionSCIMEventList); err != nil { + return nil, err } switch obj.Resolver.(type) { @@ -1713,13 +1693,13 @@ func (r *sCIMEventConnectionResolver) TotalCount(ctx context.Context, obj *types count, err := r.iam.OrganizationService.CountSCIMEvents(ctx, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count scim events", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &count, nil } r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } // Identity is the resolver for the identity field. @@ -1733,7 +1713,7 @@ func (r *sessionResolver) Identity(ctx context.Context, obj *types.Session) (*ty identity, err := r.iam.AccountService.GetIdentity(ctx, obj.Identity.ID) if err != nil { r.logger.ErrorCtx(ctx, "cannot get identity for session", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return types.NewIdentity(identity), nil @@ -1751,14 +1731,14 @@ func (r *sessionConnectionResolver) TotalCount(ctx context.Context, obj *types.S count, err := r.iam.AccountService.CountSessions(ctx, obj.ParentID) if err != nil { r.logger.ErrorCtx(ctx, "cannot count sessions", log.Error(err)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } return &count, nil } r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver)) - return nil, gqlutils.InternalServerError(ctx) + return nil, gqlutils.Internal(ctx) } // Identity returns schema.IdentityResolver implementation. diff --git a/pkg/server/api/console/v1/graphql_handler.go b/pkg/server/api/console/v1/graphql_handler.go new file mode 100644 index 000000000..4de50f234 --- /dev/null +++ b/pkg/server/api/console/v1/graphql_handler.go @@ -0,0 +1,41 @@ +// Copyright (c) 2025 Probo Inc . +// +// 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 console_v1 + +import ( + "net/http" + + "go.gearno.de/kit/log" + "go.probo.inc/probo/pkg/iam" + "go.probo.inc/probo/pkg/probo" + connect_v1 "go.probo.inc/probo/pkg/server/api/connect/v1" + "go.probo.inc/probo/pkg/server/api/console/v1/schema" + "go.probo.inc/probo/pkg/server/gqlutils" +) + +func NewGraphQLHandler(iamSvc *iam.Service, proboSvc *probo.Service, customDomainCname string, logger *log.Logger) http.Handler { + config := schema.Config{ + Resolvers: &Resolver{ + authorize: connect_v1.NewAuthorizeFunc(iamSvc, logger), + probo: proboSvc, + iam: iamSvc, + customDomainCname: customDomainCname, + }, + } + + es := schema.NewExecutableSchema(config) + gqlh := gqlutils.NewHandler(es, logger) + return gqlh +} diff --git a/pkg/server/api/console/v1/resolver.go b/pkg/server/api/console/v1/resolver.go index 2462bf7cc..597b61f1e 100644 --- a/pkg/server/api/console/v1/resolver.go +++ b/pkg/server/api/console/v1/resolver.go @@ -19,14 +19,11 @@ package console_v1 import ( "context" "encoding/json" - "errors" "fmt" "net/http" "strings" - "github.com/99designs/gqlgen/graphql" "github.com/go-chi/chi/v5" - "github.com/vektah/gqlparser/v2/gqlerror" "go.gearno.de/crypto/uuid" "go.gearno.de/kit/httpserver" "go.gearno.de/kit/log" @@ -39,36 +36,19 @@ import ( "go.probo.inc/probo/pkg/saferedirect" "go.probo.inc/probo/pkg/securecookie" connect_v1 "go.probo.inc/probo/pkg/server/api/connect/v1" - "go.probo.inc/probo/pkg/server/api/console/v1/schema" "go.probo.inc/probo/pkg/server/api/console/v1/types" - "go.probo.inc/probo/pkg/server/gqlutils" "go.probo.inc/probo/pkg/statelesstoken" ) type ( Resolver struct { + authorize connect_v1.AuthorizeFunc probo *probo.Service iam *iam.Service customDomainCname string } ) -func ensureAuthenticated(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { - identity := connect_v1.IdentityFromContext(ctx) - - if identity == nil { - return func(ctx context.Context) *graphql.Response { - return &graphql.Response{ - Errors: gqlerror.List{ - gqlutils.Unauthorized(), - }, - } - } - } - - return next(ctx) -} - func NewMux( logger *log.Logger, proboSvc *probo.Service, @@ -85,19 +65,11 @@ func NewMux( r.Use(connect_v1.NewSessionMiddleware(iamSvc, cookieConfig)) r.Use(connect_v1.NewAPIKeyMiddleware(iamSvc, tokenSecret)) + r.Use(connect_v1.NewIdentityPresenceMiddleware()) - config := schema.Config{ - Resolvers: &Resolver{ - probo: proboSvc, - iam: iamSvc, - customDomainCname: customDomainCname, - }, - } - es := schema.NewExecutableSchema(config) - h := gqlutils.NewHandler(es, logger) - h.AroundOperations(ensureAuthenticated) + graphqlHandler := NewGraphQLHandler(iamSvc, proboSvc, customDomainCname, logger) - r.Handle("/graphql", h) + r.Handle("/graphql", graphqlHandler) r.Get( "/documents/signing-requests", @@ -238,10 +210,16 @@ func NewMux( httpserver.RenderError(w, http.StatusUnauthorized, fmt.Errorf("authentication required")) return } + session := connect_v1.SessionFromContext(r.Context()) + if session == nil { + httpserver.RenderError(w, http.StatusUnauthorized, fmt.Errorf("authentication required")) + return + } if err := iamSvc.Authorizer.Authorize(r.Context(), iam.AuthorizeParams{ Principal: identity.ID, Resource: organizationID, + Session: &session.ID, Action: probo.ActionConnectorInitiate, }); err != nil { httpserver.RenderError(w, http.StatusForbidden, err) @@ -317,42 +295,6 @@ func (r *Resolver) ProboService(ctx context.Context, tenantID gid.TenantID) *pro return r.probo.WithTenant(tenantID) } -func (r *Resolver) MustAuthorize(ctx context.Context, entityID gid.GID, action iam.Action) { - identity := connect_v1.IdentityFromContext(ctx) - - err := r.iam.Authorizer.Authorize( - ctx, - iam.AuthorizeParams{ - Principal: identity.ID, - Resource: entityID, - Action: action, - }, - ) - if err != nil { - panic(err) - } -} - func (r *Resolver) Permission(ctx context.Context, obj types.Node, action string) (bool, error) { - identity := connect_v1.IdentityFromContext(ctx) - - err := r.iam.Authorizer.Authorize( - ctx, - iam.AuthorizeParams{ - Principal: identity.ID, - Resource: obj.GetID(), - Action: action, - }, - ) - - if err != nil { - var errInsufficientPermissions *iam.ErrInsufficientPermissions - if errors.As(err, &errInsufficientPermissions) { - return false, nil - } - - panic(fmt.Errorf("cannot authorize: %w", err)) - } - - return true, nil + return r.authorize(ctx, obj.GetID(), action) == nil, nil } diff --git a/pkg/server/api/console/v1/v1_resolver.go b/pkg/server/api/console/v1/v1_resolver.go index ca7f76f67..3798cee7c 100644 --- a/pkg/server/api/console/v1/v1_resolver.go +++ b/pkg/server/api/console/v1/v1_resolver.go @@ -27,14 +27,16 @@ import ( // Owner is the resolver for the owner field. func (r *assetResolver) Owner(ctx context.Context, obj *types.Asset) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleGet) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) owner, err := prb.Peoples.Get(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get owner: %w", err)) @@ -45,7 +47,9 @@ func (r *assetResolver) Owner(ctx context.Context, obj *types.Asset) (*types.Peo // Vendors is the resolver for the vendors field. func (r *assetResolver) Vendors(ctx context.Context, obj *types.Asset, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) (*types.VendorConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorList) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -72,7 +76,9 @@ func (r *assetResolver) Vendors(ctx context.Context, obj *types.Asset, first *in // Organization is the resolver for the organization field. func (r *assetResolver) Organization(ctx context.Context, obj *types.Asset) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -85,7 +91,7 @@ func (r *assetResolver) Organization(ctx context.Context, obj *types.Asset) (*ty org, err := prb.Organizations.Get(ctx, asset.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) @@ -101,7 +107,9 @@ func (r *assetResolver) Permission(ctx context.Context, obj *types.Asset, action // TotalCount is the resolver for the totalCount field. func (r *assetConnectionResolver) TotalCount(ctx context.Context, obj *types.AssetConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionAssetList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionAssetList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -124,14 +132,16 @@ func (r *assetConnectionResolver) TotalCount(ctx context.Context, obj *types.Ass // Organization is the resolver for the organization field. func (r *auditResolver) Organization(ctx context.Context, obj *types.Audit) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load organization: %w", err)) @@ -142,14 +152,16 @@ func (r *auditResolver) Organization(ctx context.Context, obj *types.Audit) (*ty // Framework is the resolver for the framework field. func (r *auditResolver) Framework(ctx context.Context, obj *types.Audit) (*types.Framework, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionFrameworkGet) + if err := r.authorize(ctx, obj.ID, probo.ActionFrameworkGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) framework, err := prb.Frameworks.Get(ctx, obj.Framework.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load framework: %w", err)) @@ -160,7 +172,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) { - r.MustAuthorize(ctx, obj.ID, probo.ActionReportGet) + if err := r.authorize(ctx, obj.ID, probo.ActionReportGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -179,7 +193,9 @@ func (r *auditResolver) Report(ctx context.Context, obj *types.Audit) (*types.Re // ReportURL is the resolver for the reportUrl field. func (r *auditResolver) ReportURL(ctx context.Context, obj *types.Audit) (*string, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionReportGetReportUrl) + if err := r.authorize(ctx, obj.ID, probo.ActionReportGetReportUrl); err != nil { + return nil, err + } if obj.Report == nil { return nil, nil @@ -197,7 +213,9 @@ func (r *auditResolver) ReportURL(ctx context.Context, obj *types.Audit) (*strin // Controls is the resolver for the controls field. func (r *auditResolver) Controls(ctx context.Context, obj *types.Audit, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionControlList) + if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -234,7 +252,9 @@ func (r *auditResolver) Permission(ctx context.Context, obj *types.Audit, action // TotalCount is the resolver for the totalCount field. func (r *auditConnectionResolver) TotalCount(ctx context.Context, obj *types.AuditConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionAuditList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionAuditList); err != nil { + return 0, err + } // TODO missing switch case @@ -249,14 +269,16 @@ func (r *auditConnectionResolver) TotalCount(ctx context.Context, obj *types.Aud // Organization is the resolver for the organization field. func (r *continualImprovementResolver) Organization(ctx context.Context, obj *types.ContinualImprovement) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get continual improvement organization: %w", err)) @@ -267,14 +289,16 @@ func (r *continualImprovementResolver) Organization(ctx context.Context, obj *ty // Owner is the resolver for the owner field. func (r *continualImprovementResolver) Owner(ctx context.Context, obj *types.ContinualImprovement) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleGet) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) people, err := prb.Peoples.Get(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get continual improvement owner: %w", err)) @@ -290,7 +314,9 @@ func (r *continualImprovementResolver) Permission(ctx context.Context, obj *type // TotalCount is the resolver for the totalCount field. func (r *continualImprovementConnectionResolver) TotalCount(ctx context.Context, obj *types.ContinualImprovementConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionContinualImprovementList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionContinualImprovementList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -314,14 +340,16 @@ func (r *continualImprovementConnectionResolver) TotalCount(ctx context.Context, // Organization is the resolver for the organization field. func (r *controlResolver) Organization(ctx context.Context, obj *types.Control) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -332,14 +360,16 @@ func (r *controlResolver) Organization(ctx context.Context, obj *types.Control) // Framework is the resolver for the framework field. func (r *controlResolver) Framework(ctx context.Context, obj *types.Control) (*types.Framework, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionFrameworkGet) + if err := r.authorize(ctx, obj.ID, probo.ActionFrameworkGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) framework, err := prb.Frameworks.Get(ctx, obj.Framework.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -351,7 +381,9 @@ func (r *controlResolver) Framework(ctx context.Context, obj *types.Control) (*t // Measures is the resolver for the measures field. func (r *controlResolver) Measures(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) (*types.MeasureConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionMeasureList) + if err := r.authorize(ctx, obj.ID, probo.ActionMeasureList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -384,7 +416,9 @@ func (r *controlResolver) Measures(ctx context.Context, obj *types.Control, firs // Documents is the resolver for the documents field. func (r *controlResolver) Documents(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) (*types.DocumentConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDocumentList) + if err := r.authorize(ctx, obj.ID, probo.ActionDocumentList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -416,7 +450,9 @@ func (r *controlResolver) Documents(ctx context.Context, obj *types.Control, fir // Audits is the resolver for the audits field. func (r *controlResolver) Audits(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AuditOrderBy) (*types.AuditConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionAuditList) + if err := r.authorize(ctx, obj.ID, probo.ActionAuditList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -443,7 +479,9 @@ func (r *controlResolver) Audits(ctx context.Context, obj *types.Control, first // Obligations is the resolver for the obligations field. func (r *controlResolver) Obligations(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ObligationOrderBy, filter *types.ObligationFilter) (*types.ObligationConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionObligationList) + if err := r.authorize(ctx, obj.ID, probo.ActionObligationList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -475,7 +513,9 @@ func (r *controlResolver) Obligations(ctx context.Context, obj *types.Control, f // Snapshots is the resolver for the snapshots field. func (r *controlResolver) Snapshots(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SnapshotOrderBy) (*types.SnapshotConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionSnapshotList) + if err := r.authorize(ctx, obj.ID, probo.ActionSnapshotList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -503,7 +543,9 @@ func (r *controlResolver) Snapshots(ctx context.Context, obj *types.Control, fir // StateOfApplicabilityControls is the resolver for the stateOfApplicabilityControls field. func (r *controlResolver) StateOfApplicabilityControls(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.StateOfApplicabilityOrderBy) (*types.StateOfApplicabilityControlConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionStateOfApplicabilityList) + if err := r.authorize(ctx, obj.ID, probo.ActionStateOfApplicabilityList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -535,7 +577,9 @@ func (r *controlResolver) Permission(ctx context.Context, obj *types.Control, ac // TotalCount is the resolver for the totalCount field. func (r *controlConnectionResolver) TotalCount(ctx context.Context, obj *types.ControlConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionControlList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionControlList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -588,7 +632,9 @@ func (r *customDomainResolver) Permission(ctx context.Context, obj *types.Custom // ProcessingActivity is the resolver for the processingActivity field. func (r *dataProtectionImpactAssessmentResolver) ProcessingActivity(ctx context.Context, obj *types.DataProtectionImpactAssessment) (*types.ProcessingActivity, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionProcessingActivityList) + if err := r.authorize(ctx, obj.ID, probo.ActionProcessingActivityList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -607,7 +653,9 @@ func (r *dataProtectionImpactAssessmentResolver) ProcessingActivity(ctx context. // Organization is the resolver for the organization field. func (r *dataProtectionImpactAssessmentResolver) Organization(ctx context.Context, obj *types.DataProtectionImpactAssessment) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -619,7 +667,7 @@ func (r *dataProtectionImpactAssessmentResolver) Organization(ctx context.Contex organization, err := prb.Organizations.Get(ctx, dpia.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) } @@ -634,7 +682,9 @@ func (r *dataProtectionImpactAssessmentResolver) Permission(ctx context.Context, // TotalCount is the resolver for the totalCount field. func (r *dataProtectionImpactAssessmentConnectionResolver) TotalCount(ctx context.Context, obj *types.DataProtectionImpactAssessmentConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionDataProtectionImpactAssessmentList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionDataProtectionImpactAssessmentList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -652,14 +702,16 @@ func (r *dataProtectionImpactAssessmentConnectionResolver) TotalCount(ctx contex // Owner is the resolver for the owner field. func (r *datumResolver) Owner(ctx context.Context, obj *types.Datum) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleGet) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) people, err := prb.Peoples.Get(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } return nil, fmt.Errorf("cannot get owner: %w", err) @@ -670,7 +722,9 @@ func (r *datumResolver) Owner(ctx context.Context, obj *types.Datum) (*types.Peo // Vendors is the resolver for the vendors field. func (r *datumResolver) Vendors(ctx context.Context, obj *types.Datum, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) (*types.VendorConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorList) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -698,14 +752,16 @@ func (r *datumResolver) Vendors(ctx context.Context, obj *types.Datum, first *in // Organization is the resolver for the organization field. func (r *datumResolver) Organization(ctx context.Context, obj *types.Datum) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) org, err := prb.Organizations.Get(ctx, obj.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -722,7 +778,9 @@ func (r *datumResolver) Permission(ctx context.Context, obj *types.Datum, action // TotalCount is the resolver for the totalCount field. func (r *datumConnectionResolver) TotalCount(ctx context.Context, obj *types.DatumConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionDatumList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionDatumList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -746,7 +804,9 @@ func (r *datumConnectionResolver) TotalCount(ctx context.Context, obj *types.Dat // Owner is the resolver for the owner field. func (r *documentResolver) Owner(ctx context.Context, obj *types.Document) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleGet) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -754,7 +814,7 @@ func (r *documentResolver) Owner(ctx context.Context, obj *types.Document) (*typ owner, err := prb.Peoples.Get(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -766,14 +826,16 @@ func (r *documentResolver) Owner(ctx context.Context, obj *types.Document) (*typ // Organization is the resolver for the organization field. func (r *documentResolver) Organization(ctx context.Context, obj *types.Document) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -785,7 +847,9 @@ func (r *documentResolver) Organization(ctx context.Context, obj *types.Document // Versions is the resolver for the versions field. func (r *documentResolver) Versions(ctx context.Context, obj *types.Document, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionOrderBy, filter *types.DocumentVersionFilter) (*types.DocumentVersionConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDocumentVersionList) + if err := r.authorize(ctx, obj.ID, probo.ActionDocumentVersionList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -815,7 +879,9 @@ func (r *documentResolver) Versions(ctx context.Context, obj *types.Document, fi // Controls is the resolver for the controls field. func (r *documentResolver) Controls(ctx context.Context, obj *types.Document, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionControlList) + if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -853,7 +919,9 @@ func (r *documentResolver) Permission(ctx context.Context, obj *types.Document, // TotalCount is the resolver for the totalCount field. func (r *documentConnectionResolver) TotalCount(ctx context.Context, obj *types.DocumentConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionDocumentList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionDocumentList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -887,14 +955,16 @@ func (r *documentConnectionResolver) TotalCount(ctx context.Context, obj *types. // Document is the resolver for the document field. func (r *documentVersionResolver) Document(ctx context.Context, obj *types.DocumentVersion) (*types.Document, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDocumentGet) + if err := r.authorize(ctx, obj.ID, probo.ActionDocumentGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) document, err := prb.Documents.Get(ctx, obj.Document.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -906,14 +976,16 @@ func (r *documentVersionResolver) Document(ctx context.Context, obj *types.Docum // Owner is the resolver for the owner field. func (r *documentVersionResolver) Owner(ctx context.Context, obj *types.DocumentVersion) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleGet) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) owner, err := prb.Peoples.Get(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -925,7 +997,9 @@ func (r *documentVersionResolver) Owner(ctx context.Context, obj *types.Document // Signatures is the resolver for the signatures field. func (r *documentVersionResolver) Signatures(ctx context.Context, obj *types.DocumentVersion, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionSignatureOrder, filter *types.DocumentVersionSignatureFilter) (*types.DocumentVersionSignatureConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDocumentVersionSignatureList) + if err := r.authorize(ctx, obj.ID, probo.ActionDocumentVersionSignatureList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -959,7 +1033,9 @@ func (r *documentVersionResolver) Signatures(ctx context.Context, obj *types.Doc // Signed is the resolver for the signed field. func (r *documentVersionResolver) Signed(ctx context.Context, obj *types.DocumentVersion) (bool, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDocumentVersionGet) + if err := r.authorize(ctx, obj.ID, probo.ActionDocumentVersionGet); err != nil { + return false, err + } identity := connect_v1.IdentityFromContext(ctx) @@ -981,7 +1057,9 @@ func (r *documentVersionResolver) Permission(ctx context.Context, obj *types.Doc // DocumentVersion is the resolver for the documentVersion field. func (r *documentVersionSignatureResolver) DocumentVersion(ctx context.Context, obj *types.DocumentVersionSignature) (*types.DocumentVersion, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDocumentVersionGet) + if err := r.authorize(ctx, obj.ID, probo.ActionDocumentVersionGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -996,14 +1074,16 @@ func (r *documentVersionSignatureResolver) DocumentVersion(ctx context.Context, // SignedBy is the resolver for the signedBy field. func (r *documentVersionSignatureResolver) SignedBy(ctx context.Context, obj *types.DocumentVersionSignature) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleGet) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) people, err := prb.Peoples.Get(ctx, obj.SignedBy.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -1020,7 +1100,9 @@ func (r *documentVersionSignatureResolver) Permission(ctx context.Context, obj * // File is the resolver for the file field. func (r *evidenceResolver) File(ctx context.Context, obj *types.Evidence) (*types.File, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionFileGet) + if err := r.authorize(ctx, obj.ID, probo.ActionFileGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -1031,7 +1113,7 @@ func (r *evidenceResolver) File(ctx context.Context, obj *types.Evidence) (*type file, err := prb.Files.Get(ctx, obj.File.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load evidence file: %w", err)) @@ -1042,7 +1124,9 @@ func (r *evidenceResolver) File(ctx context.Context, obj *types.Evidence) (*type // Task is the resolver for the task field. func (r *evidenceResolver) Task(ctx context.Context, obj *types.Evidence) (*types.Task, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTaskGet) + if err := r.authorize(ctx, obj.ID, probo.ActionTaskGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -1053,7 +1137,7 @@ func (r *evidenceResolver) Task(ctx context.Context, obj *types.Evidence) (*type task, err := prb.Tasks.Get(ctx, obj.Task.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -1065,14 +1149,16 @@ func (r *evidenceResolver) Task(ctx context.Context, obj *types.Evidence) (*type // Measure is the resolver for the measure field. func (r *evidenceResolver) Measure(ctx context.Context, obj *types.Evidence) (*types.Measure, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionMeasureGet) + if err := r.authorize(ctx, obj.ID, probo.ActionMeasureGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) measure, err := prb.Measures.Get(ctx, obj.Measure.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -1089,7 +1175,9 @@ func (r *evidenceResolver) Permission(ctx context.Context, obj *types.Evidence, // TotalCount is the resolver for the totalCount field. func (r *evidenceConnectionResolver) TotalCount(ctx context.Context, obj *types.EvidenceConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionEvidenceList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionEvidenceList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -1116,7 +1204,9 @@ func (r *evidenceConnectionResolver) TotalCount(ctx context.Context, obj *types. // DownloadURL is the resolver for the downloadUrl field. func (r *fileResolver) DownloadURL(ctx context.Context, obj *types.File) (string, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionFileDownloadUrl) + if err := r.authorize(ctx, obj.ID, probo.ActionFileDownloadUrl); err != nil { + return "", err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -1132,14 +1222,16 @@ func (r *fileResolver) DownloadURL(ctx context.Context, obj *types.File) (string // Organization is the resolver for the organization field. func (r *frameworkResolver) Organization(ctx context.Context, obj *types.Framework) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -1151,7 +1243,9 @@ func (r *frameworkResolver) Organization(ctx context.Context, obj *types.Framewo // Controls is the resolver for the controls field. func (r *frameworkResolver) Controls(ctx context.Context, obj *types.Framework, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionControlList) + if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -1184,7 +1278,9 @@ func (r *frameworkResolver) Controls(ctx context.Context, obj *types.Framework, // LightLogoURL is the resolver for the lightLogoURL field. func (r *frameworkResolver) LightLogoURL(ctx context.Context, obj *types.Framework) (*string, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionFrameworkGet) + if err := r.authorize(ctx, obj.ID, probo.ActionFrameworkGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -1193,7 +1289,9 @@ func (r *frameworkResolver) LightLogoURL(ctx context.Context, obj *types.Framewo // DarkLogoURL is the resolver for the darkLogoURL field. func (r *frameworkResolver) DarkLogoURL(ctx context.Context, obj *types.Framework) (*string, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionFrameworkGet) + if err := r.authorize(ctx, obj.ID, probo.ActionFrameworkGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -1207,7 +1305,9 @@ func (r *frameworkResolver) Permission(ctx context.Context, obj *types.Framework // TotalCount is the resolver for the totalCount field. func (r *frameworkConnectionResolver) TotalCount(ctx context.Context, obj *types.FrameworkConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionFrameworkList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionFrameworkList); err != nil { + return 0, err + } switch obj.Resolver.(type) { case *organizationResolver: @@ -1227,7 +1327,9 @@ func (r *frameworkConnectionResolver) TotalCount(ctx context.Context, obj *types // Evidences is the resolver for the evidences field. func (r *measureResolver) Evidences(ctx context.Context, obj *types.Measure, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.EvidenceOrderBy) (*types.EvidenceConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionEvidenceList) + if err := r.authorize(ctx, obj.ID, probo.ActionEvidenceList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -1255,7 +1357,9 @@ func (r *measureResolver) Evidences(ctx context.Context, obj *types.Measure, fir // Tasks is the resolver for the tasks field. func (r *measureResolver) Tasks(ctx context.Context, obj *types.Measure, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TaskOrderBy) (*types.TaskConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTaskList) + if err := r.authorize(ctx, obj.ID, probo.ActionTaskList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -1283,7 +1387,9 @@ func (r *measureResolver) Tasks(ctx context.Context, obj *types.Measure, first * // Risks is the resolver for the risks field. func (r *measureResolver) Risks(ctx context.Context, obj *types.Measure, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.RiskOrderBy, filter *types.RiskFilter) (*types.RiskConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionRiskList) + if err := r.authorize(ctx, obj.ID, probo.ActionRiskList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -1316,7 +1422,9 @@ func (r *measureResolver) Risks(ctx context.Context, obj *types.Measure, first * // Controls is the resolver for the controls field. func (r *measureResolver) Controls(ctx context.Context, obj *types.Measure, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionControlList) + if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -1354,7 +1462,9 @@ func (r *measureResolver) Permission(ctx context.Context, obj *types.Measure, ac // TotalCount is the resolver for the totalCount field. func (r *measureConnectionResolver) TotalCount(ctx context.Context, obj *types.MeasureConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionMeasureList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionMeasureList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -1390,7 +1500,9 @@ func (r *measureConnectionResolver) TotalCount(ctx context.Context, obj *types.M func (r *meetingResolver) Attendees(ctx context.Context, obj *types.Meeting) ([]*types.People, error) { // TODO bug must be paginated - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleList) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -1414,14 +1526,16 @@ func (r *meetingResolver) Attendees(ctx context.Context, obj *types.Meeting) ([] // Organization is the resolver for the organization field. func (r *meetingResolver) Organization(ctx context.Context, obj *types.Meeting) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -1438,7 +1552,9 @@ func (r *meetingResolver) Permission(ctx context.Context, obj *types.Meeting, ac // TotalCount is the resolver for the totalCount field. func (r *meetingConnectionResolver) TotalCount(ctx context.Context, obj *types.MeetingConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionMeetingList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionMeetingList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -1458,7 +1574,9 @@ func (r *meetingConnectionResolver) TotalCount(ctx context.Context, obj *types.M // UpdateOrganizationContext is the resolver for the updateOrganizationContext field. func (r *mutationResolver) UpdateOrganizationContext(ctx context.Context, input types.UpdateOrganizationContextInput) (*types.UpdateOrganizationContextPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionOrganizationContextUpdate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionOrganizationContextUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -1480,7 +1598,9 @@ func (r *mutationResolver) UpdateOrganizationContext(ctx context.Context, input // UpdateTrustCenter is the resolver for the updateTrustCenter field. func (r *mutationResolver) UpdateTrustCenter(ctx context.Context, input types.UpdateTrustCenterInput) (*types.UpdateTrustCenterPayload, error) { - r.MustAuthorize(ctx, input.TrustCenterID, probo.ActionTrustCenterUpdate) + if err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.TrustCenterID.TenantID()) @@ -1503,7 +1623,9 @@ 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) { - r.MustAuthorize(ctx, input.TrustCenterID, probo.ActionTrustCenterNonDisclosureAgreementUpload) + if err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterNonDisclosureAgreementUpload); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.TrustCenterID.TenantID()) @@ -1527,7 +1649,9 @@ 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) { - r.MustAuthorize(ctx, input.TrustCenterID, probo.ActionTrustCenterNonDisclosureAgreementDelete) + if err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterNonDisclosureAgreementDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.TrustCenterID.TenantID()) @@ -1544,7 +1668,9 @@ func (r *mutationResolver) DeleteTrustCenterNda(ctx context.Context, input types // CreateTrustCenterAccess is the resolver for the createTrustCenterAccess field. func (r *mutationResolver) CreateTrustCenterAccess(ctx context.Context, input types.CreateTrustCenterAccessInput) (*types.CreateTrustCenterAccessPayload, error) { - r.MustAuthorize(ctx, input.TrustCenterID, probo.ActionTrustCenterAccessCreate) + if err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterAccessCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.TrustCenterID.TenantID()) @@ -1558,7 +1684,7 @@ func (r *mutationResolver) CreateTrustCenterAccess(ctx context.Context, input ty ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -1572,7 +1698,9 @@ func (r *mutationResolver) CreateTrustCenterAccess(ctx context.Context, input ty // UpdateTrustCenterAccess is the resolver for the updateTrustCenterAccess field. func (r *mutationResolver) UpdateTrustCenterAccess(ctx context.Context, input types.UpdateTrustCenterAccessInput) (*types.UpdateTrustCenterAccessPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionTrustCenterAccessUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterAccessUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -1620,7 +1748,9 @@ 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) { - r.MustAuthorize(ctx, input.ID, probo.ActionTrustCenterAccessDelete) + if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterAccessDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -1637,7 +1767,9 @@ 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) { - r.MustAuthorize(ctx, input.TrustCenterID, probo.ActionTrustCenterReferenceCreate) + if err := r.authorize(ctx, input.TrustCenterID, probo.ActionTrustCenterReferenceCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.TrustCenterID.TenantID()) @@ -1668,7 +1800,9 @@ 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) { - r.MustAuthorize(ctx, input.ID, probo.ActionTrustCenterReferenceUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterReferenceUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -1702,7 +1836,9 @@ 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) { - r.MustAuthorize(ctx, input.ID, probo.ActionTrustCenterReferenceDelete) + if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterReferenceDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -1719,7 +1855,9 @@ func (r *mutationResolver) DeleteTrustCenterReference(ctx context.Context, input // CreateTrustCenterFile is the resolver for the createTrustCenterFile field. func (r *mutationResolver) CreateTrustCenterFile(ctx context.Context, input types.CreateTrustCenterFileInput) (*types.CreateTrustCenterFilePayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionTrustCenterFileCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionTrustCenterFileCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -1750,7 +1888,9 @@ 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) { - r.MustAuthorize(ctx, input.ID, probo.ActionTrustCenterFileUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterFileUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -1775,7 +1915,9 @@ 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) { - r.MustAuthorize(ctx, input.ID, probo.ActionTrustCenterFileGet) + if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterFileGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -1792,7 +1934,9 @@ 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) { - r.MustAuthorize(ctx, input.ID, probo.ActionTrustCenterFileDelete) + if err := r.authorize(ctx, input.ID, probo.ActionTrustCenterFileDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -1809,7 +1953,9 @@ func (r *mutationResolver) DeleteTrustCenterFile(ctx context.Context, input type // CreatePeople is the resolver for the createPeople field. func (r *mutationResolver) CreatePeople(ctx context.Context, input types.CreatePeopleInput) (*types.CreatePeoplePayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionPeopleCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionPeopleCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -1829,7 +1975,7 @@ func (r *mutationResolver) CreatePeople(ctx context.Context, input types.CreateP if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -1843,7 +1989,9 @@ func (r *mutationResolver) CreatePeople(ctx context.Context, input types.CreateP // UpdatePeople is the resolver for the updatePeople field. func (r *mutationResolver) UpdatePeople(ctx context.Context, input types.UpdatePeopleInput) (*types.UpdatePeoplePayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionPeopleUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionPeopleUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -1872,14 +2020,16 @@ func (r *mutationResolver) UpdatePeople(ctx context.Context, input types.UpdateP // DeletePeople is the resolver for the deletePeople field. func (r *mutationResolver) DeletePeople(ctx context.Context, input types.DeletePeopleInput) (*types.DeletePeoplePayload, error) { - r.MustAuthorize(ctx, input.PeopleID, probo.ActionPeopleDelete) + if err := r.authorize(ctx, input.PeopleID, probo.ActionPeopleDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.PeopleID.TenantID()) err := prb.Peoples.Delete(ctx, input.PeopleID) if err != nil { if errors.Is(err, coredata.ErrResourceInUse) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -1893,7 +2043,9 @@ func (r *mutationResolver) DeletePeople(ctx context.Context, input types.DeleteP // CreateVendor is the resolver for the createVendor field. func (r *mutationResolver) CreateVendor(ctx context.Context, input types.CreateVendorInput) (*types.CreateVendorPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionVendorCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionVendorCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -1924,7 +2076,7 @@ func (r *mutationResolver) CreateVendor(ctx context.Context, input types.CreateV ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -1937,7 +2089,9 @@ func (r *mutationResolver) CreateVendor(ctx context.Context, input types.CreateV // UpdateVendor is the resolver for the updateVendor field. func (r *mutationResolver) UpdateVendor(ctx context.Context, input types.UpdateVendorInput) (*types.UpdateVendorPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionVendorUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionVendorUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -1979,7 +2133,9 @@ func (r *mutationResolver) UpdateVendor(ctx context.Context, input types.UpdateV // DeleteVendor is the resolver for the deleteVendor field. func (r *mutationResolver) DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (*types.DeleteVendorPayload, error) { - r.MustAuthorize(ctx, input.VendorID, probo.ActionVendorDelete) + if err := r.authorize(ctx, input.VendorID, probo.ActionVendorDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.VendorID.TenantID()) @@ -1996,7 +2152,9 @@ func (r *mutationResolver) DeleteVendor(ctx context.Context, input types.DeleteV // CreateVendorContact is the resolver for the createVendorContact field. func (r *mutationResolver) CreateVendorContact(ctx context.Context, input types.CreateVendorContactInput) (*types.CreateVendorContactPayload, error) { - r.MustAuthorize(ctx, input.VendorID, probo.ActionVendorContactCreate) + if err := r.authorize(ctx, input.VendorID, probo.ActionVendorContactCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.VendorID.TenantID()) @@ -2021,7 +2179,9 @@ func (r *mutationResolver) CreateVendorContact(ctx context.Context, input types. // UpdateVendorContact is the resolver for the updateVendorContact field. func (r *mutationResolver) UpdateVendorContact(ctx context.Context, input types.UpdateVendorContactInput) (*types.UpdateVendorContactPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionVendorContactUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionVendorContactUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -2046,7 +2206,9 @@ func (r *mutationResolver) UpdateVendorContact(ctx context.Context, input types. // DeleteVendorContact is the resolver for the deleteVendorContact field. func (r *mutationResolver) DeleteVendorContact(ctx context.Context, input types.DeleteVendorContactInput) (*types.DeleteVendorContactPayload, error) { - r.MustAuthorize(ctx, input.VendorContactID, probo.ActionVendorContactDelete) + if err := r.authorize(ctx, input.VendorContactID, probo.ActionVendorContactDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.VendorContactID.TenantID()) @@ -2063,7 +2225,9 @@ func (r *mutationResolver) DeleteVendorContact(ctx context.Context, input types. // CreateVendorService is the resolver for the createVendorService field. func (r *mutationResolver) CreateVendorService(ctx context.Context, input types.CreateVendorServiceInput) (*types.CreateVendorServicePayload, error) { - r.MustAuthorize(ctx, input.VendorID, probo.ActionVendorServiceCreate) + if err := r.authorize(ctx, input.VendorID, probo.ActionVendorServiceCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.VendorID.TenantID()) @@ -2086,7 +2250,9 @@ func (r *mutationResolver) CreateVendorService(ctx context.Context, input types. // UpdateVendorService is the resolver for the updateVendorService field. func (r *mutationResolver) UpdateVendorService(ctx context.Context, input types.UpdateVendorServiceInput) (*types.UpdateVendorServicePayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionVendorServiceUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionVendorServiceUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -2109,7 +2275,9 @@ func (r *mutationResolver) UpdateVendorService(ctx context.Context, input types. // DeleteVendorService is the resolver for the deleteVendorService field. func (r *mutationResolver) DeleteVendorService(ctx context.Context, input types.DeleteVendorServiceInput) (*types.DeleteVendorServicePayload, error) { - r.MustAuthorize(ctx, input.VendorServiceID, probo.ActionVendorServiceDelete) + if err := r.authorize(ctx, input.VendorServiceID, probo.ActionVendorServiceDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.VendorServiceID.TenantID()) @@ -2126,7 +2294,9 @@ func (r *mutationResolver) DeleteVendorService(ctx context.Context, input types. // CreateFramework is the resolver for the createFramework field. func (r *mutationResolver) CreateFramework(ctx context.Context, input types.CreateFrameworkInput) (*types.CreateFrameworkPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionFrameworkCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionFrameworkCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -2149,7 +2319,9 @@ func (r *mutationResolver) CreateFramework(ctx context.Context, input types.Crea // UpdateFramework is the resolver for the updateFramework field. func (r *mutationResolver) UpdateFramework(ctx context.Context, input types.UpdateFrameworkInput) (*types.UpdateFrameworkPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionFrameworkUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionFrameworkUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -2173,7 +2345,9 @@ func (r *mutationResolver) UpdateFramework(ctx context.Context, input types.Upda // ImportFramework is the resolver for the importFramework field. func (r *mutationResolver) ImportFramework(ctx context.Context, input types.ImportFrameworkInput) (*types.ImportFrameworkPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionFrameworkImport) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionFrameworkImport); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -2185,7 +2359,7 @@ func (r *mutationResolver) ImportFramework(ctx context.Context, input types.Impo framework, err := prb.Frameworks.Import(ctx, input.OrganizationID, req) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -2199,7 +2373,9 @@ func (r *mutationResolver) ImportFramework(ctx context.Context, input types.Impo // DeleteFramework is the resolver for the deleteFramework field. func (r *mutationResolver) DeleteFramework(ctx context.Context, input types.DeleteFrameworkInput) (*types.DeleteFrameworkPayload, error) { - r.MustAuthorize(ctx, input.FrameworkID, probo.ActionFrameworkDelete) + if err := r.authorize(ctx, input.FrameworkID, probo.ActionFrameworkDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.FrameworkID.TenantID()) @@ -2216,7 +2392,9 @@ func (r *mutationResolver) DeleteFramework(ctx context.Context, input types.Dele // GenerateFrameworkStateOfApplicability is the resolver for the generateFrameworkStateOfApplicability field. func (r *mutationResolver) GenerateFrameworkStateOfApplicability(ctx context.Context, input types.GenerateFrameworkStateOfApplicabilityInput) (*types.GenerateFrameworkStateOfApplicabilityPayload, error) { - r.MustAuthorize(ctx, input.FrameworkID, probo.ActionFrameworkStateOfApplicabilityGenerate) + if err := r.authorize(ctx, input.FrameworkID, probo.ActionFrameworkStateOfApplicabilityGenerate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.FrameworkID.TenantID()) @@ -2236,7 +2414,9 @@ func (r *mutationResolver) GenerateFrameworkStateOfApplicability(ctx context.Con // ExportFramework is the resolver for the exportFramework field. func (r *mutationResolver) ExportFramework(ctx context.Context, input types.ExportFrameworkInput) (*types.ExportFrameworkPayload, error) { - r.MustAuthorize(ctx, input.FrameworkID, probo.ActionFrameworkExport) + if err := r.authorize(ctx, input.FrameworkID, probo.ActionFrameworkExport); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.FrameworkID.TenantID()) identity := connect_v1.IdentityFromContext(ctx) @@ -2259,7 +2439,9 @@ func (r *mutationResolver) ExportFramework(ctx context.Context, input types.Expo // CreateControl is the resolver for the createControl field. func (r *mutationResolver) CreateControl(ctx context.Context, input types.CreateControlInput) (*types.CreateControlPayload, error) { - r.MustAuthorize(ctx, input.FrameworkID, probo.ActionControlCreate) + if err := r.authorize(ctx, input.FrameworkID, probo.ActionControlCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.FrameworkID.TenantID()) @@ -2277,7 +2459,7 @@ func (r *mutationResolver) CreateControl(ctx context.Context, input types.Create ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -2291,7 +2473,9 @@ func (r *mutationResolver) CreateControl(ctx context.Context, input types.Create // UpdateControl is the resolver for the updateControl field. func (r *mutationResolver) UpdateControl(ctx context.Context, input types.UpdateControlInput) (*types.UpdateControlPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionControlUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionControlUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -2310,7 +2494,7 @@ func (r *mutationResolver) UpdateControl(ctx context.Context, input types.Update if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -2324,7 +2508,9 @@ func (r *mutationResolver) UpdateControl(ctx context.Context, input types.Update // DeleteControl is the resolver for the deleteControl field. func (r *mutationResolver) DeleteControl(ctx context.Context, input types.DeleteControlInput) (*types.DeleteControlPayload, error) { - r.MustAuthorize(ctx, input.ControlID, probo.ActionControlDelete) + if err := r.authorize(ctx, input.ControlID, probo.ActionControlDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ControlID.TenantID()) @@ -2341,7 +2527,9 @@ func (r *mutationResolver) DeleteControl(ctx context.Context, input types.Delete // // CreateMeasure is the resolver for the createMeasure field. func (r *mutationResolver) CreateMeasure(ctx context.Context, input types.CreateMeasureInput) (*types.CreateMeasurePayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionMeasureCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionMeasureCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -2356,7 +2544,7 @@ func (r *mutationResolver) CreateMeasure(ctx context.Context, input types.Create ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } panic(fmt.Errorf("cannot create measure: %w", err)) @@ -2369,7 +2557,9 @@ func (r *mutationResolver) CreateMeasure(ctx context.Context, input types.Create // UpdateMeasure is the resolver for the updateMeasure field. func (r *mutationResolver) UpdateMeasure(ctx context.Context, input types.UpdateMeasureInput) (*types.UpdateMeasurePayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionMeasureUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionMeasureUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -2395,7 +2585,9 @@ func (r *mutationResolver) UpdateMeasure(ctx context.Context, input types.Update // ImportMeasure is the resolver for the importMeasure field. func (r *mutationResolver) ImportMeasure(ctx context.Context, input types.ImportMeasureInput) (*types.ImportMeasurePayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionMeasureImport) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionMeasureImport); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -2423,7 +2615,9 @@ func (r *mutationResolver) ImportMeasure(ctx context.Context, input types.Import // DeleteMeasure is the resolver for the deleteMeasure field. func (r *mutationResolver) DeleteMeasure(ctx context.Context, input types.DeleteMeasureInput) (*types.DeleteMeasurePayload, error) { - r.MustAuthorize(ctx, input.MeasureID, probo.ActionMeasureDelete) + if err := r.authorize(ctx, input.MeasureID, probo.ActionMeasureDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.MeasureID.TenantID()) @@ -2440,7 +2634,9 @@ func (r *mutationResolver) DeleteMeasure(ctx context.Context, input types.Delete // CreateControlMeasureMapping is the resolver for the createControlMeasureMapping field. func (r *mutationResolver) CreateControlMeasureMapping(ctx context.Context, input types.CreateControlMeasureMappingInput) (*types.CreateControlMeasureMappingPayload, error) { - r.MustAuthorize(ctx, input.ControlID, probo.ActionControlMeasureMappingCreate) + if err := r.authorize(ctx, input.ControlID, probo.ActionControlMeasureMappingCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.MeasureID.TenantID()) @@ -2458,14 +2654,16 @@ func (r *mutationResolver) CreateControlMeasureMapping(ctx context.Context, inpu // CreateControlDocumentMapping is the resolver for the createControlDocumentMapping field. func (r *mutationResolver) CreateControlDocumentMapping(ctx context.Context, input types.CreateControlDocumentMappingInput) (*types.CreateControlDocumentMappingPayload, error) { - r.MustAuthorize(ctx, input.ControlID, probo.ActionControlDocumentMappingCreate) + if err := r.authorize(ctx, input.ControlID, probo.ActionControlDocumentMappingCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DocumentID.TenantID()) control, document, err := prb.Controls.CreateDocumentMapping(ctx, input.ControlID, input.DocumentID) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -2480,7 +2678,9 @@ func (r *mutationResolver) CreateControlDocumentMapping(ctx context.Context, inp // DeleteControlMeasureMapping is the resolver for the deleteControlMeasureMapping field. func (r *mutationResolver) DeleteControlMeasureMapping(ctx context.Context, input types.DeleteControlMeasureMappingInput) (*types.DeleteControlMeasureMappingPayload, error) { - r.MustAuthorize(ctx, input.ControlID, probo.ActionControlMeasureMappingDelete) + if err := r.authorize(ctx, input.ControlID, probo.ActionControlMeasureMappingDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.MeasureID.TenantID()) @@ -2498,7 +2698,9 @@ func (r *mutationResolver) DeleteControlMeasureMapping(ctx context.Context, inpu // DeleteControlDocumentMapping is the resolver for the deleteControlDocumentMapping field. func (r *mutationResolver) DeleteControlDocumentMapping(ctx context.Context, input types.DeleteControlDocumentMappingInput) (*types.DeleteControlDocumentMappingPayload, error) { - r.MustAuthorize(ctx, input.ControlID, probo.ActionControlDocumentMappingDelete) + if err := r.authorize(ctx, input.ControlID, probo.ActionControlDocumentMappingDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DocumentID.TenantID()) @@ -2516,7 +2718,9 @@ func (r *mutationResolver) DeleteControlDocumentMapping(ctx context.Context, inp // CreateStateOfApplicabilityControlMapping is the resolver for the createStateOfApplicabilityControlMapping field. func (r *mutationResolver) CreateStateOfApplicabilityControlMapping(ctx context.Context, input types.CreateStateOfApplicabilityControlMappingInput) (*types.CreateStateOfApplicabilityControlMappingPayload, error) { - r.MustAuthorize(ctx, input.ControlID, probo.ActionStateOfApplicabilityControlMappingCreate) + if err := r.authorize(ctx, input.ControlID, probo.ActionStateOfApplicabilityControlMappingCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.StateOfApplicabilityID.TenantID()) @@ -2532,7 +2736,9 @@ func (r *mutationResolver) CreateStateOfApplicabilityControlMapping(ctx context. // DeleteStateOfApplicabilityControlMapping is the resolver for the deleteStateOfApplicabilityControlMapping field. func (r *mutationResolver) DeleteStateOfApplicabilityControlMapping(ctx context.Context, input types.DeleteStateOfApplicabilityControlMappingInput) (*types.DeleteStateOfApplicabilityControlMappingPayload, error) { - r.MustAuthorize(ctx, input.StateOfApplicabilityID, probo.ActionStateOfApplicabilityControlMappingDelete) + if err := r.authorize(ctx, input.StateOfApplicabilityID, probo.ActionStateOfApplicabilityControlMappingDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.StateOfApplicabilityID.TenantID()) @@ -2550,7 +2756,9 @@ func (r *mutationResolver) DeleteStateOfApplicabilityControlMapping(ctx context. // CreateControlAuditMapping is the resolver for the createControlAuditMapping field. func (r *mutationResolver) CreateControlAuditMapping(ctx context.Context, input types.CreateControlAuditMappingInput) (*types.CreateControlAuditMappingPayload, error) { - r.MustAuthorize(ctx, input.ControlID, probo.ActionControlAuditMappingCreate) + if err := r.authorize(ctx, input.ControlID, probo.ActionControlAuditMappingCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.AuditID.TenantID()) @@ -2568,7 +2776,9 @@ func (r *mutationResolver) CreateControlAuditMapping(ctx context.Context, input // DeleteControlAuditMapping is the resolver for the deleteControlAuditMapping field. func (r *mutationResolver) DeleteControlAuditMapping(ctx context.Context, input types.DeleteControlAuditMappingInput) (*types.DeleteControlAuditMappingPayload, error) { - r.MustAuthorize(ctx, input.ControlID, probo.ActionControlAuditMappingDelete) + if err := r.authorize(ctx, input.ControlID, probo.ActionControlAuditMappingDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.AuditID.TenantID()) @@ -2586,7 +2796,9 @@ func (r *mutationResolver) DeleteControlAuditMapping(ctx context.Context, input // CreateControlObligationMapping is the resolver for the createControlObligationMapping field. func (r *mutationResolver) CreateControlObligationMapping(ctx context.Context, input types.CreateControlObligationMappingInput) (*types.CreateControlObligationMappingPayload, error) { - r.MustAuthorize(ctx, input.ControlID, probo.ActionControlObligationMappingCreate) + if err := r.authorize(ctx, input.ControlID, probo.ActionControlObligationMappingCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ObligationID.TenantID()) @@ -2603,7 +2815,9 @@ func (r *mutationResolver) CreateControlObligationMapping(ctx context.Context, i // DeleteControlObligationMapping is the resolver for the deleteControlObligationMapping field. func (r *mutationResolver) DeleteControlObligationMapping(ctx context.Context, input types.DeleteControlObligationMappingInput) (*types.DeleteControlObligationMappingPayload, error) { - r.MustAuthorize(ctx, input.ControlID, probo.ActionControlObligationMappingDelete) + if err := r.authorize(ctx, input.ControlID, probo.ActionControlObligationMappingDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ObligationID.TenantID()) @@ -2620,7 +2834,9 @@ func (r *mutationResolver) DeleteControlObligationMapping(ctx context.Context, i // CreateControlSnapshotMapping is the resolver for the createControlSnapshotMapping field. func (r *mutationResolver) CreateControlSnapshotMapping(ctx context.Context, input types.CreateControlSnapshotMappingInput) (*types.CreateControlSnapshotMappingPayload, error) { - r.MustAuthorize(ctx, input.ControlID, probo.ActionControlSnapshotMappingCreate) + if err := r.authorize(ctx, input.ControlID, probo.ActionControlSnapshotMappingCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.SnapshotID.TenantID()) @@ -2638,7 +2854,9 @@ func (r *mutationResolver) CreateControlSnapshotMapping(ctx context.Context, inp // DeleteControlSnapshotMapping is the resolver for the deleteControlSnapshotMapping field. func (r *mutationResolver) DeleteControlSnapshotMapping(ctx context.Context, input types.DeleteControlSnapshotMappingInput) (*types.DeleteControlSnapshotMappingPayload, error) { - r.MustAuthorize(ctx, input.ControlID, probo.ActionControlSnapshotMappingDelete) + if err := r.authorize(ctx, input.ControlID, probo.ActionControlSnapshotMappingDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.SnapshotID.TenantID()) @@ -2656,7 +2874,9 @@ func (r *mutationResolver) DeleteControlSnapshotMapping(ctx context.Context, inp // CreateTask is the resolver for the createTask field. func (r *mutationResolver) CreateTask(ctx context.Context, input types.CreateTaskInput) (*types.CreateTaskPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionTaskCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionTaskCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -2674,7 +2894,7 @@ func (r *mutationResolver) CreateTask(ctx context.Context, input types.CreateTas ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -2688,7 +2908,9 @@ func (r *mutationResolver) CreateTask(ctx context.Context, input types.CreateTas // UpdateTask is the resolver for the updateTask field. func (r *mutationResolver) UpdateTask(ctx context.Context, input types.UpdateTaskInput) (*types.UpdateTaskPayload, error) { - r.MustAuthorize(ctx, input.TaskID, probo.ActionTaskUpdate) + if err := r.authorize(ctx, input.TaskID, probo.ActionTaskUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.TaskID.TenantID()) @@ -2717,7 +2939,9 @@ func (r *mutationResolver) UpdateTask(ctx context.Context, input types.UpdateTas // DeleteTask is the resolver for the deleteTask field. func (r *mutationResolver) DeleteTask(ctx context.Context, input types.DeleteTaskInput) (*types.DeleteTaskPayload, error) { - r.MustAuthorize(ctx, input.TaskID, probo.ActionTaskDelete) + if err := r.authorize(ctx, input.TaskID, probo.ActionTaskDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.TaskID.TenantID()) @@ -2734,7 +2958,9 @@ func (r *mutationResolver) DeleteTask(ctx context.Context, input types.DeleteTas // CreateRisk is the resolver for the createRisk field. func (r *mutationResolver) CreateRisk(ctx context.Context, input types.CreateRiskInput) (*types.CreateRiskPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionRiskCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionRiskCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -2756,7 +2982,7 @@ func (r *mutationResolver) CreateRisk(ctx context.Context, input types.CreateRis ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -2770,7 +2996,9 @@ func (r *mutationResolver) CreateRisk(ctx context.Context, input types.CreateRis // UpdateRisk is the resolver for the updateRisk field. func (r *mutationResolver) UpdateRisk(ctx context.Context, input types.UpdateRiskInput) (*types.UpdateRiskPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionRiskUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionRiskUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -2802,7 +3030,9 @@ func (r *mutationResolver) UpdateRisk(ctx context.Context, input types.UpdateRis // DeleteRisk is the resolver for the deleteRisk field. func (r *mutationResolver) DeleteRisk(ctx context.Context, input types.DeleteRiskInput) (*types.DeleteRiskPayload, error) { - r.MustAuthorize(ctx, input.RiskID, probo.ActionRiskDelete) + if err := r.authorize(ctx, input.RiskID, probo.ActionRiskDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.RiskID.TenantID()) @@ -2819,7 +3049,9 @@ func (r *mutationResolver) DeleteRisk(ctx context.Context, input types.DeleteRis // CreateRiskMeasureMapping is the resolver for the createRiskMeasureMapping field. func (r *mutationResolver) CreateRiskMeasureMapping(ctx context.Context, input types.CreateRiskMeasureMappingInput) (*types.CreateRiskMeasureMappingPayload, error) { - r.MustAuthorize(ctx, input.RiskID, probo.ActionRiskMeasureMappingCreate) + if err := r.authorize(ctx, input.RiskID, probo.ActionRiskMeasureMappingCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.RiskID.TenantID()) @@ -2837,7 +3069,9 @@ func (r *mutationResolver) CreateRiskMeasureMapping(ctx context.Context, input t // DeleteRiskMeasureMapping is the resolver for the deleteRiskMeasureMapping field. func (r *mutationResolver) DeleteRiskMeasureMapping(ctx context.Context, input types.DeleteRiskMeasureMappingInput) (*types.DeleteRiskMeasureMappingPayload, error) { - r.MustAuthorize(ctx, input.RiskID, probo.ActionRiskMeasureMappingDelete) + if err := r.authorize(ctx, input.RiskID, probo.ActionRiskMeasureMappingDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.RiskID.TenantID()) @@ -2855,7 +3089,9 @@ func (r *mutationResolver) DeleteRiskMeasureMapping(ctx context.Context, input t // CreateRiskDocumentMapping is the resolver for the createRiskDocumentMapping field. func (r *mutationResolver) CreateRiskDocumentMapping(ctx context.Context, input types.CreateRiskDocumentMappingInput) (*types.CreateRiskDocumentMappingPayload, error) { - r.MustAuthorize(ctx, input.RiskID, probo.ActionRiskDocumentMappingCreate) + if err := r.authorize(ctx, input.RiskID, probo.ActionRiskDocumentMappingCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.RiskID.TenantID()) @@ -2873,7 +3109,9 @@ func (r *mutationResolver) CreateRiskDocumentMapping(ctx context.Context, input // DeleteRiskDocumentMapping is the resolver for the deleteRiskDocumentMapping field. func (r *mutationResolver) DeleteRiskDocumentMapping(ctx context.Context, input types.DeleteRiskDocumentMappingInput) (*types.DeleteRiskDocumentMappingPayload, error) { - r.MustAuthorize(ctx, input.RiskID, probo.ActionRiskDocumentMappingDelete) + if err := r.authorize(ctx, input.RiskID, probo.ActionRiskDocumentMappingDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.RiskID.TenantID()) @@ -2891,7 +3129,9 @@ func (r *mutationResolver) DeleteRiskDocumentMapping(ctx context.Context, input // CreateRiskObligationMapping is the resolver for the createRiskObligationMapping field. func (r *mutationResolver) CreateRiskObligationMapping(ctx context.Context, input types.CreateRiskObligationMappingInput) (*types.CreateRiskObligationMappingPayload, error) { - r.MustAuthorize(ctx, input.RiskID, probo.ActionRiskObligationMappingCreate) + if err := r.authorize(ctx, input.RiskID, probo.ActionRiskObligationMappingCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.RiskID.TenantID()) @@ -2909,7 +3149,9 @@ func (r *mutationResolver) CreateRiskObligationMapping(ctx context.Context, inpu // DeleteRiskObligationMapping is the resolver for the deleteRiskObligationMapping field. func (r *mutationResolver) DeleteRiskObligationMapping(ctx context.Context, input types.DeleteRiskObligationMappingInput) (*types.DeleteRiskObligationMappingPayload, error) { - r.MustAuthorize(ctx, input.RiskID, probo.ActionRiskObligationMappingDelete) + if err := r.authorize(ctx, input.RiskID, probo.ActionRiskObligationMappingDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.RiskID.TenantID()) @@ -2927,7 +3169,9 @@ func (r *mutationResolver) DeleteRiskObligationMapping(ctx context.Context, inpu // DeleteEvidence is the resolver for the deleteEvidence field. func (r *mutationResolver) DeleteEvidence(ctx context.Context, input types.DeleteEvidenceInput) (*types.DeleteEvidencePayload, error) { - r.MustAuthorize(ctx, input.EvidenceID, probo.ActionEvidenceDelete) + if err := r.authorize(ctx, input.EvidenceID, probo.ActionEvidenceDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.EvidenceID.TenantID()) @@ -2944,7 +3188,9 @@ func (r *mutationResolver) DeleteEvidence(ctx context.Context, input types.Delet // UploadMeasureEvidence is the resolver for the uploadMeasureEvidence field. func (r *mutationResolver) UploadMeasureEvidence(ctx context.Context, input types.UploadMeasureEvidenceInput) (*types.UploadMeasureEvidencePayload, error) { - r.MustAuthorize(ctx, input.MeasureID, probo.ActionMeasureEvidenceUpload) + if err := r.authorize(ctx, input.MeasureID, probo.ActionMeasureEvidenceUpload); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.MeasureID.TenantID()) @@ -2972,7 +3218,9 @@ func (r *mutationResolver) UploadMeasureEvidence(ctx context.Context, input type // UploadVendorComplianceReport is the resolver for the uploadVendorComplianceReport field. func (r *mutationResolver) UploadVendorComplianceReport(ctx context.Context, input types.UploadVendorComplianceReportInput) (*types.UploadVendorComplianceReportPayload, error) { - r.MustAuthorize(ctx, input.VendorID, probo.ActionVendorComplianceReportUpload) + if err := r.authorize(ctx, input.VendorID, probo.ActionVendorComplianceReportUpload); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.VendorID.TenantID()) @@ -2998,7 +3246,9 @@ func (r *mutationResolver) UploadVendorComplianceReport(ctx context.Context, inp // DeleteVendorComplianceReport is the resolver for the deleteVendorComplianceReport field. func (r *mutationResolver) DeleteVendorComplianceReport(ctx context.Context, input types.DeleteVendorComplianceReportInput) (*types.DeleteVendorComplianceReportPayload, error) { - r.MustAuthorize(ctx, input.ReportID, probo.ActionVendorComplianceReportDelete) + if err := r.authorize(ctx, input.ReportID, probo.ActionVendorComplianceReportDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ReportID.TenantID()) @@ -3015,7 +3265,9 @@ func (r *mutationResolver) DeleteVendorComplianceReport(ctx context.Context, inp // UploadVendorBusinessAssociateAgreement is the resolver for the uploadVendorBusinessAssociateAgreement field. func (r *mutationResolver) UploadVendorBusinessAssociateAgreement(ctx context.Context, input types.UploadVendorBusinessAssociateAgreementInput) (*types.UploadVendorBusinessAssociateAgreementPayload, error) { - r.MustAuthorize(ctx, input.VendorID, probo.ActionVendorBusinessAssociateAgreementUpload) + if err := r.authorize(ctx, input.VendorID, probo.ActionVendorBusinessAssociateAgreementUpload); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.VendorID.TenantID()) @@ -3041,7 +3293,9 @@ func (r *mutationResolver) UploadVendorBusinessAssociateAgreement(ctx context.Co // UpdateVendorBusinessAssociateAgreement is the resolver for the updateVendorBusinessAssociateAgreement field. func (r *mutationResolver) UpdateVendorBusinessAssociateAgreement(ctx context.Context, input types.UpdateVendorBusinessAssociateAgreementInput) (*types.UpdateVendorBusinessAssociateAgreementPayload, error) { - r.MustAuthorize(ctx, input.VendorID, probo.ActionVendorBusinessAssociateAgreementUpdate) + if err := r.authorize(ctx, input.VendorID, probo.ActionVendorBusinessAssociateAgreementUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.VendorID.TenantID()) @@ -3065,7 +3319,9 @@ func (r *mutationResolver) UpdateVendorBusinessAssociateAgreement(ctx context.Co // DeleteVendorBusinessAssociateAgreement is the resolver for the deleteVendorBusinessAssociateAgreement field. func (r *mutationResolver) DeleteVendorBusinessAssociateAgreement(ctx context.Context, input types.DeleteVendorBusinessAssociateAgreementInput) (*types.DeleteVendorBusinessAssociateAgreementPayload, error) { - r.MustAuthorize(ctx, input.VendorID, probo.ActionVendorBusinessAssociateAgreementDelete) + if err := r.authorize(ctx, input.VendorID, probo.ActionVendorBusinessAssociateAgreementDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.VendorID.TenantID()) @@ -3082,7 +3338,9 @@ func (r *mutationResolver) DeleteVendorBusinessAssociateAgreement(ctx context.Co // UploadVendorDataPrivacyAgreement is the resolver for the uploadVendorDataPrivacyAgreement field. func (r *mutationResolver) UploadVendorDataPrivacyAgreement(ctx context.Context, input types.UploadVendorDataPrivacyAgreementInput) (*types.UploadVendorDataPrivacyAgreementPayload, error) { - r.MustAuthorize(ctx, input.VendorID, probo.ActionVendorDataPrivacyAgreementUpload) + if err := r.authorize(ctx, input.VendorID, probo.ActionVendorDataPrivacyAgreementUpload); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.VendorID.TenantID()) @@ -3108,7 +3366,9 @@ func (r *mutationResolver) UploadVendorDataPrivacyAgreement(ctx context.Context, // UpdateVendorDataPrivacyAgreement is the resolver for the updateVendorDataPrivacyAgreement field. func (r *mutationResolver) UpdateVendorDataPrivacyAgreement(ctx context.Context, input types.UpdateVendorDataPrivacyAgreementInput) (*types.UpdateVendorDataPrivacyAgreementPayload, error) { - r.MustAuthorize(ctx, input.VendorID, probo.ActionVendorDataPrivacyAgreementUpdate) + if err := r.authorize(ctx, input.VendorID, probo.ActionVendorDataPrivacyAgreementUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.VendorID.TenantID()) @@ -3132,7 +3392,9 @@ func (r *mutationResolver) UpdateVendorDataPrivacyAgreement(ctx context.Context, // DeleteVendorDataPrivacyAgreement is the resolver for the deleteVendorDataPrivacyAgreement field. func (r *mutationResolver) DeleteVendorDataPrivacyAgreement(ctx context.Context, input types.DeleteVendorDataPrivacyAgreementInput) (*types.DeleteVendorDataPrivacyAgreementPayload, error) { - r.MustAuthorize(ctx, input.VendorID, probo.ActionVendorDataPrivacyAgreementDelete) + if err := r.authorize(ctx, input.VendorID, probo.ActionVendorDataPrivacyAgreementDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.VendorID.TenantID()) @@ -3149,7 +3411,9 @@ func (r *mutationResolver) DeleteVendorDataPrivacyAgreement(ctx context.Context, // CreateDocument is the resolver for the createDocument field. func (r *mutationResolver) CreateDocument(ctx context.Context, input types.CreateDocumentInput) (*types.CreateDocumentPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionDocumentCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionDocumentCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -3167,7 +3431,7 @@ func (r *mutationResolver) CreateDocument(ctx context.Context, input types.Creat ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -3182,7 +3446,9 @@ func (r *mutationResolver) CreateDocument(ctx context.Context, input types.Creat // UpdateDocument is the resolver for the updateDocument field. func (r *mutationResolver) UpdateDocument(ctx context.Context, input types.UpdateDocumentInput) (*types.UpdateDocumentPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionDocumentUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionDocumentUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -3210,7 +3476,9 @@ func (r *mutationResolver) UpdateDocument(ctx context.Context, input types.Updat // DeleteDocument is the resolver for the deleteDocument field. func (r *mutationResolver) DeleteDocument(ctx context.Context, input types.DeleteDocumentInput) (*types.DeleteDocumentPayload, error) { - r.MustAuthorize(ctx, input.DocumentID, probo.ActionDocumentDelete) + if err := r.authorize(ctx, input.DocumentID, probo.ActionDocumentDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DocumentID.TenantID()) @@ -3227,7 +3495,9 @@ func (r *mutationResolver) DeleteDocument(ctx context.Context, input types.Delet // CreateMeeting is the resolver for the createMeeting field. func (r *mutationResolver) CreateMeeting(ctx context.Context, input types.CreateMeetingInput) (*types.CreateMeetingPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionMeetingCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionMeetingCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -3253,7 +3523,9 @@ func (r *mutationResolver) CreateMeeting(ctx context.Context, input types.Create // UpdateMeeting is the resolver for the updateMeeting field. func (r *mutationResolver) UpdateMeeting(ctx context.Context, input types.UpdateMeetingInput) (*types.UpdateMeetingPayload, error) { - r.MustAuthorize(ctx, input.MeetingID, probo.ActionMeetingUpdate) + if err := r.authorize(ctx, input.MeetingID, probo.ActionMeetingUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.MeetingID.TenantID()) @@ -3284,7 +3556,9 @@ func (r *mutationResolver) UpdateMeeting(ctx context.Context, input types.Update // DeleteMeeting is the resolver for the deleteMeeting field. func (r *mutationResolver) DeleteMeeting(ctx context.Context, input types.DeleteMeetingInput) (*types.DeleteMeetingPayload, error) { - r.MustAuthorize(ctx, input.MeetingID, probo.ActionMeetingDelete) + if err := r.authorize(ctx, input.MeetingID, probo.ActionMeetingDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.MeetingID.TenantID()) @@ -3301,7 +3575,9 @@ func (r *mutationResolver) DeleteMeeting(ctx context.Context, input types.Delete // CreateStateOfApplicability is the resolver for the createStateOfApplicability field. func (r *mutationResolver) CreateStateOfApplicability(ctx context.Context, input types.CreateStateOfApplicabilityInput) (*types.CreateStateOfApplicabilityPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionStateOfApplicabilityCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionStateOfApplicabilityCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -3315,7 +3591,7 @@ func (r *mutationResolver) CreateStateOfApplicability(ctx context.Context, input ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } panic(fmt.Errorf("cannot create state_of_applicability: %w", err)) } @@ -3327,7 +3603,9 @@ func (r *mutationResolver) CreateStateOfApplicability(ctx context.Context, input // UpdateStateOfApplicability is the resolver for the updateStateOfApplicability field. func (r *mutationResolver) UpdateStateOfApplicability(ctx context.Context, input types.UpdateStateOfApplicabilityInput) (*types.UpdateStateOfApplicabilityPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionStateOfApplicabilityUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionStateOfApplicabilityUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -3346,7 +3624,7 @@ func (r *mutationResolver) UpdateStateOfApplicability(ctx context.Context, input ) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } panic(fmt.Errorf("cannot update state_of_applicability: %w", err)) } @@ -3358,7 +3636,9 @@ func (r *mutationResolver) UpdateStateOfApplicability(ctx context.Context, input // DeleteStateOfApplicability is the resolver for the deleteStateOfApplicability field. func (r *mutationResolver) DeleteStateOfApplicability(ctx context.Context, input types.DeleteStateOfApplicabilityInput) (*types.DeleteStateOfApplicabilityPayload, error) { - r.MustAuthorize(ctx, input.StateOfApplicabilityID, probo.ActionStateOfApplicabilityDelete) + if err := r.authorize(ctx, input.StateOfApplicabilityID, probo.ActionStateOfApplicabilityDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.StateOfApplicabilityID.TenantID()) @@ -3374,7 +3654,9 @@ func (r *mutationResolver) DeleteStateOfApplicability(ctx context.Context, input // ExportStateOfApplicabilityPDF is the resolver for the exportStateOfApplicabilityPDF field. func (r *mutationResolver) ExportStateOfApplicabilityPDF(ctx context.Context, input types.ExportStateOfApplicabilityPDFInput) (*types.ExportStateOfApplicabilityPDFPayload, error) { - r.MustAuthorize(ctx, input.StateOfApplicabilityID, probo.ActionStateOfApplicabilityExport) + if err := r.authorize(ctx, input.StateOfApplicabilityID, probo.ActionStateOfApplicabilityExport); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.StateOfApplicabilityID.TenantID()) @@ -3393,7 +3675,9 @@ func (r *mutationResolver) ExportStateOfApplicabilityPDF(ctx context.Context, in // PublishDocumentVersion is the resolver for the publishDocumentVersion field. func (r *mutationResolver) PublishDocumentVersion(ctx context.Context, input types.PublishDocumentVersionInput) (*types.PublishDocumentVersionPayload, error) { - r.MustAuthorize(ctx, input.DocumentID, probo.ActionDocumentVersionPublish) + if err := r.authorize(ctx, input.DocumentID, probo.ActionDocumentVersionPublish); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DocumentID.TenantID()) @@ -3403,7 +3687,7 @@ func (r *mutationResolver) PublishDocumentVersion(ctx context.Context, input typ if err != nil { var errNoChanges *probo.ErrDocumentVersionNoChanges if errors.As(err, &errNoChanges) { - return nil, gqlutils.Invalid(errNoChanges, nil) + return nil, gqlutils.Invalid(ctx, errNoChanges) } // TODO no panic use gqlutils.InternalError @@ -3426,7 +3710,9 @@ func (r *mutationResolver) BulkPublishDocumentVersions(ctx context.Context, inpu } for _, documentID := range input.DocumentIds { - r.MustAuthorize(ctx, documentID, probo.ActionDocumentVersionPublish) + if err := r.authorize(ctx, documentID, probo.ActionDocumentVersionPublish); err != nil { + return nil, err + } } prb := r.ProboService(ctx, input.DocumentIds[0].TenantID()) @@ -3444,7 +3730,7 @@ func (r *mutationResolver) BulkPublishDocumentVersions(ctx context.Context, inpu if err != nil { var errNoChanges *probo.ErrDocumentVersionNoChanges if errors.As(err, &errNoChanges) { - return nil, gqlutils.Invalid(errNoChanges, nil) + return nil, gqlutils.Invalid(ctx, errNoChanges) } // TODO no panic use gqlutils.InternalError @@ -3466,7 +3752,9 @@ func (r *mutationResolver) BulkDeleteDocuments(ctx context.Context, input types. } for _, documentID := range input.DocumentIds { - r.MustAuthorize(ctx, documentID, probo.ActionDocumentDelete) + if err := r.authorize(ctx, documentID, probo.ActionDocumentDelete); err != nil { + return nil, err + } } prb := r.ProboService(ctx, input.DocumentIds[0].TenantID()) @@ -3489,7 +3777,9 @@ func (r *mutationResolver) BulkExportDocuments(ctx context.Context, input types. // TODO have a way to batch authorize for resources for _, documentID := range input.DocumentIds { - r.MustAuthorize(ctx, documentID, probo.ActionDocumentVersionExport) + if err := r.authorize(ctx, documentID, probo.ActionDocumentVersionExport); err != nil { + return nil, err + } } prb := r.ProboService(ctx, input.DocumentIds[0].TenantID()) @@ -3514,7 +3804,9 @@ func (r *mutationResolver) BulkExportDocuments(ctx context.Context, input types. // GenerateDocumentChangelog is the resolver for the generateDocumentChangelog field. func (r *mutationResolver) GenerateDocumentChangelog(ctx context.Context, input types.GenerateDocumentChangelogInput) (*types.GenerateDocumentChangelogPayload, error) { - r.MustAuthorize(ctx, input.DocumentID, probo.ActionDocumentChangelogGenerate) + if err := r.authorize(ctx, input.DocumentID, probo.ActionDocumentChangelogGenerate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DocumentID.TenantID()) @@ -3531,7 +3823,9 @@ func (r *mutationResolver) GenerateDocumentChangelog(ctx context.Context, input // CreateDraftDocumentVersion is the resolver for the createDraftDocumentVersion field. func (r *mutationResolver) CreateDraftDocumentVersion(ctx context.Context, input types.CreateDraftDocumentVersionInput) (*types.CreateDraftDocumentVersionPayload, error) { - r.MustAuthorize(ctx, input.DocumentID, probo.ActionDocumentDraftVersionCreate) + if err := r.authorize(ctx, input.DocumentID, probo.ActionDocumentDraftVersionCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DocumentID.TenantID()) @@ -3548,7 +3842,9 @@ func (r *mutationResolver) CreateDraftDocumentVersion(ctx context.Context, input // DeleteDraftDocumentVersion is the resolver for the deleteDraftDocumentVersion field. func (r *mutationResolver) DeleteDraftDocumentVersion(ctx context.Context, input types.DeleteDraftDocumentVersionInput) (*types.DeleteDraftDocumentVersionPayload, error) { - r.MustAuthorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionDeleteDraft) + if err := r.authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionDeleteDraft); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) @@ -3565,7 +3861,9 @@ func (r *mutationResolver) DeleteDraftDocumentVersion(ctx context.Context, input // UpdateDocumentVersion is the resolver for the updateDocumentVersion field. func (r *mutationResolver) UpdateDocumentVersion(ctx context.Context, input types.UpdateDocumentVersionInput) (*types.UpdateDocumentVersionPayload, error) { - r.MustAuthorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionUpdate) + if err := r.authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) @@ -3588,7 +3886,9 @@ func (r *mutationResolver) UpdateDocumentVersion(ctx context.Context, input type // RequestSignature is the resolver for the requestSignature field. func (r *mutationResolver) RequestSignature(ctx context.Context, input types.RequestSignatureInput) (*types.RequestSignaturePayload, error) { - r.MustAuthorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionSignatureRequest) + if err := r.authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionSignatureRequest); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) @@ -3618,7 +3918,9 @@ func (r *mutationResolver) BulkRequestSignatures(ctx context.Context, input type } for _, documentID := range input.DocumentIds { - r.MustAuthorize(ctx, documentID, probo.ActionDocumentVersionSignatureRequest) + if err := r.authorize(ctx, documentID, probo.ActionDocumentVersionSignatureRequest); err != nil { + return nil, err + } } prb := r.ProboService(ctx, input.DocumentIds[0].TenantID()) @@ -3642,7 +3944,9 @@ func (r *mutationResolver) BulkRequestSignatures(ctx context.Context, input type // SendSigningNotifications is the resolver for the sendSigningNotifications field. func (r *mutationResolver) SendSigningNotifications(ctx context.Context, input types.SendSigningNotificationsInput) (*types.SendSigningNotificationsPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionDocumentSendSigningNotifications) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionDocumentSendSigningNotifications); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -3659,7 +3963,9 @@ func (r *mutationResolver) SendSigningNotifications(ctx context.Context, input t // CancelSignatureRequest is the resolver for the cancelSignatureRequest field. func (r *mutationResolver) CancelSignatureRequest(ctx context.Context, input types.CancelSignatureRequestInput) (*types.CancelSignatureRequestPayload, error) { - r.MustAuthorize(ctx, input.DocumentVersionSignatureID, probo.ActionDocumentVersionCancelSignature) + if err := r.authorize(ctx, input.DocumentVersionSignatureID, probo.ActionDocumentVersionCancelSignature); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DocumentVersionSignatureID.TenantID()) @@ -3676,7 +3982,9 @@ func (r *mutationResolver) CancelSignatureRequest(ctx context.Context, input typ // SignDocument is the resolver for the signDocument field. func (r *mutationResolver) SignDocument(ctx context.Context, input types.SignDocumentInput) (*types.SignDocumentPayload, error) { - r.MustAuthorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionSign) + if err := r.authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionSign); err != nil { + return nil, err + } identity := connect_v1.IdentityFromContext(ctx) prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) @@ -3684,7 +3992,7 @@ func (r *mutationResolver) SignDocument(ctx context.Context, input types.SignDoc documentVersionSignature, err := prb.Documents.SignDocumentVersionByEmail(ctx, input.DocumentVersionID, identity.EmailAddress) if err != nil { if errors.Is(err, coredata.ErrResourceAlreadyExists) { - return nil, gqlutils.Conflict(err) + return nil, gqlutils.Conflict(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -3698,7 +4006,9 @@ func (r *mutationResolver) SignDocument(ctx context.Context, input types.SignDoc // ExportDocumentVersionPDF is the resolver for the exportDocumentVersionPDF field. func (r *mutationResolver) ExportDocumentVersionPDF(ctx context.Context, input types.ExportDocumentVersionPDFInput) (*types.ExportDocumentVersionPDFPayload, error) { - r.MustAuthorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionExportPDF) + if err := r.authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionExportPDF); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) @@ -3721,7 +4031,9 @@ func (r *mutationResolver) ExportDocumentVersionPDF(ctx context.Context, input t // ExportSignableVersionDocumentPDF is the resolver for the exportSignableVersionDocumentPDF field. func (r *mutationResolver) ExportSignableVersionDocumentPDF(ctx context.Context, input types.ExportSignableDocumentVersionPDFInput) (*types.ExportSignableDocumentVersionPDFPayload, error) { - r.MustAuthorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionExportSignable) + if err := r.authorize(ctx, input.DocumentVersionID, probo.ActionDocumentVersionExportSignable); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) @@ -3737,7 +4049,7 @@ func (r *mutationResolver) ExportSignableVersionDocumentPDF(ctx context.Context, _, err = prb.Documents.GetWithFilter(ctx, documentVersion.DocumentID, documentFilter) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -3763,7 +4075,9 @@ func (r *mutationResolver) ExportSignableVersionDocumentPDF(ctx context.Context, // ExportProcessingActivitiesPDF is the resolver for the exportProcessingActivitiesPDF field. func (r *mutationResolver) ExportProcessingActivitiesPDF(ctx context.Context, input types.ExportProcessingActivitiesPDFInput) (*types.ExportProcessingActivitiesPDFPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionProcessingActivityExport) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionProcessingActivityExport); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -3775,9 +4089,8 @@ func (r *mutationResolver) ExportProcessingActivitiesPDF(ctx context.Context, in pdf, err := prb.ProcessingActivities.ExportPDF(ctx, input.OrganizationID, processingActivityFilter) if err != nil { - var errNotFound *coredata.ErrNoProcessingActivitiesFound - if errors.As(err, &errNotFound) { - return nil, gqlutils.NotFound(errNotFound) + if errors.Is(err, coredata.ErrResourceNotFound) { + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot export processing activities PDF: %w", err)) } @@ -3789,7 +4102,9 @@ func (r *mutationResolver) ExportProcessingActivitiesPDF(ctx context.Context, in // ExportDataProtectionImpactAssessmentsPDF is the resolver for the exportDataProtectionImpactAssessmentsPDF field. func (r *mutationResolver) ExportDataProtectionImpactAssessmentsPDF(ctx context.Context, input types.ExportDataProtectionImpactAssessmentsPDFInput) (*types.ExportDataProtectionImpactAssessmentsPDFPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionDataProtectionImpactAssessmentExport) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionDataProtectionImpactAssessmentExport); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -3802,7 +4117,7 @@ func (r *mutationResolver) ExportDataProtectionImpactAssessmentsPDF(ctx context. pdf, err := prb.DataProtectionImpactAssessments.ExportPDF(ctx, input.OrganizationID, dpiaFilter) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot export data protection impact assessments PDF: %w", err)) } @@ -3814,7 +4129,9 @@ func (r *mutationResolver) ExportDataProtectionImpactAssessmentsPDF(ctx context. // ExportTransferImpactAssessmentsPDF is the resolver for the exportTransferImpactAssessmentsPDF field. func (r *mutationResolver) ExportTransferImpactAssessmentsPDF(ctx context.Context, input types.ExportTransferImpactAssessmentsPDFInput) (*types.ExportTransferImpactAssessmentsPDFPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionTransferImpactAssessmentExport) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionTransferImpactAssessmentExport); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -3827,7 +4144,7 @@ func (r *mutationResolver) ExportTransferImpactAssessmentsPDF(ctx context.Contex pdf, err := prb.TransferImpactAssessments.ExportPDF(ctx, input.OrganizationID, tiaFilter) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot export transfer impact assessments PDF: %w", err)) } @@ -3839,7 +4156,9 @@ func (r *mutationResolver) ExportTransferImpactAssessmentsPDF(ctx context.Contex // CreateVendorRiskAssessment is the resolver for the createVendorRiskAssessment field. func (r *mutationResolver) CreateVendorRiskAssessment(ctx context.Context, input types.CreateVendorRiskAssessmentInput) (*types.CreateVendorRiskAssessmentPayload, error) { - r.MustAuthorize(ctx, input.VendorID, probo.ActionVendorRiskAssessmentCreate) + if err := r.authorize(ctx, input.VendorID, probo.ActionVendorRiskAssessmentCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.VendorID.TenantID()) @@ -3865,7 +4184,9 @@ func (r *mutationResolver) CreateVendorRiskAssessment(ctx context.Context, input // AssessVendor is the resolver for the assessVendor field. func (r *mutationResolver) AssessVendor(ctx context.Context, input types.AssessVendorInput) (*types.AssessVendorPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionVendorAssess) + if err := r.authorize(ctx, input.ID, probo.ActionVendorAssess); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -3888,7 +4209,9 @@ func (r *mutationResolver) AssessVendor(ctx context.Context, input types.AssessV // CreateAsset is the resolver for the createAsset field. func (r *mutationResolver) CreateAsset(ctx context.Context, input types.CreateAssetInput) (*types.CreateAssetPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionAssetCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionAssetCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -3917,7 +4240,9 @@ func (r *mutationResolver) CreateAsset(ctx context.Context, input types.CreateAs // UpdateAsset is the resolver for the updateAsset field. func (r *mutationResolver) UpdateAsset(ctx context.Context, input types.UpdateAssetInput) (*types.UpdateAssetPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionAssetUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionAssetUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -3945,7 +4270,9 @@ func (r *mutationResolver) UpdateAsset(ctx context.Context, input types.UpdateAs // DeleteAsset is the resolver for the deleteAsset field. func (r *mutationResolver) DeleteAsset(ctx context.Context, input types.DeleteAssetInput) (*types.DeleteAssetPayload, error) { - r.MustAuthorize(ctx, input.AssetID, probo.ActionAssetDelete) + if err := r.authorize(ctx, input.AssetID, probo.ActionAssetDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.AssetID.TenantID()) @@ -3962,7 +4289,9 @@ func (r *mutationResolver) DeleteAsset(ctx context.Context, input types.DeleteAs // CreateDatum is the resolver for the createDatum field. func (r *mutationResolver) CreateDatum(ctx context.Context, input types.CreateDatumInput) (*types.CreateDatumPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionDatumCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionDatumCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -3989,7 +4318,9 @@ func (r *mutationResolver) CreateDatum(ctx context.Context, input types.CreateDa // UpdateDatum is the resolver for the updateDatum field. func (r *mutationResolver) UpdateDatum(ctx context.Context, input types.UpdateDatumInput) (*types.UpdateDatumPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionDatumUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionDatumUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -4016,7 +4347,9 @@ func (r *mutationResolver) UpdateDatum(ctx context.Context, input types.UpdateDa // DeleteDatum is the resolver for the deleteDatum field. func (r *mutationResolver) DeleteDatum(ctx context.Context, input types.DeleteDatumInput) (*types.DeleteDatumPayload, error) { - r.MustAuthorize(ctx, input.DatumID, probo.ActionDatumDelete) + if err := r.authorize(ctx, input.DatumID, probo.ActionDatumDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DatumID.TenantID()) @@ -4032,7 +4365,9 @@ func (r *mutationResolver) DeleteDatum(ctx context.Context, input types.DeleteDa // CreateAudit is the resolver for the createAudit field. func (r *mutationResolver) CreateAudit(ctx context.Context, input types.CreateAuditInput) (*types.CreateAuditPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionAuditCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionAuditCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -4059,7 +4394,9 @@ func (r *mutationResolver) CreateAudit(ctx context.Context, input types.CreateAu // UpdateAudit is the resolver for the updateAudit field. func (r *mutationResolver) UpdateAudit(ctx context.Context, input types.UpdateAuditInput) (*types.UpdateAuditPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionAuditUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionAuditUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -4085,7 +4422,9 @@ func (r *mutationResolver) UpdateAudit(ctx context.Context, input types.UpdateAu // DeleteAudit is the resolver for the deleteAudit field. func (r *mutationResolver) DeleteAudit(ctx context.Context, input types.DeleteAuditInput) (*types.DeleteAuditPayload, error) { - r.MustAuthorize(ctx, input.AuditID, probo.ActionAuditDelete) + if err := r.authorize(ctx, input.AuditID, probo.ActionAuditDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.AuditID.TenantID()) @@ -4102,7 +4441,9 @@ func (r *mutationResolver) DeleteAudit(ctx context.Context, input types.DeleteAu // UploadAuditReport is the resolver for the uploadAuditReport field. func (r *mutationResolver) UploadAuditReport(ctx context.Context, input types.UploadAuditReportInput) (*types.UploadAuditReportPayload, error) { - r.MustAuthorize(ctx, input.AuditID, probo.ActionAuditReportUpload) + if err := r.authorize(ctx, input.AuditID, probo.ActionAuditReportUpload); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.AuditID.TenantID()) @@ -4129,7 +4470,9 @@ func (r *mutationResolver) UploadAuditReport(ctx context.Context, input types.Up // DeleteAuditReport is the resolver for the deleteAuditReport field. func (r *mutationResolver) DeleteAuditReport(ctx context.Context, input types.DeleteAuditReportInput) (*types.DeleteAuditReportPayload, error) { - r.MustAuthorize(ctx, input.AuditID, probo.ActionAuditReportDelete) + if err := r.authorize(ctx, input.AuditID, probo.ActionAuditReportDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.AuditID.TenantID()) @@ -4146,7 +4489,9 @@ func (r *mutationResolver) DeleteAuditReport(ctx context.Context, input types.De // CreateNonconformity is the resolver for the createNonconformity field. func (r *mutationResolver) CreateNonconformity(ctx context.Context, input types.CreateNonconformityInput) (*types.CreateNonconformityPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionNonconformityCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionNonconformityCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -4177,7 +4522,9 @@ func (r *mutationResolver) CreateNonconformity(ctx context.Context, input types. // UpdateNonconformity is the resolver for the updateNonconformity field. func (r *mutationResolver) UpdateNonconformity(ctx context.Context, input types.UpdateNonconformityInput) (*types.UpdateNonconformityPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionNonconformityUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionNonconformityUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -4208,7 +4555,9 @@ func (r *mutationResolver) UpdateNonconformity(ctx context.Context, input types. // DeleteNonconformity is the resolver for the deleteNonconformity field. func (r *mutationResolver) DeleteNonconformity(ctx context.Context, input types.DeleteNonconformityInput) (*types.DeleteNonconformityPayload, error) { - r.MustAuthorize(ctx, input.NonconformityID, probo.ActionNonconformityDelete) + if err := r.authorize(ctx, input.NonconformityID, probo.ActionNonconformityDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.NonconformityID.TenantID()) @@ -4225,7 +4574,9 @@ func (r *mutationResolver) DeleteNonconformity(ctx context.Context, input types. // CreateObligation is the resolver for the createObligation field. func (r *mutationResolver) CreateObligation(ctx context.Context, input types.CreateObligationInput) (*types.CreateObligationPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionObligationCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionObligationCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -4256,7 +4607,9 @@ func (r *mutationResolver) CreateObligation(ctx context.Context, input types.Cre // UpdateObligation is the resolver for the updateObligation field. func (r *mutationResolver) UpdateObligation(ctx context.Context, input types.UpdateObligationInput) (*types.UpdateObligationPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionObligationUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionObligationUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -4287,7 +4640,9 @@ func (r *mutationResolver) UpdateObligation(ctx context.Context, input types.Upd // DeleteObligation is the resolver for the deleteObligation field. func (r *mutationResolver) DeleteObligation(ctx context.Context, input types.DeleteObligationInput) (*types.DeleteObligationPayload, error) { - r.MustAuthorize(ctx, input.ObligationID, probo.ActionObligationDelete) + if err := r.authorize(ctx, input.ObligationID, probo.ActionObligationDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ObligationID.TenantID()) @@ -4304,7 +4659,9 @@ func (r *mutationResolver) DeleteObligation(ctx context.Context, input types.Del // CreateContinualImprovement is the resolver for the createContinualImprovement field. func (r *mutationResolver) CreateContinualImprovement(ctx context.Context, input types.CreateContinualImprovementInput) (*types.CreateContinualImprovementPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionContinualImprovementCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionContinualImprovementCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -4332,7 +4689,9 @@ func (r *mutationResolver) CreateContinualImprovement(ctx context.Context, input // UpdateContinualImprovement is the resolver for the updateContinualImprovement field. func (r *mutationResolver) UpdateContinualImprovement(ctx context.Context, input types.UpdateContinualImprovementInput) (*types.UpdateContinualImprovementPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionContinualImprovementUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionContinualImprovementUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -4360,7 +4719,9 @@ func (r *mutationResolver) UpdateContinualImprovement(ctx context.Context, input // DeleteContinualImprovement is the resolver for the deleteContinualImprovement field. func (r *mutationResolver) DeleteContinualImprovement(ctx context.Context, input types.DeleteContinualImprovementInput) (*types.DeleteContinualImprovementPayload, error) { - r.MustAuthorize(ctx, input.ContinualImprovementID, probo.ActionContinualImprovementDelete) + if err := r.authorize(ctx, input.ContinualImprovementID, probo.ActionContinualImprovementDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ContinualImprovementID.TenantID()) @@ -4377,7 +4738,9 @@ func (r *mutationResolver) DeleteContinualImprovement(ctx context.Context, input // CreateRightsRequest is the resolver for the createRightsRequest field. func (r *mutationResolver) CreateRightsRequest(ctx context.Context, input types.CreateRightsRequestInput) (*types.CreateRightsRequestPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionRightsRequestCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionRightsRequestCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -4404,7 +4767,9 @@ func (r *mutationResolver) CreateRightsRequest(ctx context.Context, input types. // UpdateRightsRequest is the resolver for the updateRightsRequest field. func (r *mutationResolver) UpdateRightsRequest(ctx context.Context, input types.UpdateRightsRequestInput) (*types.UpdateRightsRequestPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionRightsRequestUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionRightsRequestUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -4431,7 +4796,9 @@ func (r *mutationResolver) UpdateRightsRequest(ctx context.Context, input types. // DeleteRightsRequest is the resolver for the deleteRightsRequest field. func (r *mutationResolver) DeleteRightsRequest(ctx context.Context, input types.DeleteRightsRequestInput) (*types.DeleteRightsRequestPayload, error) { - r.MustAuthorize(ctx, input.RightsRequestID, probo.ActionRightsRequestDelete) + if err := r.authorize(ctx, input.RightsRequestID, probo.ActionRightsRequestDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.RightsRequestID.TenantID()) @@ -4447,7 +4814,9 @@ func (r *mutationResolver) DeleteRightsRequest(ctx context.Context, input types. // CreateProcessingActivity is the resolver for the createProcessingActivity field. func (r *mutationResolver) CreateProcessingActivity(ctx context.Context, input types.CreateProcessingActivityInput) (*types.CreateProcessingActivityPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionProcessingActivityCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionProcessingActivityCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -4487,7 +4856,9 @@ func (r *mutationResolver) CreateProcessingActivity(ctx context.Context, input t // UpdateProcessingActivity is the resolver for the updateProcessingActivity field. func (r *mutationResolver) UpdateProcessingActivity(ctx context.Context, input types.UpdateProcessingActivityInput) (*types.UpdateProcessingActivityPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionProcessingActivityUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionProcessingActivityUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -4527,7 +4898,9 @@ func (r *mutationResolver) UpdateProcessingActivity(ctx context.Context, input t // DeleteProcessingActivity is the resolver for the deleteProcessingActivity field. func (r *mutationResolver) DeleteProcessingActivity(ctx context.Context, input types.DeleteProcessingActivityInput) (*types.DeleteProcessingActivityPayload, error) { - r.MustAuthorize(ctx, input.ProcessingActivityID, probo.ActionProcessingActivityDelete) + if err := r.authorize(ctx, input.ProcessingActivityID, probo.ActionProcessingActivityDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ProcessingActivityID.TenantID()) @@ -4544,7 +4917,9 @@ func (r *mutationResolver) DeleteProcessingActivity(ctx context.Context, input t // CreateDataProtectionImpactAssessment is the resolver for the createDataProtectionImpactAssessment field. func (r *mutationResolver) CreateDataProtectionImpactAssessment(ctx context.Context, input types.CreateDataProtectionImpactAssessmentInput) (*types.CreateDataProtectionImpactAssessmentPayload, error) { - r.MustAuthorize(ctx, input.ProcessingActivityID, probo.ActionDataProtectionImpactAssessmentCreate) + if err := r.authorize(ctx, input.ProcessingActivityID, probo.ActionDataProtectionImpactAssessmentCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ProcessingActivityID.TenantID()) @@ -4569,7 +4944,9 @@ func (r *mutationResolver) CreateDataProtectionImpactAssessment(ctx context.Cont // UpdateDataProtectionImpactAssessment is the resolver for the updateDataProtectionImpactAssessment field. func (r *mutationResolver) UpdateDataProtectionImpactAssessment(ctx context.Context, input types.UpdateDataProtectionImpactAssessmentInput) (*types.UpdateDataProtectionImpactAssessmentPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionDataProtectionImpactAssessmentUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionDataProtectionImpactAssessmentUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -4594,7 +4971,9 @@ func (r *mutationResolver) UpdateDataProtectionImpactAssessment(ctx context.Cont // DeleteDataProtectionImpactAssessment is the resolver for the deleteDataProtectionImpactAssessment field. func (r *mutationResolver) DeleteDataProtectionImpactAssessment(ctx context.Context, input types.DeleteDataProtectionImpactAssessmentInput) (*types.DeleteDataProtectionImpactAssessmentPayload, error) { - r.MustAuthorize(ctx, input.DataProtectionImpactAssessmentID, probo.ActionDataProtectionImpactAssessmentDelete) + if err := r.authorize(ctx, input.DataProtectionImpactAssessmentID, probo.ActionDataProtectionImpactAssessmentDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.DataProtectionImpactAssessmentID.TenantID()) @@ -4610,7 +4989,9 @@ func (r *mutationResolver) DeleteDataProtectionImpactAssessment(ctx context.Cont // CreateTransferImpactAssessment is the resolver for the createTransferImpactAssessment field. func (r *mutationResolver) CreateTransferImpactAssessment(ctx context.Context, input types.CreateTransferImpactAssessmentInput) (*types.CreateTransferImpactAssessmentPayload, error) { - r.MustAuthorize(ctx, input.ProcessingActivityID, probo.ActionTransferImpactAssessmentCreate) + if err := r.authorize(ctx, input.ProcessingActivityID, probo.ActionTransferImpactAssessmentCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ProcessingActivityID.TenantID()) @@ -4635,7 +5016,9 @@ func (r *mutationResolver) CreateTransferImpactAssessment(ctx context.Context, i // UpdateTransferImpactAssessment is the resolver for the updateTransferImpactAssessment field. func (r *mutationResolver) UpdateTransferImpactAssessment(ctx context.Context, input types.UpdateTransferImpactAssessmentInput) (*types.UpdateTransferImpactAssessmentPayload, error) { - r.MustAuthorize(ctx, input.ID, probo.ActionTransferImpactAssessmentUpdate) + if err := r.authorize(ctx, input.ID, probo.ActionTransferImpactAssessmentUpdate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.ID.TenantID()) @@ -4660,7 +5043,9 @@ func (r *mutationResolver) UpdateTransferImpactAssessment(ctx context.Context, i // DeleteTransferImpactAssessment is the resolver for the deleteTransferImpactAssessment field. func (r *mutationResolver) DeleteTransferImpactAssessment(ctx context.Context, input types.DeleteTransferImpactAssessmentInput) (*types.DeleteTransferImpactAssessmentPayload, error) { - r.MustAuthorize(ctx, input.TransferImpactAssessmentID, probo.ActionTransferImpactAssessmentDelete) + if err := r.authorize(ctx, input.TransferImpactAssessmentID, probo.ActionTransferImpactAssessmentDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.TransferImpactAssessmentID.TenantID()) @@ -4676,7 +5061,9 @@ func (r *mutationResolver) DeleteTransferImpactAssessment(ctx context.Context, i // CreateSnapshot is the resolver for the createSnapshot field. func (r *mutationResolver) CreateSnapshot(ctx context.Context, input types.CreateSnapshotInput) (*types.CreateSnapshotPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionSnapshotCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionSnapshotCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -4701,7 +5088,9 @@ func (r *mutationResolver) CreateSnapshot(ctx context.Context, input types.Creat // DeleteSnapshot is the resolver for the deleteSnapshot field. func (r *mutationResolver) DeleteSnapshot(ctx context.Context, input types.DeleteSnapshotInput) (*types.DeleteSnapshotPayload, error) { - r.MustAuthorize(ctx, input.SnapshotID, probo.ActionSnapshotDelete) + if err := r.authorize(ctx, input.SnapshotID, probo.ActionSnapshotDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.SnapshotID.TenantID()) @@ -4718,7 +5107,9 @@ func (r *mutationResolver) DeleteSnapshot(ctx context.Context, input types.Delet // CreateCustomDomain is the resolver for the createCustomDomain field. func (r *mutationResolver) CreateCustomDomain(ctx context.Context, input types.CreateCustomDomainInput) (*types.CreateCustomDomainPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionCustomDomainCreate) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionCustomDomainCreate); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -4741,7 +5132,9 @@ func (r *mutationResolver) CreateCustomDomain(ctx context.Context, input types.C // DeleteCustomDomain is the resolver for the deleteCustomDomain field. func (r *mutationResolver) DeleteCustomDomain(ctx context.Context, input types.DeleteCustomDomainInput) (*types.DeleteCustomDomainPayload, error) { - r.MustAuthorize(ctx, input.OrganizationID, probo.ActionCustomDomainDelete) + if err := r.authorize(ctx, input.OrganizationID, probo.ActionCustomDomainDelete); err != nil { + return nil, err + } prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -4770,14 +5163,16 @@ func (r *mutationResolver) DeleteCustomDomain(ctx context.Context, input types.D // Organization is the resolver for the organization field. func (r *nonconformityResolver) Organization(ctx context.Context, obj *types.Nonconformity) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -4789,7 +5184,9 @@ func (r *nonconformityResolver) Organization(ctx context.Context, obj *types.Non // Audit is the resolver for the audit field. func (r *nonconformityResolver) Audit(ctx context.Context, obj *types.Nonconformity) (*types.Audit, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionAuditGet) + if err := r.authorize(ctx, obj.ID, probo.ActionAuditGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -4800,7 +5197,7 @@ func (r *nonconformityResolver) Audit(ctx context.Context, obj *types.Nonconform audit, err := prb.Audits.Get(ctx, obj.Audit.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -4812,14 +5209,16 @@ func (r *nonconformityResolver) Audit(ctx context.Context, obj *types.Nonconform // Owner is the resolver for the owner field. func (r *nonconformityResolver) Owner(ctx context.Context, obj *types.Nonconformity) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleGet) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) people, err := prb.Peoples.Get(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -4836,7 +5235,9 @@ func (r *nonconformityResolver) Permission(ctx context.Context, obj *types.Nonco // TotalCount is the resolver for the totalCount field. func (r *nonconformityConnectionResolver) TotalCount(ctx context.Context, obj *types.NonconformityConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionNonconformityList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionNonconformityList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { @@ -4860,14 +5261,16 @@ func (r *nonconformityConnectionResolver) TotalCount(ctx context.Context, obj *t // Organization is the resolver for the organization field. func (r *obligationResolver) Organization(ctx context.Context, obj *types.Obligation) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -4879,14 +5282,16 @@ func (r *obligationResolver) Organization(ctx context.Context, obj *types.Obliga // Owner is the resolver for the owner field. func (r *obligationResolver) Owner(ctx context.Context, obj *types.Obligation) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleGet) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) people, err := prb.Peoples.Get(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -4903,7 +5308,9 @@ func (r *obligationResolver) Permission(ctx context.Context, obj *types.Obligati // TotalCount is the resolver for the totalCount field. func (r *obligationConnectionResolver) TotalCount(ctx context.Context, obj *types.ObligationConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionObligationList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionObligationList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -4940,7 +5347,9 @@ func (r *obligationConnectionResolver) TotalCount(ctx context.Context, obj *type // LogoURL is the resolver for the logoUrl field. func (r *organizationResolver) LogoURL(ctx context.Context, obj *types.Organization) (*string, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGetLogoUrl) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGetLogoUrl); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -4955,7 +5364,9 @@ func (r *organizationResolver) LogoURL(ctx context.Context, obj *types.Organizat // HorizontalLogoURL is the resolver for the horizontalLogoUrl field. func (r *organizationResolver) HorizontalLogoURL(ctx context.Context, obj *types.Organization) (*string, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGetHorizontalLogoUrl) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGetHorizontalLogoUrl); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -4970,7 +5381,9 @@ func (r *organizationResolver) HorizontalLogoURL(ctx context.Context, obj *types // Context is the resolver for the context field. func (r *organizationResolver) Context(ctx context.Context, obj *types.Organization) (*types.OrganizationContext, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationContextGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationContextGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -4985,7 +5398,9 @@ func (r *organizationResolver) Context(ctx context.Context, obj *types.Organizat // SlackConnections is the resolver for the slackConnections field. func (r *organizationResolver) SlackConnections(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.SlackConnectionConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionSlackConnectionList) + if err := r.authorize(ctx, obj.ID, probo.ActionSlackConnectionList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5010,7 +5425,9 @@ func (r *organizationResolver) SlackConnections(ctx context.Context, obj *types. // Frameworks is the resolver for the frameworks field. func (r *organizationResolver) Frameworks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.FrameworkOrderBy) (*types.FrameworkConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionFrameworkList) + if err := r.authorize(ctx, obj.ID, probo.ActionFrameworkList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5038,7 +5455,9 @@ func (r *organizationResolver) Frameworks(ctx context.Context, obj *types.Organi // Controls is the resolver for the controls field. func (r *organizationResolver) Controls(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionControlList) + if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5071,7 +5490,9 @@ func (r *organizationResolver) Controls(ctx context.Context, obj *types.Organiza // Vendors is the resolver for the vendors field. func (r *organizationResolver) Vendors(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy, filter *types.VendorFilter) (*types.VendorConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorList) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5104,7 +5525,9 @@ func (r *organizationResolver) Vendors(ctx context.Context, obj *types.Organizat // Peoples is the resolver for the peoples field. func (r *organizationResolver) Peoples(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.PeopleOrderBy, filter *types.PeopleFilter) (*types.PeopleConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleList) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5137,7 +5560,9 @@ func (r *organizationResolver) Peoples(ctx context.Context, obj *types.Organizat // Documents is the resolver for the documents field. func (r *organizationResolver) Documents(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) (*types.DocumentConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDocumentList) + if err := r.authorize(ctx, obj.ID, probo.ActionDocumentList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5170,7 +5595,9 @@ func (r *organizationResolver) Documents(ctx context.Context, obj *types.Organiz // Meetings is the resolver for the meetings field. func (r *organizationResolver) Meetings(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeetingOrderBy) (*types.MeetingConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionMeetingList) + if err := r.authorize(ctx, obj.ID, probo.ActionMeetingList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5198,7 +5625,9 @@ func (r *organizationResolver) Meetings(ctx context.Context, obj *types.Organiza // StatesOfApplicability is the resolver for the statesOfApplicability field. func (r *organizationResolver) StatesOfApplicability(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.StateOfApplicabilityOrderBy, filter *types.StateOfApplicabilityFilter) (*types.StateOfApplicabilityConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionStateOfApplicabilityList) + if err := r.authorize(ctx, obj.ID, probo.ActionStateOfApplicabilityList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5230,7 +5659,9 @@ func (r *organizationResolver) StatesOfApplicability(ctx context.Context, obj *t // Measures is the resolver for the measures field. func (r *organizationResolver) Measures(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) (*types.MeasureConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionMeasureList) + if err := r.authorize(ctx, obj.ID, probo.ActionMeasureList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5263,7 +5694,9 @@ func (r *organizationResolver) Measures(ctx context.Context, obj *types.Organiza // Risks is the resolver for the risks field. func (r *organizationResolver) Risks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.RiskOrderBy, filter *types.RiskFilter) (*types.RiskConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionRiskList) + if err := r.authorize(ctx, obj.ID, probo.ActionRiskList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5296,7 +5729,9 @@ func (r *organizationResolver) Risks(ctx context.Context, obj *types.Organizatio // Tasks is the resolver for the tasks field. func (r *organizationResolver) Tasks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TaskOrderBy) (*types.TaskConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTaskList) + if err := r.authorize(ctx, obj.ID, probo.ActionTaskList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5324,7 +5759,9 @@ func (r *organizationResolver) Tasks(ctx context.Context, obj *types.Organizatio // Assets is the resolver for the assets field. func (r *organizationResolver) Assets(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AssetOrderBy, filter *types.AssetFilter) (*types.AssetConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionAssetList) + if err := r.authorize(ctx, obj.ID, probo.ActionAssetList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5357,7 +5794,9 @@ func (r *organizationResolver) Assets(ctx context.Context, obj *types.Organizati // Assets is the resolver for the assets field. func (r *organizationResolver) Data(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DatumOrderBy, filter *types.DatumFilter) (*types.DatumConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDatumList) + if err := r.authorize(ctx, obj.ID, probo.ActionDatumList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5390,7 +5829,9 @@ func (r *organizationResolver) Data(ctx context.Context, obj *types.Organization // Audits is the resolver for the audits field. func (r *organizationResolver) Audits(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AuditOrderBy) (*types.AuditConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionAuditList) + if err := r.authorize(ctx, obj.ID, probo.ActionAuditList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5418,7 +5859,9 @@ func (r *organizationResolver) Audits(ctx context.Context, obj *types.Organizati // Nonconformities is the resolver for the nonconformities field. func (r *organizationResolver) Nonconformities(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.NonconformityOrderBy, filter *types.NonconformityFilter) (*types.NonconformityConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionNonconformityList) + if err := r.authorize(ctx, obj.ID, probo.ActionNonconformityList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5452,7 +5895,9 @@ func (r *organizationResolver) Nonconformities(ctx context.Context, obj *types.O // Obligations is the resolver for the obligations field. func (r *organizationResolver) Obligations(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ObligationOrderBy, filter *types.ObligationFilter) (*types.ObligationConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionObligationList) + if err := r.authorize(ctx, obj.ID, probo.ActionObligationList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5486,7 +5931,9 @@ func (r *organizationResolver) Obligations(ctx context.Context, obj *types.Organ // ContinualImprovements is the resolver for the continualImprovements field. func (r *organizationResolver) ContinualImprovements(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ContinualImprovementOrderBy, filter *types.ContinualImprovementFilter) (*types.ContinualImprovementConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionContinualImprovementList) + if err := r.authorize(ctx, obj.ID, probo.ActionContinualImprovementList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5520,7 +5967,9 @@ func (r *organizationResolver) ContinualImprovements(ctx context.Context, obj *t // RightsRequests is the resolver for the rightsRequests field. func (r *organizationResolver) RightsRequests(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.RightsRequestOrderBy) (*types.RightsRequestConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionRightsRequestList) + if err := r.authorize(ctx, obj.ID, probo.ActionRightsRequestList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5548,7 +5997,9 @@ func (r *organizationResolver) RightsRequests(ctx context.Context, obj *types.Or // ProcessingActivities is the resolver for the processingActivities field. func (r *organizationResolver) ProcessingActivities(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProcessingActivityOrderBy, filter *types.ProcessingActivityFilter) (*types.ProcessingActivityConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionProcessingActivityList) + if err := r.authorize(ctx, obj.ID, probo.ActionProcessingActivityList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5582,7 +6033,9 @@ func (r *organizationResolver) ProcessingActivities(ctx context.Context, obj *ty // DataProtectionImpactAssessments is the resolver for the dataProtectionImpactAssessments field. func (r *organizationResolver) DataProtectionImpactAssessments(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DataProtectionImpactAssessmentOrderBy, filter *types.DataProtectionImpactAssessmentFilter) (*types.DataProtectionImpactAssessmentConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDataProtectionImpactAssessmentList) + if err := r.authorize(ctx, obj.ID, probo.ActionDataProtectionImpactAssessmentList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5615,7 +6068,9 @@ func (r *organizationResolver) DataProtectionImpactAssessments(ctx context.Conte // TransferImpactAssessments is the resolver for the transferImpactAssessments field. func (r *organizationResolver) TransferImpactAssessments(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TransferImpactAssessmentOrderBy, filter *types.TransferImpactAssessmentFilter) (*types.TransferImpactAssessmentConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTransferImpactAssessmentList) + if err := r.authorize(ctx, obj.ID, probo.ActionTransferImpactAssessmentList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5648,7 +6103,9 @@ func (r *organizationResolver) TransferImpactAssessments(ctx context.Context, ob // Snapshots is the resolver for the snapshots field. func (r *organizationResolver) Snapshots(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SnapshotOrderBy) (*types.SnapshotConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionSnapshotList) + if err := r.authorize(ctx, obj.ID, probo.ActionSnapshotList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5676,7 +6133,9 @@ func (r *organizationResolver) Snapshots(ctx context.Context, obj *types.Organiz // 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) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTrustCenterFileList) + if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterFileList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5704,7 +6163,9 @@ func (r *organizationResolver) TrustCenterFiles(ctx context.Context, obj *types. // TrustCenter is the resolver for the trustCenter field. func (r *organizationResolver) TrustCenter(ctx context.Context, obj *types.Organization) (*types.TrustCenter, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTrustCenterGet) + if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5719,7 +6180,9 @@ func (r *organizationResolver) TrustCenter(ctx context.Context, obj *types.Organ // CustomDomain is the resolver for the customDomain field. func (r *organizationResolver) CustomDomain(ctx context.Context, obj *types.Organization) (*types.CustomDomain, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionCustomDomainGet) + if err := r.authorize(ctx, obj.ID, probo.ActionCustomDomainGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5748,7 +6211,9 @@ func (r *peopleResolver) Permission(ctx context.Context, obj *types.People, acti // TotalCount is the resolver for the totalCount field. func (r *peopleConnectionResolver) TotalCount(ctx context.Context, obj *types.PeopleConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionPeopleList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionPeopleList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -5769,14 +6234,16 @@ func (r *peopleConnectionResolver) TotalCount(ctx context.Context, obj *types.Pe // Organization is the resolver for the organization field. func (r *processingActivityResolver) Organization(ctx context.Context, obj *types.ProcessingActivity) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -5788,7 +6255,9 @@ func (r *processingActivityResolver) Organization(ctx context.Context, obj *type // DataProtectionOfficer is the resolver for the dataProtectionOfficer field. func (r *processingActivityResolver) DataProtectionOfficer(ctx context.Context, obj *types.ProcessingActivity) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDataProtectionOfficerList) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5811,7 +6280,9 @@ func (r *processingActivityResolver) DataProtectionOfficer(ctx context.Context, // Vendors is the resolver for the vendors field. func (r *processingActivityResolver) Vendors(ctx context.Context, obj *types.ProcessingActivity, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) (*types.VendorConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorList) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5839,7 +6310,9 @@ func (r *processingActivityResolver) Vendors(ctx context.Context, obj *types.Pro // DataProtectionImpactAssessment is the resolver for the dataProtectionImpactAssessment field. func (r *processingActivityResolver) DataProtectionImpactAssessment(ctx context.Context, obj *types.ProcessingActivity) (*types.DataProtectionImpactAssessment, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDataProtectionImpactAssessmentList) + if err := r.authorize(ctx, obj.ID, probo.ActionDataProtectionImpactAssessmentGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5856,7 +6329,9 @@ func (r *processingActivityResolver) DataProtectionImpactAssessment(ctx context. // TransferImpactAssessment is the resolver for the transferImpactAssessment field. func (r *processingActivityResolver) TransferImpactAssessment(ctx context.Context, obj *types.ProcessingActivity) (*types.TransferImpactAssessment, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTransferImpactAssessmentList) + if err := r.authorize(ctx, obj.ID, probo.ActionTransferImpactAssessmentGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -5878,7 +6353,9 @@ func (r *processingActivityResolver) Permission(ctx context.Context, obj *types. // TotalCount is the resolver for the totalCount field. func (r *processingActivityConnectionResolver) TotalCount(ctx context.Context, obj *types.ProcessingActivityConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionProcessingActivityList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionProcessingActivityList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -6194,12 +6671,14 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error default: } - r.MustAuthorize(ctx, id, action) + if err := r.authorize(ctx, id, action); err != nil { + return nil, err + } node, err := loadNode(ctx, id) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load node: %w", err)) @@ -6229,7 +6708,9 @@ func (r *queryResolver) Viewer(ctx context.Context) (*types.Viewer, error) { // DownloadURL is the resolver for the downloadUrl field. func (r *reportResolver) DownloadURL(ctx context.Context, obj *types.Report) (*string, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionReportDownloadUrlGet) + if err := r.authorize(ctx, obj.ID, probo.ActionReportDownloadUrlGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6244,7 +6725,9 @@ func (r *reportResolver) DownloadURL(ctx context.Context, obj *types.Report) (*s // Audit is the resolver for the audit field. func (r *reportResolver) Audit(ctx context.Context, obj *types.Report) (*types.Audit, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionAuditGet) + if err := r.authorize(ctx, obj.ID, probo.ActionAuditGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6264,7 +6747,9 @@ func (r *reportResolver) Permission(ctx context.Context, obj *types.Report, acti // Organization is the resolver for the organization field. func (r *rightsRequestResolver) Organization(ctx context.Context, obj *types.RightsRequest) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, iam.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6276,7 +6761,7 @@ func (r *rightsRequestResolver) Organization(ctx context.Context, obj *types.Rig organization, err := prb.Organizations.Get(ctx, rightsRequest.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) } @@ -6291,7 +6776,9 @@ func (r *rightsRequestResolver) Permission(ctx context.Context, obj *types.Right // TotalCount is the resolver for the totalCount field. func (r *rightsRequestConnectionResolver) TotalCount(ctx context.Context, obj *types.RightsRequestConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionRightsRequestList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionRightsRequestList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -6310,7 +6797,9 @@ func (r *rightsRequestConnectionResolver) TotalCount(ctx context.Context, obj *t // Owner is the resolver for the owner field. func (r *riskResolver) Owner(ctx context.Context, obj *types.Risk) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleGet) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6321,7 +6810,7 @@ func (r *riskResolver) Owner(ctx context.Context, obj *types.Risk) (*types.Peopl owner, err := prb.Peoples.Get(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -6333,14 +6822,16 @@ func (r *riskResolver) Owner(ctx context.Context, obj *types.Risk) (*types.Peopl // Organization is the resolver for the organization field. func (r *riskResolver) Organization(ctx context.Context, obj *types.Risk) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } // TODO no panic use gqlutils.InternalError @@ -6352,7 +6843,9 @@ func (r *riskResolver) Organization(ctx context.Context, obj *types.Risk) (*type // Measures is the resolver for the measures field. func (r *riskResolver) Measures(ctx context.Context, obj *types.Risk, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) (*types.MeasureConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionMeasureList) + if err := r.authorize(ctx, obj.ID, probo.ActionMeasureList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6385,7 +6878,9 @@ func (r *riskResolver) Measures(ctx context.Context, obj *types.Risk, first *int // Documents is the resolver for the documents field. func (r *riskResolver) Documents(ctx context.Context, obj *types.Risk, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) (*types.DocumentConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDocumentList) + if err := r.authorize(ctx, obj.ID, probo.ActionDocumentList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6418,7 +6913,9 @@ func (r *riskResolver) Documents(ctx context.Context, obj *types.Risk, first *in // Controls is the resolver for the controls field. func (r *riskResolver) Controls(ctx context.Context, obj *types.Risk, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionControlList) + if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6450,7 +6947,9 @@ func (r *riskResolver) Controls(ctx context.Context, obj *types.Risk, first *int // Obligations is the resolver for the obligations field. func (r *riskResolver) Obligations(ctx context.Context, obj *types.Risk, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ObligationOrderBy, filter *types.ObligationFilter) (*types.ObligationConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionObligationList) + if err := r.authorize(ctx, obj.ID, probo.ActionObligationList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6488,7 +6987,9 @@ func (r *riskResolver) Permission(ctx context.Context, obj *types.Risk, action s // TotalCount is the resolver for the totalCount field. func (r *riskConnectionResolver) TotalCount(ctx context.Context, obj *types.RiskConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionRiskList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionRiskList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -6515,7 +7016,9 @@ func (r *riskConnectionResolver) TotalCount(ctx context.Context, obj *types.Risk // Signed is the resolver for the signed field. func (r *signableDocumentResolver) Signed(ctx context.Context, obj *types.SignableDocument) (bool, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDocumentGet) + if err := r.authorize(ctx, obj.ID, probo.ActionDocumentGet); err != nil { + return false, err + } identity := connect_v1.IdentityFromContext(ctx) @@ -6531,7 +7034,9 @@ func (r *signableDocumentResolver) Signed(ctx context.Context, obj *types.Signab // Versions is the resolver for the versions field. func (r *signableDocumentResolver) Versions(ctx context.Context, obj *types.SignableDocument, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionOrderBy, filter *types.DocumentVersionFilter) (*types.DocumentVersionConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDocumentVersionList) + if err := r.authorize(ctx, obj.ID, probo.ActionDocumentVersionList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6562,7 +7067,9 @@ func (r *signableDocumentResolver) Versions(ctx context.Context, obj *types.Sign // Organization is the resolver for the organization field. func (r *snapshotResolver) Organization(ctx context.Context, obj *types.Snapshot) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6574,7 +7081,7 @@ func (r *snapshotResolver) Organization(ctx context.Context, obj *types.Snapshot organization, err := prb.Organizations.Get(ctx, snapshot.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) @@ -6585,7 +7092,9 @@ func (r *snapshotResolver) Organization(ctx context.Context, obj *types.Snapshot // Controls is the resolver for the controls field. func (r *snapshotResolver) Controls(ctx context.Context, obj *types.Snapshot, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionControlList) + if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6622,7 +7131,9 @@ func (r *snapshotResolver) Permission(ctx context.Context, obj *types.Snapshot, // TotalCount is the resolver for the totalCount field. func (r *snapshotConnectionResolver) TotalCount(ctx context.Context, obj *types.SnapshotConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionSnapshotList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionSnapshotList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -6640,14 +7151,16 @@ func (r *snapshotConnectionResolver) TotalCount(ctx context.Context, obj *types. // Organization is the resolver for the organization field. func (r *stateOfApplicabilityResolver) Organization(ctx context.Context, obj *types.StateOfApplicability) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load organization: %w", err)) } @@ -6657,14 +7170,16 @@ func (r *stateOfApplicabilityResolver) Organization(ctx context.Context, obj *ty // Owner is the resolver for the owner field. func (r *stateOfApplicabilityResolver) Owner(ctx context.Context, obj *types.StateOfApplicability) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleGet) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) people, err := prb.Peoples.Get(ctx, obj.Owner.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load owner: %w", err)) } @@ -6679,7 +7194,9 @@ func (r *stateOfApplicabilityResolver) Permission(ctx context.Context, obj *type // Controls is the resolver for the controls field. func (r *stateOfApplicabilityResolver) Controls(ctx context.Context, obj *types.StateOfApplicability, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionControlList) + if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6711,7 +7228,9 @@ func (r *stateOfApplicabilityResolver) Controls(ctx context.Context, obj *types. // AvailableControls is the resolver for the availableControls field. func (r *stateOfApplicabilityResolver) AvailableControls(ctx context.Context, obj *types.StateOfApplicability) ([]*types.AvailableStateOfApplicabilityControl, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionControlList) + if err := r.authorize(ctx, obj.ID, probo.ActionControlList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6760,7 +7279,9 @@ func (r *stateOfApplicabilityConnectionResolver) TotalCount(ctx context.Context, // StateOfApplicability is the resolver for the stateOfApplicability field. func (r *stateOfApplicabilityControlResolver) StateOfApplicability(ctx context.Context, obj *types.StateOfApplicabilityControl) (*types.StateOfApplicability, error) { - r.MustAuthorize(ctx, obj.StateOfApplicabilityID, probo.ActionStateOfApplicabilityGet) + if err := r.authorize(ctx, obj.StateOfApplicabilityID, probo.ActionStateOfApplicabilityGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.StateOfApplicabilityID.TenantID()) @@ -6774,7 +7295,9 @@ func (r *stateOfApplicabilityControlResolver) StateOfApplicability(ctx context.C // AssignedTo is the resolver for the assignedTo field. func (r *taskResolver) AssignedTo(ctx context.Context, obj *types.Task) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleGet) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6785,7 +7308,7 @@ func (r *taskResolver) AssignedTo(ctx context.Context, obj *types.Task) (*types. people, err := prb.Peoples.Get(ctx, obj.AssignedTo.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get assigned to: %w", err)) @@ -6796,14 +7319,16 @@ func (r *taskResolver) AssignedTo(ctx context.Context, obj *types.Task) (*types. // Organization is the resolver for the organization field. func (r *taskResolver) Organization(ctx context.Context, obj *types.Task) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) @@ -6814,7 +7339,9 @@ func (r *taskResolver) Organization(ctx context.Context, obj *types.Task) (*type // Measure is the resolver for the measure field. func (r *taskResolver) Measure(ctx context.Context, obj *types.Task) (*types.Measure, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionMeasureGet) + if err := r.authorize(ctx, obj.ID, probo.ActionMeasureGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6825,7 +7352,7 @@ func (r *taskResolver) Measure(ctx context.Context, obj *types.Task) (*types.Mea measure, err := prb.Measures.Get(ctx, obj.Measure.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get measure: %w", err)) @@ -6836,7 +7363,9 @@ func (r *taskResolver) Measure(ctx context.Context, obj *types.Task) (*types.Mea // Evidences is the resolver for the evidences field. func (r *taskResolver) Evidences(ctx context.Context, obj *types.Task, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.EvidenceOrderBy) (*types.EvidenceConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionEvidenceList) + if err := r.authorize(ctx, obj.ID, probo.ActionEvidenceList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6867,7 +7396,9 @@ func (r *taskResolver) Permission(ctx context.Context, obj *types.Task, action s // TotalCount is the resolver for the totalCount field. func (r *taskConnectionResolver) TotalCount(ctx context.Context, obj *types.TaskConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionTaskList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionTaskList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -6891,7 +7422,9 @@ func (r *taskConnectionResolver) TotalCount(ctx context.Context, obj *types.Task // ProcessingActivity is the resolver for the processingActivity field. func (r *transferImpactAssessmentResolver) ProcessingActivity(ctx context.Context, obj *types.TransferImpactAssessment) (*types.ProcessingActivity, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionProcessingActivityGet) + if err := r.authorize(ctx, obj.ID, probo.ActionProcessingActivityGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6905,14 +7438,16 @@ func (r *transferImpactAssessmentResolver) ProcessingActivity(ctx context.Contex // Organization is the resolver for the organization field. func (r *transferImpactAssessmentResolver) Organization(ctx context.Context, obj *types.TransferImpactAssessment) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) @@ -6928,7 +7463,9 @@ func (r *transferImpactAssessmentResolver) Permission(ctx context.Context, obj * // TotalCount is the resolver for the totalCount field. func (r *transferImpactAssessmentConnectionResolver) TotalCount(ctx context.Context, obj *types.TransferImpactAssessmentConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionTransferImpactAssessmentList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionTransferImpactAssessmentList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -6946,19 +7483,15 @@ func (r *transferImpactAssessmentConnectionResolver) TotalCount(ctx context.Cont // NdaFileURL is the resolver for the ndaFileUrl field. func (r *trustCenterResolver) NdaFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) { - if err := r.iam.Authorizer.Authorize(ctx, iam.AuthorizeParams{ - Principal: connect_v1.IdentityFromContext(ctx).ID, - Resource: obj.ID, - Action: "core:trust-center:get-nda-file-url", - }); err != nil { - var errInsufficientPermissions *iam.ErrInsufficientPermissions - if errors.As(err, &errInsufficientPermissions) { - return nil, nil - } - + hasPermission, err := r.Permission(ctx, obj, probo.ActionTrustCenterGetNda) + if err != nil { panic(fmt.Errorf("cannot authorize: %w", err)) } + if !hasPermission { + return nil, nil + } + prb := r.ProboService(ctx, obj.ID.TenantID()) fileURL, err := prb.TrustCenters.GenerateNDAFileURL(ctx, obj.ID, 15*time.Minute) @@ -6971,7 +7504,9 @@ func (r *trustCenterResolver) NdaFileURL(ctx context.Context, obj *types.TrustCe // Organization is the resolver for the organization field. func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -6983,7 +7518,7 @@ func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.Trust organization, err := prb.Organizations.Get(ctx, trustCenter.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) @@ -6994,7 +7529,9 @@ 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) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTrustCenterAccessList) + if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterAccessList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7021,7 +7558,9 @@ 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) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTrustCenterReferenceList) + if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterReferenceList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7053,7 +7592,9 @@ func (r *trustCenterResolver) Permission(ctx context.Context, obj *types.TrustCe // PendingRequestCount is the resolver for the pendingRequestCount field. func (r *trustCenterAccessResolver) PendingRequestCount(ctx context.Context, obj *types.TrustCenterAccess) (int, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTrustCenterAccessGet) + if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterAccessGet); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7067,7 +7608,9 @@ 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) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTrustCenterAccessGet) + if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterAccessGet); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) count, err := prb.TrustCenterAccesses.CountActiveDocumentAccesses(ctx, obj.ID) @@ -7080,7 +7623,9 @@ func (r *trustCenterAccessResolver) ActiveCount(ctx context.Context, obj *types. // 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) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTrustCenterAccessGet) + if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterAccessGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7112,7 +7657,9 @@ func (r *trustCenterAccessResolver) Permission(ctx context.Context, obj *types.T // Document is the resolver for the document field. func (r *trustCenterDocumentAccessResolver) Document(ctx context.Context, obj *types.TrustCenterDocumentAccess) (*types.Document, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionDocumentGet) + if err := r.authorize(ctx, obj.ID, probo.ActionDocumentGet); err != nil { + return nil, err + } if obj.DocumentID == nil { return nil, nil @@ -7123,7 +7670,7 @@ func (r *trustCenterDocumentAccessResolver) Document(ctx context.Context, obj *t document, err := prb.Documents.Get(ctx, *obj.DocumentID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load document: %w", err)) @@ -7134,7 +7681,9 @@ func (r *trustCenterDocumentAccessResolver) Document(ctx context.Context, obj *t // Report is the resolver for the report field. func (r *trustCenterDocumentAccessResolver) Report(ctx context.Context, obj *types.TrustCenterDocumentAccess) (*types.Report, error) { - r.MustAuthorize(ctx, obj.TrustCenterAccessID, probo.ActionReportGet) + if err := r.authorize(ctx, obj.TrustCenterAccessID, probo.ActionReportGet); err != nil { + return nil, err + } if obj.ReportID == nil { return nil, nil @@ -7152,7 +7701,9 @@ func (r *trustCenterDocumentAccessResolver) Report(ctx context.Context, obj *typ // TrustCenterFile is the resolver for the trustCenterFile field. func (r *trustCenterDocumentAccessResolver) TrustCenterFile(ctx context.Context, obj *types.TrustCenterDocumentAccess) (*types.TrustCenterFile, error) { - r.MustAuthorize(ctx, obj.TrustCenterAccessID, probo.ActionTrustCenterFileGet) + if err := r.authorize(ctx, obj.TrustCenterAccessID, probo.ActionTrustCenterFileGet); err != nil { + return nil, err + } if obj.TrustCenterFileID == nil { return nil, nil @@ -7170,7 +7721,9 @@ 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) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionTrustCenterDocumentAccessList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionTrustCenterDocumentAccessList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -7184,7 +7737,9 @@ func (r *trustCenterDocumentAccessConnectionResolver) TotalCount(ctx context.Con // FileURL is the resolver for the fileUrl field. func (r *trustCenterFileResolver) FileURL(ctx context.Context, obj *types.TrustCenterFile) (string, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTrustCenterFileGetFileUrl) + if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterFileGetFileUrl); err != nil { + return "", err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7198,7 +7753,9 @@ func (r *trustCenterFileResolver) FileURL(ctx context.Context, obj *types.TrustC // Organization is the resolver for the organization field. func (r *trustCenterFileResolver) Organization(ctx context.Context, obj *types.TrustCenterFile) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7210,7 +7767,7 @@ func (r *trustCenterFileResolver) Organization(ctx context.Context, obj *types.T organization, err := prb.Organizations.Get(ctx, trustCenterFile.OrganizationID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) @@ -7226,7 +7783,9 @@ 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) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionTrustCenterFileList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionTrustCenterFileList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -7239,7 +7798,9 @@ func (r *trustCenterFileConnectionResolver) TotalCount(ctx context.Context, obj // LogoURL is the resolver for the logoUrl field. func (r *trustCenterReferenceResolver) LogoURL(ctx context.Context, obj *types.TrustCenterReference) (string, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionTrustCenterReferenceGetLogoUrl) + if err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterReferenceGetLogoUrl); err != nil { + return "", err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7258,7 +7819,9 @@ 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) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionTrustCenterReferenceList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionTrustCenterReferenceList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -7272,14 +7835,16 @@ func (r *trustCenterReferenceConnectionResolver) TotalCount(ctx context.Context, // Organization is the resolver for the organization field. func (r *vendorResolver) Organization(ctx context.Context, obj *types.Vendor) (*types.Organization, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionOrganizationGet) + if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) organization, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get organization: %w", err)) @@ -7290,7 +7855,9 @@ func (r *vendorResolver) Organization(ctx context.Context, obj *types.Vendor) (* // ComplianceReports is the resolver for the complianceReports field. func (r *vendorResolver) ComplianceReports(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorComplianceReportOrderBy) (*types.VendorComplianceReportConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorComplianceReportList) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorComplianceReportList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7317,7 +7884,9 @@ func (r *vendorResolver) ComplianceReports(ctx context.Context, obj *types.Vendo // BusinessAssociateAgreement is the resolver for the businessAssociateAgreement field. func (r *vendorResolver) BusinessAssociateAgreement(ctx context.Context, obj *types.Vendor) (*types.VendorBusinessAssociateAgreement, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorBusinessAssociateAgreementGet) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorBusinessAssociateAgreementGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7335,7 +7904,9 @@ func (r *vendorResolver) BusinessAssociateAgreement(ctx context.Context, obj *ty // DataPrivacyAgreement is the resolver for the dataPrivacyAgreement field. func (r *vendorResolver) DataPrivacyAgreement(ctx context.Context, obj *types.Vendor) (*types.VendorDataPrivacyAgreement, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorDataPrivacyAgreementGet) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorDataPrivacyAgreementGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7353,7 +7924,9 @@ func (r *vendorResolver) DataPrivacyAgreement(ctx context.Context, obj *types.Ve // Contacts is the resolver for the contacts field. func (r *vendorResolver) Contacts(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorContactOrderBy) (*types.VendorContactConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorContactList) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorContactList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7380,7 +7953,9 @@ func (r *vendorResolver) Contacts(ctx context.Context, obj *types.Vendor, first // Services is the resolver for the services field. func (r *vendorResolver) Services(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorServiceOrderBy) (*types.VendorServiceConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorServiceList) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorServiceList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7407,7 +7982,9 @@ func (r *vendorResolver) Services(ctx context.Context, obj *types.Vendor, first // RiskAssessments is the resolver for the riskAssessments field. func (r *vendorResolver) RiskAssessments(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorRiskAssessmentOrder) (*types.VendorRiskAssessmentConnection, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorRiskAssessmentList) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorRiskAssessmentList); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7434,14 +8011,16 @@ func (r *vendorResolver) RiskAssessments(ctx context.Context, obj *types.Vendor, // BusinessOwner is the resolver for the businessOwner field. func (r *vendorResolver) BusinessOwner(ctx context.Context, obj *types.Vendor) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleGet) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get vendor: %w", err)) @@ -7454,7 +8033,7 @@ func (r *vendorResolver) BusinessOwner(ctx context.Context, obj *types.Vendor) ( people, err := prb.Peoples.Get(ctx, *vendor.BusinessOwnerID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get business owner: %w", err)) @@ -7465,14 +8044,16 @@ func (r *vendorResolver) BusinessOwner(ctx context.Context, obj *types.Vendor) ( // SecurityOwner is the resolver for the securityOwner field. func (r *vendorResolver) SecurityOwner(ctx context.Context, obj *types.Vendor) (*types.People, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionPeopleGet) + if err := r.authorize(ctx, obj.ID, probo.ActionPeopleGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get vendor: %w", err)) @@ -7485,7 +8066,7 @@ func (r *vendorResolver) SecurityOwner(ctx context.Context, obj *types.Vendor) ( people, err := prb.Peoples.Get(ctx, *vendor.SecurityOwnerID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get security owner: %w", err)) @@ -7501,14 +8082,16 @@ func (r *vendorResolver) Permission(ctx context.Context, obj *types.Vendor, acti // Vendor is the resolver for the vendor field. func (r *vendorBusinessAssociateAgreementResolver) Vendor(ctx context.Context, obj *types.VendorBusinessAssociateAgreement) (*types.Vendor, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorGet) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } return nil, fmt.Errorf("cannot get vendor: %w", err) @@ -7519,7 +8102,9 @@ func (r *vendorBusinessAssociateAgreementResolver) Vendor(ctx context.Context, o // FileURL is the resolver for the fileUrl field. func (r *vendorBusinessAssociateAgreementResolver) FileURL(ctx context.Context, obj *types.VendorBusinessAssociateAgreement) (string, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionFileDownloadUrl) + if err := r.authorize(ctx, obj.ID, probo.ActionFileDownloadUrl); err != nil { + return "", err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7538,14 +8123,16 @@ func (r *vendorBusinessAssociateAgreementResolver) Permission(ctx context.Contex // Vendor is the resolver for the vendor field. func (r *vendorComplianceReportResolver) Vendor(ctx context.Context, obj *types.VendorComplianceReport) (*types.Vendor, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorGet) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get vendor: %w", err)) @@ -7556,7 +8143,9 @@ func (r *vendorComplianceReportResolver) Vendor(ctx context.Context, obj *types. // File is the resolver for the file field. func (r *vendorComplianceReportResolver) File(ctx context.Context, obj *types.VendorComplianceReport) (*types.File, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionFileGet) + if err := r.authorize(ctx, obj.ID, probo.ActionFileGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7572,7 +8161,7 @@ func (r *vendorComplianceReportResolver) File(ctx context.Context, obj *types.Ve file, err := prb.Files.Get(ctx, *evidence.ReportFileId) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot load evidence file: %w", err)) @@ -7588,7 +8177,9 @@ func (r *vendorComplianceReportResolver) Permission(ctx context.Context, obj *ty // TotalCount is the resolver for the totalCount field. func (r *vendorConnectionResolver) TotalCount(ctx context.Context, obj *types.VendorConnection) (int, error) { - r.MustAuthorize(ctx, obj.ParentID, probo.ActionVendorList) + if err := r.authorize(ctx, obj.ParentID, probo.ActionVendorList); err != nil { + return 0, err + } prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -7618,7 +8209,9 @@ func (r *vendorConnectionResolver) TotalCount(ctx context.Context, obj *types.Ve // Vendor is the resolver for the vendor field. func (r *vendorContactResolver) Vendor(ctx context.Context, obj *types.VendorContact) (*types.Vendor, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorGet) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7631,7 +8224,7 @@ func (r *vendorContactResolver) Vendor(ctx context.Context, obj *types.VendorCon vendor, err := prb.Vendors.Get(ctx, vendorContact.VendorID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get vendor: %w", err)) @@ -7647,14 +8240,16 @@ func (r *vendorContactResolver) Permission(ctx context.Context, obj *types.Vendo // Vendor is the resolver for the vendor field. func (r *vendorDataPrivacyAgreementResolver) Vendor(ctx context.Context, obj *types.VendorDataPrivacyAgreement) (*types.Vendor, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorGet) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get vendor: %w", err)) @@ -7665,7 +8260,9 @@ func (r *vendorDataPrivacyAgreementResolver) Vendor(ctx context.Context, obj *ty // FileURL is the resolver for the fileUrl field. func (r *vendorDataPrivacyAgreementResolver) FileURL(ctx context.Context, obj *types.VendorDataPrivacyAgreement) (string, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionFileDownloadUrl) + if err := r.authorize(ctx, obj.ID, probo.ActionFileDownloadUrl); err != nil { + return "", err + } prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -7684,14 +8281,16 @@ func (r *vendorDataPrivacyAgreementResolver) Permission(ctx context.Context, obj // Vendor is the resolver for the vendor field. func (r *vendorRiskAssessmentResolver) Vendor(ctx context.Context, obj *types.VendorRiskAssessment) (*types.Vendor, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorGet) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.GetByRiskAssessmentID(ctx, obj.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get vendor: %w", err)) @@ -7707,14 +8306,16 @@ func (r *vendorRiskAssessmentResolver) Permission(ctx context.Context, obj *type // Vendor is the resolver for the vendor field. func (r *vendorServiceResolver) Vendor(ctx context.Context, obj *types.VendorService) (*types.Vendor, error) { - r.MustAuthorize(ctx, obj.ID, probo.ActionVendorGet) + if err := r.authorize(ctx, obj.ID, probo.ActionVendorGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.Vendor.ID) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get vendor: %w", err)) @@ -7730,7 +8331,9 @@ func (r *vendorServiceResolver) Permission(ctx context.Context, obj *types.Vendo // SignableDocuments is the resolver for the signableDocuments field. func (r *viewerResolver) SignableDocuments(ctx context.Context, obj *types.Viewer, organizationID gid.GID, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy) (*types.SignableDocumentConnection, error) { - r.MustAuthorize(ctx, organizationID, probo.ActionDocumentList) + if err := r.authorize(ctx, organizationID, probo.ActionDocumentList); err != nil { + return nil, err + } prb := r.ProboService(ctx, organizationID.TenantID()) @@ -7775,7 +8378,9 @@ func (r *viewerResolver) SignableDocuments(ctx context.Context, obj *types.Viewe // SignableDocument is the resolver for the signableDocument field. func (r *viewerResolver) SignableDocument(ctx context.Context, obj *types.Viewer, id gid.GID) (*types.SignableDocument, error) { - r.MustAuthorize(ctx, id, probo.ActionDocumentGet) + if err := r.authorize(ctx, id, probo.ActionDocumentGet); err != nil { + return nil, err + } prb := r.ProboService(ctx, id.TenantID()) @@ -7785,7 +8390,7 @@ func (r *viewerResolver) SignableDocument(ctx context.Context, obj *types.Viewer document, err := prb.Documents.GetWithFilter(ctx, id, documentFilter) if err != nil { if errors.Is(err, coredata.ErrResourceNotFound) { - return nil, gqlutils.NotFound(err) + return nil, gqlutils.NotFound(ctx, err) } panic(fmt.Errorf("cannot get signable document: %w", err)) diff --git a/pkg/server/api/mcp/mcputils/recovery.go b/pkg/server/api/mcp/mcputils/recovery.go index 360fd46a1..9b149ab9d 100644 --- a/pkg/server/api/mcp/mcputils/recovery.go +++ b/pkg/server/api/mcp/mcputils/recovery.go @@ -47,11 +47,6 @@ func convertPanicToError(ctx context.Context, logger *log.Logger, panicValue any return fmt.Errorf("internal server error") } - var tenantAccessErr *iam.TenantAccessError - if errTyped, ok := panicValue.(error); ok && errors.As(errTyped, &tenantAccessErr) { - return fmt.Errorf("not authorized: %s", tenantAccessErr.Message) - } - var permissionDeniedErr *iam.ErrInsufficientPermissions if errTyped, ok := panicValue.(error); ok && errors.As(errTyped, &permissionDeniedErr) { return fmt.Errorf("permission denied: %s", permissionDeniedErr.Error()) diff --git a/pkg/server/gqlutils/errors.go b/pkg/server/gqlutils/errors.go index 8a91f05bc..071e017cf 100644 --- a/pkg/server/gqlutils/errors.go +++ b/pkg/server/gqlutils/errors.go @@ -16,76 +16,106 @@ package gqlutils import ( "context" + "errors" + "fmt" "maps" "github.com/99designs/gqlgen/graphql" "github.com/vektah/gqlparser/v2/gqlerror" + "go.probo.inc/probo/pkg/validator" ) -func Unauthorized() *gqlerror.Error { +func Unauthenticated(ctx context.Context, err error) *gqlerror.Error { return &gqlerror.Error{ - Message: "not authorized", + Message: err.Error(), + Path: graphql.GetPath(ctx), Extensions: map[string]any{ - "code": "UNAUTHORIZED", + "code": "UNAUTHENTICATED", }, } } -func Forbidden(err error) *gqlerror.Error { +func Unauthenticatedf(ctx context.Context, format string, a ...any) *gqlerror.Error { + return Unauthenticated(ctx, fmt.Errorf(format, a...)) +} + +func AlreadyUnauthenticated(ctx context.Context, err error) *gqlerror.Error { + return &gqlerror.Error{ + Message: "Authentication not allowed for this resource/action", + Extensions: map[string]any{ + "code": "ALREADY_AUTHENTICATED", + }, + } +} + +func Forbidden(ctx context.Context, err error) *gqlerror.Error { return &gqlerror.Error{ Message: err.Error(), + Path: graphql.GetPath(ctx), Extensions: map[string]any{ "code": "FORBIDDEN", }, } } -func AuthenticationRequired(details map[string]any) *gqlerror.Error { - extensions := map[string]any{"code": "AUTHENTICATION_REQUIRED"} - maps.Copy(extensions, details) - - return &gqlerror.Error{ - Message: "Additional authentication required to access this organization", - Extensions: extensions, - } -} - -func NotFound(err error) *gqlerror.Error { +func NotFound(ctx context.Context, err error) *gqlerror.Error { return &gqlerror.Error{ Message: err.Error(), + Path: graphql.GetPath(ctx), Extensions: map[string]any{ "code": "NOT_FOUND", }, } } -func Conflict(err error) *gqlerror.Error { +func Conflict(ctx context.Context, err error) *gqlerror.Error { return &gqlerror.Error{ Message: err.Error(), + Path: graphql.GetPath(ctx), Extensions: map[string]any{ "code": "CONFLICT", }, } } -func Invalid(err error, details map[string]any) *gqlerror.Error { - extensions := map[string]any{"code": "INVALID_REQUEST"} +func Conflictf(ctx context.Context, format string, a ...any) *gqlerror.Error { + return Conflict(ctx, fmt.Errorf(format, a...)) +} + +func Invalid(ctx context.Context, err error) *gqlerror.Error { + var errValidation *validator.ValidationError + + var details map[string]any + + if errors.As(err, &errValidation) { + details = map[string]any{ + "cause": errValidation.Code, + "field": errValidation.Field, + "value": errValidation.Value, + } + } + extensions := map[string]any{"code": "INVALID"} if details != nil { maps.Copy(extensions, details) } return &gqlerror.Error{ Message: err.Error(), + Path: graphql.GetPath(ctx), Extensions: extensions, } } -func InternalServerError(ctx context.Context) *gqlerror.Error { +func Invalidf(ctx context.Context, format string, a ...any) *gqlerror.Error { + return Invalid(ctx, fmt.Errorf(format, a...)) +} + +func Internal(ctx context.Context) *gqlerror.Error { return &gqlerror.Error{ Message: "An internal server error occurred. Please try again later.", Path: graphql.GetPath(ctx), Extensions: map[string]any{ - "code": "INTERNAL_SERVER_ERROR", + "code": "INTERNAL", }, } } diff --git a/pkg/server/gqlutils/recovery.go b/pkg/server/gqlutils/recovery.go index 14aca165e..fb4e51806 100644 --- a/pkg/server/gqlutils/recovery.go +++ b/pkg/server/gqlutils/recovery.go @@ -31,26 +31,6 @@ func RecoverFunc(ctx context.Context, err any) error { return gqlErr } - // TODO: multi session here - // var errSAMLRequired iam.ErrSAMLAuthRequired - // if errors.As(asError(err), &errSAMLRequired) { - // return AuthenticationRequired(map[string]any{ - // "requiresSaml": true, - // "redirectUrl": errSAMLRequired.RedirectURL, - // "samlConfigId": errSAMLRequired.ConfigID.String(), - // "organizationId": errSAMLRequired.OrganizationID.String(), - // }) - // } - - // var errPasswordRequired iam.ErrPasswordAuthRequired - // if errors.As(asError(err), &errPasswordRequired) { - // return AuthenticationRequired(map[string]any{ - // "requiresSaml": false, - // "redirectUrl": errPasswordRequired.RedirectURL, - // "organizationId": errPasswordRequired.OrganizationID.String(), - // }) - // } - var errValidations validator.ValidationErrors if errors.As(asError(err), &errValidations) { gqlErrors := gqlerror.List{} @@ -59,12 +39,8 @@ func RecoverFunc(ctx context.Context, err any) error { gqlErrors = append( gqlErrors, Invalid( + ctx, err, - map[string]any{ - "cause": err.Code, - "field": err.Field, - "value": err.Value, - }, ), ) } @@ -72,14 +48,9 @@ func RecoverFunc(ctx context.Context, err any) error { return gqlErrors } - var tenantAccessErr *iam.TenantAccessError - if errTyped, ok := err.(error); ok && errors.As(errTyped, &tenantAccessErr) { - return Unauthorized() - } - var permissionDeniedErr *iam.ErrInsufficientPermissions if errTyped, ok := err.(error); ok && errors.As(errTyped, &permissionDeniedErr) { - return Forbidden(permissionDeniedErr) + return Forbidden(ctx, permissionDeniedErr) } logger := httpserver.LoggerFromContext(ctx)