Files
bj_power/bj_power_mes/internal/middleware/permission.go
T

103 lines
2.6 KiB
Go

package middleware
import (
"net/http"
"path"
"strings"
"bj_power_mes/common/errorx"
"bj_power_mes/common/httpx"
"bj_power_mes/ent"
"bj_power_mes/internal/svc"
"github.com/zeromicro/go-zero/core/collection"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/rest"
"github.com/zeromicro/go-zero/rest/httpx"
)
type HttpRequest struct {
Path string `json:"path"`
Method string `json:"method"`
}
func NewHttpRequest(path, method string) HttpRequest {
return HttpRequest{Path: path, Method: strings.ToUpper(method)}
}
var ignorePermissions = collection.NewSet()
func init() {
ignorePermissions.Add([]any{
NewHttpRequest("/sse", "GET"),
NewHttpRequest("/api/v1/roles", "POST"),
NewHttpRequest("/api/v1/equipments", "POST"),
NewHttpRequest("/api/v1/login", "POST"),
NewHttpRequest("/api/v1/userinfo", "GET"),
NewHttpRequest("/api/v1/refreshToken", "POST"),
}...)
}
func CheckPermission(svcCtx *svc.ServiceContext) rest.Middleware {
return func(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
method := strings.ToUpper(r.Method)
reqPath := r.URL.Path
if ignorePermissions.Contains(NewHttpRequest(reqPath, method)) {
next(w, r)
return
}
userId := xhttp.GetUidFromCtx(r.Context())
logx.WithContext(r.Context()).Debugf("check permission [%s %s]", method, reqPath)
u, err := svcCtx.EntClient.User.Get(r.Context(), int(userId))
if ent.IsNotFound(err) {
httpx.ErrorCtx(r.Context(), w, errorx.WithStack(err, errorx.UserNotFound))
return
} else if err != nil {
httpx.ErrorCtx(r.Context(), w, errorx.WithStack(err, errorx.DbError))
return
}
if u.RoleId == 1 {
next(w, r)
return
}
rows, err := svcCtx.EntClient.QueryContext(r.Context(), `select id, path, method from api
left join permission_apis as pa on pa.api_id = api.id
left join role_permissions as rp on rp.permission_id = pa.permission_id
where rp.role_id = $1`, u.RoleId)
if err != nil {
httpx.ErrorCtx(r.Context(), w, errorx.WithStack(err, errorx.DbError))
return
}
defer rows.Close()
var apis []ent.Api
for rows.Next() {
var api ent.Api
err = rows.Scan(&api.ID, &api.Path, &api.Method)
if err != nil {
httpx.ErrorCtx(r.Context(), w, errorx.WithStack(err, errorx.DbError))
return
}
apis = append(apis, api)
}
for _, api := range apis {
if strings.EqualFold(api.Method, method) || api.Method == "*" {
if match, _ := path.Match(api.Path, reqPath); match {
next(w, r)
return
}
}
}
http.Error(w, "access forbidden", 403)
}
}
}