diff --git a/controllers/enforcer.go b/controllers/enforcer.go new file mode 100644 index 00000000..47d38001 --- /dev/null +++ b/controllers/enforcer.go @@ -0,0 +1,88 @@ +// Copyright 2022 The Casdoor Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package controllers + +import ( + "encoding/json" + + "github.com/casdoor/casdoor/object" +) + +func (c *ApiController) Enforce() { + userId := c.GetSessionUsername() + if userId == "" { + c.ResponseError("Please sign in first") + return + } + + var permissionRule object.PermissionRule + err := json.Unmarshal(c.Ctx.Input.RequestBody, &permissionRule) + if err != nil { + panic(err) + } + + c.Data["json"] = object.Enforce(userId, &permissionRule) + c.ServeJSON() +} + +func (c *ApiController) BatchEnforce() { + userId := c.GetSessionUsername() + if userId == "" { + c.ResponseError("Please sign in first") + return + } + + var permissionRules []object.PermissionRule + err := json.Unmarshal(c.Ctx.Input.RequestBody, &permissionRules) + if err != nil { + panic(err) + } + + c.Data["json"] = object.BatchEnforce(userId, permissionRules) + c.ServeJSON() +} + +func (c *ApiController) GetAllObjects() { + userId := c.GetSessionUsername() + if userId == "" { + c.ResponseError("Please sign in first") + return + } + + c.Data["json"] = object.GetAllObjects(userId) + c.ServeJSON() +} + +func (c *ApiController) GetAllActions() { + userId := c.GetSessionUsername() + if userId == "" { + c.ResponseError("Please sign in first") + return + } + + c.Data["json"] = object.GetAllActions(userId) + c.ServeJSON() +} + +func (c *ApiController) GetAllRoles() { + userId := c.GetSessionUsername() + if userId == "" { + c.ResponseError("Please sign in first") + return + } + + c.Data["json"] = object.GetAllRoles(userId) + c.ServeJSON() +} diff --git a/object/permission.go b/object/permission.go index bcb26a35..56205181 100644 --- a/object/permission.go +++ b/object/permission.go @@ -45,13 +45,13 @@ type Permission struct { } type PermissionRule struct { - PType string `xorm:"varchar(100) index not null default ''"` - V0 string `xorm:"varchar(100) index not null default ''"` - V1 string `xorm:"varchar(100) index not null default ''"` - V2 string `xorm:"varchar(100) index not null default ''"` - V3 string `xorm:"varchar(100) index not null default ''"` - V4 string `xorm:"varchar(100) index not null default ''"` - V5 string `xorm:"varchar(100) index not null default ''"` + Ptype string `xorm:"varchar(100) index not null default ''" json:"ptype"` + V0 string `xorm:"varchar(100) index not null default ''" json:"v0"` + V1 string `xorm:"varchar(100) index not null default ''" json:"v1"` + V2 string `xorm:"varchar(100) index not null default ''" json:"v2"` + V3 string `xorm:"varchar(100) index not null default ''" json:"v3"` + V4 string `xorm:"varchar(100) index not null default ''" json:"v4"` + V5 string `xorm:"varchar(100) index not null default ''" json:"v5"` } func GetPermissionCount(owner, field, value string) int { @@ -208,6 +208,13 @@ func getPolicies(permission *Permission) [][]string { } } } + for _, role := range permission.Roles { + for _, resource := range permission.Resources { + for _, action := range permission.Actions { + policies = append(policies, []string{permission.GetId(), role, resource, strings.ToLower(action)}) + } + } + } return policies } @@ -239,3 +246,62 @@ func GetPermissionsByUser(userId string) []*Permission { return permissions } + +func Enforce(userId string, permissionRule *PermissionRule) bool { + permission := GetPermission(permissionRule.V0) + enforcer := getEnforcer(permission) + allow, err := enforcer.Enforce(userId, permissionRule.V2, permissionRule.V3) + if err != nil { + panic(err) + } + return allow +} + +func BatchEnforce(userId string, permissionRules []PermissionRule) []bool { + var requests [][]interface{} + for _, permissionRule := range permissionRules { + requests = append(requests, []interface{}{userId, permissionRule.V2, permissionRule.V3}) + } + permission := GetPermission(permissionRules[0].V0) + enforcer := getEnforcer(permission) + allow, err := enforcer.BatchEnforce(requests) + if err != nil { + panic(err) + } + return allow +} + +func getAllValues(userId string, sec string, fieldIndex int) []string { + permissions := GetPermissionsByUser(userId) + var values []string + for _, permission := range permissions { + enforcer := getEnforcer(permission) + enforcer.ClearPolicy() + err := enforcer.LoadFilteredPolicy(xormadapter.Filter{V0: []string{permission.GetId()}, V1: []string{userId}}) + if err != nil { + return nil + } + + for _, value := range enforcer.GetModel().GetValuesForFieldInPolicyAllTypes(sec, fieldIndex) { + values = append(values, value) + } + } + return values +} + +func GetAllObjects(userId string) []string { + return getAllValues(userId, "p", 2) +} + +func GetAllActions(userId string) []string { + return getAllValues(userId, "p", 3) +} + +func GetAllRoles(userId string) []string { + roles := GetRolesByUser(userId) + var res []string + for _, role := range roles { + res = append(res, role.Name) + } + return res +} diff --git a/routers/router.go b/routers/router.go index 543ac1e0..ca59fabe 100644 --- a/routers/router.go +++ b/routers/router.go @@ -83,6 +83,12 @@ func initAPI() { beego.Router("/api/add-permission", &controllers.ApiController{}, "POST:AddPermission") beego.Router("/api/delete-permission", &controllers.ApiController{}, "POST:DeletePermission") + beego.Router("/api/enforce", &controllers.ApiController{}, "POST:Enforce") + beego.Router("/api/batch-enforce", &controllers.ApiController{}, "POST:BatchEnforce") + beego.Router("/api/get-all-objects", &controllers.ApiController{}, "GET:GetAllObjects") + beego.Router("/api/get-all-actions", &controllers.ApiController{}, "GET:GetAllActions") + beego.Router("/api/get-all-roles", &controllers.ApiController{}, "GET:GetAllRoles") + beego.Router("/api/get-models", &controllers.ApiController{}, "GET:GetModels") beego.Router("/api/get-model", &controllers.ApiController{}, "GET:GetModel") beego.Router("/api/update-model", &controllers.ApiController{}, "POST:UpdateModel")