rbac
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"portal-mini-go/internal/model/admin"
|
||||
"portal-mini-go/internal/pkg/response"
|
||||
)
|
||||
|
||||
// simulateLoader 模拟 PermissionLoader 把角色与权限集写入 context。
|
||||
func simulateLoader(roles, perms []string) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Set(adminRolesCtxKey, roles)
|
||||
set := make(map[string]struct{}, len(perms))
|
||||
for _, p := range perms {
|
||||
set[p] = struct{}{}
|
||||
}
|
||||
c.Set(adminPermsCtxKey, set)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func doReq(r *gin.Engine, method, path string) (int, int) {
|
||||
req := httptest.NewRequest(method, path, bytes.NewReader(nil))
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
var body response.Response
|
||||
_ = json.Unmarshal(w.Body.Bytes(), &body)
|
||||
return w.Code, body.Code
|
||||
}
|
||||
|
||||
func TestRequirePerm(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
roles []string
|
||||
perms []string
|
||||
need []string
|
||||
wantCode int // 业务码:0 通过,40300 禁止
|
||||
}{
|
||||
{"super_admin 短路", []string{admin.SuperAdminRoleCode}, nil, []string{"any:perm"}, 0},
|
||||
{"拥有所需权限", nil, []string{"user:view"}, []string{"user:view"}, 0},
|
||||
{"缺少所需权限", nil, []string{"other"}, []string{"user:view"}, 40300},
|
||||
{"多权限全部满足", nil, []string{"a", "b"}, []string{"a", "b"}, 0},
|
||||
{"多权限部分缺失", nil, []string{"a"}, []string{"a", "b"}, 40300},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
r := gin.New()
|
||||
r.Use(ErrorHandler())
|
||||
g := r.Group("/x")
|
||||
g.Use(simulateLoader(tc.roles, tc.perms))
|
||||
g.GET("/need", RequirePerm(tc.need...), func(c *gin.Context) {
|
||||
c.Status(http.StatusOK)
|
||||
})
|
||||
_, code := doReq(r, http.MethodGet, "/x/need")
|
||||
require.Equal(t, tc.wantCode, code)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user