feat(12.1-01): cabana.ForbiddenError answers a refused write with 403
- hooks and bulk, record, toolbar and widget actions may return it - 403 forbidden with the localized message and field details; the write's transaction is rolled back; other errors stay the opaque 500 - form shows a refused save as a persistent banner and keeps the values; a refused delete is a toast - smoke tests, OpenAPI notes, dist, README, docs
This commit is contained in:
@@ -858,6 +858,12 @@ func relationSelects(db *gorm.DB, cr *CompiledRelation, target any, cols []Relat
|
||||
return out
|
||||
}
|
||||
|
||||
// transaction runs fn in lagoon.Transaction on the service's database and
|
||||
// localizes a *ForbiddenError a relation hook returned (D-27).
|
||||
func (s RelationService) transaction(ctx context.Context, fn func(ctx context.Context, tx *gorm.DB) error) error {
|
||||
return localizeForbidden(ctx, s.tr, lagoon.Transaction(ctx, s.DB, fn))
|
||||
}
|
||||
|
||||
// Link links eligible related records to the parent and never restamps
|
||||
// existing links. On a belongsToMany it writes pivot rows (with the pivot
|
||||
// form's values when the body carries a pivot object for one id); on a
|
||||
@@ -877,7 +883,7 @@ func (s RelationService) Link(ctx context.Context, cc *CompiledController, relat
|
||||
return RelationMutationResult{}, err
|
||||
}
|
||||
var result RelationMutationResult
|
||||
err = lagoon.Transaction(ctx, s.DB, func(ctx context.Context, tx *gorm.DB) error {
|
||||
err = s.transaction(ctx, func(ctx context.Context, tx *gorm.DB) error {
|
||||
ctx = withTx(ctx, tx)
|
||||
parent, err := s.loadParent(ctx, tx, cc, cr, ownerID)
|
||||
if err != nil {
|
||||
@@ -1194,7 +1200,7 @@ func (s RelationService) Unlink(ctx context.Context, cc *CompiledController, rel
|
||||
return RelationMutationResult{}, err
|
||||
}
|
||||
var result RelationMutationResult
|
||||
err = lagoon.Transaction(ctx, s.DB, func(ctx context.Context, tx *gorm.DB) error {
|
||||
err = s.transaction(ctx, func(ctx context.Context, tx *gorm.DB) error {
|
||||
ctx = withTx(ctx, tx)
|
||||
parent, err := s.loadParent(ctx, tx, cc, cr, ownerID)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user