refactor: extract magic numbers to named constants for mnd lint compliance

This commit is contained in:
ryan
2026-06-09 13:44:29 +08:00
parent b05d26c9c6
commit e06f76436e
24 changed files with 650 additions and 440 deletions
+17 -8
View File
@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package cap 提供人机验证(CAPTCHA)功能
package cap
import (
@@ -29,7 +30,15 @@ import (
"time"
)
const jwtHeaderB64 = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
const (
jwtHeaderB64 = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
jwtPartsCount = 3 // JWT 三段结构
defaultChallengeCount = 50 // 默认 PoW 难题数
defaultChallengeSize = 32 // 默认盐值长度
defaultDifficulty = 4 // 默认难度
defaultNonceLength = 25 // 随机 Nonce 字节长度
defaultExpires = 10 * time.Minute // 默认过期时间
)
// ChallengeConfig holds parameters for the PoW challenge
type ChallengeConfig struct {
@@ -104,7 +113,7 @@ func jwtSign(payload []byte, secret []byte) string {
func jwtVerify(token string, secret []byte) ([]byte, error) {
parts := strings.Split(token, ".")
if len(parts) != 3 {
if len(parts) != jwtPartsCount {
return nil, errors.New(errInvalidTokenFormat)
}
if parts[0] != jwtHeaderB64 {
@@ -135,7 +144,7 @@ func jwtVerify(token string, secret []byte) ([]byte, error) {
func jwtSigHex(token string) string {
parts := strings.Split(token, ".")
if len(parts) != 3 {
if len(parts) != jwtPartsCount {
return ""
}
sigBytes, err := b64urlDecode(parts[2])
@@ -148,23 +157,23 @@ func jwtSigHex(token string) string {
// GenerateChallenge produces a new challenge and signed token
func GenerateChallenge(secret []byte, conf ChallengeConfig, scope string) (*ChallengeResponse, error) {
if conf.Count <= 0 {
conf.Count = 50
conf.Count = defaultChallengeCount
}
if conf.Size <= 0 {
conf.Size = 32
conf.Size = defaultChallengeSize
}
if conf.Difficulty <= 0 {
conf.Difficulty = 4
conf.Difficulty = defaultDifficulty
}
if conf.Expires <= 0 {
conf.Expires = 10 * time.Minute
conf.Expires = defaultExpires
}
now := time.Now().UnixNano() / int64(time.Millisecond)
expires := now + int64(conf.Expires/time.Millisecond)
payload := ChallengePayload{
Nonce: randomHex(25),
Nonce: randomHex(defaultNonceLength),
Count: conf.Count,
Size: conf.Size,
Difficulty: conf.Difficulty,
+26 -14
View File
@@ -30,6 +30,18 @@ import (
"github.com/Rain-kl/Wavelet/internal/model"
)
const (
managerDefaultChallengeCount = 1
managerDefaultChallengeSize = 32
defaultChallengeDifficulty = 4
defaultChallengeTTL = 10 * time.Minute
defaultTokenTTL = 20 * time.Minute
redeemTokenIDLength = 8 // 兑换 Token ID 字节长度
redeemVerTokenLength = 15 // 兑换验证 Token 字节长度
tokenPartsCount = 2 // 兑换 Token 由两部分组成
valuePartsCount = 2 // 存储值由 scope 和过期时间组成
)
// Config holds settings for the CAPTCHA manager
type Config struct {
Secret []byte // HMAC signing key
@@ -49,19 +61,19 @@ type Manager struct {
// NewManager creates a new CAPTCHA Manager
func NewManager(conf Config, store Store) *Manager {
if conf.ChallengeCount <= 0 {
conf.ChallengeCount = 1
conf.ChallengeCount = managerDefaultChallengeCount
}
if conf.ChallengeSize <= 0 {
conf.ChallengeSize = 32
conf.ChallengeSize = managerDefaultChallengeSize
}
if conf.ChallengeDifficulty <= 0 {
conf.ChallengeDifficulty = 4
conf.ChallengeDifficulty = defaultChallengeDifficulty
}
if conf.ChallengeTTL <= 0 {
conf.ChallengeTTL = 10 * time.Minute
conf.ChallengeTTL = defaultChallengeTTL
}
if conf.TokenTTL <= 0 {
conf.TokenTTL = 20 * time.Minute
conf.TokenTTL = defaultTokenTTL
}
return &Manager{
conf: conf,
@@ -116,8 +128,8 @@ func (m *Manager) Redeem(ctx context.Context, token string, solutions []int, sco
}
// Generate a redeem token formatted as "id:verToken"
id := randomHex(8)
verToken := randomHex(15)
id := randomHex(redeemTokenIDLength)
verToken := randomHex(redeemVerTokenLength)
verHashBytes := sha256.Sum256([]byte(verToken))
verHashHex := hex.EncodeToString(verHashBytes[:])
@@ -147,7 +159,7 @@ func (m *Manager) VerifyToken(ctx context.Context, token string, expectedScope s
return false, nil
}
parts := strings.Split(token, ":")
if len(parts) != 2 {
if len(parts) != tokenPartsCount {
return false, nil
}
id := parts[0]
@@ -169,7 +181,7 @@ func (m *Manager) VerifyToken(ctx context.Context, token string, expectedScope s
}
valParts := strings.Split(val, "|")
if len(valParts) != 2 {
if len(valParts) != valuePartsCount {
return false, nil
}
@@ -253,11 +265,11 @@ func GetDefaultManager() *Manager {
secret = []byte("default-captcha-secret-key-at-least-16-bytes")
}
challengeCount := 1
challengeSize := 32
challengeDifficulty := 4
challengeTTL := 10 * time.Minute
tokenTTL := 20 * time.Minute
challengeCount := managerDefaultChallengeCount
challengeSize := managerDefaultChallengeSize
challengeDifficulty := defaultChallengeDifficulty
challengeTTL := defaultChallengeTTL
tokenTTL := defaultTokenTTL
var store Store
if config.Config != nil && config.Config.Redis.Enabled && db.Redis != nil {