Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
valerie 2024-12-23 19:04:59 -05:00
commit af6ee6ab66
Signed by: valnyx
GPG key ID: CC10324DD962CB7E

View file

@ -8,6 +8,7 @@ import (
"git.terah.dev/imterah/hermes/api/dbcore" "git.terah.dev/imterah/hermes/api/dbcore"
"git.terah.dev/imterah/hermes/api/jwtcore" "git.terah.dev/imterah/hermes/api/jwtcore"
"git.terah.dev/imterah/hermes/api/permissions" "git.terah.dev/imterah/hermes/api/permissions"
"git.terah.dev/imterah/hermes/commonbackend"
"github.com/charmbracelet/log" "github.com/charmbracelet/log"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
@ -18,17 +19,22 @@ type ConnectionsRequest struct {
Id uint `validate:"required" json:"id"` Id uint `validate:"required" json:"id"`
} }
type SanitizedBackends struct { type ConnectionDetailsForConnection struct {
UserID uint `json:"user_id"` SourceIP string `json:"sourceIP"`
Name string `json:"name"` SourcePort uint16 `json:"sourcePort"`
Description string `json:"description"` DestPort uint16 `json:"destPort"`
Backend string `json:"backend"` }
BackendParameters string `json:"backend_parameters"`
type SanitizedConnection struct {
ClientIP string `json:"ip"`
Port uint16 `json:"port"`
ConnectionDetails *ConnectionDetailsForConnection `json:"connectionDetails"`
} }
type ConnectionsResponse struct { type ConnectionsResponse struct {
Success bool `json:"success"` Success bool `json:"success"`
Data []*SanitizedBackends `json:"data"` Data []*SanitizedConnection `json:"data"`
} }
func Connections(c *gin.Context) { func Connections(c *gin.Context) {
@ -62,7 +68,7 @@ func Connections(c *gin.Context) {
log.Warnf("Failed to get user from the provided JWT token: %s", err.Error()) log.Warnf("Failed to get user from the provided JWT token: %s", err.Error())
c.JSON(http.StatusInternalServerError, gin.H{ c.JSON(http.StatusInternalServerError, gin.H{
"error": "failed to parse token", "error": "Failed to parse token",
}) })
return return
@ -77,11 +83,11 @@ func Connections(c *gin.Context) {
return return
} }
var routes []dbcore.Proxy var proxy dbcore.Proxy
routesRequest := dbcore.DB.Where("id = ?", req.Id).First(&routes) proxyRequest := dbcore.DB.Where("id = ?", req.Id).First(&proxy)
if routesRequest.Error != nil { if proxyRequest.Error != nil {
log.Warnf("failed to find proxy: %s", routesRequest.Error) log.Warnf("failed to find proxy: %s", proxyRequest.Error)
c.JSON(http.StatusInternalServerError, gin.H{ c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to find forward entry", "error": "Failed to find forward entry",
@ -90,9 +96,9 @@ func Connections(c *gin.Context) {
return return
} }
routesExist := routesRequest.RowsAffected > 0 proxyExists := proxyRequest.RowsAffected > 0
if !routesExist { if !proxyExists {
c.JSON(http.StatusBadRequest, gin.H{ c.JSON(http.StatusBadRequest, gin.H{
"error": "No forward entry found", "error": "No forward entry found",
}) })
@ -100,13 +106,81 @@ func Connections(c *gin.Context) {
return return
} }
// FIXME(greysoh): not finished var backend dbcore.Backend
var backends []dbcore.Backend backendRequest := dbcore.DB.Where("id = ?", proxy.BackendID).First(&backend)
sanitizedBackends := make([]*SanitizedBackends, len(backends)) if backendRequest.Error != nil {
log.Warnf("failed to find backend: %s", backendRequest.Error)
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusInternalServerError, gin.H{
"success": true, "error": "Failed to find backend entry",
"data": sanitizedBackends,
}) })
return
}
backendExists := backendRequest.RowsAffected > 0
if !backendExists {
c.JSON(http.StatusBadRequest, gin.H{
"error": "No forward entry found",
})
return
}
backendRuntime, ok := backendruntime.RunningBackends[backend.ID]
if !ok {
log.Warnf("Couldn't fetch backend runtime from backend ID #%d", backend.ID)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Couldn't fetch backend runtime",
})
return
}
backendRuntime.RuntimeCommands <- &commonbackend.ProxyConnectionsRequest{
Type: "proxyConnectionsRequest",
}
backendResponse := <-backendRuntime.RuntimeCommands
switch responseMessage := backendResponse.(type) {
case error:
log.Warnf("Failed to get response for backend: %s", responseMessage.Error())
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to get status response from backend",
})
case *commonbackend.ProxyConnectionsResponse:
sanitizedConnections := []*SanitizedConnection{}
for _, connection := range responseMessage.Connections {
if connection.SourceIP == proxy.SourceIP && connection.SourcePort == proxy.SourcePort && proxy.DestinationPort == proxy.DestinationPort {
sanitizedConnections = append(sanitizedConnections, &SanitizedConnection{
ClientIP: connection.ClientIP,
Port: connection.ClientPort,
ConnectionDetails: &ConnectionDetailsForConnection{
SourceIP: proxy.SourceIP,
SourcePort: proxy.SourcePort,
DestPort: proxy.DestinationPort,
},
})
}
}
c.JSON(http.StatusOK, &ConnectionsResponse{
Success: true,
Data: sanitizedConnections,
})
default:
log.Warnf("Got illegal response type for backend: %T", responseMessage)
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Got illegal response type",
})
}
} }