|
@@ -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
|