mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-18 06:29:42 +02:00
fix(api/proxmox): add websocket validation to journalctl and tail endpoints
Add required websocket check at the beginning of both journalctl and tail endpoint handlers to ensure these endpoints only accept websocket connections.
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/yusing/godoxy/internal/proxmox"
|
"github.com/yusing/godoxy/internal/proxmox"
|
||||||
"github.com/yusing/goutils/apitypes"
|
"github.com/yusing/goutils/apitypes"
|
||||||
|
"github.com/yusing/goutils/http/httpheaders"
|
||||||
"github.com/yusing/goutils/http/websocket"
|
"github.com/yusing/goutils/http/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,10 +16,10 @@ import (
|
|||||||
// e.g. ws://localhost:8889/api/v1/proxmox/journalctl/pve/127?service=pveproxy&service=pvedaemon&limit=10
|
// e.g. ws://localhost:8889/api/v1/proxmox/journalctl/pve/127?service=pveproxy&service=pvedaemon&limit=10
|
||||||
|
|
||||||
type JournalctlRequest struct {
|
type JournalctlRequest struct {
|
||||||
Node string `form:"node" uri:"node" binding:"required"` // Node name
|
Node string `form:"node" uri:"node" binding:"required"` // Node name
|
||||||
VMID *int `form:"vmid" uri:"vmid"` // Container VMID (optional - if not provided, streams node journalctl)
|
VMID *int `form:"vmid" uri:"vmid"` // Container VMID (optional - if not provided, streams node journalctl)
|
||||||
Services []string `form:"service" uri:"service"` // Service names
|
Services []string `form:"service" uri:"service"` // Service names
|
||||||
Limit *int `form:"limit" uri:"limit" default:"100" binding:"min=1,max=1000"` // Limit output lines (1-1000)
|
Limit *int `form:"limit" uri:"limit" default:"100" binding:"omitempty,min=1,max=1000"` // Limit output lines (1-1000)
|
||||||
} // @name ProxmoxJournalctlRequest
|
} // @name ProxmoxJournalctlRequest
|
||||||
|
|
||||||
// @x-id "journalctl"
|
// @x-id "journalctl"
|
||||||
@@ -40,6 +41,11 @@ type JournalctlRequest struct {
|
|||||||
// @Router /proxmox/journalctl/{node}/{vmid} [get]
|
// @Router /proxmox/journalctl/{node}/{vmid} [get]
|
||||||
// @Router /proxmox/journalctl/{node}/{vmid}/{service} [get]
|
// @Router /proxmox/journalctl/{node}/{vmid}/{service} [get]
|
||||||
func Journalctl(c *gin.Context) {
|
func Journalctl(c *gin.Context) {
|
||||||
|
if !httpheaders.IsWebsocket(c.Request.Header) {
|
||||||
|
c.JSON(http.StatusBadRequest, apitypes.Error("websocket required"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var request JournalctlRequest
|
var request JournalctlRequest
|
||||||
uriErr := c.ShouldBindUri(&request)
|
uriErr := c.ShouldBindUri(&request)
|
||||||
queryErr := c.ShouldBindQuery(&request)
|
queryErr := c.ShouldBindQuery(&request)
|
||||||
@@ -48,6 +54,10 @@ func Journalctl(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if request.Limit == nil {
|
||||||
|
request.Limit = new(100)
|
||||||
|
}
|
||||||
|
|
||||||
node, ok := proxmox.Nodes.Get(request.Node)
|
node, ok := proxmox.Nodes.Get(request.Node)
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(http.StatusNotFound, apitypes.Error("node not found"))
|
c.JSON(http.StatusNotFound, apitypes.Error("node not found"))
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/yusing/godoxy/internal/proxmox"
|
"github.com/yusing/godoxy/internal/proxmox"
|
||||||
"github.com/yusing/goutils/apitypes"
|
"github.com/yusing/goutils/apitypes"
|
||||||
|
"github.com/yusing/goutils/http/httpheaders"
|
||||||
"github.com/yusing/goutils/http/websocket"
|
"github.com/yusing/goutils/http/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -34,6 +35,11 @@ type TailRequest struct {
|
|||||||
// @Failure 500 {object} apitypes.ErrorResponse "Internal server error"
|
// @Failure 500 {object} apitypes.ErrorResponse "Internal server error"
|
||||||
// @Router /proxmox/tail [get]
|
// @Router /proxmox/tail [get]
|
||||||
func Tail(c *gin.Context) {
|
func Tail(c *gin.Context) {
|
||||||
|
if !httpheaders.IsWebsocket(c.Request.Header) {
|
||||||
|
c.JSON(http.StatusBadRequest, apitypes.Error("websocket required"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var request TailRequest
|
var request TailRequest
|
||||||
if err := c.ShouldBindQuery(&request); err != nil {
|
if err := c.ShouldBindQuery(&request); err != nil {
|
||||||
c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", err))
|
c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", err))
|
||||||
|
|||||||
Reference in New Issue
Block a user