added explicit errors when trying to truncate view collections or deleting view records

This commit is contained in:
Gani Georgiev 2024-10-09 11:51:03 +03:00
parent 2c2246ecb9
commit c09cd8364a
7 changed files with 61 additions and 4 deletions

View File

@ -1,3 +1,11 @@
## v0.23.0-rc4 (WIP)
> [!CAUTION]
> **This is a prerelease intended for test and experimental purposes only!**
- Added more user friendly view collection truncate error message.
## v0.23.0-rc3 ## v0.23.0-rc3
> [!CAUTION] > [!CAUTION]

View File

@ -169,6 +169,10 @@ func collectionTruncate(e *core.RequestEvent) error {
return e.NotFoundError("", err) return e.NotFoundError("", err)
} }
if collection.IsView() {
return e.BadRequestError("View collections cannot be truncated since they don't store their own records.", nil)
}
err = e.App.TruncateCollection(collection) err = e.App.TruncateCollection(collection)
if err != nil { if err != nil {
return e.BadRequestError("Failed to truncate collection (most likely due to required cascade delete record references).", err) return e.BadRequestError("Failed to truncate collection (most likely due to required cascade delete record references).", err)

View File

@ -1493,6 +1493,17 @@ func TestCollectionTruncate(t *testing.T) {
"OnRecordAfterUpdateError": 2, "OnRecordAfterUpdateError": 2,
}, },
}, },
{
Name: "authorized as superuser trying to truncate view collection",
Method: http.MethodDelete,
URL: "/api/collections/view2/truncate",
Headers: map[string]string{
"Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiY18zMzIzODY2MzM5IiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.v_bMAygr6hXPwD2DpPrFpNQ7dd68Q3pGstmYAsvNBJg",
},
ExpectedStatus: 400,
ExpectedContent: []string{`"data":{}`},
ExpectedEvents: map[string]int{"*": 0},
},
} }
for _, scenario := range scenarios { for _, scenario := range scenarios {

View File

@ -176,6 +176,10 @@ func (app *BaseApp) FindCollectionReferences(collection *Collection, excludeIds
// Note that this method will also trigger the records related // Note that this method will also trigger the records related
// cascade and file delete actions. // cascade and file delete actions.
func (app *BaseApp) TruncateCollection(collection *Collection) error { func (app *BaseApp) TruncateCollection(collection *Collection) error {
if collection.IsView() {
return errors.New("view collections cannot be truncated since they don't store their own records.")
}
return app.RunInTransaction(func(txApp App) error { return app.RunInTransaction(func(txApp App) error {
records := make([]*Record, 0, 500) records := make([]*Record, 0, 500)

View File

@ -299,6 +299,18 @@ func TestFindCollectionTruncate(t *testing.T) {
return len(entries), err return len(entries), err
} }
t.Run("truncate view", func(t *testing.T) {
view2, err := app.FindCollectionByNameOrId("view2")
if err != nil {
t.Fatal(err)
}
err = app.TruncateCollection(view2)
if err == nil {
t.Fatalf("Expected truncate to fail because view collections can't be truncated")
}
})
t.Run("truncate failure", func(t *testing.T) { t.Run("truncate failure", func(t *testing.T) {
demo3, err := app.FindCollectionByNameOrId("demo3") demo3, err := app.FindCollectionByNameOrId("demo3")
if err != nil { if err != nil {

View File

@ -378,7 +378,13 @@ func (app *BaseApp) registerRecordHooks() {
e.Context, e.Context,
e.App, e.App,
InterceptorActionDelete, InterceptorActionDelete,
e.Next, func() error {
if e.Record.Collection().IsView() {
return errors.New("view records cannot be deleted")
}
return e.Next()
},
) )
}, },
Priority: -99, Priority: -99,

View File

@ -1841,9 +1841,21 @@ func TestRecordDelete(t *testing.T) {
// delete unsaved record // delete unsaved record
// --- // ---
rec0 := core.NewRecord(demoCollection) newRec := core.NewRecord(demoCollection)
if err := app.Delete(rec0); err == nil { if err := app.Delete(newRec); err == nil {
t.Fatal("(rec0) Didn't expect to succeed deleting unsaved record") t.Fatal("(newRec) Didn't expect to succeed deleting unsaved record")
}
// delete view record
// ---
viewRec, _ := app.FindRecordById("view2", "84nmscqy84lsi1t")
if err := app.Delete(viewRec); err == nil {
t.Fatal("(viewRec) Didn't expect to succeed deleting view record")
}
// check if it still exists
viewRec, _ = app.FindRecordById(viewRec.Collection().Id, viewRec.Id)
if viewRec == nil {
t.Fatal("(viewRec) Expected view record to still exists")
} }
// delete existing record + external auths // delete existing record + external auths