Selaa lähdekoodia

权限过滤器

yxh 6 vuotta sitten
vanhempi
säilyke
903dac499d

+ 34 - 27
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, "删除成功")
 }

+ 1 - 1
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)

+ 1 - 1
app/model/user/user_model.go

@@ -133,7 +133,7 @@ func (m *arModel) Offset(offset int) *arModel {
 // The parameter <page> 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.

+ 10 - 8
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
 		}

+ 7 - 9
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()

+ 10 - 2
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 = &gtoken.GfToken{
 		CacheMode:        g.Cfg().GetInt8("gToken.CacheMode"),
 		CacheKey:         g.Cfg().GetString("gToken.CacheKey"),

+ 2 - 1
config/config.toml

@@ -48,4 +48,5 @@ policyFile="./config/casbin_conf/rbac_policy.csv"
 
 #后台相关配置
 [adminInfo]
-pageNum = 5  #后台列表分页长度
+notCheckAuthAdminIds = [1,2]  #无需验证后台权限的用户id
+pageNum = 5  #后台列表分页长度

+ 1 - 1
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
 )
 

+ 3 - 12
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
-}

+ 64 - 1
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()
+}

+ 1 - 0
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))
 }

+ 1 - 3
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))
+
 }