123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- package mycasbin
- import (
- "errors"
- "fmt"
- "github.com/casbin/casbin/v2"
- "github.com/casbin/casbin/v2/model"
- "github.com/casbin/casbin/v2/util"
- "gorm.io/gorm"
- "net/http"
- )
- // Model语法 https://casbin.org/docs/zh-CN/syntax-for-models
- // sub, obj, act 表示经典三元组: 访问实体 (Subject),访问资源 (Object) 和访问方法 (Action)。
- // sub:希望访问资源的用户
- // dom:域/域租户 https://casbin.org/docs/zh-CN/rbac-with-domains
- // obj:要访问的资源
- // act:用户对资源执行的操作
- var text = `
- [request_definition]
- r = sub, dom, obj, act
- [policy_definition]
- p = sub, dom, obj, act
- [role_definition]
- g = _, _, _
- [policy_effect]
- e = some(where (p.eft == allow))
- [matchers]
- m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && (keyMatch2(r.obj, p.obj) || keyMatch(r.obj, p.obj)) && r.act == p.act || r.sub == "role:admin"
- `
- // m = g(r.sub, p.sub, r.dom) && MyDomKeyMatch2(r.obj, p.obj, r.dom, p.dom) && MyRegexMatch(r.act, p.act, r.dom, p.dom) || r.sub == "role:admin")
- //m = r.sub == p.sub && (keyMatch2(r.obj, p.obj) || keyMatch(r.obj, p.obj)) && (r.act == p.act || p.act == "*")
- func Setup(db *gorm.DB) *casbin.SyncedEnforcer {
- Apter, err := NewAdapterByDB(db)
- if err != nil {
- panic(err)
- }
- m, err := model.NewModelFromString(text)
- if err != nil {
- panic(err)
- }
- e, err := casbin.NewSyncedEnforcer(m, Apter)
- if err != nil {
- panic(err)
- }
- err = e.LoadPolicy()
- if err != nil {
- panic(err)
- }
- //e.StartAutoLoadPolicy(time.Minute)
- //e.AddFunction("MyDomKeyMatch2", MyDomKeyMatch2Func)
- //e.AddFunction("MyRegexMatch", MyRegexMatchFunc)
- e.EnableLog(true)
- return e
- }
- // validate the variadic parameter size and type as string
- func validateVariadicArgs(expectedLen int, args ...interface{}) error {
- if len(args) != expectedLen {
- return fmt.Errorf("Expected %d arguments, but got %d", expectedLen, len(args))
- }
- for _, p := range args {
- _, ok := p.(string)
- if !ok {
- return errors.New("Argument must be a string")
- }
- }
- return nil
- }
- // MyDomKeyMatch2Func 定义域KeyMatch2
- func MyDomKeyMatch2Func(args ...interface{}) (interface{}, error) {
- if err := validateVariadicArgs(4, args...); err != nil {
- return false,fmt.Errorf("%s: %s", "keyMatch2", err)
- }
- name1 := args[0].(string)
- name2 := args[1].(string)
- dom1 := args[2].(string)
- dom2 := args[3].(string)
- return (bool)(dom1 == dom2 && util.KeyMatch2(name1, name2)),nil
- }
- // MyRegexMatchFunc 定义域RegexMatch
- func MyRegexMatchFunc(args ...interface{}) (interface{}, error) {
- if err := validateVariadicArgs(4, args...); err != nil {
- return false, fmt.Errorf("%s: %s", "RegexMatch", err)
- }
- name1 := args[0].(string)
- name2 := args[1].(string)
- dom1 := args[2].(string)
- dom2 := args[3].(string)
- return (bool)(dom1 == dom2 && util.RegexMatch(name1, name2)),nil
- }
- // EnforceRoute 验证web路由
- func EnforceRoute(roleKey, serviceID string, req *http.Request, enforcer casbin.IEnforcer) (bool, error) {
- sub := fmt.Sprintf("role:%s", roleKey) // 希望访问资源的用户
- dom := fmt.Sprintf("service:%s:api", serviceID) // 域/域租户,这里以资源为单位
- obj := req.URL.Path // 要访问的资源
- act := req.Method // 用户对资源执行的操作
- return enforcer.Enforce(sub, dom, obj, act)
- }
- // EnforceRouteForScopeCode 验证web路由
- func EnforceRouteForScopeCode(roleKey, serviceID string, req *http.Request, enforcer casbin.IEnforcer) (bool, error) {
- sub := fmt.Sprintf("scope:%s", roleKey) // 希望访问资源的用户
- dom := fmt.Sprintf("service:%s:api", serviceID) // 域/域租户,这里以资源为单位
- obj := req.URL.Path // 要访问的资源
- act := req.Method // 用户对资源执行的操作
- return enforcer.Enforce(sub, dom, obj, act)
- }
|