Skip to content

Commit fdc9c9a

Browse files
laychopyLuis Albarenga
and
Luis Albarenga
authored
feat: improve casbin mw (#107)
* feat: improve test readability and include README.md --------- Co-authored-by: Luis Albarenga <[email protected]>
1 parent 939b0a9 commit fdc9c9a

File tree

2 files changed

+98
-38
lines changed

2 files changed

+98
-38
lines changed

casbin/README.md

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Usage
2+
Simple example:
3+
```go
4+
package main
5+
6+
import (
7+
"github.com/casbin/casbin/v2"
8+
"github.com/labstack/echo/v4"
9+
casbin_mw "github.com/labstack/echo-contrib/casbin"
10+
)
11+
12+
func main() {
13+
e := echo.New()
14+
15+
// Mediate the access for every request
16+
e.Use(casbin_mw.Middleware(casbin.NewEnforcer("auth_model.conf", "auth_policy.csv")))
17+
18+
e.Logger.Fatal(e.Start(":1323"))
19+
}
20+
```
21+
22+
Advanced example:
23+
```go
24+
package main
25+
26+
import (
27+
"github.com/casbin/casbin/v2"
28+
"github.com/labstack/echo/v4"
29+
casbin_mw "github.com/labstack/echo-contrib/casbin"
30+
)
31+
32+
func main() {
33+
ce, _ := casbin.NewEnforcer("auth_model.conf", "")
34+
ce.AddRoleForUser("alice", "admin")
35+
ce.AddPolicy("added_user", "data1", "read")
36+
37+
e := echo.New()
38+
39+
e.Use(casbin_mw.Middleware(ce))
40+
41+
e.Logger.Fatal(e.Start(":1323"))
42+
}
43+
```
44+
45+
# API Reference
46+
See [API Overview](https://casbin.org/docs/api-overview).

casbin/casbin_test.go

+52-38
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,11 @@ func testRequest(t *testing.T, h echo.HandlerFunc, user string, path string, met
2626
err := h(c)
2727

2828
if err != nil {
29-
if errObj, ok := err.(*echo.HTTPError); ok {
29+
var errObj *echo.HTTPError
30+
if errors.As(err, &errObj) {
3031
if errObj.Code != code {
3132
t.Errorf("%s, %s, %s: %d, supposed to be %d", user, path, method, errObj.Code, code)
3233
}
33-
} else {
34-
t.Error(err)
3534
}
3635
} else {
3736
if c.Response().Status != code {
@@ -46,10 +45,10 @@ func TestAuth(t *testing.T) {
4645
return c.String(http.StatusOK, "test")
4746
})
4847

49-
testRequest(t, h, "alice", "/dataset1/resource1", echo.GET, 200)
50-
testRequest(t, h, "alice", "/dataset1/resource1", echo.POST, 200)
51-
testRequest(t, h, "alice", "/dataset1/resource2", echo.GET, 200)
52-
testRequest(t, h, "alice", "/dataset1/resource2", echo.POST, 403)
48+
testRequest(t, h, "alice", "/dataset1/resource1", echo.GET, http.StatusOK)
49+
testRequest(t, h, "alice", "/dataset1/resource1", echo.POST, http.StatusOK)
50+
testRequest(t, h, "alice", "/dataset1/resource2", echo.GET, http.StatusOK)
51+
testRequest(t, h, "alice", "/dataset1/resource2", echo.POST, http.StatusForbidden)
5352
}
5453

5554
func TestPathWildcard(t *testing.T) {
@@ -58,19 +57,19 @@ func TestPathWildcard(t *testing.T) {
5857
return c.String(http.StatusOK, "test")
5958
})
6059

61-
testRequest(t, h, "bob", "/dataset2/resource1", "GET", 200)
62-
testRequest(t, h, "bob", "/dataset2/resource1", "POST", 200)
63-
testRequest(t, h, "bob", "/dataset2/resource1", "DELETE", 200)
64-
testRequest(t, h, "bob", "/dataset2/resource2", "GET", 200)
65-
testRequest(t, h, "bob", "/dataset2/resource2", "POST", 403)
66-
testRequest(t, h, "bob", "/dataset2/resource2", "DELETE", 403)
67-
68-
testRequest(t, h, "bob", "/dataset2/folder1/item1", "GET", 403)
69-
testRequest(t, h, "bob", "/dataset2/folder1/item1", "POST", 200)
70-
testRequest(t, h, "bob", "/dataset2/folder1/item1", "DELETE", 403)
71-
testRequest(t, h, "bob", "/dataset2/folder1/item2", "GET", 403)
72-
testRequest(t, h, "bob", "/dataset2/folder1/item2", "POST", 200)
73-
testRequest(t, h, "bob", "/dataset2/folder1/item2", "DELETE", 403)
60+
testRequest(t, h, "bob", "/dataset2/resource1", echo.GET, http.StatusOK)
61+
testRequest(t, h, "bob", "/dataset2/resource1", echo.POST, http.StatusOK)
62+
testRequest(t, h, "bob", "/dataset2/resource1", echo.DELETE, http.StatusOK)
63+
testRequest(t, h, "bob", "/dataset2/resource2", echo.GET, http.StatusOK)
64+
testRequest(t, h, "bob", "/dataset2/resource2", echo.POST, http.StatusForbidden)
65+
testRequest(t, h, "bob", "/dataset2/resource2", echo.DELETE, http.StatusForbidden)
66+
67+
testRequest(t, h, "bob", "/dataset2/folder1/item1", echo.GET, http.StatusForbidden)
68+
testRequest(t, h, "bob", "/dataset2/folder1/item1", echo.POST, http.StatusOK)
69+
testRequest(t, h, "bob", "/dataset2/folder1/item1", echo.DELETE, http.StatusForbidden)
70+
testRequest(t, h, "bob", "/dataset2/folder1/item2", echo.GET, http.StatusForbidden)
71+
testRequest(t, h, "bob", "/dataset2/folder1/item2", echo.POST, http.StatusOK)
72+
testRequest(t, h, "bob", "/dataset2/folder1/item2", echo.DELETE, http.StatusForbidden)
7473
}
7574

7675
func TestRBAC(t *testing.T) {
@@ -80,22 +79,22 @@ func TestRBAC(t *testing.T) {
8079
})
8180

8281
// cathy can access all /dataset1/* resources via all methods because it has the dataset1_admin role.
83-
testRequest(t, h, "cathy", "/dataset1/item", "GET", 200)
84-
testRequest(t, h, "cathy", "/dataset1/item", "POST", 200)
85-
testRequest(t, h, "cathy", "/dataset1/item", "DELETE", 200)
86-
testRequest(t, h, "cathy", "/dataset2/item", "GET", 403)
87-
testRequest(t, h, "cathy", "/dataset2/item", "POST", 403)
88-
testRequest(t, h, "cathy", "/dataset2/item", "DELETE", 403)
82+
testRequest(t, h, "cathy", "/dataset1/item", echo.GET, http.StatusOK)
83+
testRequest(t, h, "cathy", "/dataset1/item", echo.POST, http.StatusOK)
84+
testRequest(t, h, "cathy", "/dataset1/item", echo.DELETE, http.StatusOK)
85+
testRequest(t, h, "cathy", "/dataset2/item", echo.GET, http.StatusForbidden)
86+
testRequest(t, h, "cathy", "/dataset2/item", echo.POST, http.StatusForbidden)
87+
testRequest(t, h, "cathy", "/dataset2/item", echo.DELETE, http.StatusForbidden)
8988

9089
// delete all roles on user cathy, so cathy cannot access any resources now.
9190
ce.DeleteRolesForUser("cathy")
9291

93-
testRequest(t, h, "cathy", "/dataset1/item", "GET", 403)
94-
testRequest(t, h, "cathy", "/dataset1/item", "POST", 403)
95-
testRequest(t, h, "cathy", "/dataset1/item", "DELETE", 403)
96-
testRequest(t, h, "cathy", "/dataset2/item", "GET", 403)
97-
testRequest(t, h, "cathy", "/dataset2/item", "POST", 403)
98-
testRequest(t, h, "cathy", "/dataset2/item", "DELETE", 403)
92+
testRequest(t, h, "cathy", "/dataset1/item", echo.GET, http.StatusForbidden)
93+
testRequest(t, h, "cathy", "/dataset1/item", echo.POST, http.StatusForbidden)
94+
testRequest(t, h, "cathy", "/dataset1/item", echo.DELETE, http.StatusForbidden)
95+
testRequest(t, h, "cathy", "/dataset2/item", echo.GET, http.StatusForbidden)
96+
testRequest(t, h, "cathy", "/dataset2/item", echo.POST, http.StatusForbidden)
97+
testRequest(t, h, "cathy", "/dataset2/item", echo.DELETE, http.StatusForbidden)
9998
}
10099

101100
func TestEnforceError(t *testing.T) {
@@ -104,7 +103,7 @@ func TestEnforceError(t *testing.T) {
104103
return c.String(http.StatusOK, "test")
105104
})
106105

107-
testRequest(t, h, "cathy", "/dataset1/item", "GET", 500)
106+
testRequest(t, h, "cathy", "/dataset1/item", echo.GET, http.StatusInternalServerError)
108107
}
109108

110109
func TestCustomUserGetter(t *testing.T) {
@@ -119,7 +118,7 @@ func TestCustomUserGetter(t *testing.T) {
119118
h := MiddlewareWithConfig(cnf)(func(c echo.Context) error {
120119
return c.String(http.StatusOK, "test")
121120
})
122-
testRequest(t, h, "cathy", "/dataset1/item", "GET", 403)
121+
testRequest(t, h, "cathy", "/dataset1/item", echo.GET, http.StatusForbidden)
123122
}
124123

125124
func TestUserGetterError(t *testing.T) {
@@ -134,7 +133,7 @@ func TestUserGetterError(t *testing.T) {
134133
h := MiddlewareWithConfig(cnf)(func(c echo.Context) error {
135134
return c.String(http.StatusOK, "test")
136135
})
137-
testRequest(t, h, "cathy", "/dataset1/item", "GET", 403)
136+
testRequest(t, h, "cathy", "/dataset1/item", echo.GET, http.StatusForbidden)
138137
}
139138

140139
func TestCustomEnforceHandler(t *testing.T) {
@@ -156,7 +155,22 @@ func TestCustomEnforceHandler(t *testing.T) {
156155
h := MiddlewareWithConfig(cnf)(func(c echo.Context) error {
157156
return c.String(http.StatusOK, "test")
158157
})
159-
testRequest(t, h, "bob", "/dataset2/resource1", "GET", http.StatusOK)
160-
testRequest(t, h, "bob", "/user/alice", "PATCH", http.StatusForbidden)
161-
testRequest(t, h, "bob", "/user/bob", "PATCH", http.StatusOK)
158+
testRequest(t, h, "bob", "/dataset2/resource1", echo.GET, http.StatusOK)
159+
testRequest(t, h, "bob", "/user/alice", echo.PATCH, http.StatusForbidden)
160+
testRequest(t, h, "bob", "/user/bob", echo.PATCH, http.StatusOK)
161+
}
162+
163+
func TestCustomSkipper(t *testing.T) {
164+
ce, _ := casbin.NewEnforcer("auth_model.conf", "auth_policy.csv")
165+
cnf := Config{
166+
Skipper: func(c echo.Context) bool {
167+
return c.Request().URL.Path == "/dataset1/resource1"
168+
},
169+
Enforcer: ce,
170+
}
171+
h := MiddlewareWithConfig(cnf)(func(c echo.Context) error {
172+
return c.String(http.StatusOK, "test")
173+
})
174+
testRequest(t, h, "alice", "/dataset1/resource1", echo.GET, http.StatusOK)
175+
testRequest(t, h, "alice", "/dataset1/resource2", echo.POST, http.StatusForbidden)
162176
}

0 commit comments

Comments
 (0)