package config import ( "context" "errors" "fmt" "gadmin/internal/gorm/model" "gadmin/internal/gorm/query" "gadmin/utility/character" jsoniter "github.com/json-iterator/go" "github.com/sirupsen/logrus" "net/http" "strings" ) const AuthSuperRoleId = 1 // 超管角色ID // 权限分组 const ( AuthGMUpdate = 1 // GM玩家属性修改 AuthBanPlayer = 2 // 玩家封禁 AuthMail = 3 // 邮件操作 AuthNotice = 4 // 广播操作 AuthRedeemCode = 5 // 兑换码 AuthClearRank = 6 // 清除排行榜排名 AuthServConfig = 7 // 服务配置修改权限 AuthDelPlayer = 8 // 玩家删除 AuthVerifyMail = 9 //邮件审核、确认发送 AuthChatLog = 10 //客服聊天记录 ) // AuthNameMap 权限分组名称映射 var AuthNameMap = map[int]string{ AuthGMUpdate: "GM玩家属性修改", AuthBanPlayer: "玩家封禁", AuthMail: "邮件操作", AuthNotice: "广播操作", AuthRedeemCode: "兑换码", AuthClearRank: "清除排行榜排名", AuthServConfig: "服务配置修改", AuthDelPlayer: "玩家删除", AuthVerifyMail: "邮件审核发送", AuthChatLog: "客服聊天记录", } // AuthMenuMap 权限分组菜单映射 // key 对应路由分组 value对应菜单name var AuthMenuMap = map[int]string{ AuthChatLog: "ChatLog", } var ( authVerifyMethods []string // 需要验证的请求方式 permissions map[int][]string // 权限分组 authWhitelist []string // 白名单,免验证 ) // GM玩家属性修改权限、玩家封禁权限、发送邮件权限、发送广播权限、兑换码创建权限、排行榜删榜权限、服务配置修改权限 func init() { authVerifyMethods = append(authVerifyMethods, []string{http.MethodPost}...) permissions = make(map[int][]string) permissions[AuthGMUpdate] = append(permissions[AuthGMUpdate], []string{ "/api/gm/userRoles", "/api/gm/updatePlayerBase", "/api/gm/updateChapter", "/api/gm/updateTalents", "/api/gm/updateGuides", "/api/gm/addEquipment", "/api/gm/addMaterial", "/api/gm/addExp", "/api/gm/addStamina", "/api/gm/upgradeRole", "/api/gm/addCoin", "/api/gm/add_equipment", "/api/gm/add_material", "/api/gm/upgrade_role", "/api/gm/openAccount", "/api/gm/retrofitGroup/edit", "/api/gm/retrofitGroup/delete", "/api/gm/retrofit/edit", "/api/gm/retrofit/delete", "/api/grandmaster/setDanScore", }...) permissions[AuthBanPlayer] = append(permissions[AuthBanPlayer], []string{ "/api/userAccount/userBan", "/api/userAccount/singleBanUser", "/api/userAccount/banUserChat", }...) permissions[AuthMail] = append(permissions[AuthMail], []string{ "/api/gm/letters/add", "/api/gm/letters/del", "/api/email/list", "/api/email/add", }...) permissions[AuthNotice] = append(permissions[AuthNotice], []string{ "/api/gm/notices", "/api/gm/del_notice", "/api/notice/add", "/api/notice/cancel", }...) permissions[AuthRedeemCode] = append(permissions[AuthRedeemCode], []string{ "/api/cdk/add", "/api/cdk/del", }...) permissions[AuthClearRank] = append(permissions[AuthClearRank], []string{ "/api/gm/update_el_rank", "/api/gm/delRank", }...) permissions[AuthServConfig] = append(permissions[AuthServConfig], []string{ "/api/gm/set_conf_path", "/api/gm/updateSwitchers", "/api/drainageServer/edit", "/api/drainageServer/editDisplay", "/api/drainageServer/editWhiteList", "/api/gm/getServerDate", "/api/gm/releaseVersion", // 服务部署 "/api/deploy/task", "/api/deploy/stop", "/api/deploy/edit", "/api/deploy/edit", "/api/deploy/delete", }...) permissions[AuthDelPlayer] = append(permissions[AuthDelPlayer], []string{ "/api/gm/delete_player", }...) permissions[AuthVerifyMail] = append(permissions[AuthVerifyMail], []string{ "/api/email/verify", }...) permissions[AuthChatLog] = append(permissions[AuthChatLog], []string{ "/api/gm/chatLog/playerList", "/api/gm/chatLog/info", }...) authWhitelist = append(authWhitelist, []string{ "/api/user/logout", "/api/gm/userRoles", "/api/gm/tools/restart", "/api/channel/statEdit", "/api/admin/updatePassword", // 配装 "/api/retrofitGroup/edit", "/api/retrofit/edit", "/api/retrofit/delete", "/api/retrofitGroup/delete", }...) } // IsSuperRole 是否是超管角色 func IsSuperRole(roleId int64) bool { return roleId == AuthSuperRoleId } // ValidityAuth 验证权限 func ValidityAuth(roleId int64, method, path string, systemId int32) (err error) { path = strings.TrimPrefix(path, "/entrance") // 超管无需验证 if IsSuperRole(roleId) { return nil } // 无需验证的请求方式 if !character.InSlice(authVerifyMethods, method) { return nil } // 免验证的白名单 if character.InSlice(authWhitelist, path) { return nil } if roleId <= 0 { return errors.New("当前登录用户角色信息异常,请退出重新登录") } rdb := query.Use(AdminDB).AdminRole result, err := rdb.Where(rdb.ID.Eq(roleId)).First() if err != nil { logrus.Warnf("AdminRole... err:%+v", err) return } if result == nil { return errors.New("获取角色信息失败") } if result.Status != 1 { return errors.New("角色权限已被禁用") } //rpdb := query.Use(AdminDB).AdminRolePermission //var possess []int //err = rpdb.Where(rpdb.SystemID.Eq(systemId), rpdb.RoleID.Eq(int32(roleId))).Pluck(rpdb.PermissionID, &possess) ////err = json.Unmarshal([]byte(result.Permissions), &possess) //if err != nil { // return fmt.Errorf("权限解析时发生错误:%v,请联系管理员", err.Error()) //} permissionList, err := GetRoleSystemPermissions(roleId, int64(systemId)) if err != nil { return fmt.Errorf("获取角色权限错误:%v,请联系管理员", err.Error()) } if len(permissionList) == 0 { return errors.New("角色没有分配权限") } checkFlag := false for _, it := range permissionList { if it.API == path { checkFlag = true break } } if !checkFlag { return errors.New("你还没有获得该操作权限") } return nil //// 拥有的全部权限 //var allPermission []string //for _, v := range possess { // p, ok := permissions[v] // if !ok { // continue // } // allPermission = append(allPermission, p...) //} // //// 检查分配的权限中包含当前请求的权限 //if !character.InSlice(allPermission, path) { // return errors.New("你还没有获得该操作权限") //} //return nil } type Permission struct { ID int32 `json:"id"` Name string `json:"name"` Apis []string `json:"apis"` } // GetAllPermissions 获取所有权限 func GetAllPermissions() ([]*Permission, error) { q := query.Use(AdminDB).AdminPermission permissionList, err := q.WithContext(context.Background()).Order(q.ID).Find() if err != nil { return nil, err } var result []*Permission for _, v := range permissionList { apis := make([]string, 0) if err := jsoniter.UnmarshalFromString(v.Apis, &apis); err != nil { return nil, err } result = append(result, &Permission{ ID: v.ID, Name: v.Name, Apis: apis, }) } return result, nil } // GetRoleSystemPermissions 获取角色下的权限 func GetRoleSystemPermissions(roleId, systemId int64) ([]*model.AdminOperation, error) { rpq := query.Use(AdminDB).AdminRolePermission oq := query.Use(AdminDB).AdminOperation pIds := make([]int32, 0) err := rpq.Where(rpq.RoleID.Eq(int32(roleId)), rpq.SystemID.Eq(int32(systemId))).Pluck(rpq.PermissionID, &pIds) if err != nil { return nil, err } permissionList, err := oq.WithContext(context.Background()).Where(oq.ID.In(pIds...)).Find() if err != nil { return nil, err } return permissionList, nil //var result []*Permission //for _, v := range permissionList { // apis := make([]string, 0) // if err := jsoniter.UnmarshalFromString(v.Apis, &apis); err != nil { // return nil, err // } // result = append(result, &Permission{ // ID: v.ID, // Name: v.Name, // Apis: apis, // }) //} //return result, nil }