From dccac5c088b152bb0dfc7ff57d7c999c4e1f5cc1 Mon Sep 17 00:00:00 2001 From: Bryan Frimin Date: Mon, 22 Dec 2025 14:02:12 +0100 Subject: [PATCH] Move UnwrapOmittable in a dedicated helper Signed-off-by: Bryan Frimin --- pkg/server/api/connect/v1/resolver.go | 9 -- pkg/server/api/connect/v1/v1_resolver.go | 8 +- pkg/server/api/console/v1/resolver.go | 15 +- pkg/server/api/console/v1/v1_resolver.go | 166 +++++++++++------------ pkg/server/gqlutils/nullable.go | 29 ++++ 5 files changed, 118 insertions(+), 109 deletions(-) create mode 100644 pkg/server/gqlutils/nullable.go diff --git a/pkg/server/api/connect/v1/resolver.go b/pkg/server/api/connect/v1/resolver.go index 73c1ec311..24271e6e1 100644 --- a/pkg/server/api/connect/v1/resolver.go +++ b/pkg/server/api/connect/v1/resolver.go @@ -19,7 +19,6 @@ package connect_v1 import ( "time" - "github.com/99designs/gqlgen/graphql" "github.com/go-chi/chi/v5" "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/baseurl" @@ -66,11 +65,3 @@ func NewMux(logger *log.Logger, svc *iam.Service, cookieConfig securecookie.Conf return r } - -func UnwrapOmittable[T any](field graphql.Omittable[T]) *T { - if !field.IsSet() { - return nil - } - value := field.Value() - return &value -} diff --git a/pkg/server/api/connect/v1/v1_resolver.go b/pkg/server/api/connect/v1/v1_resolver.go index f43cb28b0..b06fe8949 100644 --- a/pkg/server/api/connect/v1/v1_resolver.go +++ b/pkg/server/api/connect/v1/v1_resolver.go @@ -699,10 +699,10 @@ func (r *mutationResolver) CreateOrganization(ctx context.Context, input types.C func (r *mutationResolver) UpdateOrganization(ctx context.Context, input types.UpdateOrganizationInput) (*types.UpdateOrganizationPayload, error) { req := &iam.UpdateOrganizationRequest{ Name: input.Name, - Description: UnwrapOmittable(input.Description), - WebsiteURL: UnwrapOmittable(input.WebsiteURL), - Email: UnwrapOmittable(input.Email), - HeadquarterAddress: UnwrapOmittable(input.HeadquarterAddress), + Description: gqlutils.UnwrapOmittable(input.Description), + WebsiteURL: gqlutils.UnwrapOmittable(input.WebsiteURL), + Email: gqlutils.UnwrapOmittable(input.Email), + HeadquarterAddress: gqlutils.UnwrapOmittable(input.HeadquarterAddress), } if input.LogoFile != nil { diff --git a/pkg/server/api/console/v1/resolver.go b/pkg/server/api/console/v1/resolver.go index 3e7e38f9c..c97a4915c 100644 --- a/pkg/server/api/console/v1/resolver.go +++ b/pkg/server/api/console/v1/resolver.go @@ -81,11 +81,8 @@ func NewMux( safeRedirect := &saferedirect.SafeRedirect{AllowedHost: baseURL.Host()} - sessionMiddleware := connect_v1.NewSessionMiddleware(iamSvc, cookieConfig) - apiKeyMiddleware := connect_v1.NewAPIKeyMiddleware(iamSvc) - - r.Use(sessionMiddleware) - r.Use(apiKeyMiddleware) + r.Use(connect_v1.NewSessionMiddleware(iamSvc, cookieConfig)) + r.Use(connect_v1.NewAPIKeyMiddleware(iamSvc)) config := schema.Config{ Resolvers: &Resolver{ @@ -315,14 +312,6 @@ func (r *Resolver) ProboService(ctx context.Context, tenantID gid.TenantID) *pro return GetTenantService(ctx, r.probo, tenantID) } -func UnwrapOmittable[T any](field graphql.Omittable[T]) *T { - if !field.IsSet() { - return nil - } - value := field.Value() - return &value -} - func GetTenantService(ctx context.Context, proboSvc *probo.Service, tenantID gid.TenantID) *probo.TenantService { return proboSvc.WithTenant(tenantID) } diff --git a/pkg/server/api/console/v1/v1_resolver.go b/pkg/server/api/console/v1/v1_resolver.go index 3d09bd41a..32d624352 100644 --- a/pkg/server/api/console/v1/v1_resolver.go +++ b/pkg/server/api/console/v1/v1_resolver.go @@ -1449,7 +1449,7 @@ func (r *mutationResolver) UpdateOrganizationContext(ctx context.Context, input req := probo.UpdateOrganizationContextRequest{ OrganizationID: input.OrganizationID, - Summary: UnwrapOmittable(input.Summary), + Summary: gqlutils.UnwrapOmittable(input.Summary), } organizationContext, err := prb.Organizations.UpdateContext(ctx, req) @@ -1637,7 +1637,7 @@ func (r *mutationResolver) UpdateTrustCenterReference(ctx context.Context, input req := &probo.UpdateTrustCenterReferenceRequest{ ID: input.ID, Name: input.Name, - Description: UnwrapOmittable(input.Description), + Description: gqlutils.UnwrapOmittable(input.Description), WebsiteURL: input.WebsiteURL, Rank: input.Rank, } @@ -1804,11 +1804,11 @@ func (r *mutationResolver) UpdatePeople(ctx context.Context, input types.UpdateP ID: input.ID, FullName: input.FullName, PrimaryEmailAddress: input.PrimaryEmailAddress, - AdditionalEmailAddresses: UnwrapOmittable(input.AdditionalEmailAddresses), + AdditionalEmailAddresses: gqlutils.UnwrapOmittable(input.AdditionalEmailAddresses), Kind: input.Kind, - Position: UnwrapOmittable(input.Position), - ContractStartDate: UnwrapOmittable(input.ContractStartDate), - ContractEndDate: UnwrapOmittable(input.ContractEndDate), + Position: gqlutils.UnwrapOmittable(input.Position), + ContractStartDate: gqlutils.UnwrapOmittable(input.ContractStartDate), + ContractEndDate: gqlutils.UnwrapOmittable(input.ContractEndDate), }, ) if err != nil { @@ -1892,23 +1892,23 @@ func (r *mutationResolver) UpdateVendor(ctx context.Context, input types.UpdateV vendor, err := prb.Vendors.Update(ctx, probo.UpdateVendorRequest{ ID: input.ID, Name: input.Name, - Description: UnwrapOmittable(input.Description), - StatusPageURL: UnwrapOmittable(input.StatusPageURL), - TermsOfServiceURL: UnwrapOmittable(input.TermsOfServiceURL), - PrivacyPolicyURL: UnwrapOmittable(input.PrivacyPolicyURL), - ServiceLevelAgreementURL: UnwrapOmittable(input.ServiceLevelAgreementURL), - DataProcessingAgreementURL: UnwrapOmittable(input.DataProcessingAgreementURL), - BusinessAssociateAgreementURL: UnwrapOmittable(input.BusinessAssociateAgreementURL), - SubprocessorsListURL: UnwrapOmittable(input.SubprocessorsListURL), - SecurityPageURL: UnwrapOmittable(input.SecurityPageURL), - TrustPageURL: UnwrapOmittable(input.TrustPageURL), - HeadquarterAddress: UnwrapOmittable(input.HeadquarterAddress), - LegalName: UnwrapOmittable(input.LegalName), - WebsiteURL: UnwrapOmittable(input.WebsiteURL), + Description: gqlutils.UnwrapOmittable(input.Description), + StatusPageURL: gqlutils.UnwrapOmittable(input.StatusPageURL), + TermsOfServiceURL: gqlutils.UnwrapOmittable(input.TermsOfServiceURL), + PrivacyPolicyURL: gqlutils.UnwrapOmittable(input.PrivacyPolicyURL), + ServiceLevelAgreementURL: gqlutils.UnwrapOmittable(input.ServiceLevelAgreementURL), + DataProcessingAgreementURL: gqlutils.UnwrapOmittable(input.DataProcessingAgreementURL), + BusinessAssociateAgreementURL: gqlutils.UnwrapOmittable(input.BusinessAssociateAgreementURL), + SubprocessorsListURL: gqlutils.UnwrapOmittable(input.SubprocessorsListURL), + SecurityPageURL: gqlutils.UnwrapOmittable(input.SecurityPageURL), + TrustPageURL: gqlutils.UnwrapOmittable(input.TrustPageURL), + HeadquarterAddress: gqlutils.UnwrapOmittable(input.HeadquarterAddress), + LegalName: gqlutils.UnwrapOmittable(input.LegalName), + WebsiteURL: gqlutils.UnwrapOmittable(input.WebsiteURL), Category: input.Category, Certifications: input.Certifications, - BusinessOwnerID: UnwrapOmittable(input.BusinessOwnerID), - SecurityOwnerID: UnwrapOmittable(input.SecurityOwnerID), + BusinessOwnerID: gqlutils.UnwrapOmittable(input.BusinessOwnerID), + SecurityOwnerID: gqlutils.UnwrapOmittable(input.SecurityOwnerID), ShowOnTrustCenter: input.ShowOnTrustCenter, Countries: input.Countries, }) @@ -1969,10 +1969,10 @@ func (r *mutationResolver) UpdateVendorContact(ctx context.Context, input types. req := probo.UpdateVendorContactRequest{ ID: input.ID, - FullName: UnwrapOmittable(input.FullName), - Email: UnwrapOmittable(input.Email), - Phone: UnwrapOmittable(input.Phone), - Role: UnwrapOmittable(input.Role), + FullName: gqlutils.UnwrapOmittable(input.FullName), + Email: gqlutils.UnwrapOmittable(input.Email), + Phone: gqlutils.UnwrapOmittable(input.Phone), + Role: gqlutils.UnwrapOmittable(input.Role), } vendorContact, err := prb.VendorContacts.Update(ctx, req) @@ -2032,7 +2032,7 @@ func (r *mutationResolver) UpdateVendorService(ctx context.Context, input types. req := probo.UpdateVendorServiceRequest{ ID: input.ID, Name: input.Name, - Description: UnwrapOmittable(input.Description), + Description: gqlutils.UnwrapOmittable(input.Description), } vendorService, err := prb.VendorServices.Update(ctx, req) @@ -2089,7 +2089,7 @@ func (r *mutationResolver) UpdateFramework(ctx context.Context, input types.Upda framework, err := prb.Frameworks.Update(ctx, probo.UpdateFrameworkRequest{ ID: input.ID, Name: input.Name, - Description: UnwrapOmittable(input.Description), + Description: gqlutils.UnwrapOmittable(input.Description), }) if err != nil { return nil, fmt.Errorf("cannot update framework: %w", err) @@ -2219,7 +2219,7 @@ func (r *mutationResolver) UpdateControl(ctx context.Context, input types.Update control, err := prb.Controls.Update(ctx, probo.UpdateControlRequest{ ID: input.ID, Name: input.Name, - Description: UnwrapOmittable(input.Description), + Description: gqlutils.UnwrapOmittable(input.Description), SectionTitle: input.SectionTitle, Status: input.Status, ExclusionJustification: input.ExclusionJustification, @@ -2286,7 +2286,7 @@ func (r *mutationResolver) UpdateMeasure(ctx context.Context, input types.Update measure, err := prb.Measures.Update(ctx, probo.UpdateMeasureRequest{ ID: input.ID, Name: input.Name, - Description: UnwrapOmittable(input.Description), + Description: gqlutils.UnwrapOmittable(input.Description), Category: input.Category, State: input.State, }) @@ -2586,12 +2586,12 @@ func (r *mutationResolver) UpdateTask(ctx context.Context, input types.UpdateTas task, err := prb.Tasks.Update(ctx, probo.UpdateTaskRequest{ TaskID: input.TaskID, Name: input.Name, - Description: UnwrapOmittable(input.Description), + Description: gqlutils.UnwrapOmittable(input.Description), State: input.State, - TimeEstimate: UnwrapOmittable(input.TimeEstimate), - Deadline: UnwrapOmittable(input.Deadline), - AssignedToID: UnwrapOmittable(input.AssignedToID), - MeasureID: UnwrapOmittable(input.MeasureID), + TimeEstimate: gqlutils.UnwrapOmittable(input.TimeEstimate), + Deadline: gqlutils.UnwrapOmittable(input.Deadline), + AssignedToID: gqlutils.UnwrapOmittable(input.AssignedToID), + MeasureID: gqlutils.UnwrapOmittable(input.MeasureID), }) if err != nil { panic(fmt.Errorf("cannot update task: %w", err)) @@ -2664,10 +2664,10 @@ func (r *mutationResolver) UpdateRisk(ctx context.Context, input types.UpdateRis probo.UpdateRiskRequest{ ID: input.ID, Name: input.Name, - Description: UnwrapOmittable(input.Description), + Description: gqlutils.UnwrapOmittable(input.Description), Category: input.Category, Treatment: input.Treatment, - OwnerID: UnwrapOmittable(input.OwnerID), + OwnerID: gqlutils.UnwrapOmittable(input.OwnerID), InherentLikelihood: input.InherentLikelihood, InherentImpact: input.InherentImpact, ResidualLikelihood: input.ResidualLikelihood, @@ -2921,8 +2921,8 @@ func (r *mutationResolver) UpdateVendorBusinessAssociateAgreement(ctx context.Co ctx, input.VendorID, &probo.VendorBusinessAssociateAgreementUpdateRequest{ - ValidFrom: UnwrapOmittable(input.ValidFrom), - ValidUntil: UnwrapOmittable(input.ValidUntil), + ValidFrom: gqlutils.UnwrapOmittable(input.ValidFrom), + ValidUntil: gqlutils.UnwrapOmittable(input.ValidUntil), }, ) if err != nil { @@ -2985,8 +2985,8 @@ func (r *mutationResolver) UpdateVendorDataPrivacyAgreement(ctx context.Context, ctx, input.VendorID, &probo.VendorDataPrivacyAgreementUpdateRequest{ - ValidFrom: UnwrapOmittable(input.ValidFrom), - ValidUntil: UnwrapOmittable(input.ValidUntil), + ValidFrom: gqlutils.UnwrapOmittable(input.ValidFrom), + ValidUntil: gqlutils.UnwrapOmittable(input.ValidUntil), }, ) if err != nil { @@ -3131,7 +3131,7 @@ func (r *mutationResolver) UpdateMeeting(ctx context.Context, input types.Update Name: input.Name, Date: input.Date, AttendeeIDs: attendeeIDs, - Minutes: UnwrapOmittable(input.Minutes), + Minutes: gqlutils.UnwrapOmittable(input.Minutes), }, ) if err != nil { @@ -3874,7 +3874,7 @@ func (r *mutationResolver) UpdateAudit(ctx context.Context, input types.UpdateAu req := probo.UpdateAuditRequest{ ID: input.ID, - Name: UnwrapOmittable(input.Name), + Name: gqlutils.UnwrapOmittable(input.Name), ValidFrom: input.ValidFrom, ValidUntil: input.ValidUntil, State: input.State, @@ -3988,15 +3988,15 @@ func (r *mutationResolver) UpdateNonconformity(ctx context.Context, input types. req := probo.UpdateNonconformityRequest{ ID: input.ID, ReferenceID: input.ReferenceID, - Description: UnwrapOmittable(input.Description), - DateIdentified: UnwrapOmittable(input.DateIdentified), + Description: gqlutils.UnwrapOmittable(input.Description), + DateIdentified: gqlutils.UnwrapOmittable(input.DateIdentified), RootCause: input.RootCause, - CorrectiveAction: UnwrapOmittable(input.CorrectiveAction), + CorrectiveAction: gqlutils.UnwrapOmittable(input.CorrectiveAction), OwnerID: input.OwnerID, - AuditID: UnwrapOmittable(input.AuditID), - DueDate: UnwrapOmittable(input.DueDate), + AuditID: gqlutils.UnwrapOmittable(input.AuditID), + DueDate: gqlutils.UnwrapOmittable(input.DueDate), Status: input.Status, - EffectivenessCheck: UnwrapOmittable(input.EffectivenessCheck), + EffectivenessCheck: gqlutils.UnwrapOmittable(input.EffectivenessCheck), } nonconformity, err := prb.Nonconformities.Update(ctx, &req) @@ -4063,14 +4063,14 @@ func (r *mutationResolver) UpdateObligation(ctx context.Context, input types.Upd req := probo.UpdateObligationRequest{ ID: input.ID, - Area: UnwrapOmittable(input.Area), - Source: UnwrapOmittable(input.Source), - Requirement: UnwrapOmittable(input.Requirement), - ActionsToBeImplemented: UnwrapOmittable(input.ActionsToBeImplemented), - Regulator: UnwrapOmittable(input.Regulator), + Area: gqlutils.UnwrapOmittable(input.Area), + Source: gqlutils.UnwrapOmittable(input.Source), + Requirement: gqlutils.UnwrapOmittable(input.Requirement), + ActionsToBeImplemented: gqlutils.UnwrapOmittable(input.ActionsToBeImplemented), + Regulator: gqlutils.UnwrapOmittable(input.Regulator), OwnerID: input.OwnerID, - LastReviewDate: UnwrapOmittable(input.LastReviewDate), - DueDate: UnwrapOmittable(input.DueDate), + LastReviewDate: gqlutils.UnwrapOmittable(input.LastReviewDate), + DueDate: gqlutils.UnwrapOmittable(input.DueDate), Status: input.Status, Type: input.Type, } @@ -4137,10 +4137,10 @@ func (r *mutationResolver) UpdateContinualImprovement(ctx context.Context, input req := probo.UpdateContinualImprovementRequest{ ID: input.ID, ReferenceID: input.ReferenceID, - Description: UnwrapOmittable(input.Description), - Source: UnwrapOmittable(input.Source), + Description: gqlutils.UnwrapOmittable(input.Description), + Source: gqlutils.UnwrapOmittable(input.Source), OwnerID: input.OwnerID, - TargetDate: UnwrapOmittable(input.TargetDate), + TargetDate: gqlutils.UnwrapOmittable(input.TargetDate), Status: input.Status, Priority: input.Priority, } @@ -4208,11 +4208,11 @@ func (r *mutationResolver) UpdateRightsRequest(ctx context.Context, input types. ID: input.ID, RequestType: input.RequestType, RequestState: input.RequestState, - DataSubject: UnwrapOmittable(input.DataSubject), - Contact: UnwrapOmittable(input.Contact), - Details: UnwrapOmittable(input.Details), - Deadline: UnwrapOmittable(input.Deadline), - ActionTaken: UnwrapOmittable(input.ActionTaken), + DataSubject: gqlutils.UnwrapOmittable(input.DataSubject), + Contact: gqlutils.UnwrapOmittable(input.Contact), + Details: gqlutils.UnwrapOmittable(input.Details), + Deadline: gqlutils.UnwrapOmittable(input.Deadline), + ActionTaken: gqlutils.UnwrapOmittable(input.ActionTaken), } rightsRequest, err := prb.RightsRequests.Update(ctx, &req) @@ -4289,23 +4289,23 @@ func (r *mutationResolver) UpdateProcessingActivity(ctx context.Context, input t req := probo.UpdateProcessingActivityRequest{ ID: input.ID, Name: input.Name, - Purpose: UnwrapOmittable(input.Purpose), - DataSubjectCategory: UnwrapOmittable(input.DataSubjectCategory), - PersonalDataCategory: UnwrapOmittable(input.PersonalDataCategory), + Purpose: gqlutils.UnwrapOmittable(input.Purpose), + DataSubjectCategory: gqlutils.UnwrapOmittable(input.DataSubjectCategory), + PersonalDataCategory: gqlutils.UnwrapOmittable(input.PersonalDataCategory), SpecialOrCriminalData: input.SpecialOrCriminalData, LawfulBasis: input.LawfulBasis, - Recipients: UnwrapOmittable(input.Recipients), - Location: UnwrapOmittable(input.Location), + Recipients: gqlutils.UnwrapOmittable(input.Recipients), + Location: gqlutils.UnwrapOmittable(input.Location), InternationalTransfers: input.InternationalTransfers, - TransferSafeguard: UnwrapOmittable(input.TransferSafeguards), - RetentionPeriod: UnwrapOmittable(input.RetentionPeriod), - SecurityMeasures: UnwrapOmittable(input.SecurityMeasures), + TransferSafeguard: gqlutils.UnwrapOmittable(input.TransferSafeguards), + RetentionPeriod: gqlutils.UnwrapOmittable(input.RetentionPeriod), + SecurityMeasures: gqlutils.UnwrapOmittable(input.SecurityMeasures), DataProtectionImpactAssessmentNeeded: input.DataProtectionImpactAssessmentNeeded, TransferImpactAssessmentNeeded: input.TransferImpactAssessmentNeeded, - LastReviewDate: UnwrapOmittable(input.LastReviewDate), - NextReviewDate: UnwrapOmittable(input.NextReviewDate), + LastReviewDate: gqlutils.UnwrapOmittable(input.LastReviewDate), + NextReviewDate: gqlutils.UnwrapOmittable(input.NextReviewDate), Role: input.Role, - DataProtectionOfficerID: UnwrapOmittable(input.DataProtectionOfficerID), + DataProtectionOfficerID: gqlutils.UnwrapOmittable(input.DataProtectionOfficerID), VendorIDs: &input.VendorIds, } @@ -4368,10 +4368,10 @@ func (r *mutationResolver) UpdateDataProtectionImpactAssessment(ctx context.Cont req := probo.UpdateDataProtectionImpactAssessmentRequest{ ID: input.ID, - Description: UnwrapOmittable(input.Description), - NecessityAndProportionality: UnwrapOmittable(input.NecessityAndProportionality), - PotentialRisk: UnwrapOmittable(input.PotentialRisk), - Mitigations: UnwrapOmittable(input.Mitigations), + Description: gqlutils.UnwrapOmittable(input.Description), + NecessityAndProportionality: gqlutils.UnwrapOmittable(input.NecessityAndProportionality), + PotentialRisk: gqlutils.UnwrapOmittable(input.PotentialRisk), + Mitigations: gqlutils.UnwrapOmittable(input.Mitigations), ResidualRisk: input.ResidualRisk, } @@ -4434,11 +4434,11 @@ func (r *mutationResolver) UpdateTransferImpactAssessment(ctx context.Context, i req := probo.UpdateTransferImpactAssessmentRequest{ ID: input.ID, - DataSubjects: UnwrapOmittable(input.DataSubjects), - LegalMechanism: UnwrapOmittable(input.LegalMechanism), - Transfer: UnwrapOmittable(input.Transfer), - LocalLawRisk: UnwrapOmittable(input.LocalLawRisk), - SupplementaryMeasures: UnwrapOmittable(input.SupplementaryMeasures), + DataSubjects: gqlutils.UnwrapOmittable(input.DataSubjects), + LegalMechanism: gqlutils.UnwrapOmittable(input.LegalMechanism), + Transfer: gqlutils.UnwrapOmittable(input.Transfer), + LocalLawRisk: gqlutils.UnwrapOmittable(input.LocalLawRisk), + SupplementaryMeasures: gqlutils.UnwrapOmittable(input.SupplementaryMeasures), } tia, err := prb.TransferImpactAssessments.Update(ctx, &req) diff --git a/pkg/server/gqlutils/nullable.go b/pkg/server/gqlutils/nullable.go new file mode 100644 index 000000000..f92f3ad7b --- /dev/null +++ b/pkg/server/gqlutils/nullable.go @@ -0,0 +1,29 @@ +// 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 gqlutils + +import ( + "github.com/99designs/gqlgen/graphql" +) + +func UnwrapOmittable[T any](field graphql.Omittable[T]) *T { + if !field.IsSet() { + return nil + } + + value := field.Value() + + return &value +}