Skip to content

Commit 09dc51f

Browse files
committed
allow context key to be []interface as well as []string
1 parent 5c0eddd commit 09dc51f

File tree

2 files changed

+94
-14
lines changed

2 files changed

+94
-14
lines changed

casbin.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,23 @@ func CasbinWithConfig(config Config) echo.MiddlewareFunc {
122122
}
123123
} else {
124124
var ok bool
125-
roles, ok = c.Get(config.ContextKey).([]string)
125+
k := c.Get(config.ContextKey)
126+
if k != nil {
127+
switch k.(type) {
128+
case []string:
129+
roles = k.([]string)
130+
ok = true
131+
case []interface{}:
132+
for _, role := range k.([]interface{}) {
133+
_, str := role.(string)
134+
if str {
135+
roles = append(roles, role.(string))
136+
}
137+
}
138+
ok = true
139+
}
140+
}
141+
126142
if !ok {
127143
roles = []string{}
128144
}

casbin_test.go

Lines changed: 77 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -252,25 +252,89 @@ func TestJWTWithConfig_RolesHeaderFunc(t *testing.T) {
252252
}
253253
}
254254

255-
func TestJWTWithConfig_Skipper(t *testing.T) {
256-
e := echo.New()
255+
func TestJWTWithConfig_RolesContext_Slice_String(t *testing.T) {
256+
testCases := []struct {
257+
name string
258+
roles []string
259+
endpoint string
260+
method string
261+
statusCode int
262+
}{
263+
{"root no role", []string{}, "/", http.MethodGet, http.StatusOK},
264+
{"user user", []string{"user"}, "/user", http.MethodGet, http.StatusOK},
265+
{"admin admin", []string{"user", "admin"}, "/admin", http.MethodGet, http.StatusOK},
266+
}
257267

258-
e.GET("/", func(c echo.Context) error {
259-
return c.JSON(http.StatusOK, "ok")
260-
})
268+
for _, tc := range testCases {
269+
t.Run(tc.name, func(t *testing.T) {
270+
e := echo.New()
261271

262-
config := Config{
263-
Enforcer: enforcer,
264-
Skipper: func(c echo.Context) bool { return true },
272+
e.Any(tc.endpoint, func(c echo.Context) error {
273+
assert.Equal(t, tc.roles, c.Get("roles"))
274+
return c.JSON(http.StatusOK, "ok")
275+
})
276+
277+
e.Use(
278+
func(next echo.HandlerFunc) echo.HandlerFunc {
279+
return func(c echo.Context) error {
280+
c.Set("roles", tc.roles)
281+
return next(c)
282+
}
283+
},
284+
Casbin(enforcer),
285+
)
286+
287+
req := httptest.NewRequest(tc.method, tc.endpoint, nil)
288+
resp := httptest.NewRecorder()
289+
290+
e.ServeHTTP(resp, req)
291+
292+
assert.Equal(t, tc.statusCode, resp.Code)
293+
})
265294
}
266-
e.Use(CasbinWithConfig(config))
295+
}
267296

268-
req := httptest.NewRequest(http.MethodGet, "/", nil)
269-
resp := httptest.NewRecorder()
297+
func TestJWTWithConfig_RolesContext_Slice_Any(t *testing.T) {
298+
testCases := []struct {
299+
name string
300+
roles []any
301+
endpoint string
302+
method string
303+
statusCode int
304+
}{
305+
{"root no role", []any{}, "/", http.MethodGet, http.StatusOK},
306+
{"user user", []any{"user"}, "/user", http.MethodGet, http.StatusOK},
307+
{"admin admin", []any{"user", "admin"}, "/admin", http.MethodGet, http.StatusOK},
308+
{"skip invalid roles", []any{1, 2.0, []string{"nope"}, "user"}, "/user", http.MethodGet, http.StatusOK},
309+
}
270310

271-
e.ServeHTTP(resp, req)
311+
for _, tc := range testCases {
312+
t.Run(tc.name, func(t *testing.T) {
313+
e := echo.New()
272314

273-
assert.Equal(t, http.StatusOK, resp.Code)
315+
e.Any(tc.endpoint, func(c echo.Context) error {
316+
assert.Equal(t, tc.roles, c.Get("roles"))
317+
return c.JSON(http.StatusOK, "ok")
318+
})
319+
320+
e.Use(
321+
func(next echo.HandlerFunc) echo.HandlerFunc {
322+
return func(c echo.Context) error {
323+
c.Set("roles", tc.roles)
324+
return next(c)
325+
}
326+
},
327+
Casbin(enforcer),
328+
)
329+
330+
req := httptest.NewRequest(tc.method, tc.endpoint, nil)
331+
resp := httptest.NewRecorder()
332+
333+
e.ServeHTTP(resp, req)
334+
335+
assert.Equal(t, tc.statusCode, resp.Code)
336+
})
337+
}
274338
}
275339

276340
func TestJWTWithConfig_Enforcer_Panic(t *testing.T) {

0 commit comments

Comments
 (0)