Browse Source

feat(config): 为 Casbin Enforcer 指定专用数据库配置

- 在 local.yml 和 prod.yml 中添加了 admin 数据库配置,并设置了 casbin: true 标志
- 修改了 NewCasbinEnforcer 函数,以支持使用专用数据库连接
- 优化了日志记录,增加了对 Casbin专用数据库配置的检测和警告日志
fusu 1 month ago
parent
commit
cd5a93f451
3 changed files with 59 additions and 16 deletions
  1. 5 3
      config/local.yml
  2. 8 0
      config/prod.yml
  3. 46 13
      internal/repository/repository.go

+ 5 - 3
config/local.yml

@@ -19,9 +19,11 @@ data:
       driver: mysql
       dsn: root:Mgrj9hMF3QQ3atX5hFIo@tcp(115.238.186.121:3306)/0panel?charset=utf8mb4&parseTime=True&loc=Local
       logLevel: "info"
-  #    user:
-  #      driver: sqlite
-  #      dsn: storage/nunu-test.db?_busy_timeout=5000
+    admin:
+      driver: mysql
+      dsn: admin:GhCbHDRDnMbAkZHw@tcp(110.42.96.15:3306)/admin?charset=utf8mb4&parseTime=True&loc=Local
+      logLevel: "info"
+      casbin: true
   #    user:
   #      driver: postgres
   #      dsn: host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai

+ 8 - 0
config/prod.yml

@@ -15,6 +15,14 @@ data:
       driver: mysql
       dsn: 183_136_132_25:xGrNJphcmGcXiajE@tcp(183.136.132.25:3306)/183_136_132_25?charset=utf8mb4&parseTime=True&loc=Local
       logLevel: "warn"
+      casbin:
+        driver: sqlite
+        dsn: storage/nunu-test.db?_busy_timeout=5000
+      admin:
+        driver: mysql
+        dsn: admin:GhCbHDRDnMbAkZHw@tcp(110.42.96.15:3306)/admin?charset=utf8mb4&parseTime=True&loc=Local
+        logLevel: "info"
+        casbin: true
 #    second:
 #      driver: mysql
 #      dsn: root:Mgrj9hMF3QQ3atX5hFIo@tcp(115.238.186.121:3306)/0panel?charset=utf8mb4&parseTime=True&loc=Local

+ 46 - 13
internal/repository/repository.go

@@ -309,8 +309,6 @@ func NewMongoDB(client *qmgo.Client, conf *viper.Viper) *qmgo.Database {
 }
 
 func NewRabbitMQ(conf *viper.Viper, logger *log.Logger) (*rabbitmq.RabbitMQ, func()) {
-
-
 	var cfg rabbitmq.Config
 	if err := conf.UnmarshalKey("rabbitmq", &cfg); err != nil {
 		panic(fmt.Sprintf("unmarshal rabbitmq config error: %s", err.Error()))
@@ -334,9 +332,46 @@ func NewRabbitMQ(conf *viper.Viper, logger *log.Logger) (*rabbitmq.RabbitMQ, fun
 	return mq, cleanup
 }
 
-
 func NewCasbinEnforcer(conf *viper.Viper, l *log.Logger, db *gorm.DB) *casbin.SyncedEnforcer {
-	a, _ := gormadapter.NewAdapterByDB(db)
+	var (
+		adapter  *gormadapter.Adapter
+		err      error
+		casbinDb *gorm.DB = db // 默认使用主数据库连接
+	)
+
+	// 创建一个专门给Enforcer使用的、日志级别为Warn的日志记录器,以屏蔽轮询日志。
+	// 这不会影响数据库连接的全局日志配置。
+	enforcerLogger := zapgorm2.New(l.Logger).LogMode(gormlogger.Warn)
+
+	// 扫描配置,查找为Casbin指定的数据库
+	dbSettings := conf.GetStringMap("data.db")
+	foundSpecialDb := false
+	for dbKey := range dbSettings {
+		casbinFlagPath := fmt.Sprintf("data.db.%s.casbin", dbKey)
+		if conf.GetBool(casbinFlagPath) {
+			l.Info(fmt.Sprintf("检测到Casbin专用数据库配置: '%s'。Enforcer将使用此数据库连接。", dbKey))
+			// 从全局连接池中获取指定的数据库连接
+			casbinDb = db.Clauses(dbresolver.Use(dbKey))
+			foundSpecialDb = true
+			break
+		}
+	}
+
+	if !foundSpecialDb {
+		l.Warn("未找到Casbin的专用数据库配置 (缺少 'casbin: true' 标志),Enforcer将回退使用主数据库连接。")
+	}
+
+	// 为Enforcer创建一个带有“安静”日志记录器的GORM会话。
+	// 这样可以确保只有Enforcer自身的操作是安静的,
+	// 而通过DBWithName()进行的直接数据库操作仍将使用原始的、更详细的日志记录器。
+	dbForEnforcer := casbinDb.Session(&gorm.Session{Logger: enforcerLogger})
+
+	// 使用带有“安静”日志记录器的会话来创建适配器
+	adapter, err = gormadapter.NewAdapterByDB(dbForEnforcer)
+	if err != nil {
+		panic(fmt.Sprintf("创建Casbin gorm-adapter失败: %s", err))
+	}
+
 	m, err := model.NewModelFromString(`
 [request_definition]
 r = sub, obj, act
@@ -353,21 +388,19 @@ e = some(where (p.eft == allow))
 [matchers]
 m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
 `)
+	if err != nil {
+		panic(fmt.Sprintf("创建Casbin模型失败: %s", err))
+	}
 
+	e, err := casbin.NewSyncedEnforcer(m, adapter)
 	if err != nil {
-		panic(err)
+		panic(fmt.Sprintf("创建Casbin Enforcer失败: %s", err))
 	}
-	e, _ := casbin.NewSyncedEnforcer(m, a)
 
-	// 每10秒自动加载策略,防止启动多服务进程策略不一致
-	// 如果不想用轮询DB的方式,你也可以使用Casbin Watchers来同步策略,该方式需要基于Redis、Etcd等存储中间件
-	// Watchers相关文档:https://casbin.org/zh/docs/watchers
+	// 每10秒自动加载策略
 	e.StartAutoLoadPolicy(10 * time.Second)
 
-	// Enable Logger, decide whether to show it in terminal
-	//e.EnableLog(true)
-
-	// Save the policy back to DB.
+	// 自动保存策略
 	e.EnableAutoSave(true)
 
 	return e