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) } } }