feat: add basic enforcer manager (#2130)

* feat: add basic enforcer manager

* chore: generate swagger
This commit is contained in:
Yaodong Yu
2023-07-25 17:17:59 +08:00
committed by GitHub
parent d1f88ca9b8
commit 949feb18af
15 changed files with 1223 additions and 30 deletions

View File

@ -197,6 +197,11 @@ func (a *Adapter) createTable() {
panic(err)
}
err = a.Engine.Sync2(new(Enforcer))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Provider))
if err != nil {
panic(err)

View File

@ -100,6 +100,13 @@ func UpdateCasbinAdapter(id string, casbinAdapter *CasbinAdapter) (bool, error)
return false, err
}
if name != casbinAdapter.Name {
err := casbinAdapterChangeTrigger(name, casbinAdapter.Name)
if err != nil {
return false, err
}
}
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
if casbinAdapter.Password == "***" {
session.Omit("password")
@ -180,6 +187,26 @@ func initEnforcer(modelObj *Model, casbinAdapter *CasbinAdapter) (*casbin.Enforc
return enforcer, nil
}
func casbinAdapterChangeTrigger(oldName string, newName string) error {
session := adapter.Engine.NewSession()
defer session.Close()
err := session.Begin()
if err != nil {
return err
}
enforcer := new(Enforcer)
enforcer.Adapter = newName
_, err = session.Where("adapter=?", oldName).Update(enforcer)
if err != nil {
session.Rollback()
return err
}
return session.Commit()
}
func safeReturn(policy []string, i int) string {
if len(policy) > i {
return policy[i]

View File

@ -365,7 +365,7 @@ func CheckAccessPermission(userId string, application *Application) (bool, error
if containsAsterisk {
return true, err
}
enforcer := getEnforcer(permission)
enforcer := getPermissionEnforcer(permission)
if allowed, err = enforcer.Enforce(userId, application.Name, "read"); allowed {
return allowed, err
}

119
object/enforcer.go Normal file
View File

@ -0,0 +1,119 @@
// Copyright 2023 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 object
import (
"github.com/casbin/casbin/v2"
"github.com/casdoor/casdoor/util"
"github.com/xorm-io/core"
)
type Enforcer struct {
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
Name string `xorm:"varchar(100) notnull pk" json:"name"`
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
UpdatedTime string `xorm:"varchar(100) updated" json:"updatedTime"`
DisplayName string `xorm:"varchar(100)" json:"displayName"`
Description string `xorm:"varchar(100)" json:"description"`
Model string `xorm:"varchar(100)" json:"model"`
Adapter string `xorm:"varchar(100)" json:"adapter"`
IsEnabled bool `json:"isEnabled"`
*casbin.Enforcer
}
func GetEnforcerCount(owner, field, value string) (int64, error) {
session := GetSession(owner, -1, -1, field, value, "", "")
return session.Count(&Enforcer{})
}
func GetEnforcers(owner string) ([]*Enforcer, error) {
enforcers := []*Enforcer{}
err := adapter.Engine.Desc("created_time").Find(&enforcers, &Enforcer{Owner: owner})
if err != nil {
return enforcers, err
}
return enforcers, nil
}
func GetPaginationEnforcers(owner string, offset, limit int, field, value, sortField, sortOrder string) ([]*Enforcer, error) {
enforcers := []*Enforcer{}
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
err := session.Find(&enforcers)
if err != nil {
return enforcers, err
}
return enforcers, nil
}
func getEnforcer(owner string, name string) (*Enforcer, error) {
if owner == "" || name == "" {
return nil, nil
}
enforcer := Enforcer{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&enforcer)
if err != nil {
return &enforcer, err
}
if existed {
return &enforcer, nil
} else {
return nil, nil
}
}
func GetEnforcer(id string) (*Enforcer, error) {
owner, name := util.GetOwnerAndNameFromId(id)
return getEnforcer(owner, name)
}
func UpdateEnforcer(id string, enforcer *Enforcer) (bool, error) {
owner, name := util.GetOwnerAndNameFromId(id)
if oldEnforcer, err := getEnforcer(owner, name); err != nil {
return false, err
} else if oldEnforcer == nil {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(enforcer)
if err != nil {
return false, err
}
return affected != 0, nil
}
func AddEnforcer(enforcer *Enforcer) (bool, error) {
affected, err := adapter.Engine.Insert(enforcer)
if err != nil {
return false, err
}
return affected != 0, nil
}
func DeleteEnforcer(enforcer *Enforcer) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{enforcer.Owner, enforcer.Name}).Delete(&Enforcer{})
if err != nil {
return false, err
}
return affected != 0, nil
}

View File

@ -154,6 +154,15 @@ func modelChangeTrigger(oldName string, newName string) error {
permission.Model = newName
_, err = session.Where("model=?", oldName).Update(permission)
if err != nil {
session.Rollback()
return err
}
enforcer := new(Enforcer)
enforcer.Model = newName
_, err = session.Where("model=?", oldName).Update(enforcer)
if err != nil {
session.Rollback()
return err
}

View File

@ -118,7 +118,7 @@ func GetPermission(id string) (*Permission, error) {
// checkPermissionValid verifies if the permission is valid
func checkPermissionValid(permission *Permission) error {
enforcer := getEnforcer(permission)
enforcer := getPermissionEnforcer(permission)
enforcer.EnableAutoSave(false)
policies := getPolicies(permission)

View File

@ -26,7 +26,7 @@ import (
xormadapter "github.com/casdoor/xorm-adapter/v3"
)
func getEnforcer(p *Permission, permissionIDs ...string) *casbin.Enforcer {
func getPermissionEnforcer(p *Permission, permissionIDs ...string) *casbin.Enforcer {
// Init an enforcer instance without specifying a model or adapter.
// If you specify an adapter, it will load all policies, which is a
// heavy process that can slow down the application.
@ -204,7 +204,7 @@ func getGroupingPolicies(permission *Permission) [][]string {
}
func addPolicies(permission *Permission) {
enforcer := getEnforcer(permission)
enforcer := getPermissionEnforcer(permission)
policies := getPolicies(permission)
_, err := enforcer.AddPolicies(policies)
@ -214,7 +214,7 @@ func addPolicies(permission *Permission) {
}
func addGroupingPolicies(permission *Permission) {
enforcer := getEnforcer(permission)
enforcer := getPermissionEnforcer(permission)
groupingPolicies := getGroupingPolicies(permission)
if len(groupingPolicies) > 0 {
@ -226,7 +226,7 @@ func addGroupingPolicies(permission *Permission) {
}
func removeGroupingPolicies(permission *Permission) {
enforcer := getEnforcer(permission)
enforcer := getPermissionEnforcer(permission)
groupingPolicies := getGroupingPolicies(permission)
if len(groupingPolicies) > 0 {
@ -238,7 +238,7 @@ func removeGroupingPolicies(permission *Permission) {
}
func removePolicies(permission *Permission) {
enforcer := getEnforcer(permission)
enforcer := getPermissionEnforcer(permission)
policies := getPolicies(permission)
_, err := enforcer.RemovePolicies(policies)
@ -250,12 +250,12 @@ func removePolicies(permission *Permission) {
type CasbinRequest = []interface{}
func Enforce(permission *Permission, request *CasbinRequest, permissionIds ...string) (bool, error) {
enforcer := getEnforcer(permission, permissionIds...)
enforcer := getPermissionEnforcer(permission, permissionIds...)
return enforcer.Enforce(*request...)
}
func BatchEnforce(permission *Permission, requests *[]CasbinRequest, permissionIds ...string) ([]bool, error) {
enforcer := getEnforcer(permission, permissionIds...)
enforcer := getPermissionEnforcer(permission, permissionIds...)
return enforcer.BatchEnforce(*requests)
}
@ -276,7 +276,7 @@ func getAllValues(userId string, fn func(enforcer *casbin.Enforcer) []string) []
var values []string
for _, permission := range permissions {
enforcer := getEnforcer(permission)
enforcer := getPermissionEnforcer(permission)
values = append(values, fn(enforcer)...)
}
return values