mirror of
https://github.com/casdoor/casdoor.git
synced 2025-09-08 12:11:03 +08:00
feat: fix compatibility issue between Casbin request and model (#1478)
This commit is contained in:
@@ -68,14 +68,14 @@ func getModel(owner string, name string) *Model {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
model := Model{Owner: owner, Name: name}
|
m := Model{Owner: owner, Name: name}
|
||||||
existed, err := adapter.Engine.Get(&model)
|
existed, err := adapter.Engine.Get(&m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if existed {
|
if existed {
|
||||||
return &model
|
return &m
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -57,6 +57,40 @@ type PermissionRule struct {
|
|||||||
Id string `xorm:"varchar(100) index not null default ''" json:"id"`
|
Id string `xorm:"varchar(100) index not null default ''" json:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
builtInAvailableField = 5 // Casdoor built-in adapter, use V5 to filter permission, so has 5 available field
|
||||||
|
builtInAdapter = "permission_rule"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *Permission) GetId() string {
|
||||||
|
return util.GetId(p.Owner, p.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PermissionRule) GetRequest(adapterName string, permissionId string) ([]interface{}, error) {
|
||||||
|
request := []interface{}{p.V0, p.V1, p.V2}
|
||||||
|
|
||||||
|
if p.V3 != "" {
|
||||||
|
request = append(request, p.V3)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.V4 != "" {
|
||||||
|
request = append(request, p.V4)
|
||||||
|
}
|
||||||
|
|
||||||
|
if adapterName == builtInAdapter {
|
||||||
|
if p.V5 != "" {
|
||||||
|
return nil, fmt.Errorf("too many parameters. The maximum parameter number cannot exceed %d", builtInAvailableField)
|
||||||
|
}
|
||||||
|
request = append(request, permissionId)
|
||||||
|
return request, nil
|
||||||
|
} else {
|
||||||
|
if p.V5 != "" {
|
||||||
|
request = append(request, p.V5)
|
||||||
|
}
|
||||||
|
return request, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func GetPermissionCount(owner, field, value string) int {
|
func GetPermissionCount(owner, field, value string) int {
|
||||||
session := GetSession(owner, -1, -1, field, value, "", "")
|
session := GetSession(owner, -1, -1, field, value, "", "")
|
||||||
count, err := session.Count(&Permission{})
|
count, err := session.Count(&Permission{})
|
||||||
@@ -195,10 +229,6 @@ func DeletePermission(permission *Permission) bool {
|
|||||||
return affected != 0
|
return affected != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (permission *Permission) GetId() string {
|
|
||||||
return fmt.Sprintf("%s/%s", permission.Owner, permission.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetPermissionsByUser(userId string) []*Permission {
|
func GetPermissionsByUser(userId string) []*Permission {
|
||||||
permissions := []*Permission{}
|
permissions := []*Permission{}
|
||||||
err := adapter.Engine.Where("users like ?", "%"+userId+"%").Find(&permissions)
|
err := adapter.Engine.Where("users like ?", "%"+userId+"%").Find(&permissions)
|
||||||
|
@@ -15,9 +15,11 @@
|
|||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/casbin/casbin/v2"
|
"github.com/casbin/casbin/v2"
|
||||||
|
"github.com/casbin/casbin/v2/config"
|
||||||
"github.com/casbin/casbin/v2/model"
|
"github.com/casbin/casbin/v2/model"
|
||||||
xormadapter "github.com/casbin/xorm-adapter/v3"
|
xormadapter "github.com/casbin/xorm-adapter/v3"
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
@@ -36,26 +38,14 @@ func getEnforcer(permission *Permission) *casbin.Enforcer {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
modelText := `
|
|
||||||
[request_definition]
|
|
||||||
r = sub, obj, act
|
|
||||||
|
|
||||||
[policy_definition]
|
|
||||||
p = sub, obj, act, "", "", permissionId
|
|
||||||
|
|
||||||
[role_definition]
|
|
||||||
g = _, _
|
|
||||||
|
|
||||||
[policy_effect]
|
|
||||||
e = some(where (p.eft == allow))
|
|
||||||
|
|
||||||
[matchers]
|
|
||||||
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act`
|
|
||||||
permissionModel := getModel(permission.Owner, permission.Model)
|
permissionModel := getModel(permission.Owner, permission.Model)
|
||||||
|
m := model.Model{}
|
||||||
if permissionModel != nil {
|
if permissionModel != nil {
|
||||||
modelText = permissionModel.ModelText
|
m, err = GetBuiltInModel(permissionModel.ModelText)
|
||||||
|
} else {
|
||||||
|
m, err = GetBuiltInModel("")
|
||||||
}
|
}
|
||||||
m, err := model.NewModelFromString(modelText)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -66,16 +56,19 @@ m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act`
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load Policy with a specific Permission
|
// load Policy with a specific Permission
|
||||||
enforcer.LoadFilteredPolicy(xormadapter.Filter{
|
err = enforcer.LoadFilteredPolicy(xormadapter.Filter{
|
||||||
V5: []string{permission.Owner + "/" + permission.Name},
|
V5: []string{permission.GetId()},
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
return enforcer
|
return enforcer
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPolicies(permission *Permission) ([][]string, [][]string) {
|
func getPolicies(permission *Permission) ([][]string, [][]string) {
|
||||||
var policies [][]string
|
var policies [][]string
|
||||||
var groupingPolicies [][]string
|
var groupingPolicies [][]string
|
||||||
permissionId := permission.Owner + "/" + permission.Name
|
permissionId := permission.GetId()
|
||||||
domainExist := len(permission.Domains) > 0
|
domainExist := len(permission.Domains) > 0
|
||||||
for _, user := range permission.Users {
|
for _, user := range permission.Users {
|
||||||
for _, resource := range permission.Resources {
|
for _, resource := range permission.Resources {
|
||||||
@@ -163,10 +156,8 @@ func Enforce(permissionRule *PermissionRule) bool {
|
|||||||
permission := GetPermission(permissionRule.Id)
|
permission := GetPermission(permissionRule.Id)
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getEnforcer(permission)
|
||||||
|
|
||||||
request := []interface{}{permissionRule.V0, permissionRule.V1, permissionRule.V2}
|
request, _ := permissionRule.GetRequest(builtInAdapter, permissionRule.Id)
|
||||||
if permissionRule.V3 != "" {
|
|
||||||
request = append(request, permissionRule.V3)
|
|
||||||
}
|
|
||||||
allow, err := enforcer.Enforce(request...)
|
allow, err := enforcer.Enforce(request...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -177,11 +168,8 @@ func Enforce(permissionRule *PermissionRule) bool {
|
|||||||
func BatchEnforce(permissionRules []PermissionRule) []bool {
|
func BatchEnforce(permissionRules []PermissionRule) []bool {
|
||||||
var requests [][]interface{}
|
var requests [][]interface{}
|
||||||
for _, permissionRule := range permissionRules {
|
for _, permissionRule := range permissionRules {
|
||||||
if permissionRule.V3 != "" {
|
request, _ := permissionRule.GetRequest(builtInAdapter, permissionRule.Id)
|
||||||
requests = append(requests, []interface{}{permissionRule.V0, permissionRule.V1, permissionRule.V2, permissionRule.V3})
|
requests = append(requests, request)
|
||||||
} else {
|
|
||||||
requests = append(requests, []interface{}{permissionRule.V0, permissionRule.V1, permissionRule.V2})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
permission := GetPermission(permissionRules[0].Id)
|
permission := GetPermission(permissionRules[0].Id)
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getEnforcer(permission)
|
||||||
@@ -226,3 +214,46 @@ func GetAllRoles(userId string) []string {
|
|||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetBuiltInModel(modelText string) (model.Model, error) {
|
||||||
|
if modelText == "" {
|
||||||
|
modelText = `
|
||||||
|
[request_definition]
|
||||||
|
r = sub, obj, act
|
||||||
|
|
||||||
|
[policy_definition]
|
||||||
|
p = sub, obj, act, "", "", permissionId
|
||||||
|
|
||||||
|
[role_definition]
|
||||||
|
g = _, _
|
||||||
|
|
||||||
|
[policy_effect]
|
||||||
|
e = some(where (p.eft == allow))
|
||||||
|
|
||||||
|
[matchers]
|
||||||
|
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act`
|
||||||
|
return model.NewModelFromString(modelText)
|
||||||
|
} else {
|
||||||
|
cfg, err := config.NewConfigFromText(modelText)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// load [policy_definition]
|
||||||
|
policyDefinition := strings.Split(cfg.String("policy_definition::p"), ",")
|
||||||
|
fieldsNum := len(policyDefinition)
|
||||||
|
if fieldsNum > builtInAvailableField {
|
||||||
|
panic(fmt.Errorf("the maximum policy_definition field number cannot exceed %d", builtInAvailableField))
|
||||||
|
}
|
||||||
|
// filled empty field with "" and V5 with "permissionId"
|
||||||
|
for i := builtInAvailableField - fieldsNum; i > 0; i-- {
|
||||||
|
policyDefinition = append(policyDefinition, "")
|
||||||
|
}
|
||||||
|
policyDefinition = append(policyDefinition, "permissionId")
|
||||||
|
|
||||||
|
m, _ := model.NewModelFromString(modelText)
|
||||||
|
m.AddDef("p", "p", strings.Join(policyDefinition, ","))
|
||||||
|
|
||||||
|
return m, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user