主要更新: 1. 数据库持久化功能 - 支持三种策略:仅落库、既落库又存证、仅存证 - 实现 Cursor Worker 异步扫描和存证机制 - 实现 Retry Worker 失败重试机制 - 支持 PostgreSQL、MySQL、SQLite 等多种数据库 - 添加 ClientIP 和 ServerIP 字段(可空,仅落库) 2. 集群并发安全 - 使用 SELECT FOR UPDATE SKIP LOCKED 防止重复处理 - 实现 CAS (Compare-And-Set) 原子状态更新 - 添加 updated_at 字段支持并发控制 3. Cursor 初始化优化 - 自动基于历史数据初始化 cursor - 确保不遗漏任何历史记录 - 修复 UPSERT 逻辑 4. 测试完善 - 添加 E2E 集成测试(含 Pulsar 消费者验证) - 添加 PostgreSQL 集成测试 - 添加 Pulsar 集成测试 - 添加集群并发安全测试 - 添加 Cursor 初始化验证测试 - 补充大量单元测试,提升覆盖率 5. 工具脚本 - 添加数据库迁移脚本 - 添加 Cursor 状态检查工具 - 添加 Cursor 初始化工具 - 添加 Pulsar 消息验证工具 6. 文档清理 - 删除冗余文档,只保留根目录 README 测试结果: - 所有 E2E 测试通过(100%) - 数据库持久化与异步存证流程验证通过 - 集群环境下的并发安全性验证通过 - Cursor 自动初始化和历史数据处理验证通过
216 lines
6.7 KiB
Go
216 lines
6.7 KiB
Go
package model_test
|
||
|
||
import (
|
||
"testing"
|
||
"time"
|
||
|
||
"github.com/stretchr/testify/assert"
|
||
"github.com/stretchr/testify/require"
|
||
|
||
"go.yandata.net/iod/iod/go-trustlog/api/model"
|
||
)
|
||
|
||
// TestSignVerifyDataConsistency 详细测试加签和验签的数据一致性.
|
||
func TestSignVerifyDataConsistency(t *testing.T) {
|
||
t.Parallel()
|
||
|
||
// 生成SM2密钥对
|
||
keyPair, err := model.GenerateSM2KeyPair()
|
||
require.NoError(t, err)
|
||
|
||
// 序列化为DER格式
|
||
privateKeyDER, err := model.MarshalSM2PrivateDER(keyPair.Private)
|
||
require.NoError(t, err)
|
||
|
||
publicKeyDER, err := model.MarshalSM2PublicDER(keyPair.Public)
|
||
require.NoError(t, err)
|
||
|
||
// 创建签名器
|
||
signer := model.NewSM2Signer(privateKeyDER, publicKeyDER)
|
||
|
||
// 测试数据1
|
||
testData1 := []byte("test data for signing")
|
||
|
||
// 测试数据2(不同数据)
|
||
testData2 := []byte("different test data")
|
||
|
||
// 1. 对testData1签名
|
||
signature1, err := signer.Sign(testData1)
|
||
require.NoError(t, err)
|
||
require.NotNil(t, signature1)
|
||
|
||
// 2. 用testData1验证signature1 - 应该成功
|
||
valid, err := signer.Verify(testData1, signature1)
|
||
require.NoError(t, err)
|
||
assert.True(t, valid, "使用相同数据验证应该成功")
|
||
|
||
// 3. 用testData2验证signature1 - 应该失败
|
||
valid, err = signer.Verify(testData2, signature1)
|
||
require.Error(t, err, "使用不同数据验证应该失败")
|
||
assert.Contains(t, err.Error(), "signature verification failed")
|
||
assert.False(t, valid)
|
||
|
||
// 4. 对testData2签名
|
||
signature2, err := signer.Sign(testData2)
|
||
require.NoError(t, err)
|
||
require.NotNil(t, signature2)
|
||
|
||
// 5. 用testData2验证signature2 - 应该成功
|
||
valid, err = signer.Verify(testData2, signature2)
|
||
require.NoError(t, err)
|
||
assert.True(t, valid, "使用相同数据验证应该成功")
|
||
|
||
// 6. 用testData1验证signature2 - 应该失败
|
||
valid, err = signer.Verify(testData1, signature2)
|
||
require.Error(t, err, "使用不同数据验证应该失败")
|
||
assert.Contains(t, err.Error(), "signature verification failed")
|
||
assert.False(t, valid)
|
||
|
||
t.Logf("测试完成:签名和验证逻辑正常")
|
||
}
|
||
|
||
// TestEnvelopeBodyTampering 测试修改envelope body后验签应该失败.
|
||
func TestEnvelopeBodyTampering(t *testing.T) {
|
||
t.Parallel()
|
||
|
||
// 生成SM2密钥对
|
||
keyPair, err := model.GenerateSM2KeyPair()
|
||
require.NoError(t, err)
|
||
|
||
// 序列化为DER格式
|
||
privateKeyDER, err := model.MarshalSM2PrivateDER(keyPair.Private)
|
||
require.NoError(t, err)
|
||
|
||
publicKeyDER, err := model.MarshalSM2PublicDER(keyPair.Public)
|
||
require.NoError(t, err)
|
||
|
||
// 创建签名配置
|
||
signConfig := model.NewSM2EnvelopeConfig(privateKeyDER, publicKeyDER)
|
||
verifyConfig := model.NewSM2VerifyConfig(publicKeyDER)
|
||
|
||
// 创建测试Operation
|
||
op := &model.Operation{
|
||
OpID: "op-test-002",
|
||
Timestamp: time.Now(),
|
||
OpSource: model.OpSourceIRP,
|
||
OpType: model.OpTypeOCCreateHandle,
|
||
DoPrefix: "test",
|
||
DoRepository: "repo",
|
||
Doid: "test/repo/456",
|
||
ProducerID: "producer-2",
|
||
OpActor: "actor-2",
|
||
}
|
||
|
||
err = op.CheckAndInit()
|
||
require.NoError(t, err)
|
||
|
||
// 1. 加签:序列化为Envelope
|
||
envelopeData, err := model.MarshalOperation(op, signConfig)
|
||
require.NoError(t, err)
|
||
require.NotNil(t, envelopeData)
|
||
|
||
// 2. 验签:验证原始Envelope - 应该成功
|
||
verifiedEnv, err := model.VerifyEnvelopeWithConfig(envelopeData, verifyConfig)
|
||
require.NoError(t, err)
|
||
require.NotNil(t, verifiedEnv)
|
||
|
||
// 3. 反序列化获取原始body
|
||
originalEnv, err := model.UnmarshalEnvelope(envelopeData)
|
||
require.NoError(t, err)
|
||
originalBody := originalEnv.Body
|
||
originalSignature := originalEnv.Signature
|
||
|
||
t.Logf("原始body长度: %d", len(originalBody))
|
||
t.Logf("原始签名长度: %d", len(originalSignature))
|
||
|
||
// 4. 创建修改后的body(完全不同的数据)
|
||
modifiedBody := []byte("completely different body content")
|
||
require.NotEqual(t, originalBody, modifiedBody, "修改后的body应该不同")
|
||
|
||
// 5. 创建修改后的envelope(使用原始签名但修改body)
|
||
modifiedEnv := &model.Envelope{
|
||
ProducerID: originalEnv.ProducerID,
|
||
Signature: originalSignature, // 使用原始签名
|
||
Body: modifiedBody, // 使用修改后的body
|
||
}
|
||
modifiedData, err := model.MarshalEnvelope(modifiedEnv)
|
||
require.NoError(t, err)
|
||
|
||
// 6. 验签修改后的envelope - 应该失败
|
||
_, err = model.VerifyEnvelopeWithConfig(modifiedData, verifyConfig)
|
||
require.Error(t, err, "修改body后验签应该失败")
|
||
assert.Contains(t, err.Error(), "signature verification failed")
|
||
|
||
t.Logf("测试完成:修改body后验签正确失败")
|
||
}
|
||
|
||
// TestEnvelopeSignatureTampering 测试修改envelope signature后验签应该失败.
|
||
func TestEnvelopeSignatureTampering(t *testing.T) {
|
||
t.Parallel()
|
||
|
||
// 生成SM2密钥对
|
||
keyPair, err := model.GenerateSM2KeyPair()
|
||
require.NoError(t, err)
|
||
|
||
// 序列化为DER格式
|
||
privateKeyDER, err := model.MarshalSM2PrivateDER(keyPair.Private)
|
||
require.NoError(t, err)
|
||
|
||
publicKeyDER, err := model.MarshalSM2PublicDER(keyPair.Public)
|
||
require.NoError(t, err)
|
||
|
||
// 创建签名配置
|
||
signConfig := model.NewSM2EnvelopeConfig(privateKeyDER, publicKeyDER)
|
||
verifyConfig := model.NewSM2VerifyConfig(publicKeyDER)
|
||
|
||
// 创建测试Operation
|
||
op := &model.Operation{
|
||
OpID: "op-test-003",
|
||
Timestamp: time.Now(),
|
||
OpSource: model.OpSourceIRP,
|
||
OpType: model.OpTypeOCCreateHandle,
|
||
DoPrefix: "test",
|
||
DoRepository: "repo",
|
||
Doid: "test/repo/789",
|
||
ProducerID: "producer-3",
|
||
OpActor: "actor-3",
|
||
}
|
||
|
||
err = op.CheckAndInit()
|
||
require.NoError(t, err)
|
||
|
||
// 1. 加签:序列化为Envelope
|
||
envelopeData, err := model.MarshalOperation(op, signConfig)
|
||
require.NoError(t, err)
|
||
|
||
// 2. 反序列化获取原始signature
|
||
originalEnv, err := model.UnmarshalEnvelope(envelopeData)
|
||
require.NoError(t, err)
|
||
originalSignature := originalEnv.Signature
|
||
|
||
// 3. 创建修改后的signature(完全不同的数据)
|
||
modifiedSignature := make([]byte, len(originalSignature))
|
||
copy(modifiedSignature, originalSignature)
|
||
// 修改最后一个字节
|
||
if len(modifiedSignature) > 0 {
|
||
modifiedSignature[len(modifiedSignature)-1] ^= 0xFF
|
||
}
|
||
require.NotEqual(t, originalSignature, modifiedSignature, "修改后的signature应该不同")
|
||
|
||
// 4. 创建修改后的envelope(使用原始body但修改signature)
|
||
modifiedEnv := &model.Envelope{
|
||
ProducerID: originalEnv.ProducerID,
|
||
Signature: modifiedSignature, // 使用修改后的signature
|
||
Body: originalEnv.Body, // 使用原始body
|
||
}
|
||
modifiedData, err := model.MarshalEnvelope(modifiedEnv)
|
||
require.NoError(t, err)
|
||
|
||
// 5. 验签修改后的envelope - 应该失败
|
||
_, err = model.VerifyEnvelopeWithConfig(modifiedData, verifyConfig)
|
||
require.Error(t, err, "修改signature后验签应该失败")
|
||
assert.Contains(t, err.Error(), "signature verification failed")
|
||
|
||
t.Logf("测试完成:修改signature后验签正确失败")
|
||
}
|