From 59c8777572f8879b1f6ec716cb81b8883127d7b8 Mon Sep 17 00:00:00 2001 From: yangduo Date: Wed, 17 Jul 2024 15:29:39 +0800 Subject: [PATCH] permission --- server/adminserver/api/v1/system/sys_user.go | 67 +++++---- server/adminserver/constant/constant.go | 39 +++++ server/adminserver/middleware/auth.go | 6 +- server/adminserver/middleware/permission.go | 27 ++++ server/adminserver/mt/Permission.go | 137 ++++++++++++++++++ server/adminserver/mt/export.go | 19 ++- .../adminserver/router/system/group_member.go | 15 +- server/adminserver/router/system/mail.go | 11 +- server/adminserver/router/system/sys_annc.go | 11 +- server/adminserver/router/system/sys_audit.go | 13 +- .../router/system/sys_battle_server.go | 11 +- server/adminserver/router/system/sys_nft.go | 10 +- .../adminserver/router/system/sys_player.go | 14 +- 13 files changed, 306 insertions(+), 74 deletions(-) create mode 100644 server/adminserver/middleware/permission.go create mode 100644 server/adminserver/mt/Permission.go diff --git a/server/adminserver/api/v1/system/sys_user.go b/server/adminserver/api/v1/system/sys_user.go index 084512cd..dbb41d30 100644 --- a/server/adminserver/api/v1/system/sys_user.go +++ b/server/adminserver/api/v1/system/sys_user.go @@ -1,14 +1,15 @@ package system import ( - "q5" "f5" - "github.com/gin-gonic/gin" - "mt" . "main/global" "main/model/system" + "mt" "net/http" + "q5" "strings" + + "github.com/gin-gonic/gin" ) type UserApi struct { @@ -43,22 +44,22 @@ func (this *UserApi) Info(c *gin.Context) { }) /* - user := system.SysUser{} - err := f5.GetApp().GetOrmDb(constant.ADMIN_DB).Where("username = ?", strArr[0]).First(&user).Error - if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": 1, - "message": "暂无此用户", - }) - return - } - user.Roles = append(user.Roles, "admin") + user := system.SysUser{} + err := f5.GetApp().GetOrmDb(constant.ADMIN_DB).Where("username = ?", strArr[0]).First(&user).Error + if err != nil { + c.JSON(http.StatusOK, gin.H{ + "code": 1, + "message": "暂无此用户", + }) + return + } + user.Roles = append(user.Roles, "admin") - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": user, - })*/ + c.JSON(http.StatusOK, gin.H{ + "code": 0, + "message": "success", + "data": user, + })*/ } func (this *UserApi) Logout(c *gin.Context) { @@ -74,9 +75,9 @@ func (this *UserApi) Logout(c *gin.Context) { func (this *UserApi) MetaMaskLogin(c *gin.Context) { reqJson := struct { AccountAddress string `json:"account"` - Nonce string `json:"nonce"` - Signature string `json:"signature"` - Tips string `json:"tips"` + Nonce string `json:"nonce"` + Signature string `json:"signature"` + Tips string `json:"tips"` }{} if err := c.ShouldBindJSON(&reqJson); err != nil { f5.RspErr2(c, 1, err.Error()) @@ -92,22 +93,22 @@ func (this *UserApi) MetaMaskLogin(c *gin.Context) { } f5.GetHttpCliMgr().SendGoStyleRequest( - mt.Table.Web3ServiceCluster.RandElement().GetUrl() + "/webapp/index.php", - map[string]string { - "c": "BcService", - "a": "authVerifySignature", - "tips": reqJson.Tips, - "nonce": reqJson.Nonce, + mt.Table.Web3ServiceCluster.RandElement().GetUrl()+"/webapp/index.php", + map[string]string{ + "c": "BcService", + "a": "authVerifySignature", + "tips": reqJson.Tips, + "nonce": reqJson.Nonce, "signature": reqJson.Signature, }, - func (rsp f5.HttpCliResponse) { + func(rsp f5.HttpCliResponse) { if rsp.GetErr() != nil { f5.RspErr2(c, 500, rsp.GetErr().Error()) return } rspJson := struct { - ErrCode int32 `json:"errcode"` - ErrMsg string `json:"errmsg"` + ErrCode int32 `json:"errcode"` + ErrMsg string `json:"errmsg"` Recovered string `json:"recovered"` }{} if q5.DecodeJson(rsp.GetRawData(), &rspJson) != nil { @@ -119,10 +120,12 @@ func (this *UserApi) MetaMaskLogin(c *gin.Context) { return } s := GetSessionMgr().AddSession(reqJson.AccountAddress, reqJson.Signature) + accountaddr := s.GetAccountAddress() c.JSON(http.StatusOK, gin.H{ - "code": 0, + "code": 0, "message": "success", - "token": s.GetToken(), + "token": s.GetToken(), + "ui": mt.Table.Permission.GetUIPermission(accountaddr), }) }) } diff --git a/server/adminserver/constant/constant.go b/server/adminserver/constant/constant.go index 256bdd3f..9a4560f3 100644 --- a/server/adminserver/constant/constant.go +++ b/server/adminserver/constant/constant.go @@ -26,3 +26,42 @@ const ( API_MAIL_HOST_DEV = "localhost:9992" EMAIL_KEY = "520d8eeb8cf1d833a42c820432c020b2fd60f4b7|" + EMAIL_URL_DEV ) + +const ( + FULLPERMISSION = "*" + PLAYER_INFO = "playerinfo" //玩家基本信息查询 + BAG_QUERY = "bagquery" //玩家背包查询 + HERO_QUERY = "heroesquery" //玩家英雄查询 + GOLD_BULLION_QUERY = "goldbullionquery" //金币查询 + TICKET_CONSUME_QUERY = "ticketconsumequery" //门票消耗查询 + GAME_MALL_QUERY = "gamemallquery" //游戏内商品查询 + + ORDER_QUERY = "orderquery" //订单查询 + SALE_QUERY = "salequery" //销售查询 + NFT_QUERY = "nftquery" //NFT查询 + + SYS_USER_INFO = "userinfo" //系统用户信息 + SYS_USER_LOGOUT = "userlogout" //系统用户登出 + + ADD_MAIL_GROUP_MEMBER = "addmailgroupmember" //添加邮件组成员 + EDIT_MAIL_GROUP_MEMBER = "editmailgroupmember" //编辑邮件组成员 + DEL_MAIL_GROUP_MEMBER = "delmailgroupmember" //删除邮件组成员 + MAIL_GROUP_LIST = "mailgrouplist" //邮件组列表 + UPLOAD_EXCEL_MAIL_GROUP = "uploadexcelmailgroup" //上传excel邮件组 + + SEND_MAIL = "sendmail" //发送邮件 + EDIT_MAIL = "editmail" //编辑邮件 + LIST_MAIL = "listmail" //查看邮件列表 + + LIST_ANNOUNCEMENT = "listannouncement" //查看公告列表 + ADD_ANNOUNCEMENT = "addannouncement" //添加公告 + EDIT_ANNOUNCEMENT = "editannouncement" //编辑公告 + + LIST_AUDIT = "listaudit" //查看审核列表 + ADD_AUDIT = "addaudit" //添加审核 + EDIT_AUDIT = "editaudit" //编辑审核 + + ADD_BATTLESERVER = "addbattleserver" //添加战斗服务器 + EDIT_BATTLESERVER = "editbattleserver" //编辑战斗服务器 + LIST_BATTLESERVER = "listbattleserver" //查看战斗服务器列表 +) diff --git a/server/adminserver/middleware/auth.go b/server/adminserver/middleware/auth.go index a284d885..ecda79d8 100644 --- a/server/adminserver/middleware/auth.go +++ b/server/adminserver/middleware/auth.go @@ -1,11 +1,14 @@ package middleware import ( - "github.com/gin-gonic/gin" . "main/global" "net/http" + + "github.com/gin-gonic/gin" ) +/* + */ func Auth() gin.HandlerFunc { return func(c *gin.Context) { token := c.Request.Header.Get("Authorization") @@ -18,5 +21,6 @@ func Auth() gin.HandlerFunc { c.Abort() return } + c.Set("session", s) } } diff --git a/server/adminserver/middleware/permission.go b/server/adminserver/middleware/permission.go new file mode 100644 index 00000000..7ed98c12 --- /dev/null +++ b/server/adminserver/middleware/permission.go @@ -0,0 +1,27 @@ +package middleware + +import ( + "adminserver/common" + "net/http" + + "mt" + + "github.com/gin-gonic/gin" +) + +/* + */ +func Permission(funcName string, cb func(*gin.Context)) gin.HandlerFunc { + return func(c *gin.Context) { + s := c.MustGet("session").(common.Session) + acc := s.GetAccountAddress() + if mt.Table.Permission.CheckAPIPermission(acc, funcName) { + cb(c) + } else { + c.JSON(http.StatusOK, gin.H{ + "code": 3, + "message": "No Permission", + }) + } + } +} diff --git a/server/adminserver/mt/Permission.go b/server/adminserver/mt/Permission.go new file mode 100644 index 00000000..064be7ea --- /dev/null +++ b/server/adminserver/mt/Permission.go @@ -0,0 +1,137 @@ +package mt + +import ( + "bufio" + "encoding/json" + "fmt" + "main/constant" + "os" + "q5" + "strings" +) + +type Permission struct { + api *q5.ConcurrentMap[string, bool] + ui *q5.ConcurrentMap[string, bool] +} + +type PermissionTable struct { + accountPermission *q5.ConcurrentMap[string, *Permission] +} + +func (this *PermissionTable) IsNoLoad() bool { + return false +} + +func (this *PermissionTable) Load() { + this.accountPermission = new(q5.ConcurrentMap[string, *Permission]) + { + if f, err := os.Open("../config/permission.json"); err == nil { + jsonStr, _ := bufio.NewReader(f).ReadString(0) + + type cfgPermission struct { + API []string `json:"api"` + UI []string `json:"ui"` + } + type AccountConfig struct { + Roles []string `json:"roles"` + Special cfgPermission `json:"special"` + } + permissioncfg := struct { + Roles map[string]cfgPermission `json:"roles"` + Accounts map[string]AccountConfig `json:"accounts"` + }{} + + if err := json.Unmarshal([]byte(jsonStr), &permissioncfg); err != nil { + panic(fmt.Sprintf("load metafile json decode error %s %s", "permission.json", err)) + } + + for account, cfg := range permissioncfg.Accounts { + accpermission := new(Permission) + accpermission.api = new(q5.ConcurrentMap[string, bool]) + accpermission.ui = new(q5.ConcurrentMap[string, bool]) + //load permission of the account's roles + for _, role := range cfg.Roles { + rp, exist := permissioncfg.Roles[role] + if !exist { + continue + } + + for _, v := range rp.API { + accpermission.api.Store(v, true) + } + + for _, v := range rp.UI { + accpermission.ui.Store(v, true) + } + } + + //load special permission + for _, v := range cfg.Special.API { + ret := strings.HasPrefix(v, "-") + accpermission.api.Store(v, !ret) + } + + for _, v := range cfg.Special.UI { + ret := strings.HasPrefix(v, "-") + accpermission.ui.Store(v, !ret) + } + + this.accountPermission.Store(strings.ToLower(account), accpermission) + } + } else { + panic(fmt.Sprintf("load metafile error %s %s", "permission.json", err)) + } + } +} + +func (this *PermissionTable) PreInit1() { + +} + +func (this *PermissionTable) ElementsInit(int) { + +} + +func (this *PermissionTable) PostInit1() { + +} + +func (this *PermissionTable) CheckAPIPermission(account string, cmd string) bool { + if account == "" || cmd == "" { + return false + } + + accper, exist := this.accountPermission.Load(account) + if !exist { + return false + } + + ret, exist := (*accper).api.Load(cmd) + if exist { + return *ret + } + + ret, exist = (*accper).api.Load(constant.FULLPERMISSION) + if exist { + return *ret + } + + return false +} + +func (this *PermissionTable) GetUIPermission(account string) string { + per, exist := this.accountPermission.Load(account) + if !exist { + return "{}" + } + + kvlist := map[string]bool{} + (*per).ui.Range(func(k string, v bool) bool { + kvlist[k] = v + return true + }) + + v, _ := json.Marshal(kvlist) + return string(v) +} diff --git a/server/adminserver/mt/export.go b/server/adminserver/mt/export.go index d9a6ec51..631f26e9 100644 --- a/server/adminserver/mt/export.go +++ b/server/adminserver/mt/export.go @@ -5,15 +5,16 @@ import ( ) type table struct { - AdminCluster *AdminClusterTable + AdminCluster *AdminClusterTable Web3ServiceCluster *Web3ServiceClusterTable - GameDb *GameDbTable - FriendDb *FriendDbTable - AccountDb *AccountDbTable - MailDb *MailDbTable - AdminDb *AdminDbTable - Config *ConfigTable - NFTDb *NFTDbTable + GameDb *GameDbTable + FriendDb *FriendDbTable + AccountDb *AccountDbTable + MailDb *MailDbTable + AdminDb *AdminDbTable + Config *ConfigTable + NFTDb *NFTDbTable + Permission *PermissionTable } var Table = f5.New(func(this *table) { @@ -60,4 +61,6 @@ var Table = f5.New(func(this *table) { this.FileName = "../config/nftdb.mysql.json" this.PrimKey = "" }) + + this.Permission = new(PermissionTable) }) diff --git a/server/adminserver/router/system/group_member.go b/server/adminserver/router/system/group_member.go index bb5379f3..b5c9a762 100644 --- a/server/adminserver/router/system/group_member.go +++ b/server/adminserver/router/system/group_member.go @@ -1,8 +1,11 @@ package system import ( + v1 "main/api/v1" + "main/constant" + "main/middleware" + "github.com/gin-gonic/gin" - "main/api/v1" ) type GroupMemberRoute struct { @@ -12,10 +15,10 @@ func (this *GroupMemberRoute) InitGroupMemberRouter(priRouter *gin.RouterGroup) group := priRouter.Group("group_member") api := v1.ApiGroupApp.SystemApiGroup.GroupMemberApi { - group.POST("add", api.Add) - group.POST("edit", api.Edit) - group.POST("del", api.Del) - group.GET("list", api.List) - group.POST("uploadExcel", api.UploadExcel) + group.POST("add", middleware.Permission(constant.ADD_MAIL_GROUP_MEMBER, api.Add)) + group.POST("edit", middleware.Permission(constant.EDIT_MAIL_GROUP_MEMBER, api.Edit)) + group.POST("del", middleware.Permission(constant.DEL_MAIL_GROUP_MEMBER, api.Del)) + group.GET("list", middleware.Permission(constant.MAIL_GROUP_LIST, api.List)) + group.POST("uploadExcel", middleware.Permission(constant.UPLOAD_EXCEL_MAIL_GROUP, api.UploadExcel)) } } diff --git a/server/adminserver/router/system/mail.go b/server/adminserver/router/system/mail.go index 95aa5c8c..40d5a9fe 100644 --- a/server/adminserver/router/system/mail.go +++ b/server/adminserver/router/system/mail.go @@ -1,8 +1,11 @@ package system import ( + v1 "main/api/v1" + "main/constant" + "main/middleware" + "github.com/gin-gonic/gin" - "main/api/v1" ) type MailRoute struct{} @@ -11,8 +14,8 @@ func (this *MailRoute) InitMailRouter(priRouter *gin.RouterGroup) { priUserRouter := priRouter.Group("mail") mailApi := v1.ApiGroupApp.SystemApiGroup.MailApi { - priUserRouter.POST("add", mailApi.AddMail) - priUserRouter.POST("edit", mailApi.EditMail) - priUserRouter.GET("list", mailApi.ListMail) + priUserRouter.POST("add", middleware.Permission(constant.SEND_MAIL, mailApi.AddMail)) + priUserRouter.POST("edit", middleware.Permission(constant.EDIT_MAIL, mailApi.EditMail)) + priUserRouter.GET("list", middleware.Permission(constant.LIST_MAIL, mailApi.ListMail)) } } diff --git a/server/adminserver/router/system/sys_annc.go b/server/adminserver/router/system/sys_annc.go index 36bbcd39..7176f294 100644 --- a/server/adminserver/router/system/sys_annc.go +++ b/server/adminserver/router/system/sys_annc.go @@ -1,8 +1,11 @@ package system import ( + v1 "main/api/v1" + "main/constant" + "main/middleware" + "github.com/gin-gonic/gin" - "main/api/v1" ) type AnncRouter struct{} @@ -11,8 +14,8 @@ func (this *AnncRouter) InitAnncRouter(priRouter *gin.RouterGroup) { priUserRouter := priRouter.Group("annc") anncApi := v1.ApiGroupApp.SystemApiGroup.AnncApi { - priUserRouter.GET("anncList", anncApi.AnncList) - priUserRouter.POST("addAnnc", anncApi.AddAnnc) - priUserRouter.PUT("updateAnnc/:idx", anncApi.UpdateAnnc) + priUserRouter.GET("anncList", middleware.Permission(constant.LIST_ANNOUNCEMENT, anncApi.AnncList)) + priUserRouter.POST("addAnnc", middleware.Permission(constant.ADD_ANNOUNCEMENT, anncApi.AddAnnc)) + priUserRouter.PUT("updateAnnc/:idx", middleware.Permission(constant.EDIT_ANNOUNCEMENT, anncApi.UpdateAnnc)) } } diff --git a/server/adminserver/router/system/sys_audit.go b/server/adminserver/router/system/sys_audit.go index 81eb5732..5d185262 100644 --- a/server/adminserver/router/system/sys_audit.go +++ b/server/adminserver/router/system/sys_audit.go @@ -1,18 +1,21 @@ package system import ( + v1 "main/api/v1" + "main/constant" + "main/middleware" + "github.com/gin-gonic/gin" - "main/api/v1" ) type AuditRouter struct{} -func (this *AnncRouter) InitAuditRouter(priRouter *gin.RouterGroup) { +func (ar *AnncRouter) InitAuditRouter(priRouter *gin.RouterGroup) { priUserRouter := priRouter.Group("audit") auditApi := v1.ApiGroupApp.SystemApiGroup.AuditApi { - priUserRouter.GET("auditList", auditApi.AuditList) - priUserRouter.POST("addAudit", auditApi.AddAudit) - priUserRouter.PUT("updateAudit/:idx", auditApi.UpdateAudit) + priUserRouter.GET("auditList", middleware.Permission(constant.LIST_AUDIT, auditApi.AuditList)) + priUserRouter.POST("addAudit", middleware.Permission(constant.ADD_AUDIT, auditApi.AddAudit)) + priUserRouter.PUT("updateAudit/:idx", middleware.Permission(constant.EDIT_AUDIT, auditApi.UpdateAudit)) } } diff --git a/server/adminserver/router/system/sys_battle_server.go b/server/adminserver/router/system/sys_battle_server.go index e15977a9..a5cb7944 100644 --- a/server/adminserver/router/system/sys_battle_server.go +++ b/server/adminserver/router/system/sys_battle_server.go @@ -1,8 +1,11 @@ package system import ( + v1 "main/api/v1" + "main/constant" + "main/middleware" + "github.com/gin-gonic/gin" - "main/api/v1" ) type BattleServerRoute struct{} @@ -11,8 +14,8 @@ func (r *BattleServerRoute) InitBattleServerRouter(priRouter *gin.RouterGroup) { priUserRouter := priRouter.Group("battle_server") api := v1.ApiGroupApp.SystemApiGroup.BattleServerApi { - priUserRouter.POST("add", api.Add) - priUserRouter.GET("list", api.List) - priUserRouter.PUT("update", api.Update) + priUserRouter.POST("add", middleware.Permission(constant.ADD_BATTLESERVER, api.Add)) + priUserRouter.GET("list", middleware.Permission(constant.LIST_BATTLESERVER, api.List)) + priUserRouter.PUT("update", middleware.Permission(constant.EDIT_BATTLESERVER, api.Update)) } } diff --git a/server/adminserver/router/system/sys_nft.go b/server/adminserver/router/system/sys_nft.go index 5d6801ac..fdab0870 100644 --- a/server/adminserver/router/system/sys_nft.go +++ b/server/adminserver/router/system/sys_nft.go @@ -2,18 +2,20 @@ package system import ( v1 "main/api/v1" + "main/constant" + "main/middleware" "github.com/gin-gonic/gin" ) type NFTRouter struct{} -func (this *NFTRouter) InitNFTRouter(priRouter *gin.RouterGroup) { +func (nr *NFTRouter) InitNFTRouter(priRouter *gin.RouterGroup) { group := priRouter.Group("nft") api := v1.ApiGroupApp.SystemApiGroup.NFTApi { - group.POST("orderquery", api.OrderQuery) - group.POST("salequery", api.SaleQuery) - group.POST("nftquery", api.NFTQuery) + group.POST("orderquery", middleware.Permission(constant.ORDER_QUERY, api.OrderQuery)) + group.POST("salequery", middleware.Permission(constant.SALE_QUERY, api.SaleQuery)) + group.POST("nftquery", middleware.Permission(constant.NFT_QUERY, api.NFTQuery)) } } diff --git a/server/adminserver/router/system/sys_player.go b/server/adminserver/router/system/sys_player.go index 266d250c..4520d371 100644 --- a/server/adminserver/router/system/sys_player.go +++ b/server/adminserver/router/system/sys_player.go @@ -2,6 +2,8 @@ package system import ( v1 "main/api/v1" + "main/constant" + "main/middleware" "github.com/gin-gonic/gin" ) @@ -12,11 +14,11 @@ func (pr *PlayerRouter) InitPlayerRouter(priRouter *gin.RouterGroup) { group := priRouter.Group("player") api := v1.ApiGroupApp.SystemApiGroup.PlayerApi { - group.POST("info", api.Info) - group.POST("bagquery", api.BagQuery) - group.POST("heroesquery", api.HeroesQuery) - group.POST("goldbullionquery", api.GoldBullionQuery) - group.POST("ticketconsumequery", api.TicketConsumeQuery) - group.POST("gamemallquery", api.GameMallQuery) + group.POST("info", middleware.Permission(constant.PLAYER_INFO, api.Info)) + group.POST("bagquery", middleware.Permission(constant.BAG_QUERY, api.BagQuery)) + group.POST("heroesquery", middleware.Permission(constant.HERO_QUERY, api.HeroesQuery)) + group.POST("goldbullionquery", middleware.Permission(constant.GOLD_BULLION_QUERY, api.GoldBullionQuery)) + group.POST("ticketconsumequery", middleware.Permission(constant.TICKET_CONSUME_QUERY, api.TicketConsumeQuery)) + group.POST("gamemallquery", middleware.Permission(constant.GAME_MALL_QUERY, api.GameMallQuery)) } }