test(backend): 授权系统端到端验证测试 (21H)
util/license_key_test.go: - TestLicenseKeyRoundTrip: 签发→验签完整流程 - TestVerifyLicenseToken_TamperedPayload: 签名被篡改后被拒绝 - TestVerifyLicenseToken_WrongKey: 用错误公钥验签失败 - TestVerifyLicenseToken_InvalidFormat: 格式非法被拒绝 middleware/license_guard_test.go: - TestCalcLicensePhase: 覆盖全部 phase 边界 (perpetual→normal / future→normal / <7d→grace / 7-15d→readonly / >15d→locked) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCalcLicensePhase(t *testing.T) {
|
||||
now := time.Now()
|
||||
|
||||
// nil = perpetual → normal
|
||||
assert.Equal(t, PhaseNormal, CalcLicensePhase(nil))
|
||||
|
||||
// future expiry → normal
|
||||
future := now.Add(10 * 24 * time.Hour)
|
||||
assert.Equal(t, PhaseNormal, CalcLicensePhase(&future))
|
||||
|
||||
// just expired (1h ago) → grace
|
||||
grace := now.Add(-1 * time.Hour)
|
||||
assert.Equal(t, PhaseGrace, CalcLicensePhase(&grace))
|
||||
|
||||
// expired 6 days ago → grace (boundary)
|
||||
grace6d := now.Add(-6 * 24 * time.Hour)
|
||||
assert.Equal(t, PhaseGrace, CalcLicensePhase(&grace6d))
|
||||
|
||||
// expired 8 days ago → readonly
|
||||
readonly := now.Add(-8 * 24 * time.Hour)
|
||||
assert.Equal(t, PhaseReadOnly, CalcLicensePhase(&readonly))
|
||||
|
||||
// expired 14 days ago → readonly (boundary)
|
||||
readonly14d := now.Add(-14 * 24 * time.Hour)
|
||||
assert.Equal(t, PhaseReadOnly, CalcLicensePhase(&readonly14d))
|
||||
|
||||
// expired 16 days ago → locked
|
||||
locked := now.Add(-16 * 24 * time.Hour)
|
||||
assert.Equal(t, PhaseLocked, CalcLicensePhase(&locked))
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestLicenseKeyRoundTrip(t *testing.T) {
|
||||
priv, pub, err := GenerateEd25519KeyPair()
|
||||
require.NoError(t, err)
|
||||
|
||||
exp := time.Now().Add(30 * 24 * time.Hour).Unix()
|
||||
payload := LicensePayload{
|
||||
ShopID: 42,
|
||||
LicenseID: 7,
|
||||
Type: "annual",
|
||||
IssuedAt: time.Now().Unix(),
|
||||
ExpiresAt: &exp,
|
||||
MaxDevices: 3,
|
||||
}
|
||||
|
||||
token, err := IssueLicenseToken(payload, priv)
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, token)
|
||||
|
||||
got, err := VerifyLicenseToken(token, pub)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, payload.ShopID, got.ShopID)
|
||||
assert.Equal(t, payload.Type, got.Type)
|
||||
assert.Equal(t, payload.MaxDevices, got.MaxDevices)
|
||||
assert.Equal(t, *payload.ExpiresAt, *got.ExpiresAt)
|
||||
}
|
||||
|
||||
func TestVerifyLicenseToken_TamperedPayload(t *testing.T) {
|
||||
priv, pub, err := GenerateEd25519KeyPair()
|
||||
require.NoError(t, err)
|
||||
|
||||
exp := time.Now().Add(30 * 24 * time.Hour).Unix()
|
||||
token, err := IssueLicenseToken(LicensePayload{
|
||||
ShopID: 1, Type: "trial", IssuedAt: time.Now().Unix(), ExpiresAt: &exp, MaxDevices: 1,
|
||||
}, priv)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Flip the last byte of the signature to simulate tampering
|
||||
tampered := token[:len(token)-2] + "XX"
|
||||
_, err = VerifyLicenseToken(tampered, pub)
|
||||
assert.Error(t, err, "tampered token must be rejected")
|
||||
}
|
||||
|
||||
func TestVerifyLicenseToken_WrongKey(t *testing.T) {
|
||||
priv, _, err := GenerateEd25519KeyPair()
|
||||
require.NoError(t, err)
|
||||
_, otherPub, err := GenerateEd25519KeyPair()
|
||||
require.NoError(t, err)
|
||||
|
||||
exp := time.Now().Add(30 * 24 * time.Hour).Unix()
|
||||
token, err := IssueLicenseToken(LicensePayload{
|
||||
ShopID: 1, Type: "trial", IssuedAt: time.Now().Unix(), ExpiresAt: &exp, MaxDevices: 1,
|
||||
}, priv)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = VerifyLicenseToken(token, otherPub)
|
||||
assert.ErrorIs(t, err, ErrInvalidLicenseSignature)
|
||||
}
|
||||
|
||||
func TestVerifyLicenseToken_InvalidFormat(t *testing.T) {
|
||||
_, pub, err := GenerateEd25519KeyPair()
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = VerifyLicenseToken("not-a-valid-token", pub)
|
||||
assert.ErrorIs(t, err, ErrInvalidLicenseToken)
|
||||
}
|
||||
Reference in New Issue
Block a user