nezha/cmd/dashboard/controller/api_v1.go
2024-11-06 23:38:15 +08:00

153 lines
3.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package controller
import (
"strconv"
"strings"
"github.com/gin-gonic/gin"
"github.com/naiba/nezha/model"
"github.com/naiba/nezha/pkg/mygin"
"github.com/naiba/nezha/service/singleton"
)
type apiV1 struct {
r gin.IRouter
}
func (v *apiV1) serve() {
r := v.r.Group("")
// 强制认证的 API
r.Use(mygin.Authorize(mygin.AuthorizeOption{
MemberOnly: true,
AllowAPI: true,
IsPage: false,
Msg: "访问此接口需要认证",
Btn: "点此登录",
Redirect: "/login",
}))
r.GET("/server/list", v.serverList)
r.GET("/server/details", v.serverDetails)
r.POST("/server/register", v.RegisterServer)
// 不强制认证的 API
mr := v.r.Group("monitor")
mr.Use(mygin.Authorize(mygin.AuthorizeOption{
MemberOnly: false,
IsPage: false,
AllowAPI: true,
Msg: "访问此接口需要认证",
Btn: "点此登录",
Redirect: "/login",
}))
mr.Use(mygin.ValidateViewPassword(mygin.ValidateViewPasswordOption{
IsPage: false,
AbortWhenFail: true,
}))
mr.GET("/:id", v.monitorHistoriesById)
}
// serverList 获取服务器列表 不传入Query参数则获取全部
// header: Authorization: Token
// query: tag (服务器分组)
func (v *apiV1) serverList(c *gin.Context) {
tag := c.Query("tag")
if tag != "" {
c.JSON(200, singleton.ServerAPI.GetListByTag(tag))
return
}
c.JSON(200, singleton.ServerAPI.GetAllList())
}
// serverDetails 获取服务器信息 不传入Query参数则获取全部
// header: Authorization: Token
// query: id (服务器ID逗号分隔优先级高于tag查询)
// query: tag (服务器分组)
func (v *apiV1) serverDetails(c *gin.Context) {
var idList []uint64
idListStr := strings.Split(c.Query("id"), ",")
if c.Query("id") != "" {
idList = make([]uint64, len(idListStr))
for i, v := range idListStr {
id, _ := strconv.ParseUint(v, 10, 64)
idList[i] = id
}
}
tag := c.Query("tag")
if tag != "" {
c.JSON(200, singleton.ServerAPI.GetStatusByTag(tag))
return
}
if len(idList) != 0 {
c.JSON(200, singleton.ServerAPI.GetStatusByIDList(idList))
return
}
c.JSON(200, singleton.ServerAPI.GetAllStatus())
}
// RegisterServer adds a server and responds with the full ServerRegisterResponse
// header: Authorization: Token
// body: RegisterServer
// response: ServerRegisterResponse or Secret string
func (v *apiV1) RegisterServer(c *gin.Context) {
var rs singleton.RegisterServer
// Attempt to bind JSON to RegisterServer struct
if err := c.ShouldBindJSON(&rs); err != nil {
c.JSON(400, singleton.ServerRegisterResponse{
CommonResponse: singleton.CommonResponse{
Code: 400,
Message: "Parse JSON failed",
},
})
return
}
// Check if simple mode is requested
simple := c.Query("simple") == "true" || c.Query("simple") == "1"
// Set defaults if fields are empty
if rs.Name == "" {
rs.Name = c.ClientIP()
}
if rs.Tag == "" {
rs.Tag = "AutoRegister"
}
if rs.HideForGuest == "" {
rs.HideForGuest = "on"
}
// Call the Register function and get the response
response := singleton.ServerAPI.Register(&rs)
// Respond with Secret only if in simple mode, otherwise full response
if simple {
c.JSON(response.Code, response.Secret)
} else {
c.JSON(response.Code, response)
}
}
func (v *apiV1) monitorHistoriesById(c *gin.Context) {
idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 64)
if err != nil {
c.AbortWithStatusJSON(400, gin.H{"code": 400, "message": "id参数错误"})
return
}
server, ok := singleton.ServerList[id]
if !ok {
c.AbortWithStatusJSON(404, gin.H{
"code": 404,
"message": "id不存在",
})
return
}
_, isMember := c.Get(model.CtxKeyAuthorizedUser)
_, isViewPasswordVerfied := c.Get(model.CtxKeyViewPasswordVerified)
authorized := isMember || isViewPasswordVerfied
if server.HideForGuest && !authorized {
c.AbortWithStatusJSON(403, gin.H{"code": 403, "message": "需要认证"})
return
}
c.JSON(200, singleton.MonitorAPI.GetMonitorHistories(map[string]any{"server_id": server.ID}))
}