💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、豆包、星火、月之暗面及文生图、文生视频 广告
File: experimental-handlers/casbin/middleware/casbinmodel.conf ~~~ [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [role_definition] g = _, _ [policy_effect] e = some(where (p.eft == allow)) [matchers] m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*") File: experimental-handlers/casbin/middleware/casbinpolicy.csv p, alice, /dataset1/*, GET p, alice, /dataset1/resource1, POST p, bob, /dataset2/resource1, * p, bob, /dataset2/resource2, GET p, bob, /dataset2/folder1/*, POST ~~~ File: experimental-handlers/casbin/middleware/main.go ~~~ package main import ( "github.com/kataras/iris" "github.com/casbin/casbin" cm "github.com/iris-contrib/middleware/casbin" ) // $ go get github.com/casbin/casbin // $ go run main.go // Enforcer maps the model and the policy for the casbin service, we use this variable on the main_test too. var Enforcer = casbin.NewEnforcer("casbinmodel.conf", "casbinpolicy.csv") func newApp() *iris.Application { casbinMiddleware := cm.New(Enforcer) app := iris.New() app.Use(casbinMiddleware.ServeHTTP) app.Get("/", hi) app.Get("/dataset1/{p:path}", hi) // p, alice, /dataset1/*, GET app.Post("/dataset1/resource1", hi) app.Get("/dataset2/resource2", hi) app.Post("/dataset2/folder1/{p:path}", hi) app.Any("/dataset2/resource1", hi) return app } func main() { app := newApp() app.Run(iris.Addr(":8080")) } func hi(ctx iris.Context) { ctx.Writef("Hello %s", cm.Username(ctx.Request())) } ~~~ File: experimental-handlers/casbin/middleware/main_test.go ~~~ package main import ( "testing" "github.com/iris-contrib/httpexpect" "github.com/kataras/iris/httptest" ) func TestCasbinMiddleware(t *testing.T) { app := newApp() e := httptest.New(t, app, httptest.Debug(false)) type ttcasbin struct { username string path string method string status int } tt := []ttcasbin{ {"alice", "/dataset1/resource1", "GET", 200}, {"alice", "/dataset1/resource1", "POST", 200}, {"alice", "/dataset1/resource2", "GET", 200}, {"alice", "/dataset1/resource2", "POST", 404}, {"bob", "/dataset2/resource1", "GET", 200}, {"bob", "/dataset2/resource1", "POST", 200}, {"bob", "/dataset2/resource1", "DELETE", 200}, {"bob", "/dataset2/resource2", "GET", 200}, {"bob", "/dataset2/resource2", "POST", 404}, {"bob", "/dataset2/resource2", "DELETE", 404}, {"bob", "/dataset2/folder1/item1", "GET", 404}, {"bob", "/dataset2/folder1/item1", "POST", 200}, {"bob", "/dataset2/folder1/item1", "DELETE", 404}, {"bob", "/dataset2/folder1/item2", "GET", 404}, {"bob", "/dataset2/folder1/item2", "POST", 200}, {"bob", "/dataset2/folder1/item2", "DELETE", 404}, } for _, tt := range tt { check(e, tt.method, tt.path, tt.username, tt.status) } } func check(e *httpexpect.Expect, method, path, username string, status int) { e.Request(method, path).WithBasicAuth(username, "password").Expect().Status(status) } File: experimental-handlers/casbin/wrapper/casbinmodel.conf [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [role_definition] g = _, _ [policy_effect] e = some(where (p.eft == allow)) [matchers] m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*") File: experimental-handlers/casbin/wrapper/casbinpolicy.csv p, alice, /dataset1/*, GET p, alice, /dataset1/resource1, POST p, bob, /dataset2/resource1, * p, bob, /dataset2/resource2, GET p, bob, /dataset2/folder1/*, POST p, dataset1_admin, /dataset1/*, * g, cathrin, dataset1_admin ~~~ File: experimental-handlers/casbin/wrapper/main.go ~~~ package main import ( "github.com/kataras/iris" "github.com/casbin/casbin" cm "github.com/iris-contrib/middleware/casbin" ) // $ go get github.com/casbin/casbin // $ go run main.go // Enforcer maps the model and the policy for the casbin service, we use this variable on the main_test too. var Enforcer = casbin.NewEnforcer("casbinmodel.conf", "casbinpolicy.csv") func newApp() *iris.Application { casbinMiddleware := cm.New(Enforcer) app := iris.New() app.WrapRouter(casbinMiddleware.Wrapper()) app.Get("/", hi) app.Any("/dataset1/{p:path}", hi) // p, dataset1_admin, /dataset1/*, * && p, alice, /dataset1/*, GET app.Post("/dataset1/resource1", hi) app.Get("/dataset2/resource2", hi) app.Post("/dataset2/folder1/{p:path}", hi) app.Any("/dataset2/resource1", hi) return app } func main() { app := newApp() app.Run(iris.Addr(":8080")) } func hi(ctx iris.Context) { ctx.Writef("Hello %s", cm.Username(ctx.Request())) } ~~~ File: experimental-handlers/casbin/wrapper/main_test.go ~~~ package main import ( "testing" "github.com/iris-contrib/httpexpect" "github.com/kataras/iris/httptest" ) func TestCasbinWrapper(t *testing.T) { app := newApp() e := httptest.New(t, app) type ttcasbin struct { username string path string method string status int } tt := []ttcasbin{ {"alice", "/dataset1/resource1", "GET", 200}, {"alice", "/dataset1/resource1", "POST", 200}, {"alice", "/dataset1/resource2", "GET", 200}, {"alice", "/dataset1/resource2", "POST", 403}, {"bob", "/dataset2/resource1", "GET", 200}, {"bob", "/dataset2/resource1", "POST", 200}, {"bob", "/dataset2/resource1", "DELETE", 200}, {"bob", "/dataset2/resource2", "GET", 200}, {"bob", "/dataset2/resource2", "POST", 403}, {"bob", "/dataset2/resource2", "DELETE", 403}, {"bob", "/dataset2/folder1/item1", "GET", 403}, {"bob", "/dataset2/folder1/item1", "POST", 200}, {"bob", "/dataset2/folder1/item1", "DELETE", 403}, {"bob", "/dataset2/folder1/item2", "GET", 403}, {"bob", "/dataset2/folder1/item2", "POST", 200}, {"bob", "/dataset2/folder1/item2", "DELETE", 403}, } for _, tt := range tt { check(e, tt.method, tt.path, tt.username, tt.status) } ttAdmin := []ttcasbin{ {"cathrin", "/dataset1/item", "GET", 200}, {"cathrin", "/dataset1/item", "POST", 200}, {"cathrin", "/dataset1/item", "DELETE", 200}, {"cathrin", "/dataset2/item", "GET", 403}, {"cathrin", "/dataset2/item", "POST", 403}, {"cathrin", "/dataset2/item", "DELETE", 403}, } for _, tt := range ttAdmin { check(e, tt.method, tt.path, tt.username, tt.status) } Enforcer.DeleteRolesForUser("cathrin") ttAdminDeleted := []ttcasbin{ {"cathrin", "/dataset1/item", "GET", 403}, {"cathrin", "/dataset1/item", "POST", 403}, {"cathrin", "/dataset1/item", "DELETE", 403}, {"cathrin", "/dataset2/item", "GET", 403}, {"cathrin", "/dataset2/item", "POST", 403}, {"cathrin", "/dataset2/item", "DELETE", 403}, } for _, tt := range ttAdminDeleted { check(e, tt.method, tt.path, tt.username, tt.status) } } func check(e *httpexpect.Expect, method, path, username string, status int) { e.Request(method, path).WithBasicAuth(username, "password").Expect().Status(status) } ~~~