Skip to content

Commit 8a126d7

Browse files
committed
Refactor(auth): Refactor system configuration cache to avoid cross-database connection leaks
- Move the global configCache variable to the Service struct internally - Modify the GetSystemConfig, UpdateSystemConfig, and DeleteSystemConfig methods to use instance-level caching - Add test cases to verify the isolation of configuration cache between different database connections
1 parent fbd1903 commit 8a126d7

2 files changed

Lines changed: 50 additions & 13 deletions

File tree

‎internal/auth/service.go‎

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,17 @@ import (
1919
var (
2020
// 内存中的会话存储
2121
sessionCache = sync.Map{}
22-
// 内存中的系统配置存储
23-
configCache = sync.Map{}
2422
// OAuth2 state 缓存,防止 CSRF
2523
oauthStateCache = sync.Map{} // key:string state, value:int64 timestamp
2624
)
2725

2826
// Service 认证服务
2927
type Service struct {
30-
db *gorm.DB
31-
currentJTI string // 当前有效的 JWT ID(内存存储,避免启动时SQLite锁)
32-
jtiMutex sync.RWMutex // JTI 读写锁
33-
demoMode bool // Demo 模式开关
28+
db *gorm.DB
29+
configCache sync.Map // 系统配置缓存,跟随当前 DB 连接,避免 setup 切库时串库
30+
currentJTI string // 当前有效的 JWT ID(内存存储,避免启动时SQLite锁)
31+
jtiMutex sync.RWMutex // JTI 读写锁
32+
demoMode bool // Demo 模式开关
3433
}
3534

3635
// NewService 创建认证服务实例,需要传入GORM数据库连接
@@ -64,7 +63,7 @@ func (s *Service) VerifyPassword(password, hash string) bool {
6463
// GetSystemConfig 获取系统配置(优先缓存)
6564
func (s *Service) GetSystemConfig(key string) (string, error) {
6665
// 先检查缓存
67-
if value, ok := configCache.Load(key); ok {
66+
if value, ok := s.configCache.Load(key); ok {
6867
return value.(string), nil
6968
}
7069

@@ -79,7 +78,7 @@ func (s *Service) GetSystemConfig(key string) (string, error) {
7978
config := configs[0]
8079

8180
// 写入缓存
82-
configCache.Store(key, config.Value)
81+
s.configCache.Store(key, config.Value)
8382
return config.Value, nil
8483
}
8584

@@ -106,7 +105,7 @@ func (s *Service) SetSystemConfig(key, value string) error {
106105
}
107106

108107
// 更新缓存
109-
configCache.Store(key, value)
108+
s.configCache.Store(key, value)
110109
return nil
111110
}
112111

@@ -128,7 +127,7 @@ func (s *Service) DeleteSystemConfig(key string) error {
128127
}
129128

130129
// 删除缓存
131-
configCache.Delete(key)
130+
s.configCache.Delete(key)
132131
return nil
133132
}
134133

@@ -454,7 +453,7 @@ func (s *Service) ChangePassword(username, currentPassword, newPassword string)
454453

455454
// 验证新密码不能与默认密码相同
456455
if newPassword == DefaultAdminPassword {
457-
return false, "new password cannot be the same as default password, please set a secure password"
456+
return false, "new password cannot be the same as default password, please set a secure password"
458457
}
459458

460459
// 加密新密码
@@ -514,7 +513,7 @@ func (s *Service) UpdateSecurity(currentUsername, currentPassword, newUsername,
514513

515514
// 验证新密码不能与默认密码相同
516515
if newPassword == DefaultAdminPassword {
517-
return false, "new password cannot be the same as default password, please set a secure password"
516+
return false, "new password cannot be the same as default password, please set a secure password"
518517
}
519518

520519
// 允许设置任何用户名,包括默认用户名

‎internal/auth/service_test.go‎

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package auth
22

3-
import "testing"
3+
import (
4+
"NodePassDash/internal/models"
5+
"testing"
6+
7+
"gorm.io/driver/sqlite"
8+
"gorm.io/gorm"
9+
)
410

511
func TestValidateAdminCredentials(t *testing.T) {
612
cases := []struct {
@@ -30,3 +36,35 @@ func TestValidateAdminCredentials(t *testing.T) {
3036
})
3137
}
3238
}
39+
40+
func TestConfigCacheDoesNotLeakAcrossServiceDatabases(t *testing.T) {
41+
openDB := func(t *testing.T) *gorm.DB {
42+
t.Helper()
43+
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
44+
if err != nil {
45+
t.Fatalf("open sqlite: %v", err)
46+
}
47+
if err := db.AutoMigrate(&models.SystemConfig{}); err != nil {
48+
t.Fatalf("migrate system_configs: %v", err)
49+
}
50+
return db
51+
}
52+
53+
initializedDB := openDB(t)
54+
initializedService := NewService(initializedDB)
55+
if err := initializedService.SetSystemConfig(ConfigKeyIsInitialized, "true"); err != nil {
56+
t.Fatalf("seed initialized config: %v", err)
57+
}
58+
if !initializedService.IsSystemInitialized() {
59+
t.Fatalf("seeded service should be initialized")
60+
}
61+
62+
freshDB := openDB(t)
63+
freshService := NewService(freshDB)
64+
if freshService.IsSystemInitialized() {
65+
t.Fatalf("fresh service should not reuse initialized flag from another database")
66+
}
67+
if err := freshService.InitializeSystemWithCredentials("admin", "12345678"); err != nil {
68+
t.Fatalf("initialize fresh service: %v", err)
69+
}
70+
}

0 commit comments

Comments
 (0)