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 d27e5daa9..a31f7bae6 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 30f640b4e..a197fdd74 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 3f3217e4e..3a4b87f96 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 8dfcda462..006f38b84 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 58e928070..fd0a69bed 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 fabd588c6..2e4aed635 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 b6dc7815d..2857fc062 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 2a6d2cccd..7d058cd30 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 0049c6ccb..d2b4fe048 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 457f72dd5..27fe8c420 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 b0ae99939..1c1fad91d 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 3bd1414aa..95feabda4 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 89c01ad61..67b365373 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 05e47edcb..441c13876 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 69199ed45..aedbe8a15 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 b66f852b9..861da4f23 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 0a3478ce9..5aafc53dd 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 ca1dae1f2..4463d32eb 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 8f5fe59e4..a00eb4f3b 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 ca2978201..07a33f857 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 2889a42a6..72e9c2796 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 14537915a..c865d64fa 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 99f1e0364..7e91d025a 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 25a9768c1..f52deb8d1 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 350d797df..d0abe9fba 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 643c62de6..b390deabc 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 2170f79cb..0284b031b 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 7f748abb8..a24cc344b 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 7bee89951..1837c572d 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 65aaeb575..633ee8891 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 2d04e09cd..8e3526ab1 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 0b9f48759..e5ea40299 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 a6320fa42..ea0e17e34 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 d4e0b4667..b3a7cdc4d 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 eac1e1ab5..576ee6484 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 827c0fe0f..095a97321 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 290e1e0fc..ba42dd870 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 f92009266..729b71b6f 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 2be48202b..b5d533116 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 bc1c192ca..1857b347d 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 52076a4f6..fccbd04f5 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 57ab1920d..e0ff19d56 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)