feat: v2.0.0 完整代码优化升级
🔴 高优先级 (6项全部完成): - 数据库事务支持 (InsertMessageWithLog) - SQL注入修复 (参数化查询) - 配置验证 (Validate方法) - 会话密钥强化 (长度验证) - 签名验证增强 (SignVerificationResult) - 密码哈希支持 (bcrypt) 🟡 中优先级 (15项全部完成): - 连接池配置 (MaxOpenConns, MaxIdleConns) - 查询优化 (范围查询, 索引) - 健康检查增强 (/health 端点) - API版本控制 (/api/v1/*) - 认证中间件 (RequireAuth, RequireAPIAuth) - 定时任务优化 (robfig/cron) - 配置文件示例 (config.example.yaml) - 常量定义 (config/constants.go) - 开发文档 (DEVELOPMENT.md) 🟢 低优先级 (9项全部完成): - Docker支持 (Dockerfile, docker-compose.yml) - Makefile构建脚本 - 优化报告 (OPTIMIZATION_REPORT.md) - 密码哈希工具 (tools/password_hash.go) - 14个新文件 - 30项优化100%完成 版本: v2.0.0
This commit is contained in:
@@ -2,6 +2,7 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
@@ -33,12 +34,77 @@ type SecurityConfig struct {
|
||||
Enabled bool `mapstructure:"enabled"`
|
||||
Username string `mapstructure:"username"`
|
||||
Password string `mapstructure:"password"`
|
||||
PasswordHash string `mapstructure:"password_hash"` // bcrypt 哈希值(推荐使用)
|
||||
SessionLifetime int `mapstructure:"session_lifetime"`
|
||||
SecretKey string `mapstructure:"secret_key"`
|
||||
SignVerify bool `mapstructure:"sign_verify"`
|
||||
SignMaxAge int64 `mapstructure:"sign_max_age"`
|
||||
}
|
||||
|
||||
// Validate 验证配置的有效性
|
||||
func (c *Config) Validate() error {
|
||||
// 验证数据库路径
|
||||
if c.Database.Path == "" {
|
||||
return fmt.Errorf("数据库路径不能为空")
|
||||
}
|
||||
|
||||
// 验证安全密钥
|
||||
if c.Security.SecretKey == "" {
|
||||
return fmt.Errorf("安全密钥不能为空,请在配置文件中设置 secret_key")
|
||||
}
|
||||
|
||||
// 验证密钥长度(至少16字节)
|
||||
key := []byte(c.Security.SecretKey)
|
||||
if len(key) < 16 {
|
||||
return fmt.Errorf("安全密钥长度不足,建议至少16字节(当前: %d 字节)", len(key))
|
||||
}
|
||||
|
||||
// 设置默认值
|
||||
if c.Security.SessionLifetime == 0 {
|
||||
c.Security.SessionLifetime = DefaultSessionLifetime
|
||||
log.Printf("使用默认会话有效期: %d 秒", DefaultSessionLifetime)
|
||||
}
|
||||
if c.Security.SignMaxAge == 0 {
|
||||
c.Security.SignMaxAge = DefaultSignMaxAge
|
||||
log.Printf("使用默认签名有效期: %d 毫秒", DefaultSignMaxAge)
|
||||
}
|
||||
|
||||
// 如果启用了登录验证,验证用户名和密码
|
||||
if c.Security.Enabled {
|
||||
if c.Security.Username == "" {
|
||||
return fmt.Errorf("启用登录验证时,用户名不能为空")
|
||||
}
|
||||
if c.Security.Password == "" && c.Security.PasswordHash == "" {
|
||||
return fmt.Errorf("启用登录验证时,必须设置 password 或 password_hash")
|
||||
}
|
||||
}
|
||||
|
||||
// 验证服务器端口
|
||||
if c.Server.Port < 1 || c.Server.Port > 65535 {
|
||||
return fmt.Errorf("服务器端口无效: %d", c.Server.Port)
|
||||
}
|
||||
|
||||
// 验证时区
|
||||
if c.Timezone == "" {
|
||||
c.Timezone = "Asia/Shanghai"
|
||||
log.Printf("使用默认时区: %s", c.Timezone)
|
||||
}
|
||||
// 检查时区是否有效
|
||||
if _, err := time.LoadLocation(c.Timezone); err != nil {
|
||||
return fmt.Errorf("无效的时区配置: %s", c.Timezone)
|
||||
}
|
||||
|
||||
// 日志提示
|
||||
if c.Security.Password != "" && c.Security.PasswordHash != "" {
|
||||
log.Printf("警告: 同时设置了 password 和 password_hash,将优先使用 password_hash")
|
||||
}
|
||||
if c.Security.Password != "" {
|
||||
log.Printf("警告: 使用明文密码不安全,建议使用 password_hash")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type SMSConfig struct {
|
||||
MaxMessages int `mapstructure:"max_messages"`
|
||||
AutoCleanup bool `mapstructure:"auto_cleanup"`
|
||||
@@ -74,6 +140,11 @@ func Load(configPath string) (*Config, error) {
|
||||
return nil, fmt.Errorf("解析配置文件失败: %w", err)
|
||||
}
|
||||
|
||||
// 验证配置
|
||||
if err := cfg.Validate(); err != nil {
|
||||
return nil, fmt.Errorf("配置验证失败: %w", err)
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
|
||||
21
config/constants.go
Normal file
21
config/constants.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package config
|
||||
|
||||
// 分页默认值
|
||||
const (
|
||||
DefaultPageSize = 20
|
||||
DefaultLogsPerPage = 50
|
||||
MaxPageSize = 100
|
||||
)
|
||||
|
||||
// 默认配置值
|
||||
const (
|
||||
DefaultSessionLifetime = 3600 // 1小时(秒)
|
||||
DefaultSignMaxAge = 300000 // 5分钟(毫秒)
|
||||
DefaultCleanupDays = 90 // 默认保留90天的消息
|
||||
)
|
||||
|
||||
// 时间戳精度说明
|
||||
const (
|
||||
TimestampPrecision = "毫秒级" // timestamp 字段存储毫秒级时间戳
|
||||
CreatedAtPrecision = "秒级" // created_at 字段存储 SQLite TIMESTAMP(秒级精度)
|
||||
)
|
||||
Reference in New Issue
Block a user