103 lines
2.6 KiB
Go
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.DB.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)
|
|
}
|
|
}
|
|
}
|