diff --git a/casbin/broken_auth_model.conf b/casbin/broken_auth_model.conf new file mode 100644 index 0000000..b692c34 --- /dev/null +++ b/casbin/broken_auth_model.conf @@ -0,0 +1,14 @@ +[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(, p.sub) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*") diff --git a/casbin/casbin.go b/casbin/casbin.go index 6c45f8d..ab4cb3c 100644 --- a/casbin/casbin.go +++ b/casbin/casbin.go @@ -5,16 +5,16 @@ Simple example: package main import ( - "github.com/casbin/casbin" + "github.com/casbin/casbin/v2" "github.com/labstack/echo/v4" - "github.com/labstack/echo-contrib/casbin" casbin-mw + casbin_mw "github.com/labstack/echo-contrib/casbin" ) func main() { e := echo.New() // Mediate the access for every request - e.Use(casbin-mw.Middleware(casbin.NewEnforcer("auth_model.conf", "auth_policy.csv"))) + e.Use(casbin_mw.Middleware(casbin.NewEnforcer("auth_model.conf", "auth_policy.csv"))) e.Logger.Fatal(e.Start(":1323")) } @@ -24,19 +24,19 @@ Advanced example: package main import ( - "github.com/casbin/casbin" + "github.com/casbin/casbin/v2" "github.com/labstack/echo/v4" - "github.com/labstack/echo-contrib/casbin" casbin-mw + casbin_mw "github.com/labstack/echo-contrib/casbin" ) func main() { - ce := casbin.NewEnforcer("auth_model.conf", "") + ce, _ := casbin.NewEnforcer("auth_model.conf", "") ce.AddRoleForUser("alice", "admin") ce.AddPolicy(...) e := echo.New() - echo.Use(casbin-mw.Middleware(ce)) + e.Use(casbin_mw.Middleware(ce)) e.Logger.Fatal(e.Start(":1323")) } @@ -45,7 +45,9 @@ Advanced example: package casbin import ( - "github.com/casbin/casbin" + "net/http" + + "github.com/casbin/casbin/v2" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" ) @@ -89,8 +91,14 @@ func MiddlewareWithConfig(config Config) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { - if config.Skipper(c) || config.CheckPermission(c) { + if config.Skipper(c) { + return next(c) + } + + if pass, err := config.CheckPermission(c); err == nil && pass { return next(c) + } else if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) } return echo.ErrForbidden @@ -107,7 +115,7 @@ func (a *Config) GetUserName(c echo.Context) string { // CheckPermission checks the user/method/path combination from the request. // Returns true (permission granted) or false (permission forbidden) -func (a *Config) CheckPermission(c echo.Context) bool { +func (a *Config) CheckPermission(c echo.Context) (bool, error) { user := a.GetUserName(c) method := c.Request().Method path := c.Request().URL.Path diff --git a/casbin/casbin_test.go b/casbin/casbin_test.go index b30db12..4286fc5 100644 --- a/casbin/casbin_test.go +++ b/casbin/casbin_test.go @@ -5,7 +5,7 @@ import ( "net/http/httptest" "testing" - "github.com/casbin/casbin" + "github.com/casbin/casbin/v2" "github.com/labstack/echo/v4" ) @@ -37,7 +37,7 @@ func testRequest(t *testing.T, ce *casbin.Enforcer, user string, path string, me } func TestAuth(t *testing.T) { - ce := casbin.NewEnforcer("auth_model.conf", "auth_policy.csv") + ce, _ := casbin.NewEnforcer("auth_model.conf", "auth_policy.csv") testRequest(t, ce, "alice", "/dataset1/resource1", echo.GET, 200) testRequest(t, ce, "alice", "/dataset1/resource1", echo.POST, 200) @@ -46,7 +46,7 @@ func TestAuth(t *testing.T) { } func TestPathWildcard(t *testing.T) { - ce := casbin.NewEnforcer("auth_model.conf", "auth_policy.csv") + ce, _ := casbin.NewEnforcer("auth_model.conf", "auth_policy.csv") testRequest(t, ce, "bob", "/dataset2/resource1", "GET", 200) testRequest(t, ce, "bob", "/dataset2/resource1", "POST", 200) @@ -64,7 +64,7 @@ func TestPathWildcard(t *testing.T) { } func TestRBAC(t *testing.T) { - ce := casbin.NewEnforcer("auth_model.conf", "auth_policy.csv") + ce, _ := casbin.NewEnforcer("auth_model.conf", "auth_policy.csv") // cathy can access all /dataset1/* resources via all methods because it has the dataset1_admin role. testRequest(t, ce, "cathy", "/dataset1/item", "GET", 200) @@ -84,3 +84,8 @@ func TestRBAC(t *testing.T) { testRequest(t, ce, "cathy", "/dataset2/item", "POST", 403) testRequest(t, ce, "cathy", "/dataset2/item", "DELETE", 403) } + +func TestEnforceError(t *testing.T) { + ce, _ := casbin.NewEnforcer("broken_auth_model.conf", "auth_policy.csv") + testRequest(t, ce, "cathy", "/dataset1/item", "GET", 500) +} diff --git a/go.mod b/go.mod index 856ed9a..20add34 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,8 @@ module github.com/labstack/echo-contrib require ( - github.com/casbin/casbin v1.8.2 + github.com/casbin/casbin/v2 v2.0.0 + github.com/casbin/casbin/v2 v2.0.0 github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect github.com/gorilla/context v1.1.1 github.com/gorilla/sessions v1.1.3 diff --git a/go.sum b/go.sum index dbe9afe..46ad883 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,6 @@ github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/casbin/casbin v1.8.2 h1:hJrnZxIXnsxyxQ8zvrUWYrR+MJK+J1X7sBeA5DuLh+o= -github.com/casbin/casbin v1.8.2/go.mod h1:z8uPsfBJGUsnkagrt3G8QvjgTKFMBJ32UP8HpZllfog= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= +github.com/casbin/casbin/v2 v2.0.0/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -44,7 +42,6 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=