admin handler

This commit is contained in:
uubulb 2024-12-17 22:33:47 +08:00
parent 0caca56dfd
commit e39e793b5b
4 changed files with 67 additions and 34 deletions

View File

@ -80,8 +80,8 @@ func routers(r *gin.Engine, frontendDist fs.FS) {
auth.GET("/profile", commonHandler(getProfile)) auth.GET("/profile", commonHandler(getProfile))
auth.POST("/profile", commonHandler(updateProfile)) auth.POST("/profile", commonHandler(updateProfile))
auth.GET("/user", commonHandler(listUser)) auth.GET("/user", commonHandler(listUser))
auth.POST("/user", commonHandler(createUser)) auth.POST("/user", adminHandler(createUser))
auth.POST("/batch-delete/user", commonHandler(batchDeleteUser)) auth.POST("/batch-delete/user", adminHandler(batchDeleteUser))
auth.GET("/service/list", listHandler(listService)) auth.GET("/service/list", listHandler(listService))
auth.POST("/service", commonHandler(createService)) auth.POST("/service", commonHandler(createService))
@ -130,9 +130,9 @@ func routers(r *gin.Engine, frontendDist fs.FS) {
auth.POST("/batch-delete/nat", commonHandler(batchDeleteNAT)) auth.POST("/batch-delete/nat", commonHandler(batchDeleteNAT))
auth.GET("/waf", commonHandler(listBlockedAddress)) auth.GET("/waf", commonHandler(listBlockedAddress))
auth.POST("/batch-delete/waf", commonHandler(batchDeleteBlockedAddress)) auth.POST("/batch-delete/waf", adminHandler(batchDeleteBlockedAddress))
auth.PATCH("/setting", commonHandler(updateConfig)) auth.PATCH("/setting", adminHandler(updateConfig))
r.NoRoute(fallbackToFrontend(frontendDist)) r.NoRoute(fallbackToFrontend(frontendDist))
} }
@ -190,26 +190,48 @@ func (we *wsError) Error() string {
func commonHandler[T any](handler handlerFunc[T]) func(*gin.Context) { func commonHandler[T any](handler handlerFunc[T]) func(*gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
data, err := handler(c) handle(c, handler)
if err == nil { }
c.JSON(http.StatusOK, model.CommonResponse[T]{Success: true, Data: data}) }
func adminHandler[T any](handler handlerFunc[T]) func(*gin.Context) {
return func(c *gin.Context) {
auth, ok := c.Get(model.CtxKeyAuthorizedUser)
if !ok {
c.JSON(http.StatusOK, newErrorResponse(singleton.Localizer.ErrorT("unauthorized")))
return return
} }
switch err.(type) {
case *gormError: user := *auth.(*model.User)
log.Printf("NEZHA>> gorm error: %v", err) if user.Role != model.RoleAdmin {
c.JSON(http.StatusOK, newErrorResponse(singleton.Localizer.ErrorT("database error"))) c.JSON(http.StatusOK, newErrorResponse(singleton.Localizer.ErrorT("permission denied")))
return
case *wsError:
// Connection is upgraded to WebSocket, so c.Writer is no longer usable
if msg := err.Error(); msg != "" {
log.Printf("NEZHA>> websocket error: %v", err)
}
return
default:
c.JSON(http.StatusOK, newErrorResponse(err))
return return
} }
handle(c, handler)
}
}
func handle[T any](c *gin.Context, handler handlerFunc[T]) {
data, err := handler(c)
if err == nil {
c.JSON(http.StatusOK, model.CommonResponse[T]{Success: true, Data: data})
return
}
switch err.(type) {
case *gormError:
log.Printf("NEZHA>> gorm error: %v", err)
c.JSON(http.StatusOK, newErrorResponse(singleton.Localizer.ErrorT("database error")))
return
case *wsError:
// Connection is upgraded to WebSocket, so c.Writer is no longer usable
if msg := err.Error(); msg != "" {
log.Printf("NEZHA>> websocket error: %v", err)
}
return
default:
c.JSON(http.StatusOK, newErrorResponse(err))
return
} }
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/hashicorp/go-uuid" "github.com/hashicorp/go-uuid"
"github.com/nezhahq/nezha/model" "github.com/nezhahq/nezha/model"
"github.com/nezhahq/nezha/pkg/utils" "github.com/nezhahq/nezha/pkg/utils"
"github.com/nezhahq/nezha/pkg/websocketx" "github.com/nezhahq/nezha/pkg/websocketx"
@ -31,13 +32,6 @@ func createFM(c *gin.Context) (*model.CreateFMResponse, error) {
return nil, err return nil, err
} }
streamId, err := uuid.GenerateUUID()
if err != nil {
return nil, err
}
rpc.NezhaHandlerSingleton.CreateStream(streamId)
singleton.ServerLock.RLock() singleton.ServerLock.RLock()
server := singleton.ServerList[id] server := singleton.ServerList[id]
singleton.ServerLock.RUnlock() singleton.ServerLock.RUnlock()
@ -45,6 +39,17 @@ func createFM(c *gin.Context) (*model.CreateFMResponse, error) {
return nil, singleton.Localizer.ErrorT("server not found or not connected") return nil, singleton.Localizer.ErrorT("server not found or not connected")
} }
if !server.HasPermission(c) {
return nil, singleton.Localizer.ErrorT("permission denied")
}
streamId, err := uuid.GenerateUUID()
if err != nil {
return nil, err
}
rpc.NezhaHandlerSingleton.CreateStream(streamId)
fmData, _ := utils.Json.Marshal(&model.TaskFM{ fmData, _ := utils.Json.Marshal(&model.TaskFM{
StreamID: streamId, StreamID: streamId,
}) })

