Files
junhong_cmp_fiber/internal/service/asset/enterprise_scope.go
邹进 82a2fcc306
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m25s
fix: 企业账号只能访问授权给本企业的资产
/assets/:identifier/* 共用 AssetService.Resolve 解析资产,而店铺数据范围 ApplyShopFilter 对企业账号不加条件,
企业账号可以查询并操作任意卡或设备(资产详情、订单、套餐、停复机、停用、改套餐有效期与已用量、开关轮询、改实名状态)。

- Resolve 对企业账号校验卡或设备当前授权给本企业,未授权与不存在同样返回未找到
- 改套餐有效期、改已用量、停用、开关轮询、改实名状态对企业账号返回无权限;停复机按授权范围放行

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 15:05:05 +09:00

43 lines
1.5 KiB
Go

package asset
import (
"context"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/errors"
"github.com/break/junhong_cmp_fiber/pkg/middleware"
)
// ensureEnterpriseAssetVisible 校验企业账号只能访问当前授权给本企业的卡或设备。
// 非企业账号直接放行(由原有店铺数据范围约束)。未授权与不存在返回同一错误,不暴露资产是否存在。
// 设备授权时会同步为设备内的卡写入卡授权记录,因此卡只看卡授权表。
func (s *Service) ensureEnterpriseAssetVisible(ctx context.Context, assetType string, assetID uint) error {
if middleware.GetUserTypeFromContext(ctx) != constants.UserTypeEnterprise {
return nil
}
notFound := errors.New(errors.CodeNotFound, "未找到匹配的资产")
enterpriseID := middleware.GetEnterpriseIDFromContext(ctx)
if enterpriseID == 0 || assetID == 0 {
return notFound
}
table, column := "", ""
switch assetType {
case "card", constants.AssetTypeIotCard:
table, column = "tb_enterprise_card_authorization", "card_id"
case constants.AssetTypeDevice:
table, column = "tb_enterprise_device_authorization", "device_id"
default:
return notFound
}
var count int64
if err := s.db.WithContext(ctx).Table(table).
Where(column+" = ? AND enterprise_id = ? AND revoked_at IS NULL AND deleted_at IS NULL", assetID, enterpriseID).
Count(&count).Error; err != nil {
return errors.Wrap(errors.CodeDatabaseError, err, "校验企业资产授权失败")
}
if count == 0 {
return notFound
}
return nil
}