feat: 客户端授权防护——响应签名/激活令牌/宽限期/换座限制/在线清扫/疑似共享标记
This commit is contained in:
1 parent
37d9e8ca56
commit
b76111dfc3
11 files changed
+437
-54
No files matched your search
@@ -1,12 +1,14 @@
|
||||
package license
|
||||
|
||||
import (
|
||||
"backend/config"
|
||||
"backend/internal/dto"
|
||||
"backend/internal/model"
|
||||
customersvc "backend/internal/service/customer"
|
||||
"backend/utils"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -16,12 +18,32 @@ import (
|
||||
|
||||
// LicenseService License 业务逻辑层 // Logan.Li
|
||||
type LicenseService struct {
|
||||
db *gorm.DB
|
||||
db *gorm.DB
|
||||
cfg *config.Config
|
||||
guard *clientGuard
|
||||
}
|
||||
|
||||
// NewLicenseService 创建 service 实例 // Logan.Li
|
||||
func NewLicenseService(db *gorm.DB) *LicenseService {
|
||||
return &LicenseService{db: db}
|
||||
// NewLicenseService 创建 service 实例(cfg 提供防护配置与响应签名密钥) // Logan.Li
|
||||
func NewLicenseService(db *gorm.DB, cfg *config.Config) *LicenseService {
|
||||
svc := &LicenseService{db: db, cfg: cfg}
|
||||
if cfg != nil {
|
||||
g := &clientGuard{
|
||||
gracePeriodDays: cfg.GracePeriodDays,
|
||||
activateDailyLimit: cfg.ActivateDailyLimit,
|
||||
onlineTTLMinutes: cfg.OnlineTTLMinutes,
|
||||
deactivateRequireToken: cfg.DeactivateRequireToken,
|
||||
}
|
||||
if seed := strings.TrimSpace(cfg.OfflineLicenseSeed); seed != "" {
|
||||
if kp, err := utils.DeriveOfflineKeyPair(seed); err == nil {
|
||||
g.kp = kp
|
||||
} else {
|
||||
// seed 非法只降级签名能力,不阻断启动(离线签发侧会再次报错) // Logan.Li
|
||||
log.Printf("[安全] 离线 seed 派生失败,响应签名将不可用: %v", err)
|
||||
}
|
||||
}
|
||||
svc.guard = g
|
||||
}
|
||||
return svc
|
||||
}
|
||||
|
||||
// ListQuery 列表查询参数 // Logan.Li
|
||||
@@ -67,7 +89,9 @@ func (s *LicenseService) List(page, pageSize int, q ListQuery) ([]dto.LicenseRes
|
||||
|
||||
results := make([]dto.LicenseResponse, 0, len(licenses))
|
||||
for _, l := range licenses {
|
||||
results = append(results, toLicenseResponse(l))
|
||||
resp := toLicenseResponse(l)
|
||||
attachAbuseStats(&resp, l)
|
||||
results = append(results, resp)
|
||||
}
|
||||
return results, total, nil
|
||||
}
|
||||
@@ -81,6 +105,7 @@ func (s *LicenseService) GetByID(id uint) (*dto.LicenseResponse, []dto.Activatio
|
||||
}
|
||||
|
||||
resp := toLicenseResponse(lic)
|
||||
attachAbuseStats(&resp, lic)
|
||||
activations := make([]dto.ActivationResponse, 0, len(lic.Activations))
|
||||
for _, a := range lic.Activations {
|
||||
activations = append(activations, toActivationResponse(a))
|
||||
@@ -180,9 +205,9 @@ func (s *LicenseService) Delete(id uint) (*model.License, error) {
|
||||
|
||||
// BatchDeleteResult 批量删除结果 // Logan.Li
|
||||
type BatchDeleteResult struct {
|
||||
Deleted int `json:"deleted"`
|
||||
Skipped int `json:"skipped"`
|
||||
Failed int `json:"failed"`
|
||||
Deleted int `json:"deleted"`
|
||||
Skipped int `json:"skipped"`
|
||||
Failed int `json:"failed"`
|
||||
SkippedIDs []uint `json:"skipped_ids,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user