View File

@ -6,6 +6,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/hashicorp/go-uuid" "github.com/hashicorp/go-uuid"
"github.com/nezhahq/nezha/model" "github.com/nezhahq/nezha/model"
"github.com/nezhahq/nezha/pkg/utils" "github.com/nezhahq/nezha/pkg/utils"
"github.com/nezhahq/nezha/pkg/websocketx" "github.com/nezhahq/nezha/pkg/websocketx"
@ -29,13 +30,6 @@ func createTerminal(c *gin.Context) (*model.CreateTerminalResponse, error) {
return nil, err return nil, err
} }
streamId, err := uuid.GenerateUUID()
if err != nil {
return nil, err
}
rpc.NezhaHandlerSingleton.CreateStream(streamId)
singleton.ServerLock.RLock() singleton.ServerLock.RLock()
server := singleton.ServerList[createTerminalReq.ServerID] server := singleton.ServerList[createTerminalReq.ServerID]
singleton.ServerLock.RUnlock() singleton.ServerLock.RUnlock()
@ -43,6 +37,17 @@ func createTerminal(c *gin.Context) (*model.CreateTerminalResponse, error) {
return nil, singleton.Localizer.ErrorT("server not found or not connected") return nil, singleton.Localizer.ErrorT("server not found or not connected")
} }
if !server.HasPermission(c) {
return nil, singleton.Localizer.ErrorT("permission denied")
}
streamId, err := uuid.GenerateUUID()
if err != nil {
return nil, err
}
rpc.NezhaHandlerSingleton.CreateStream(streamId)
terminalData, _ := utils.Json.Marshal(&model.TerminalTask{ terminalData, _ := utils.Json.Marshal(&model.TerminalTask{
StreamID: streamId, StreamID: streamId,
}) })

View File

@ -114,6 +114,7 @@ func createUser(c *gin.Context) (uint64, error) {
var u model.User var u model.User
u.Username = uf.Username u.Username = uf.Username
u.Role = model.RoleMember
hash, err := bcrypt.GenerateFromPassword([]byte(uf.Password), bcrypt.DefaultCost) hash, err := bcrypt.GenerateFromPassword([]byte(uf.Password), bcrypt.DefaultCost)
if err != nil { if err != nil {