This commit is contained in:
uubulb 2024-12-16 23:38:31 +08:00
parent af7427666a
commit 2c8ab28efe
6 changed files with 39 additions and 16 deletions

View File

@ -59,7 +59,7 @@ func routers(r *gin.Engine, frontendDist fs.FS) {
optionalAuth := api.Group("", optionalAuthMiddleware(authMiddleware)) optionalAuth := api.Group("", optionalAuthMiddleware(authMiddleware))
optionalAuth.GET("/ws/server", commonHandler(serverStream)) optionalAuth.GET("/ws/server", commonHandler(serverStream))
optionalAuth.GET("/server-group", listHandler(listServerGroup)) optionalAuth.GET("/server-group", commonHandler(listServerGroup))
optionalAuth.GET("/service", commonHandler(showService)) optionalAuth.GET("/service", commonHandler(showService))
optionalAuth.GET("/service/:id", commonHandler(listServiceHistory)) optionalAuth.GET("/service/:id", commonHandler(listServiceHistory))
@ -83,7 +83,7 @@ func routers(r *gin.Engine, frontendDist fs.FS) {
auth.POST("/user", commonHandler(createUser)) auth.POST("/user", commonHandler(createUser))
auth.POST("/batch-delete/user", commonHandler(batchDeleteUser)) auth.POST("/batch-delete/user", commonHandler(batchDeleteUser))
auth.GET("/service/list", commonHandler(listService)) auth.GET("/service/list", listHandler(listService))
auth.POST("/service", commonHandler(createService)) auth.POST("/service", commonHandler(createService))
auth.PATCH("/service/:id", commonHandler(updateService)) auth.PATCH("/service/:id", commonHandler(updateService))
auth.POST("/batch-delete/service", commonHandler(batchDeleteService)) auth.POST("/batch-delete/service", commonHandler(batchDeleteService))
@ -97,17 +97,17 @@ func routers(r *gin.Engine, frontendDist fs.FS) {
auth.PATCH("/notification-group/:id", commonHandler(updateNotificationGroup)) auth.PATCH("/notification-group/:id", commonHandler(updateNotificationGroup))
auth.POST("/batch-delete/notification-group", commonHandler(batchDeleteNotificationGroup)) auth.POST("/batch-delete/notification-group", commonHandler(batchDeleteNotificationGroup))
auth.GET("/server", commonHandler(listServer)) auth.GET("/server", listHandler(listServer))
auth.PATCH("/server/:id", commonHandler(updateServer)) auth.PATCH("/server/:id", commonHandler(updateServer))
auth.POST("/batch-delete/server", commonHandler(batchDeleteServer)) auth.POST("/batch-delete/server", commonHandler(batchDeleteServer))
auth.POST("/force-update/server", commonHandler(forceUpdateServer)) auth.POST("/force-update/server", commonHandler(forceUpdateServer))
auth.GET("/notification", commonHandler(listNotification)) auth.GET("/notification", listHandler(listNotification))
auth.POST("/notification", commonHandler(createNotification)) auth.POST("/notification", commonHandler(createNotification))
auth.PATCH("/notification/:id", commonHandler(updateNotification)) auth.PATCH("/notification/:id", commonHandler(updateNotification))
auth.POST("/batch-delete/notification", commonHandler(batchDeleteNotification)) auth.POST("/batch-delete/notification", commonHandler(batchDeleteNotification))
auth.GET("/alert-rule", commonHandler(listAlertRule)) auth.GET("/alert-rule", listHandler(listAlertRule))
auth.POST("/alert-rule", commonHandler(createAlertRule)) auth.POST("/alert-rule", commonHandler(createAlertRule))
auth.PATCH("/alert-rule/:id", commonHandler(updateAlertRule)) auth.PATCH("/alert-rule/:id", commonHandler(updateAlertRule))
auth.POST("/batch-delete/alert-rule", commonHandler(batchDeleteAlertRule)) auth.POST("/batch-delete/alert-rule", commonHandler(batchDeleteAlertRule))
@ -231,6 +231,11 @@ func filter[S ~[]E, E model.CommonInterface](ctx *gin.Context, s S) S {
}) })
} }
func getUid(c *gin.Context) uint64 {
user, _ := c.MustGet(model.CtxKeyAuthorizedUser).(*model.User)
return user.ID
}
func fallbackToFrontend(frontendDist fs.FS) func(*gin.Context) { func fallbackToFrontend(frontendDist fs.FS) func(*gin.Context) {
checkLocalFileOrFs := func(c *gin.Context, fs fs.FS, path string) bool { checkLocalFileOrFs := func(c *gin.Context, fs fs.FS, path string) bool {
if _, err := os.Stat(path); err == nil { if _, err := os.Stat(path); err == nil {

View File

@ -20,7 +20,7 @@ import (
// @Produce json // @Produce json
// @Success 200 {object} model.CommonResponse[[]model.NotificationGroupResponseItem] // @Success 200 {object} model.CommonResponse[[]model.NotificationGroupResponseItem]
// @Router /notification-group [get] // @Router /notification-group [get]
func listNotificationGroup(c *gin.Context) ([]model.NotificationGroupResponseItem, error) { func listNotificationGroup(c *gin.Context) ([]*model.NotificationGroupResponseItem, error) {
var ng []model.NotificationGroup var ng []model.NotificationGroup
if err := singleton.DB.Find(&ng).Error; err != nil { if err := singleton.DB.Find(&ng).Error; err != nil {
return nil, err return nil, err
@ -39,9 +39,9 @@ func listNotificationGroup(c *gin.Context) ([]model.NotificationGroupResponseIte
groupNotifications[n.NotificationGroupID] = append(groupNotifications[n.NotificationGroupID], n.NotificationID) groupNotifications[n.NotificationGroupID] = append(groupNotifications[n.NotificationGroupID], n.NotificationID)
} }
ngRes := make([]model.NotificationGroupResponseItem, 0, len(ng)) ngRes := make([]*model.NotificationGroupResponseItem, 0, len(ng))
for _, n := range ng { for _, n := range ng {
ngRes = append(ngRes, model.NotificationGroupResponseItem{ ngRes = append(ngRes, &model.NotificationGroupResponseItem{
Group: n, Group: n,
Notifications: groupNotifications[n.ID], Notifications: groupNotifications[n.ID],
}) })

View File

@ -61,6 +61,10 @@ func updateServer(c *gin.Context) (any, error) {
return nil, singleton.Localizer.ErrorT("server id %d does not exist", id) return nil, singleton.Localizer.ErrorT("server id %d does not exist", id)
} }
if !s.HasPermission(c) {
return nil, singleton.Localizer.ErrorT("unauthorized")
}
s.Name = sf.Name s.Name = sf.Name
s.DisplayIndex = sf.DisplayIndex s.DisplayIndex = sf.DisplayIndex
s.Note = sf.Note s.Note = sf.Note
@ -99,11 +103,23 @@ func updateServer(c *gin.Context) (any, error) {
// @Success 200 {object} model.CommonResponse[any] // @Success 200 {object} model.CommonResponse[any]
// @Router /batch-delete/server [post] // @Router /batch-delete/server [post]
func batchDeleteServer(c *gin.Context) (any, error) { func batchDeleteServer(c *gin.Context) (any, error) {
var servers []uint64 var serversRaw []uint64
if err := c.ShouldBindJSON(&servers); err != nil { if err := c.ShouldBindJSON(&serversRaw); err != nil {
return nil, err return nil, err
} }
var servers []uint64
singleton.ServerLock.RLock()
for _, sid := range serversRaw {
if s, ok := singleton.ServerList[sid]; ok {
if !s.HasPermission(c) {
return nil, singleton.Localizer.ErrorT("permission denied")
}
servers = append(servers, s.ID)
}
}
singleton.ServerLock.RUnlock()
err := singleton.DB.Transaction(func(tx *gorm.DB) error { err := singleton.DB.Transaction(func(tx *gorm.DB) error {
if err := tx.Unscoped().Delete(&model.Server{}, "id in (?)", servers).Error; err != nil { if err := tx.Unscoped().Delete(&model.Server{}, "id in (?)", servers).Error; err != nil {
return err return err

View File

@ -190,7 +190,10 @@ func createService(c *gin.Context) (uint64, error) {
return 0, err return 0, err
} }
uid := getUid(c)
var m model.Service var m model.Service
m.UserID = uid
m.Name = mf.Name m.Name = mf.Name
m.Target = strings.TrimSpace(mf.Target) m.Target = strings.TrimSpace(mf.Target)
m.Type = mf.Type m.Type = mf.Type

View File

@ -23,6 +23,10 @@ type Common struct {
UserID uint64 `json:"user_id,omitempty"` UserID uint64 `json:"user_id,omitempty"`
} }
func (c *Common) GetID() uint64 {
return c.ID
}
func (c *Common) HasPermission(ctx *gin.Context) bool { func (c *Common) HasPermission(ctx *gin.Context) bool {
auth, ok := ctx.Get(CtxKeyAuthorizedUser) auth, ok := ctx.Get(CtxKeyAuthorizedUser)
if !ok { if !ok {
@ -38,6 +42,7 @@ func (c *Common) HasPermission(ctx *gin.Context) bool {
} }
type CommonInterface interface { type CommonInterface interface {
GetID() uint64
HasPermission(*gin.Context) bool HasPermission(*gin.Context) bool
} }

View File

@ -1,7 +1,5 @@
package model package model
import "github.com/gin-gonic/gin"
type ServerGroupForm struct { type ServerGroupForm struct {
Name string `json:"name" minLength:"1"` Name string `json:"name" minLength:"1"`
Servers []uint64 `json:"servers"` Servers []uint64 `json:"servers"`
@ -11,7 +9,3 @@ type ServerGroupResponseItem struct {
Group ServerGroup `json:"group"` Group ServerGroup `json:"group"`
Servers []uint64 `json:"servers"` Servers []uint64 `json:"servers"`
} }
func (sg *ServerGroupResponseItem) HasPermission(c *gin.Context) bool {
return sg.Group.HasPermission(c)
}