低空智控平台 后端go
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

90 lines
2.8 KiB

package service
import (
"laic-backend/common"
"laic-backend/logger"
"laic-backend/model"
)
// BootstrapCasbin 引导默认 RBAC 策略(幂等):p 策略(角色→路径→方法)+ 用户角色映射 g 策略
func BootstrapCasbin() {
e := common.CasbinEnforcer
if e == nil {
return
}
// 清理旧的 admin 全量策略,防止历史 "admin /* *" 残留导致越权(幂等)
if _, err := e.RemoveFilteredPolicy(0, "admin"); err != nil {
logger.ERROR("清理 admin 旧策略失败", err)
}
// p 策略:
// admin —— 平台管理职能:查看用户/机巢/无人机,管理固件,管理主账号云媒体流量
// user —— 业务操作:机巢/无人机/任务/航线等(自注册普通用户)
// keyMatch2 下 "/prefix/*" 匹配所有子路径(含多级),再补 "/prefix" 精确匹配列表/新增基路径。
adminPolicies := [][]string{
// 查看所有用户信息(暂只读)
{"admin", "/v1/users", "GET"},
{"admin", "/v1/users/*", "GET"},
// 查看机巢 / 无人机(含状态与遥测)
{"admin", "/v1/docks", "GET"},
{"admin", "/v1/docks/*", "GET"},
{"admin", "/v1/drones", "GET"},
{"admin", "/v1/drones/*", "GET"},
// 固件包管理
{"admin", "/v1/firmwares", "*"},
{"admin", "/v1/firmwares/*", "*"},
// 主账号云媒体流量管理(流量余额/订单/SIM 卡)
{"admin", "/v1/account/traffic", "*"},
{"admin", "/v1/account/traffic/*", "*"},
{"admin", "/v1/account/sim-cards", "*"},
{"admin", "/v1/account/sim-cards/*", "*"},
// 平台监控:角色字典
{"admin", "/v1/roles", "GET"},
}
userPrefixes := []string{
"/v1/docks",
"/v1/drones",
"/v1/alarms",
"/v1/commands",
"/v1/tasks",
"/v1/routes",
"/v1/executions",
"/v1/account",
"/v1/live",
"/v1/videos",
"/v1/ws",
}
policies := append([][]string{}, adminPolicies...)
for _, prefix := range userPrefixes {
policies = append(policies, []string{"user", prefix, "*"}, []string{"user", prefix + "/*", "*"})
}
// 普通用户可读取已发布固件列表(选择升级)
policies = append(policies, []string{"user", "/v1/firmwares/released", "GET"})
// 普通用户查看自己的操作记录
policies = append(policies, []string{"user", "/v1/logs/operation", "GET"})
for _, p := range policies {
args := make([]any, len(p))
for i, v := range p {
args[i] = v
}
if _, err := e.AddPolicy(args...); err != nil {
logger.ERROR("添加 Casbin 策略失败", err)
}
}
// g 策略:同步现有用户角色映射
var users []model.User
if err := common.DB.Find(&users).Error; err != nil {
logger.ERROR("查询用户同步 Casbin 角色失败", err)
return
}
for _, u := range users {
if err := common.SetUserRole(u.ID, u.Role); err != nil {
logger.ERROR("同步用户角色失败", err)
}
}
}