mirror of
https://github.com/datarhei/core.git
synced 2025-10-13 03:34:05 +08:00
216 lines
5.6 KiB
Go
216 lines
5.6 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/casbin/casbin/v2"
|
|
"github.com/casbin/casbin/v2/model"
|
|
"github.com/gobwas/glob"
|
|
)
|
|
|
|
func main() {
|
|
var subject string
|
|
var domain string
|
|
var object string
|
|
var action string
|
|
|
|
flag.StringVar(&subject, "subject", "$anon", "subject of this request")
|
|
flag.StringVar(&domain, "domain", "$none", "domain of this request")
|
|
flag.StringVar(&object, "object", "", "object of this request")
|
|
flag.StringVar(&action, "action", "", "action of this request")
|
|
|
|
flag.Parse()
|
|
|
|
m := model.NewModel()
|
|
m.AddDef("r", "r", "sub, dom, obj, act")
|
|
m.AddDef("p", "p", "sub, dom, obj, act")
|
|
m.AddDef("g", "g", "_, _, _")
|
|
m.AddDef("e", "e", "some(where (p.eft == allow))")
|
|
m.AddDef("m", "m", `g(r.sub, p.sub, r.dom) && r.dom == p.dom && ResourceMatch(r.obj, r.dom, p.obj) && ActionMatch(r.act, p.act) || r.sub == "$superuser"`)
|
|
|
|
a := NewAdapter("./policy.json")
|
|
|
|
e, err := casbin.NewEnforcer(m, a)
|
|
if err != nil {
|
|
fmt.Printf("error: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
e.AddFunction("ResourceMatch", ResourceMatchFunc)
|
|
e.AddFunction("ActionMatch", ActionMatchFunc)
|
|
|
|
/*
|
|
if err := addGroup(e, "foobar"); err != nil {
|
|
fmt.Printf("error: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if err := addGroupUser(e, "foobar", "franz", "admin"); err != nil {
|
|
fmt.Printf("error: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if err := addGroupUser(e, "foobar", "$anon", "anonymous"); err != nil {
|
|
fmt.Printf("error: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
e.RemovePolicy("bob", "igelcamp", "processid:*", "COMMAND")
|
|
e.AddPolicy("bob", "igelcamp", "processid:bob-*", "COMMAND")
|
|
*/
|
|
ok, reason, err := e.EnforceEx(subject, domain, object, action)
|
|
if err != nil {
|
|
fmt.Printf("error: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if ok {
|
|
fmt.Printf("OK: %v\n", reason)
|
|
} else {
|
|
fmt.Printf("not OK\n")
|
|
}
|
|
}
|
|
|
|
func ResourceMatch(request, domain, policy string) bool {
|
|
reqPrefix, reqResource := getPrefix(request)
|
|
polPrefix, polResource := getPrefix(policy)
|
|
|
|
if reqPrefix != polPrefix {
|
|
return false
|
|
}
|
|
|
|
fmt.Printf("prefix: %s\n", reqPrefix)
|
|
fmt.Printf("requested resource: %s\n", reqResource)
|
|
fmt.Printf("requested domain: %s\n", domain)
|
|
fmt.Printf("policy resource: %s\n", polResource)
|
|
|
|
var match bool
|
|
var err error
|
|
|
|
if reqPrefix == "processid" {
|
|
match, err = Match(polResource, reqResource)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
} else if reqPrefix == "api" {
|
|
match, err = Match(polResource, reqResource, rune('/'))
|
|
if err != nil {
|
|
return false
|
|
}
|
|
} else if reqPrefix == "fs" {
|
|
match, err = Match(polResource, reqResource, rune('/'))
|
|
if err != nil {
|
|
return false
|
|
}
|
|
} else if reqPrefix == "rtmp" {
|
|
match, err = Match(polResource, reqResource)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
} else if reqPrefix == "srt" {
|
|
match, err = Match(polResource, reqResource)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
} else {
|
|
match, err = Match(polResource, reqResource)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
}
|
|
|
|
fmt.Printf("match: %v\n", match)
|
|
|
|
return match
|
|
}
|
|
|
|
func ResourceMatchFunc(args ...interface{}) (interface{}, error) {
|
|
name1 := args[0].(string)
|
|
name2 := args[1].(string)
|
|
name3 := args[2].(string)
|
|
|
|
return (bool)(ResourceMatch(name1, name2, name3)), nil
|
|
}
|
|
|
|
func ActionMatch(request string, policy string) bool {
|
|
request = strings.ToUpper(request)
|
|
actions := strings.Split(strings.ToUpper(policy), "|")
|
|
if len(actions) == 0 {
|
|
return false
|
|
}
|
|
|
|
for _, a := range actions {
|
|
if request == a {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func ActionMatchFunc(args ...interface{}) (interface{}, error) {
|
|
name1 := args[0].(string)
|
|
name2 := args[1].(string)
|
|
|
|
return (bool)(ActionMatch(name1, name2)), nil
|
|
}
|
|
|
|
func getPrefix(s string) (string, string) {
|
|
splits := strings.SplitN(s, ":", 2)
|
|
|
|
if len(splits) == 0 {
|
|
return "", ""
|
|
}
|
|
|
|
if len(splits) == 1 {
|
|
return "", splits[0]
|
|
}
|
|
|
|
return splits[0], splits[1]
|
|
}
|
|
|
|
func Match(pattern, name string, separators ...rune) (bool, error) {
|
|
g, err := glob.Compile(pattern, separators...)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return g.Match(name), nil
|
|
}
|
|
|
|
func addGroup(e *casbin.Enforcer, name string) error {
|
|
rules := [][]string{}
|
|
|
|
rules = append(rules, []string{"role:admin", name, "api:/process/**", "GET|POST|PUT|DELETE"})
|
|
rules = append(rules, []string{"role:admin", name, "processid:*", "CONFIG|PROGRESS|REPORT|METADATA|COMMAND"})
|
|
rules = append(rules, []string{"role:admin", name, "rtmp:" + name + "/*", "PUBLISH|PLAY"})
|
|
rules = append(rules, []string{"role:admin", name, "srt:" + name + "/*", "PUBLISH|PLAY"})
|
|
rules = append(rules, []string{"role:admin", name, "fs:/" + name + "/**", "GET|POST|PUT|DELETE"})
|
|
rules = append(rules, []string{"role:admin", name, "fs:/memfs/" + name + "/**", "GET|POST|PUT|DELETE"})
|
|
|
|
rules = append(rules, []string{"role:user", name, "api:/process/**", "GET"})
|
|
rules = append(rules, []string{"role:user", name, "processid:*", "PROGRESS"})
|
|
rules = append(rules, []string{"role:user", name, "rtmp:" + name + "/*", "PLAY"})
|
|
rules = append(rules, []string{"role:user", name, "srt:" + name + "/*", "PLAY"})
|
|
rules = append(rules, []string{"role:user", name, "fs:/" + name + "/**", "GET"})
|
|
rules = append(rules, []string{"role:user", name, "fs:/memfs/" + name + "/**", "GET"})
|
|
|
|
rules = append(rules, []string{"role:anonymous", name, "rtmp:" + name + "/*", "PLAY"})
|
|
rules = append(rules, []string{"role:anonymous", name, "srt:" + name + "/*", "PLAY"})
|
|
rules = append(rules, []string{"role:anonymous", name, "fs:/" + name + "/**", "GET"})
|
|
rules = append(rules, []string{"role:anonymous", name, "fs:/memfs/" + name + "/**", "GET"})
|
|
|
|
_, err := e.AddPolicies(rules)
|
|
|
|
return err
|
|
}
|
|
|
|
func addGroupUser(e *casbin.Enforcer, group, username, role string) error {
|
|
_, err := e.AddGroupingPolicy(username, "role:"+role, group)
|
|
|
|
return err
|
|
}
|