From 59ffe768a8121327acabfa3ca1c90be4e4b582dd Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Tue, 12 Oct 2021 19:49:45 +0200 Subject: [PATCH] Fix create and update with unique constraints When creating or updating resource that did not match unique constraint filters, check wrongly reported not-unique error when matching (and valid) resource was found in the store. This fix adds explicit check if resource to be stored does not match constraint filters and skips the rest of the constraint checking procedure. --- pkg/codegen/assets/store_rdbms.gen.go.tpl | 22 +++++++++-- store/rdbms/actionlog.gen.go | 8 ++++ store/rdbms/apigw_filter.gen.go | 8 ++++ store/rdbms/apigw_route.gen.go | 8 ++++ store/rdbms/applications.gen.go | 8 ++++ store/rdbms/attachments.gen.go | 8 ++++ store/rdbms/auth_clients.gen.go | 17 +++++++- store/rdbms/auth_confirmed_clients.gen.go | 14 ++++++- store/rdbms/auth_oa2tokens.gen.go | 30 +++++++++++--- store/rdbms/auth_sessions.gen.go | 14 ++++++- store/rdbms/automation_sessions.gen.go | 8 ++++ store/rdbms/automation_triggers.gen.go | 8 ++++ store/rdbms/automation_workflows.gen.go | 17 +++++++- store/rdbms/compose_attachments.gen.go | 8 ++++ store/rdbms/compose_charts.gen.go | 8 ++++ store/rdbms/compose_module_fields.gen.go | 17 +++++++- store/rdbms/compose_modules.gen.go | 17 +++++++- store/rdbms/compose_namespaces.gen.go | 17 +++++++- store/rdbms/compose_pages.gen.go | 8 ++++ store/rdbms/compose_record_values.gen.go | 8 ++++ store/rdbms/compose_records.gen.go | 8 ++++ store/rdbms/credentials.gen.go | 8 ++++ store/rdbms/federation_exposed_modules.gen.go | 8 ++++ store/rdbms/federation_module_mappings.gen.go | 8 ++++ store/rdbms/federation_nodes.gen.go | 8 ++++ store/rdbms/federation_nodes_sync.gen.go | 8 ++++ store/rdbms/federation_shared_modules.gen.go | 8 ++++ store/rdbms/flags.gen.go | 38 ++++++++++++++---- store/rdbms/labels.gen.go | 14 ++++++- store/rdbms/messagebus_queue_message.gen.go | 8 ++++ store/rdbms/messagebus_queue_settings.gen.go | 8 ++++ store/rdbms/rbac_rules.gen.go | 8 ++++ store/rdbms/reminders.gen.go | 8 ++++ store/rdbms/reports.gen.go | 17 +++++++- store/rdbms/resource_translation.gen.go | 8 ++++ store/rdbms/role_members.gen.go | 8 ++++ store/rdbms/roles.gen.go | 21 +++++++++- store/rdbms/settings.gen.go | 8 ++++ store/rdbms/templates.gen.go | 17 +++++++- store/rdbms/users.gen.go | 39 ++++++++++++++++--- store/tests/roles_test.go | 16 ++++++-- store/tests/users_test.go | 16 ++++++-- 42 files changed, 506 insertions(+), 37 deletions(-) diff --git a/pkg/codegen/assets/store_rdbms.gen.go.tpl b/pkg/codegen/assets/store_rdbms.gen.go.tpl index d27e5daa92..a31f7bae60 100644 --- a/pkg/codegen/assets/store_rdbms.gen.go.tpl +++ b/pkg/codegen/assets/store_rdbms.gen.go.tpl @@ -729,20 +729,36 @@ func (s *Store) check{{ export $.Types.Singular }}Constraints(ctx context.Contex return nil } - + var checks = make([]func () error, 0) {{- range $.Lookups }} {{ if .UniqueConstraintCheck }} - { + checks = append(checks, func () error { + // Skip lookup by {{ .Suffix }} if {{ export $.Types.Singular }} does not match filters + {{- range $field, $value := .Filter }} + if res.{{ $field }} != {{ $value }} { + return nil + } + {{ end }} + ex, err := s.{{ toggleExport .Export "Lookup" $.Types.Singular "By" .Suffix }}(ctx{{ template "extraArgsCall" $ }}{{- range .RDBMSColumns }}, res.{{ .Field }} {{- end }}) if err == nil && ex != nil {{- range $.RDBMS.Columns.PrimaryKeyFields }} && ex.{{ .Field }} != res.{{ .Field }} {{ end }} { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } - } + + return nil + }) {{ end }} {{ end }} + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + + return nil } diff --git a/store/rdbms/actionlog.gen.go b/store/rdbms/actionlog.gen.go index 30f640b4e7..a197fdd741 100644 --- a/store/rdbms/actionlog.gen.go +++ b/store/rdbms/actionlog.gen.go @@ -220,5 +220,13 @@ func (s *Store) checkActionlogConstraints(ctx context.Context, res *actionlog.Ac return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/apigw_filter.gen.go b/store/rdbms/apigw_filter.gen.go index 3f3217e4e2..3a4b87f963 100644 --- a/store/rdbms/apigw_filter.gen.go +++ b/store/rdbms/apigw_filter.gen.go @@ -567,5 +567,13 @@ func (s *Store) checkApigwFilterConstraints(ctx context.Context, res *types.Apig return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/apigw_route.gen.go b/store/rdbms/apigw_route.gen.go index 8dfcda4621..006f38b840 100644 --- a/store/rdbms/apigw_route.gen.go +++ b/store/rdbms/apigw_route.gen.go @@ -564,5 +564,13 @@ func (s *Store) checkApigwRouteConstraints(ctx context.Context, res *types.Apigw return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/applications.gen.go b/store/rdbms/applications.gen.go index 58e928070c..fd0a69bedf 100644 --- a/store/rdbms/applications.gen.go +++ b/store/rdbms/applications.gen.go @@ -602,5 +602,13 @@ func (s *Store) checkApplicationConstraints(ctx context.Context, res *types.Appl return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/attachments.gen.go b/store/rdbms/attachments.gen.go index fabd588c6f..2e4aed6357 100644 --- a/store/rdbms/attachments.gen.go +++ b/store/rdbms/attachments.gen.go @@ -351,5 +351,13 @@ func (s *Store) checkAttachmentConstraints(ctx context.Context, res *types.Attac return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/auth_clients.gen.go b/store/rdbms/auth_clients.gen.go index b6dc7815d1..2857fc0627 100644 --- a/store/rdbms/auth_clients.gen.go +++ b/store/rdbms/auth_clients.gen.go @@ -642,13 +642,28 @@ func (s *Store) checkAuthClientConstraints(ctx context.Context, res *types.AuthC return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by Handle if AuthClient does not match filters + if res.DeletedAt != nil { + return nil + } + ex, err := s.LookupAuthClientByHandle(ctx, res.Handle) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/rdbms/auth_confirmed_clients.gen.go b/store/rdbms/auth_confirmed_clients.gen.go index 2a6d2cccdc..7d058cd30f 100644 --- a/store/rdbms/auth_confirmed_clients.gen.go +++ b/store/rdbms/auth_confirmed_clients.gen.go @@ -325,13 +325,25 @@ func (s *Store) checkAuthConfirmedClientConstraints(ctx context.Context, res *ty return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by UserIDClientID if AuthConfirmedClient does not match filters + ex, err := s.LookupAuthConfirmedClientByUserIDClientID(ctx, res.UserID, res.ClientID) if err == nil && ex != nil && ex.UserID != res.UserID && ex.ClientID != res.ClientID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/rdbms/auth_oa2tokens.gen.go b/store/rdbms/auth_oa2tokens.gen.go index 0049c6ccb6..d2b4fe048d 100644 --- a/store/rdbms/auth_oa2tokens.gen.go +++ b/store/rdbms/auth_oa2tokens.gen.go @@ -297,31 +297,51 @@ func (s *Store) checkAuthOa2tokenConstraints(ctx context.Context, res *types.Aut return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by Code if AuthOa2token does not match filters + ex, err := s.LookupAuthOa2tokenByCode(ctx, res.Code) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } - } - { + return nil + }) + + checks = append(checks, func() error { + // Skip lookup by Access if AuthOa2token does not match filters + ex, err := s.LookupAuthOa2tokenByAccess(ctx, res.Access) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } - } - { + return nil + }) + + checks = append(checks, func() error { + // Skip lookup by Refresh if AuthOa2token does not match filters + ex, err := s.LookupAuthOa2tokenByRefresh(ctx, res.Refresh) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/rdbms/auth_sessions.gen.go b/store/rdbms/auth_sessions.gen.go index 457f72dd54..27fe8c4203 100644 --- a/store/rdbms/auth_sessions.gen.go +++ b/store/rdbms/auth_sessions.gen.go @@ -332,13 +332,25 @@ func (s *Store) checkAuthSessionConstraints(ctx context.Context, res *types.Auth return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by ID if AuthSession does not match filters + ex, err := s.LookupAuthSessionByID(ctx, res.ID) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/rdbms/automation_sessions.gen.go b/store/rdbms/automation_sessions.gen.go index b0ae99939d..1c1fad91d1 100644 --- a/store/rdbms/automation_sessions.gen.go +++ b/store/rdbms/automation_sessions.gen.go @@ -624,5 +624,13 @@ func (s *Store) checkAutomationSessionConstraints(ctx context.Context, res *type return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/automation_triggers.gen.go b/store/rdbms/automation_triggers.gen.go index 3bd1414aa7..95feabda47 100644 --- a/store/rdbms/automation_triggers.gen.go +++ b/store/rdbms/automation_triggers.gen.go @@ -604,5 +604,13 @@ func (s *Store) checkAutomationTriggerConstraints(ctx context.Context, res *type return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/automation_workflows.gen.go b/store/rdbms/automation_workflows.gen.go index 89c01ad617..67b3653732 100644 --- a/store/rdbms/automation_workflows.gen.go +++ b/store/rdbms/automation_workflows.gen.go @@ -643,13 +643,28 @@ func (s *Store) checkAutomationWorkflowConstraints(ctx context.Context, res *typ return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by Handle if AutomationWorkflow does not match filters + if res.DeletedAt != nil { + return nil + } + ex, err := s.LookupAutomationWorkflowByHandle(ctx, res.Handle) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/rdbms/compose_attachments.gen.go b/store/rdbms/compose_attachments.gen.go index 05e47edcb8..441c138761 100644 --- a/store/rdbms/compose_attachments.gen.go +++ b/store/rdbms/compose_attachments.gen.go @@ -354,5 +354,13 @@ func (s *Store) checkComposeAttachmentConstraints(ctx context.Context, res *type return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/compose_charts.gen.go b/store/rdbms/compose_charts.gen.go index 69199ed45d..aedbe8a155 100644 --- a/store/rdbms/compose_charts.gen.go +++ b/store/rdbms/compose_charts.gen.go @@ -610,5 +610,13 @@ func (s *Store) checkComposeChartConstraints(ctx context.Context, res *types.Cha return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/compose_module_fields.gen.go b/store/rdbms/compose_module_fields.gen.go index b66f852b9a..861da4f238 100644 --- a/store/rdbms/compose_module_fields.gen.go +++ b/store/rdbms/compose_module_fields.gen.go @@ -364,13 +364,28 @@ func (s *Store) checkComposeModuleFieldConstraints(ctx context.Context, res *typ return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by ModuleIDName if ComposeModuleField does not match filters + if res.DeletedAt != nil { + return nil + } + ex, err := s.LookupComposeModuleFieldByModuleIDName(ctx, res.ModuleID, res.Name) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/rdbms/compose_modules.gen.go b/store/rdbms/compose_modules.gen.go index 0a3478ce92..5aafc53dda 100644 --- a/store/rdbms/compose_modules.gen.go +++ b/store/rdbms/compose_modules.gen.go @@ -624,13 +624,28 @@ func (s *Store) checkComposeModuleConstraints(ctx context.Context, res *types.Mo return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by NamespaceIDHandle if ComposeModule does not match filters + if res.DeletedAt != nil { + return nil + } + ex, err := s.LookupComposeModuleByNamespaceIDHandle(ctx, res.NamespaceID, res.Handle) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/rdbms/compose_namespaces.gen.go b/store/rdbms/compose_namespaces.gen.go index ca1dae1f23..4463d32ebf 100644 --- a/store/rdbms/compose_namespaces.gen.go +++ b/store/rdbms/compose_namespaces.gen.go @@ -611,13 +611,28 @@ func (s *Store) checkComposeNamespaceConstraints(ctx context.Context, res *types return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by Slug if ComposeNamespace does not match filters + if res.DeletedAt != nil { + return nil + } + ex, err := s.LookupComposeNamespaceBySlug(ctx, res.Slug) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/rdbms/compose_pages.gen.go b/store/rdbms/compose_pages.gen.go index 8f5fe59e46..a00eb4f3ba 100644 --- a/store/rdbms/compose_pages.gen.go +++ b/store/rdbms/compose_pages.gen.go @@ -631,5 +631,13 @@ func (s *Store) checkComposePageConstraints(ctx context.Context, res *types.Page return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/compose_record_values.gen.go b/store/rdbms/compose_record_values.gen.go index ca29782012..07a33f857e 100644 --- a/store/rdbms/compose_record_values.gen.go +++ b/store/rdbms/compose_record_values.gen.go @@ -324,5 +324,13 @@ func (s *Store) checkComposeRecordValueConstraints(ctx context.Context, _mod *ty return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/compose_records.gen.go b/store/rdbms/compose_records.gen.go index 2889a42a6d..72e9c27968 100644 --- a/store/rdbms/compose_records.gen.go +++ b/store/rdbms/compose_records.gen.go @@ -489,5 +489,13 @@ func (s *Store) checkComposeRecordConstraints(ctx context.Context, _mod *types.M return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/credentials.gen.go b/store/rdbms/credentials.gen.go index 14537915ad..c865d64fa3 100644 --- a/store/rdbms/credentials.gen.go +++ b/store/rdbms/credentials.gen.go @@ -344,5 +344,13 @@ func (s *Store) checkCredentialsConstraints(ctx context.Context, res *types.Cred return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/federation_exposed_modules.gen.go b/store/rdbms/federation_exposed_modules.gen.go index 99f1e03648..7e91d025ab 100644 --- a/store/rdbms/federation_exposed_modules.gen.go +++ b/store/rdbms/federation_exposed_modules.gen.go @@ -595,5 +595,13 @@ func (s *Store) checkFederationExposedModuleConstraints(ctx context.Context, res return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/federation_module_mappings.gen.go b/store/rdbms/federation_module_mappings.gen.go index 25a9768c1d..f52deb8d13 100644 --- a/store/rdbms/federation_module_mappings.gen.go +++ b/store/rdbms/federation_module_mappings.gen.go @@ -612,5 +612,13 @@ func (s *Store) checkFederationModuleMappingConstraints(ctx context.Context, res return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/federation_nodes.gen.go b/store/rdbms/federation_nodes.gen.go index 350d797df8..d0abe9fba6 100644 --- a/store/rdbms/federation_nodes.gen.go +++ b/store/rdbms/federation_nodes.gen.go @@ -378,5 +378,13 @@ func (s *Store) checkFederationNodeConstraints(ctx context.Context, res *types.N return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/federation_nodes_sync.gen.go b/store/rdbms/federation_nodes_sync.gen.go index 643c62de64..b390deabc4 100644 --- a/store/rdbms/federation_nodes_sync.gen.go +++ b/store/rdbms/federation_nodes_sync.gen.go @@ -588,5 +588,13 @@ func (s *Store) checkFederationNodesSyncConstraints(ctx context.Context, res *ty return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/federation_shared_modules.gen.go b/store/rdbms/federation_shared_modules.gen.go index 2170f79cb5..0284b031be 100644 --- a/store/rdbms/federation_shared_modules.gen.go +++ b/store/rdbms/federation_shared_modules.gen.go @@ -592,5 +592,13 @@ func (s *Store) checkFederationSharedModuleConstraints(ctx context.Context, res return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/flags.gen.go b/store/rdbms/flags.gen.go index 7f748abb81..a24cc344b3 100644 --- a/store/rdbms/flags.gen.go +++ b/store/rdbms/flags.gen.go @@ -383,40 +383,64 @@ func (s *Store) checkFlagConstraints(ctx context.Context, res *types.Flag) error return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by KindResourceIDName if Flag does not match filters + ex, err := s.LookupFlagByKindResourceIDName(ctx, res.Kind, res.ResourceID, res.Name) if err == nil && ex != nil && ex.Kind != res.Kind && ex.ResourceID != res.ResourceID && ex.OwnedBy != res.OwnedBy && ex.Name != res.Name { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } - } - { + return nil + }) + + checks = append(checks, func() error { + // Skip lookup by KindResourceID if Flag does not match filters + ex, err := s.LookupFlagByKindResourceID(ctx, res.Kind, res.ResourceID) if err == nil && ex != nil && ex.Kind != res.Kind && ex.ResourceID != res.ResourceID && ex.OwnedBy != res.OwnedBy && ex.Name != res.Name { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } - } - { + return nil + }) + + checks = append(checks, func() error { + // Skip lookup by KindResourceIDOwnedBy if Flag does not match filters + ex, err := s.LookupFlagByKindResourceIDOwnedBy(ctx, res.Kind, res.ResourceID, res.OwnedBy) if err == nil && ex != nil && ex.Kind != res.Kind && ex.ResourceID != res.ResourceID && ex.OwnedBy != res.OwnedBy && ex.Name != res.Name { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } - } - { + return nil + }) + + checks = append(checks, func() error { + // Skip lookup by KindResourceIDOwnedByName if Flag does not match filters + ex, err := s.LookupFlagByKindResourceIDOwnedByName(ctx, res.Kind, res.ResourceID, res.OwnedBy, res.Name) if err == nil && ex != nil && ex.Kind != res.Kind && ex.ResourceID != res.ResourceID && ex.OwnedBy != res.OwnedBy && ex.Name != res.Name { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/rdbms/labels.gen.go b/store/rdbms/labels.gen.go index 7bee89951c..1837c572d5 100644 --- a/store/rdbms/labels.gen.go +++ b/store/rdbms/labels.gen.go @@ -333,13 +333,25 @@ func (s *Store) checkLabelConstraints(ctx context.Context, res *types.Label) err return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by KindResourceIDName if Label does not match filters + ex, err := s.LookupLabelByKindResourceIDName(ctx, res.Kind, res.ResourceID, res.Name) if err == nil && ex != nil && ex.Kind != res.Kind && ex.ResourceID != res.ResourceID && ex.Name != res.Name { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/rdbms/messagebus_queue_message.gen.go b/store/rdbms/messagebus_queue_message.gen.go index 65aaeb5756..633ee88918 100644 --- a/store/rdbms/messagebus_queue_message.gen.go +++ b/store/rdbms/messagebus_queue_message.gen.go @@ -519,5 +519,13 @@ func (s *Store) checkMessagebusQueueMessageConstraints(ctx context.Context, res return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/messagebus_queue_settings.gen.go b/store/rdbms/messagebus_queue_settings.gen.go index 2d04e09cd1..8e3526ab1d 100644 --- a/store/rdbms/messagebus_queue_settings.gen.go +++ b/store/rdbms/messagebus_queue_settings.gen.go @@ -578,5 +578,13 @@ func (s *Store) checkMessagebusQueueSettingConstraints(ctx context.Context, res return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/rbac_rules.gen.go b/store/rdbms/rbac_rules.gen.go index 0b9f487598..e5ea402993 100644 --- a/store/rdbms/rbac_rules.gen.go +++ b/store/rdbms/rbac_rules.gen.go @@ -315,5 +315,13 @@ func (s *Store) checkRbacRuleConstraints(ctx context.Context, res *rbac.Rule) er return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/reminders.gen.go b/store/rdbms/reminders.gen.go index a6320fa42e..ea0e17e348 100644 --- a/store/rdbms/reminders.gen.go +++ b/store/rdbms/reminders.gen.go @@ -613,5 +613,13 @@ func (s *Store) checkReminderConstraints(ctx context.Context, res *types.Reminde return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/reports.gen.go b/store/rdbms/reports.gen.go index d4e0b4667a..b3a7cdc4df 100644 --- a/store/rdbms/reports.gen.go +++ b/store/rdbms/reports.gen.go @@ -621,13 +621,28 @@ func (s *Store) checkReportConstraints(ctx context.Context, res *types.Report) e return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by Handle if Report does not match filters + if res.DeletedAt != nil { + return nil + } + ex, err := s.LookupReportByHandle(ctx, res.Handle) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/rdbms/resource_translation.gen.go b/store/rdbms/resource_translation.gen.go index eac1e1ab5d..576ee6484f 100644 --- a/store/rdbms/resource_translation.gen.go +++ b/store/rdbms/resource_translation.gen.go @@ -614,5 +614,13 @@ func (s *Store) checkResourceTranslationConstraints(ctx context.Context, res *ty return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/role_members.gen.go b/store/rdbms/role_members.gen.go index 827c0fe0f2..095a973214 100644 --- a/store/rdbms/role_members.gen.go +++ b/store/rdbms/role_members.gen.go @@ -310,5 +310,13 @@ func (s *Store) checkRoleMemberConstraints(ctx context.Context, res *types.RoleM return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/roles.gen.go b/store/rdbms/roles.gen.go index 290e1e0fcd..ba42dd870c 100644 --- a/store/rdbms/roles.gen.go +++ b/store/rdbms/roles.gen.go @@ -631,13 +631,32 @@ func (s *Store) checkRoleConstraints(ctx context.Context, res *types.Role) error return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by Handle if Role does not match filters + if res.ArchivedAt != nil { + return nil + } + + if res.DeletedAt != nil { + return nil + } + ex, err := s.LookupRoleByHandle(ctx, res.Handle) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/rdbms/settings.gen.go b/store/rdbms/settings.gen.go index f920092668..729b71b6fc 100644 --- a/store/rdbms/settings.gen.go +++ b/store/rdbms/settings.gen.go @@ -337,5 +337,13 @@ func (s *Store) checkSettingConstraints(ctx context.Context, res *types.SettingV return nil } + var checks = make([]func() error, 0) + + for _, check := range checks { + if err := check(); err != nil { + return err + } + } + return nil } diff --git a/store/rdbms/templates.gen.go b/store/rdbms/templates.gen.go index 2be48202b6..b5d533116b 100644 --- a/store/rdbms/templates.gen.go +++ b/store/rdbms/templates.gen.go @@ -627,13 +627,28 @@ func (s *Store) checkTemplateConstraints(ctx context.Context, res *types.Templat return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by Handle if Template does not match filters + if res.DeletedAt != nil { + return nil + } + ex, err := s.LookupTemplateByHandle(ctx, res.Handle) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/rdbms/users.gen.go b/store/rdbms/users.gen.go index bc1c192ca9..1857b347dc 100644 --- a/store/rdbms/users.gen.go +++ b/store/rdbms/users.gen.go @@ -664,31 +664,60 @@ func (s *Store) checkUserConstraints(ctx context.Context, res *types.User) error return nil } - { + var checks = make([]func() error, 0) + + checks = append(checks, func() error { + // Skip lookup by Email if User does not match filters + if res.DeletedAt != nil { + return nil + } + ex, err := s.LookupUserByEmail(ctx, res.Email) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } - } - { + return nil + }) + + checks = append(checks, func() error { + // Skip lookup by Handle if User does not match filters + if res.DeletedAt != nil { + return nil + } + ex, err := s.LookupUserByHandle(ctx, res.Handle) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } - } - { + return nil + }) + + checks = append(checks, func() error { + // Skip lookup by Username if User does not match filters + if res.DeletedAt != nil { + return nil + } + ex, err := s.LookupUserByUsername(ctx, res.Username) if err == nil && ex != nil && ex.ID != res.ID { return store.ErrNotUnique.Stack(1) } else if !errors.IsNotFound(err) { return err } + + return nil + }) + + for _, check := range checks { + if err := check(); err != nil { + return err + } } return nil diff --git a/store/tests/roles_test.go b/store/tests/roles_test.go index 52076a4f6c..fccbd04f5d 100644 --- a/store/tests/roles_test.go +++ b/store/tests/roles_test.go @@ -2,6 +2,10 @@ package tests import ( "context" + "strings" + "testing" + "time" + "github.com/cortezaproject/corteza-server/pkg/filter" "github.com/cortezaproject/corteza-server/pkg/id" "github.com/cortezaproject/corteza-server/pkg/rand" @@ -9,9 +13,6 @@ import ( "github.com/cortezaproject/corteza-server/system/types" _ "github.com/joho/godotenv/autoload" "github.com/stretchr/testify/require" - "strings" - "testing" - "time" ) func testRoles(t *testing.T, s store.Roles) { @@ -73,6 +74,15 @@ func testRoles(t *testing.T, s store.Roles) { req.NoError(s.UpdateRole(ctx, role)) }) + t.Run("create and update deleted with existing handle", func(t *testing.T) { + req, role := truncAndCreate(t) + deletedRole := makeNew("copy") + deletedRole.DeletedAt = now() + deletedRole.Handle = role.Handle + req.NoError(store.CreateRole(ctx, s, deletedRole)) + req.NoError(store.UpdateRole(ctx, s, deletedRole)) + }) + t.Run("lookup by handle", func(t *testing.T) { req, role := truncAndCreate(t) fetched, err := s.LookupRoleByHandle(ctx, role.Handle) diff --git a/store/tests/users_test.go b/store/tests/users_test.go index 57ab1920d8..e0ff19d56f 100644 --- a/store/tests/users_test.go +++ b/store/tests/users_test.go @@ -3,6 +3,10 @@ package tests import ( "context" "fmt" + "strings" + "testing" + "time" + "github.com/cortezaproject/corteza-server/pkg/filter" "github.com/cortezaproject/corteza-server/pkg/id" "github.com/cortezaproject/corteza-server/pkg/rand" @@ -10,9 +14,6 @@ import ( "github.com/cortezaproject/corteza-server/system/types" _ "github.com/joho/godotenv/autoload" "github.com/stretchr/testify/require" - "strings" - "testing" - "time" ) func testUsers(t *testing.T, s store.Users) { @@ -144,6 +145,15 @@ func testUsers(t *testing.T, s store.Users) { req.Equal(user.ID, fetched.ID) }) + t.Run("create and update deleted with existing email", func(t *testing.T) { + req, user := truncAndCreate(t) + deletedUser := makeNew("copy") + deletedUser.DeletedAt = now() + deletedUser.Email = user.Email + req.NoError(store.CreateUser(ctx, s, deletedUser)) + req.NoError(store.UpdateUser(ctx, s, deletedUser)) + }) + t.Run("search", func(t *testing.T) { t.Run("by ID", func(t *testing.T) { req, prefill := truncAndFill(t, 5)