Files
compute-engine/service/authz/enforcer.go
T
Pine 28e53d90fc feat: 算力引擎 Go 后端核心(new-api)
- 统一 OpenAI 兼容 /v1 中继 + 渠道/额度/令牌/流水
- 各领域包:relay 模型网关、model 数据层、controller 管理 API
2026-08-23 22:38:46 +08:00

95 lines
2.0 KiB
Go

package authz
import (
"fmt"
"sync"
"time"
"github.com/QuantumNous/new-api/common"
"github.com/casbin/casbin/v2"
casbinmodel "github.com/casbin/casbin/v2/model"
"gorm.io/gorm"
)
var (
enforcerMu sync.RWMutex
enforcer *casbin.SyncedEnforcer
)
const modelText = `
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act, eft
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act && p.eft == "allow"
`
func Init(db *gorm.DB) error {
if common.IsMasterNode {
if err := seedBuiltInRoles(db); err != nil {
return err
}
if err := resetBuiltInRolePolicies(db); err != nil {
return err
}
}
m, err := casbinmodel.NewModelFromString(modelText)
if err != nil {
return err
}
e, err := casbin.NewSyncedEnforcer(m, newGormAdapter(db))
if err != nil {
return err
}
e.EnableAutoSave(true)
enforcerMu.Lock()
enforcer = e
enforcerMu.Unlock()
if !common.IsMasterNode {
return nil
}
return seedDefaultPolicies()
}
func currentEnforcer() *casbin.SyncedEnforcer {
enforcerMu.RLock()
defer enforcerMu.RUnlock()
return enforcer
}
func ReloadPolicy() error {
enforcerMu.Lock()
defer enforcerMu.Unlock()
if enforcer == nil {
return fmt.Errorf("authz enforcer is not initialized")
}
return enforcer.LoadPolicy()
}
// StartPolicySync periodically reloads the authorization policy from the database.
// The enforcer keeps an in-memory snapshot, and permission changes are written
// straight to the DB (see SetUserPermissionsInTx) with only the local node's
// snapshot refreshed afterwards. Without this loop other instances in a
// multi-node deployment would keep serving stale permissions (including not
// honoring a revoked grant) until restart. Mirrors model.SyncOptions polling.
func StartPolicySync(frequency int) {
if frequency <= 0 {
return
}
for {
time.Sleep(time.Duration(frequency) * time.Second)
if err := ReloadPolicy(); err != nil {
common.SysError("failed to reload authz policy: " + err.Error())
}
}
}