mirror of
https://github.com/nezhahq/nezha.git
synced 2025-01-22 12:48:14 -05:00
feat: support id query for "list" apis (#908)
* feat: support id query for "list" apis * gosec
This commit is contained in:
parent
672063f4de
commit
d50605d668
@ -17,6 +17,7 @@ import (
|
||||
// @Schemes
|
||||
// @Description List Alert rules
|
||||
// @Tags auth required
|
||||
// @Param id query uint false "Resource ID"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[[]model.AlertRule]
|
||||
// @Router /alert-rule [get]
|
||||
|
@ -247,7 +247,8 @@ func listHandler[S ~[]E, E model.CommonInterface](handler handlerFunc[S]) func(*
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, model.CommonResponse[S]{Success: true, Data: filter(c, data)})
|
||||
filtered := filter(c, data)
|
||||
c.JSON(http.StatusOK, model.CommonResponse[S]{Success: true, Data: model.SearchByIDCtx(c, filtered)})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
// @Schemes
|
||||
// @Description List schedule tasks
|
||||
// @Tags auth required
|
||||
// @Param id query uint false "Resource ID"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[[]model.Cron]
|
||||
// @Router /cron [get]
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
// @Description List DDNS profiles
|
||||
// @Security BearerAuth
|
||||
// @Tags auth required
|
||||
// @Param id query uint false "Resource ID"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[[]model.DDNSProfile]
|
||||
// @Router /ddns [get]
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
// @Description List NAT profiles
|
||||
// @Security BearerAuth
|
||||
// @Tags auth required
|
||||
// @Param id query uint false "Resource ID"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[[]model.NAT]
|
||||
// @Router /nat [get]
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
// @Schemes
|
||||
// @Description List notification
|
||||
// @Tags auth required
|
||||
// @Param id query uint false "Resource ID"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[[]model.Notification]
|
||||
// @Router /notification [get]
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
// @Schemes
|
||||
// @Description List server
|
||||
// @Tags auth required
|
||||
// @Param id query uint false "Resource ID"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[[]model.Server]
|
||||
// @Router /server [get]
|
||||
|
@ -50,6 +50,7 @@ func showService(c *gin.Context) (*model.ServiceResponse, error) {
|
||||
// @Schemes
|
||||
// @Description List service
|
||||
// @Tags auth required
|
||||
// @Param id query uint false "Resource ID"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[[]model.Service]
|
||||
// @Router /service [get]
|
||||
|
@ -1,9 +1,14 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/nezhahq/nezha/pkg/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -61,6 +66,56 @@ func FindByUserID[S ~[]E, E CommonInterface](s S, uid uint64) []uint64 {
|
||||
return list
|
||||
}
|
||||
|
||||
func SearchByIDCtx[S ~[]E, E CommonInterface](c *gin.Context, x S) S {
|
||||
switch any(x).(type) {
|
||||
case []*Server:
|
||||
l := searchByIDCtxServer(c, any(x).([]*Server))
|
||||
return any(l).(S)
|
||||
default:
|
||||
var s S
|
||||
for _, idStr := range strings.Split(c.Query("id"), ",") {
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if i, ok := slices.BinarySearchFunc(x, id, func(e E, t uint64) int {
|
||||
return cmp.Compare(e.GetID(), t)
|
||||
}); ok {
|
||||
s = append(s, x[i])
|
||||
}
|
||||
}
|
||||
return utils.IfOr(len(s) > 0, s, x)
|
||||
}
|
||||
}
|
||||
|
||||
func searchByIDCtxServer(c *gin.Context, x []*Server) []*Server {
|
||||
list1, list2 := SplitList(x)
|
||||
|
||||
var clist1, clist2 []*Server
|
||||
for _, idStr := range strings.Split(c.Query("id"), ",") {
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if i, ok := slices.BinarySearchFunc(list1, id, func(e *Server, t uint64) int {
|
||||
return cmp.Compare(e.ID, t)
|
||||
}); ok {
|
||||
clist1 = append(clist1, list1[i])
|
||||
}
|
||||
|
||||
if i, ok := slices.BinarySearchFunc(list2, id, func(e *Server, t uint64) int {
|
||||
return cmp.Compare(e.ID, t)
|
||||
}); ok {
|
||||
clist2 = append(clist2, list2[i])
|
||||
}
|
||||
}
|
||||
|
||||
l := slices.Concat(clist1, clist2)
|
||||
return utils.IfOr(len(l) > 0, l, x)
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Code int `json:"code,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
|
@ -2,6 +2,7 @@ package model
|
||||
|
||||
import (
|
||||
"log"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@ -54,3 +55,20 @@ func (s *Server) AfterFind(tx *gorm.DB) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Split a sorted server list into two separate lists:
|
||||
// The first list contains servers with a priority set (DisplayIndex != 0).
|
||||
// The second list contains servers without a priority set (DisplayIndex == 0).
|
||||
// The original slice is not modified. If no server without a priority is found, it returns nil.
|
||||
func SplitList(x []*Server) ([]*Server, []*Server) {
|
||||
pri := func(s *Server) bool {
|
||||
return s.DisplayIndex == 0
|
||||
}
|
||||
|
||||
i := slices.IndexFunc(x, pri)
|
||||
if i == -1 {
|
||||
return nil, x
|
||||
}
|
||||
|
||||
return x[:i], x[i:]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user