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

128 篇文章 0 订阅
72 篇文章 0 订阅

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

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

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

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

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

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

经过最后的冲刺,完成了EngineerCMS的权限管理:树状目录的赋权、修改和查看。

效果:

像在第三节中说的,赋权还是用单选吧,多选是方便了赋权,但是查询就很难结合了,比如多选几个角色,在树状目录中就无法反应权限了。

转入正题,树状目录的权限修改服务端:

//给角色赋项目目录的权限
//先删除角色对于这个项目的所有权限
func (c *RoleController) RolePermission() {
	roleids := c.GetString("roleids")
	rolearray := strings.Split(roleids, ",")
	// beego.Info(rolearray)
	permissionids := c.GetString("permissionids")
	permissionarray := strings.Split(permissionids, ",")
	// beego.Info(permissionarray)
	sufids := c.GetString("sufids")
	sufarray := strings.Split(sufids, ",")

	treeids := c.GetString("treeids") //项目目录id,25001,25002
	treearray := strings.Split(treeids, ",")
	// beego.Info(treearray)
	treenodeids := c.GetString("treenodeids") //项目目录的nodeid 0.0.0-0.0.1-0.1.0-0.1.0
	treenodearray := strings.Split(treenodeids, ",")
	projectid := c.GetString("projid")


	var success bool
	var nodeidint int
	var projurl, action, suf1, suf string
	var err error
	//取出项目目录的顶级
	var nodesid, nodesids []string
	// beego.Info(len(treenodearray))
	if len(treenodearray) > 1 {
		nodesids, err = highest(treenodearray, nodesid, 0)
		if err != nil {
			beego.Error(err)
		}
	} else {
		nodesids = []string{"0"} //append(nodesids, "0")
	}
	// beego.Info(nodesids)

	//删除这些角色、项目id的全部权限
	for _, v1 := range rolearray {
		// var paths []beegoormadapter.CasbinRule
		o := orm.NewOrm()
		qs := o.QueryTable("casbin_rule")
		_, err := qs.Filter("PType", "p").Filter("v0", "role_"+v1).Filter("v1__contains", "/"+projectid+"/").Delete()
		if err != nil {
			beego.Error(err)
		}
	}
	// e.RemoveFilteredPolicy(1, "/onlyoffice/"+strconv.FormatInt(attachments[0].Id, 10))
e.LoadPolicy() //重载权限
for _, v1 := range rolearray {for _, v2 := range permissionarray {//定义读取、添加、修改、删除
switch v2 {
case "添加成果":
action = "POST"
suf = ".*"
case "编辑成果":
action = "PUT"
suf = ".*"
case "删除成果":
action = "DELETE"
suf = ".*"
case "读取成果":
action = "GET"
for i, v4 := range sufarray {
if v4 == "任意" {
suf = ".*"break} 
else if v4 == "" { //用户没展开则读取不到table4的select
suf = "(?i:pdf)"
break
} else {
suf1 = "(?i:" + v4 + ")"
if i == 0 {
suf = suf1
} else {
suf = suf + "," + suf1
}
}
}
}
for _, v3 := range nodesids {
nodeidint, err = strconv.Atoi(v3)
if err != nil {
beego.Error(err)
}
//id转成64位
pidNum, err := strconv.ParseInt(treearray[nodeidint], 10, 64)
if err != nil {
beego.Error(err)
}
//根据projid取出路径
proj, err := m.GetProj(pidNum)
if err != nil {
beego.Error(err)
}
if proj.ParentIdPath == "" {
projurl = "/" + strconv.FormatInt(proj.Id, 10) + "/*"
} else {
projurl = "/" + strings.Replace(proj.ParentIdPath, "-", "/", -1) + "/" + treearray[nodeidint] + "/*"
}
beego.Info(v1)
sufarray := strings.Split(suf, ",")
for _, v5 := range sufarray {
success = e.AddPolicy("role_"+v1, projurl, action, v5) //来自casbin\management_api.go
//这里应该用AddPermissionForUser(),来自casbin\rbac_api.go
}
}
}
}if success == true {
c.Data["json"] = "ok"
} else {
c.Data["json"] = "wrong"}c.ServeJSON()
}

这里两点:一是数据库中树状目录的特点:

角色对于树状目录每一级下的对应扩展名的资源有读、写等权限,稍显复杂了点,但对于casbin不算啥。但是,要自己写删除语句_, err := qs.Filter("PType", "p").Filter("v0", "role_"+v1).Filter("v1__contains", "/"+projectid+"/").Delete()

用不了casbin的方法。

第二点,用自己的方法删除数据库后,必须用e.LoadPolicy() //重载权限,就是将数据库数据读入内存。因为只是删除了数据库,内存中的没有删除。然后才用casbin的方法添加新的数据,此时是添加到了内存,同时也添加到了数据库(问题:用casbin方法添加数据后,它内部是不是已经重载了数据库数据??答案是它内部没有loadpolicy)

其实,前端蛮难的,有几点。

1.bootstrap table多组表格的单选按钮问题。要每组定义成不同的select-item-name

<table id="table"
        data-url="/admin/role/get/"
        data-toggle="table"
        data-striped="true"
        data-toolbar="#toolbar1"
        data-show-refresh="true"
        data-show-toggle="true"
        data-show-columns="true"
        data-side-pagination="client"
        data-pagination="true"
        data-click-to-select="true"
        data-page-size="5"
        data-page-list="[5, 25, 50, All]"
        data-search="false"
        data-select-item-name="role"
        >

2.本文第一张图中的表格内嵌套表格

/*数据json,"PDF":"","DWG":"","DOC":"","XLS":""*/
    // 权限表
    var json =  [{"Id":"1","Title":"添加成果","Action":"POST"},
                {"Id":"2","Title":"编辑成果","Action":"PUT"},
                {"Id":"3","Title":"删除成果","Action":"DELETE"},
                {"Id":"4","Title":"读取成果","Action":"GET"}];
    var json1 = [{"Id":"5","Title":"任意","checked":true},
                {"Id":"6","Title":"PDF"},
                {"Id":"7","Title":"DWG"},
                {"Id":"8","Title":"DOC"},
                {"Id":"9","Title":"XLS"},
                {"Id":"10","Title":"DGN"}];              
    /*初始化table数据*/
    $(function(){
      $("#table3").bootstrapTable({
              data:json,
              // onClickRow: function (row, $element) {
                // alert( "选择了行Id为: " + row.Id );
                // rowid=row.Id//全局变量
                // $('#table1').bootstrapTable('refresh', {url:'/admincategory?pid='+row.Id});
              // }
              // onExpandRow: function (index, row, $Subdetail) {
              //   oInit.InitSubTable(index, row, $Subdetail);
              // }
              onExpandRow: function (index, row, $detail) {
                expandTable(index, row,$detail);
              }
      });
    });
    function expandTable(index, row,$detail) {
        var cur_table = $detail.html('<table id="table4"></table>').find('table');
        if (index==3){
          $(cur_table).bootstrapTable({
            columns: [{
                  checkbox: true,
                  formatter: "stateFormatter"
              }, {
                  field: 'Title',
                  title: '文件扩展名'
              }],
            data:json1,
          })
        }
    }

3.嵌套表格中任意一行选择后,其他不可选

//文件扩展名选择
    $(function(){
      $("#table3").on("uncheck.bs.table",function(e,row,ele){
            if (row.Id=="5"){
              // for (var i=6;i<=10;i++){
                  // $('#table4').bootstrapTable('check',"1");
                  $('#table4 input').removeAttr("disabled"); //取消选择‘任意”后,其他变得可选
              // }
            }
        })
      $("#table3").on("check.bs.table",function(e,row,ele){
            if (row.Id=="5"){
              // for (var i=6;i<=10;i++){
                  // $('#table4').bootstrapTable('uncheckAll');
                  $('#table4 input').attr("disabled", true);//重新选择“任意”后,其他又变得不可选
                  $('[data-index="0"]').removeAttr("disabled");
                  $('#table4').bootstrapTable('check',"0");

              // }
            }
        })
    })

    function stateFormatter(value, row, index) {
      if (row.Id =="5") {
          return {
              // disabled: true,
              checked: true
          }
      }else{
        return {
              disabled: true
              // checked: true
          }
      }
      if (row.checked === true) {
          return {
              checked: true
          }
      }
      return value;
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值