From 460f0fcf37bc8f0975beb973489982ac016b12ea Mon Sep 17 00:00:00 2001 From: Tomas Buchaillot Date: Fri, 17 Jan 2025 18:55:53 +0100 Subject: [PATCH 1/3] TT-13870 Fix POST update --- resource/crud.go | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/resource/crud.go b/resource/crud.go index de96a4d9..5ab75b86 100644 --- a/resource/crud.go +++ b/resource/crud.go @@ -136,12 +136,50 @@ func (res *Resource) findManyHandler(result interface{}, context *qor.Context) e } func (res *Resource) saveHandler(result interface{}, context *qor.Context) error { - if (context.GetDB().NewScope(result).PrimaryKeyZero() && - res.HasPermission(roles.Create, context)) || // has create permission - res.HasPermission(roles.Update, context) { // has update permission - return context.GetDB().Save(result).Error + scope := context.GetDB().NewScope(result) + isPrimaryKeyZero := scope.PrimaryKeyZero() + + if isPrimaryKeyZero { + // Create operation + if !res.HasPermission(roles.Create, context) { + return roles.ErrPermissionDenied + } + return context.GetDB().Create(result).Error } - return roles.ErrPermissionDenied + + // If we have a non-zero primary key, first check if it exists + var count int + primaryField := scope.PrimaryField() + if primaryField == nil { + return fmt.Errorf("no primary key field found") + } + + query := fmt.Sprintf("%v = ?", scope.Quote(primaryField.DBName)) + if err := context.GetDB().Model(result).Where(query, scope.PrimaryKeyValue()).Count(&count).Error; err != nil { + return err + } + + // For creation attempts with existing ID + if context.Request != nil && context.Request.Method == "POST" { + if count > 0 { + return fmt.Errorf("record with primary key %v already exists", scope.PrimaryKeyValue()) + } + if !res.HasPermission(roles.Create, context) { + return roles.ErrPermissionDenied + } + return context.GetDB().Create(result).Error + } + + // Update operation + if !res.HasPermission(roles.Update, context) { + return roles.ErrPermissionDenied + } + + if count == 0 { + return fmt.Errorf("record with primary key %v not found", scope.PrimaryKeyValue()) + } + + return context.GetDB().Save(result).Error } func (res *Resource) deleteHandler(result interface{}, context *qor.Context) error { From cdfe52653fda8fd6c1ba4e95873c21c213c215a3 Mon Sep 17 00:00:00 2001 From: Tomas Buchaillot Date: Fri, 17 Jan 2025 19:04:58 +0100 Subject: [PATCH 2/3] linting --- resource/crud.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resource/crud.go b/resource/crud.go index 5ab75b86..574e48bf 100644 --- a/resource/crud.go +++ b/resource/crud.go @@ -144,11 +144,13 @@ func (res *Resource) saveHandler(result interface{}, context *qor.Context) error if !res.HasPermission(roles.Create, context) { return roles.ErrPermissionDenied } + return context.GetDB().Create(result).Error } // If we have a non-zero primary key, first check if it exists var count int + primaryField := scope.PrimaryField() if primaryField == nil { return fmt.Errorf("no primary key field found") @@ -164,9 +166,11 @@ func (res *Resource) saveHandler(result interface{}, context *qor.Context) error if count > 0 { return fmt.Errorf("record with primary key %v already exists", scope.PrimaryKeyValue()) } + if !res.HasPermission(roles.Create, context) { return roles.ErrPermissionDenied } + return context.GetDB().Create(result).Error } From f21704bfaf944eab438a950c74ec53499a9c13f5 Mon Sep 17 00:00:00 2001 From: Tomas Buchaillot Date: Fri, 17 Jan 2025 19:08:02 +0100 Subject: [PATCH 3/3] linting --- resource/crud.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resource/crud.go b/resource/crud.go index 574e48bf..c71daebc 100644 --- a/resource/crud.go +++ b/resource/crud.go @@ -144,13 +144,13 @@ func (res *Resource) saveHandler(result interface{}, context *qor.Context) error if !res.HasPermission(roles.Create, context) { return roles.ErrPermissionDenied } - + return context.GetDB().Create(result).Error } // If we have a non-zero primary key, first check if it exists var count int - + primaryField := scope.PrimaryField() if primaryField == nil { return fmt.Errorf("no primary key field found") @@ -166,11 +166,11 @@ func (res *Resource) saveHandler(result interface{}, context *qor.Context) error if count > 0 { return fmt.Errorf("record with primary key %v already exists", scope.PrimaryKeyValue()) } - + if !res.HasPermission(roles.Create, context) { return roles.ErrPermissionDenied } - + return context.GetDB().Create(result).Error }