diff --git a/app/controller/admin/auth.go b/app/controller/admin/auth.go index 1d0faba..01e3ea3 100644 --- a/app/controller/admin/auth.go +++ b/app/controller/admin/auth.go @@ -15,7 +15,6 @@ import ( "github.com/gogf/gf/text/gstr" "github.com/gogf/gf/util/gconv" "github.com/gogf/gf/util/gvalid" - "strings" ) //菜单用户组用户管理 @@ -94,12 +93,11 @@ func (c *Auth) EditMenu(r *ghttp.Request) { //删除菜单 func (c *Auth) DeleteMenu(r *ghttp.Request) { - ids := r.GetRequestArray("ids") - idsInterface := make(g.Slice, len(ids)) - for k, v := range ids { - idsInterface[k] = gconv.Int64(v) + ids := r.GetInts("ids") + if len(ids) == 0 { + response.FailJson(true, r, "删除失败,参数错误") } - _, err := auth_rule.Model.Where("id in(?)", idsInterface).Delete() + _, err := auth_rule.Model.Where("id in(?)", ids).Delete() if err != nil { g.Log().Error(err) response.FailJson(true, r, "删除失败") @@ -115,7 +113,7 @@ func (c *Auth) RoleList(r *ghttp.Request) { g.Log().Error(err) response.FailJson(true, r, "获取数据失败") } - list = utils.ParentSonSort(list, 0, 0, "parent_id", "id", "flg", "name") + list = utils.PushSonToParent(list, 0, "parent_id", "id", "children", "", nil, false) response.SusJson(true, r, "成功", g.Map{ "list": list, }) @@ -248,23 +246,22 @@ func (c *Auth) EditRole(r *ghttp.Request) { //删除角色 func (c *Auth) DeleteRole(r *ghttp.Request) { ids := r.GetRequestArray("ids") - idsInterface := make(g.Slice, len(ids)) - for k, v := range ids { - idsInterface[k] = gconv.Int64(v) + if len(ids) == 0 { + response.FailJson(true, r, "删除失败,参数错误") } tx, err := g.DB("default").Begin() //开启事务 if err != nil { g.Log().Error(err) response.FailJson(true, r, "事务处理失败") } - _, err = tx.Table(role.Table).Where("id in(?)", idsInterface).Delete() + _, err = tx.Table(role.Table).Where("id in(?)", ids).Delete() if err != nil { g.Log().Error(err) tx.Rollback() response.FailJson(true, r, "删除失败") } //删除角色的权限 - for _, v := range idsInterface { + for _, v := range ids { err = auth_service.DeleteRoleRule(gconv.Int64(v)) if err != nil { g.Log().Error(err) @@ -345,12 +342,15 @@ func (c *Auth) EditUser(r *ghttp.Request) { //用户列表 func (c *Auth) UserList(r *ghttp.Request) { keyWords := r.GetString("keywords") - g.Log().Debug("keyWords=", keyWords) + page := r.GetInt("page") + if page == 0 { + page = 1 + } var where = map[string]interface{}{} if keyWords != "" { where["keyWords"] = keyWords } - page, total, userList, err := user_service.GetAdminList(r, where) + total, userList, err := user_service.GetAdminList(where, page) if err != nil { g.Log().Error(err) response.FailJson(true, r, "获取用户列表数据失败") @@ -358,16 +358,16 @@ func (c *Auth) UserList(r *ghttp.Request) { users := make([]g.Map, len(userList)) for k, u := range userList { users[k] = gconv.Map(u) - roles, err := user_service.GetAdminRole(gconv.Int64(u.Id)) + roles, err := user_service.GetAdminRole(gconv.Int(u.Id)) if err != nil { g.Log().Error(err) response.FailJson(true, r, "获取用户角色数据失败") } - name := make([]string, len(roles)) - for rk, r := range roles { - name[rk] = r.Name + roleInfo := make(map[int]string, len(roles)) + for _, r := range roles { + roleInfo[r.Id] = r.Name } - users[k]["roles"] = strings.Join(name, ",") + users[k]["roleInfo"] = roleInfo } //获取用户对应角色 @@ -381,15 +381,22 @@ func (c *Auth) UserList(r *ghttp.Request) { //删除管理员 func (c *Auth) DeleteAdmin(r *ghttp.Request) { - ids := r.GetRequestArray("ids") - idsInterface := make(g.Slice, len(ids)) - for k, v := range ids { - idsInterface[k] = gconv.Int64(v) + ids := r.GetInts("ids") + if len(ids) > 0 { + _, err := user.Model.Where("id in(?)", ids).Delete() + if err != nil { + g.Log().Error(err) + response.FailJson(true, r, "删除失败") + } + } else { + response.FailJson(true, r, "删除失败,参数错误") } - _, err := user.Model.Where("id in(?)", idsInterface).Delete() - if err != nil { - g.Log().Error(err) - response.FailJson(true, r, "删除失败") + //删除对应权限 + enforcer, err := casbin_adapter_service.GetEnforcer() + if err == nil { + for _, v := range ids { + enforcer.RemoveFilteredGroupingPolicy(0, fmt.Sprintf("u_%d", v)) + } } response.SusJson(true, r, "删除成功") } diff --git a/app/controller/admin/index.go b/app/controller/admin/index.go index a696eb7..c5aab97 100644 --- a/app/controller/admin/index.go +++ b/app/controller/admin/index.go @@ -18,7 +18,7 @@ func (c *Index) Index(r *ghttp.Request) { //菜单列表 var menuList g.List if userInfo != nil { - userId := gconv.Int64(userInfo["id"]) + userId := gconv.Int(userInfo["id"]) delete(userInfo, "user_password") //获取用户角色信息 roles, err := user_service.GetAdminRole(userId) diff --git a/app/model/user/user_model.go b/app/model/user/user_model.go index 193b6c7..116d4d5 100644 --- a/app/model/user/user_model.go +++ b/app/model/user/user_model.go @@ -133,7 +133,7 @@ func (m *arModel) Offset(offset int) *arModel { // The parameter is started from 1 for paging. // Note that, it differs that the Limit function start from 0 for "LIMIT" statement. func (m *arModel) ForPage(page, limit int) *arModel { - return &arModel{m.Model.ForPage(page, limit)} + return &arModel{m.Model.Page(page, limit)} } // Batch sets the batch operation number for the model. diff --git a/app/service/auth_service/auth_rule.go b/app/service/auth_service/auth_rule.go index d963f45..32804d3 100644 --- a/app/service/auth_service/auth_rule.go +++ b/app/service/auth_service/auth_rule.go @@ -127,7 +127,7 @@ func AddRoleRule(iRule interface{}, roleId int64) (err error) { err = e return } - rule := iRule.([]interface{}) + rule := gconv.Strings(iRule) for _, v := range rule { _, err = enforcer.AddPolicy(fmt.Sprintf("g_%d", roleId), fmt.Sprintf("r_%s", v), "All") if err != nil { @@ -182,7 +182,7 @@ func EditRoleRule(iRule interface{}, roleId int64) (err error) { return } } - rule := iRule.([]interface{}) + rule := gconv.Strings(iRule) for _, v := range rule { _, err = enforcer.AddPolicy(fmt.Sprintf("g_%d", roleId), fmt.Sprintf("r_%s", v), "All") if err != nil { @@ -254,7 +254,7 @@ func AddUser(data map[string]interface{}) (InsertId int64, err error) { //修改用户信息 func EditUser(data map[string]interface{}) (err error) { - e := checkUserData(data, "add") + e := checkUserData(data, "edit") if e != nil { err = gerror.New(e.(*gvalid.Error).FirstString()) return @@ -269,8 +269,10 @@ func EditUser(data map[string]interface{}) (err error) { } //保存管理员信息 //提交了密码?密码加密 - if _, ok := data["user_password"]; ok { + if val, ok := data["user_password"]; ok && gconv.String(val) != "" { data["user_password"] = utils.EncryptCBC(gconv.String(data["user_password"]), utils.AdminCbcPublicKey) + } else { + delete(data, "user_password") } _, err = user.Model.Filter().Data(data).Save() if err != nil { @@ -286,9 +288,9 @@ func AddUserRole(roleIds interface{}, userId int64) (err error) { err = e return } - rule := roleIds.([]interface{}) + rule := gconv.Ints(roleIds) for _, v := range rule { - _, err = enforcer.AddGroupingPolicy(fmt.Sprintf("u_%d", userId), fmt.Sprintf("g_%s", v)) + _, err = enforcer.AddGroupingPolicy(fmt.Sprintf("u_%d", userId), fmt.Sprintf("g_%d", v)) if err != nil { return } @@ -303,11 +305,11 @@ func EditUserRole(roleIds interface{}, userId int64) (err error) { err = e return } - rule := roleIds.([]interface{}) + rule := gconv.Ints(roleIds) //删除用户旧角色信息 enforcer.RemoveFilteredGroupingPolicy(0, fmt.Sprintf("u_%d", userId)) for _, v := range rule { - _, err = enforcer.AddGroupingPolicy(fmt.Sprintf("u_%d", userId), fmt.Sprintf("g_%s", v)) + _, err = enforcer.AddGroupingPolicy(fmt.Sprintf("u_%d", userId), fmt.Sprintf("g_%d", v)) if err != nil { return } diff --git a/app/service/user_service/user.go b/app/service/user_service/user.go index 3a9e857..9d9f8de 100644 --- a/app/service/user_service/user.go +++ b/app/service/user_service/user.go @@ -15,10 +15,10 @@ import ( ) //获取登陆用户ID -func GetLoginID(r *ghttp.Request) (userId int64) { +func GetLoginID(r *ghttp.Request) (userId int) { userInfo := GetCacheAdminInfo(r) if userInfo != nil { - userId = gconv.Int64(userInfo["id"]) + userId = gconv.Int(userInfo["id"]) } return } @@ -31,8 +31,7 @@ func GetCacheAdminInfo(r *ghttp.Request) (userInfo g.Map) { } //获取管理员列表 -func GetAdminList(r *ghttp.Request, where g.Map) (page int, total int, - userList []*user.Entity, err error) { +func GetAdminList(where g.Map, page int) (total int, userList []*user.Entity, err error) { userModel := user.Model if v, ok := where["keyWords"]; ok { keyWords := gconv.String(v) @@ -43,13 +42,12 @@ func GetAdminList(r *ghttp.Request, where g.Map) (page int, total int, } } total, err = userModel.Count() - page, start := utils.SetPageLimit(r) - userList, err = userModel.Limit(start, utils.AdminPageNum).OrderBy("id asc").All() + userList, err = userModel.ForPage(page, utils.AdminPageNum).OrderBy("id asc").All() return } //获取管理员的角色信息 -func GetAdminRole(userId int64) (roles []*role.Entity, err error) { +func GetAdminRole(userId int) (roles []*role.Entity, err error) { enforcer, e := casbin_adapter_service.GetEnforcer() if e != nil { err = e @@ -58,10 +56,10 @@ func GetAdminRole(userId int64) (roles []*role.Entity, err error) { //查询关联角色规则 groupPolicy := enforcer.GetFilteredGroupingPolicy(0, fmt.Sprintf("u_%d", userId)) if len(groupPolicy) > 0 { - roleIds := make([]int64, len(groupPolicy)) + roleIds := make([]int, len(groupPolicy)) //得到角色id的切片 for k, v := range groupPolicy { - roleIds[k] = gconv.Int64(gstr.SubStr(v[1], 2)) + roleIds[k] = gconv.Int(gstr.SubStr(v[1], 2)) } //获取角色信息 roles, err = role.Model.Where("id in(?)", roleIds).All() diff --git a/boot/boot.go b/boot/boot.go index 8efc16a..bbbfcc6 100644 --- a/boot/boot.go +++ b/boot/boot.go @@ -13,6 +13,16 @@ func init() { g.Log().SetFlags(glog.F_ASYNC | glog.F_TIME_DATE | glog.F_TIME_TIME | glog.F_FILE_LONG) g.Server().SetPort(8200) g.Server().AddStaticPath("/public", g.Cfg().GetString("server.ServerRoot")) + //后台初始化配置 + initAdmin() + +} + +func initAdmin() { + //无需验证权限的用户id + utils.NotCheckAuthAdminIds = g.Cfg().GetInts("adminInfo.notCheckAuthAdminIds") + //后端分页长度配置 + utils.AdminPageNum = g.Cfg().GetInt("adminInfo.pageNum") // 设置并启动后台gtoken处理 initAdminGfToken() } @@ -20,8 +30,6 @@ func init() { func initAdminGfToken() { //多端登陆配置 utils.AdminMultiLogin = g.Cfg().GetBool("gToken.MultiLogin") - //后端分页长度配置 - utils.AdminPageNum = g.Cfg().GetInt("adminInfo.pageNum") AdminGfToken = >oken.GfToken{ CacheMode: g.Cfg().GetInt8("gToken.CacheMode"), CacheKey: g.Cfg().GetString("gToken.CacheKey"), diff --git a/config/config.toml b/config/config.toml index f5bbe19..2715f45 100644 --- a/config/config.toml +++ b/config/config.toml @@ -48,4 +48,5 @@ policyFile="./config/casbin_conf/rbac_policy.csv" #后台相关配置 [adminInfo] -pageNum = 5 #后台列表分页长度 \ No newline at end of file +notCheckAuthAdminIds = [1,2] #无需验证后台权限的用户id +pageNum = 5 #后台列表分页长度 diff --git a/go.mod b/go.mod index 0d15941..bf3fcd3 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module gfast require ( github.com/casbin/casbin/v2 v2.1.2 github.com/goflyfox/gtoken v1.3.9 - github.com/gogf/gf v1.11.2 + github.com/gogf/gf v1.11.4 github.com/mojocn/base64Captcha v1.2.2 ) diff --git a/library/utils/function.go b/library/utils/function.go index ca5edc2..f2b6ccd 100644 --- a/library/utils/function.go +++ b/library/utils/function.go @@ -22,8 +22,9 @@ import ( const AdminCbcPublicKey = "HqmP1KLMuz09Q0Bu" var ( - AdminMultiLogin bool //是否允许后台管理员多端登陆 - AdminPageNum = 20 //后台分页长度 + AdminMultiLogin bool //是否允许后台管理员多端登陆 + AdminPageNum = 20 //后台分页长度 + NotCheckAuthAdminIds []int //无需验证权限的用户id ) //获取验证码 @@ -153,13 +154,3 @@ func signIn(username, password string, r *ghttp.Request) (error, *user.QxkjUser) qxkjUser.Update() return nil, &returnData } - -//获取分页limit start -func SetPageLimit(r *ghttp.Request) (page int, start int) { - page = r.GetInt("page") - if page == 0 { - page = 1 - } - start = (page - 1) * AdminPageNum - return -} diff --git a/router/middleware.go b/router/middleware.go index dc451fb..b60fde0 100644 --- a/router/middleware.go +++ b/router/middleware.go @@ -1,8 +1,71 @@ package router -import "github.com/gogf/gf/net/ghttp" +import ( + "fmt" + "gfast/app/model/auth_rule" + "gfast/app/service/casbin_adapter_service" + "gfast/app/service/user_service" + "gfast/library/response" + "gfast/library/utils" + "github.com/gogf/gf/encoding/gurl" + "github.com/gogf/gf/frame/g" + "github.com/gogf/gf/net/ghttp" +) +//跨域处理中间件 func MiddlewareCORS(r *ghttp.Request) { r.Response.CORSDefault() r.Middleware.Next() } + +//权限判断处理中间件 +func MiddlewareAuth(r *ghttp.Request) { + //获取登陆用户id + adminId := user_service.GetLoginID(r) + //获取无需验证权限的用户id + for _, v := range utils.NotCheckAuthAdminIds { + if v == adminId { + r.Middleware.Next() + return + } + } + url := r.GetUrl() + info, err := gurl.ParseURL(url, 32) + if err != nil { + g.Log().Error(err) + response.FailJson(true, r, "请求地址错误") + } + //获取地址对应的菜单id + gValue, err := auth_rule.Model.Where("name=?", info["path"]).Fields("id").Value() + if err != nil { + g.Log().Error(err) + response.FailJson(true, r, "请求数据失败") + } + menuId := gValue.Int() + //菜单没存数据库不验证权限 + if menuId != 0 { + //判断权限操作 + enforcer, err := casbin_adapter_service.GetEnforcer() + if err != nil { + g.Log().Error(err) + response.FailJson(true, r, "获取权限失败") + } + groupPolicy := enforcer.GetFilteredGroupingPolicy(0, + fmt.Sprintf("u_%d", adminId)) + if len(groupPolicy) == 0 { + response.FailJson(true, r, "没有访问权限") + } + hasAccess := false + g.Log().Debug(groupPolicy) + for _, v := range groupPolicy { + if enforcer.HasPolicy(v[1], fmt.Sprintf("r_%d", menuId), "All") { + hasAccess = true + break + } + } + if !hasAccess { + response.FailJson(true, r, "没有访问权限") + } + } + r.Middleware.Next() +} diff --git a/router/router.go b/router/router.go index 56c76c1..b77292a 100644 --- a/router/router.go +++ b/router/router.go @@ -13,6 +13,7 @@ func init() { sysLoginGroup := group.Group("/sysLogin") sysLoginGroup.ALL("/public", new(admin.Public)) systemGroup := group.Group("/system") + //systemGroup.Middleware(MiddlewareAuth)//后台权限验证 systemGroup.ALL("/index", new(admin.Index)) systemGroup.ALL("/auth", new(admin.Auth)) } diff --git a/test/demo2_test.go b/test/demo2_test.go index 86b373a..d2ad02d 100644 --- a/test/demo2_test.go +++ b/test/demo2_test.go @@ -1,8 +1,6 @@ package test import ( - "fmt" - "strings" "testing" ) @@ -11,5 +9,5 @@ func TestDemo2(t *testing.T) { } func test21(t *testing.T) { - fmt.Println(strings.Repeat("yxh", 2)) + }