fix: add quota limit check to prevent subscription bypass

- Add quota check in preCreateOrderLogic for order preview
- Move quota check inside transaction in purchaseLogic to prevent race condition
- Add quota check in activateOrderLogic as final safeguard when creating subscription
- Add quota check in redeemCodeLogic when redeeming codes for new subscriptions
This commit is contained in:
EUForest
2026-01-10 21:18:26 +08:00
parent 2a1ae2e1cc
commit 7d4a19c9a3
4 changed files with 73 additions and 13 deletions
+18 -13
View File
@@ -87,19 +87,6 @@ func (l *PurchaseLogic) Purchase(req *types.PurchaseOrderRequest) (resp *types.P
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SubscribeOutOfStock), "subscribe out of stock")
}
// check subscribe plan limit
if sub.Quota > 0 {
var count int64
for _, v := range userSub {
if v.SubscribeId == req.SubscribeId {
count += 1
}
}
if count >= sub.Quota {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SubscribeQuotaLimit), "quota limit")
}
}
var discount float64 = 1
if sub.Discount != "" {
var dis []types.SubscribeDiscount
@@ -195,6 +182,24 @@ func (l *PurchaseLogic) Purchase(req *types.PurchaseOrderRequest) (resp *types.P
}
// Database transaction
err = l.svcCtx.DB.Transaction(func(db *gorm.DB) error {
// check subscribe plan quota limit inside transaction to prevent race condition
if sub.Quota > 0 {
var currentUserSub []user.Subscribe
if e := db.Model(&user.Subscribe{}).Where("user_id = ?", u.Id).Find(&currentUserSub).Error; e != nil {
l.Errorw("[Purchase] Database query error", logger.Field("error", e.Error()), logger.Field("user_id", u.Id))
return e
}
var count int64
for _, v := range currentUserSub {
if v.SubscribeId == req.SubscribeId {
count++
}
}
if count >= sub.Quota {
return errors.Wrapf(xerr.NewErrCode(xerr.SubscribeQuotaLimit), "quota limit")
}
}
// update user deduction && Pre deduction ,Return after canceling the order
if orderInfo.GiftAmount > 0 {
// update user deduction && Pre deduction ,Return after canceling the order