beego利用casbin进行权限管理——第一节 起步、测试

beego利用casbin进行权限管理——第二节 策略存储

beego利用casbin进行权限管理——第三节 策略查询

beego利用casbin进行权限管理——第四节 策略更新

beego利用casbin进行权限管理——第五节 策略更新(续)

EngineerCMS工程师知识(资料)管理系统github地址。该系统正是充分利用了casbin进行树状目录赋权。

上一节讲到存储策略。其实我犯了个错,应该用rbac_api.go中的现成的方法。如下2段代码替换上节。不过我没测试。

success = e.AddPolicy(v1, projurl, action, suf)
				//这里应该用AddPermissionForUser(),来自casbin\rbac_api.go
e.AddGroupingPolicy(uid, v1)
		//应该用AddRoleForUser()

这次结合bootstrap treeview来做一下角色的权限查询。

如下图,选中一个角色,选中一个权限,然后查出文件夹,并选中。很直观。


 

package controllers

import (
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/casbin/beego-orm-adapter"
	"github.com/casbin/casbin"
	_ "github.com/mattn/go-sqlite3"
	"path"
	"regexp"
	"strconv"
	"strings"
)

下面应该用casbin自己的方式查询,查询的是内存(map),应该避免采用直接数据库查询。比如management_api.go中的GetFilteredPolicy()方法,它还支持多字段查询:e.GetFilteredPolicy(1, projectid/*,"GET")——第一个参数是第一个字段的开始索引号,第二个字段及后续字段按次序排,不用索引。但是它这个字段是相等,或符合正则,如果规则是包含,而不是相等关系要专门写代码去查询数据库了,如下。另外,和getpermission方法一样,不支持继承推断。只有enforce支持用户,用户角色,角色的角色等推断。

//查询角色所具有的权限对应的项目目录
func (c *RoleController) GetRolePermission() {
	roleid := c.GetString("roleid") //角色id
	action := c.GetString("action")
	projectid := c.GetString("projectid")
	beego.Info(roleid)
	beego.Info(action)
	beego.Info(projectid)
	myRes := e.GetPermissionsForUser(roleid)
	beego.Info(myRes)
	// 	2018/01/03 21:42:15 [I] [roleControllers.go:543] [[1 /25001/* POST .*] [1 /25001
	// /* PUT .*] [1 /25001/* DELETE .*] [1 /25001/* GET .*] [1 /25001/25003/* GET (?i:
	// PDF)] [1 /25001/25002/25013/* GET (?i:PDF)] [1 /25001/25002/25012/* GET (?i:PDF)
	// ] [1 /25001/25002/25011/* GET (?i:PDF)] [1 /25001/* GET (?i:PDF)] [1 /25001/2500
	// 4/* POST .*]]

	var paths []beegoormadapter.CasbinRule//上面导入了这个包
	o := orm.NewOrm()
	qs := o.QueryTable("casbin_rule")
	_, err := qs.Filter("PType", "p").Filter("v0", roleid).Filter("v1__contains", projectid).Filter("v2", action).All(&paths)
	if err != nil {
		beego.Error(err)
	}
	// beego.Info(paths)
	var projids []string
	for _, v1 := range paths {
		projid := strings.Replace(v1.V1, "/*", "", -1)
		projids = append(projids, path.Base(projid))
	}
	//beego.Info(projids)
	c.Data["json"] = projids
	c.ServeJSON()
}

前端bootstrap treeview收到这个pathid后,将目录选中,连带下级联动,父级联动。

$.ajax({  //JQuery的Ajax  
            type: 'GET',    
            dataType : "json",//返回数据类型  
            // async:false, //同步会出现警告:Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience 
            url: "/admin/role/getpermission",//请求的action路径  
            data: {roleid:row.Id,action:action,projectid:projectid}, 
             //同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行  
            error: function () {//请求失败处理函数    
                alert('请求失败');    
            },  
            success:function(data){ //请求成功后处理函数。取到Json对象data
              // var findCheckableNodess = function() {
              //   return $('#tree').treeview('search', [ data, { ignoreCase: false, exactMatch: true } ]);//忽略大小写——这个只支持名称
              // };
              $('#tree').treeview('uncheckAll', { silent: true });
              for(var i=0;i<data.length;i++){
                // alert(data[i]);
                var findCheckableNodess = function() {
                  return $('#tree').treeview('findNodes', [data[i], 'id']);
                }; 
                var checkableNodes = findCheckableNodess();
                // $('#tree').treeview('checkNode', [ checkableNodes, { silent: true } ]);
                $('#tree').treeview('toggleNodeChecked', [ checkableNodes, { silent: true } ]);
              }
            }
          });

查询到了对应的目录后,就是修改了,将勾选的取消,将没勾选的勾选上,然后保存……要和map中的权限做对比,哪些是增加,哪些是删除。思路是直接删除map中的(remove方法),然后重新添加,避免了比对,简单粗暴,下节吧。

Logo

快速构建 Web 应用程序

更多推荐