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) } } }