You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
goctls-template/api/authortymiddleware.tpl

88 lines
2.4 KiB
Smarty

package middleware
import (
"net/http"
"strings"
"github.com/casbin/casbin/v2"
"github.com/zeromicro/go-zero/core/stores/redis"
"git.noahlan.cn/noahlan/ntools-go/core/nlog"
"git.noahlan.cn/noahlan/ntools-go/zero/statusz"
"git.noahlan.cn/noahlan/ntool-biz/core/nstatus"
{{if .useTrans}}
"git.noahlan.cn/noahlan/ntools-go/core/i18n"{{end}}
)
type AuthorityMiddleware struct {
Cbn *casbin.Enforcer
Rds *redis.Redis
}
func NewAuthorityMiddleware(cbn *casbin.Enforcer, rds *redis.Redis) *AuthorityMiddleware {
return &AuthorityMiddleware{
Cbn: cbn,
Rds: rds,
}
}
func (m *AuthorityMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
{{if .useTrans}}const transErr = true{{else}}const transErr = false{{end}}
// get the path
obj := r.URL.Path
// get the method
act := r.Method
// get the role id
roleIds := r.Context().Value("roleIds").(string)
// check jwt blacklist
jwtResult, err := m.Rds.Get("token_" + r.Header.Get("Authorization"))
if err != nil {
nlog.Errorw("redis error in jwt", nlog.Field("detail", err.Error()))
statusz.ResponseHandler(r, w, transErr, nil, nstatus.NewApiInternalErr(err.Error()))
return
}
if jwtResult == "1" {
nlog.Errorw("token in blacklist", nlog.Field("detail", r.Header.Get("Authorization")))
statusz.ResponseHandler(r, w, transErr, nil, nstatus.NewApiErrWithCode(http.StatusUnauthorized))
return
}
result := batchCheck(m.Cbn, roleIds, act, obj)
if result {
nlog.Infow("HTTP/HTTPS Request", nlog.Field("UUID", r.Context().Value("userId").(string)),
nlog.Field("path", obj), nlog.Field("method", act))
next(w, r)
return
} else {
nlog.Errorw("the role is not permitted to access the API", nlog.Field("roleIds", roleIds),
nlog.Field("path", obj), nlog.Field("method", act))
statusz.ResponseHandler(r, w, transErr, nil, nstatus.NewApiForbiddenErr("common.permissionDeny"))
return
}
}
}
func batchCheck(cbn *casbin.Enforcer, roleIds, act, obj string) bool {
var checkReq [][]any
for _, v := range strings.Split(roleIds, ",") {
checkReq = append(checkReq, []any{v, obj, act})
}
result, err := cbn.BatchEnforce(checkReq)
if err != nil {
nlog.Errorw("Casbin enforce error", nlog.Field("detail", err.Error()))
return false
}
for _, v := range result {
if v {
return true
}
}
return false
}