re-refactor code
This commit is contained in:
@@ -1,138 +1,16 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"emperror.dev/errors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/pterodactyl/wings/config"
|
||||
"github.com/pterodactyl/wings/router/middleware"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
)
|
||||
|
||||
type Middleware struct {
|
||||
serverManager server.Manager
|
||||
}
|
||||
|
||||
// A custom handler function allowing for errors bubbled up by c.Error() to be returned in a
|
||||
// standardized format with tracking UUIDs on them for easier log searching.
|
||||
func (m *Middleware) ErrorHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Next()
|
||||
err := c.Errors.Last()
|
||||
if err == nil || err.Err == nil {
|
||||
return
|
||||
}
|
||||
tracked := NewTrackedError(err.Err)
|
||||
// If there is a server in the context for this request pull it out so that we can
|
||||
// track the error specifically for that server.
|
||||
if s, ok := c.Get("server"); ok {
|
||||
tracked = NewServerError(err.Err, s.(*server.Server))
|
||||
}
|
||||
// This error occurs if you submit invalid JSON data to an endpoint.
|
||||
if err.Err.Error() == io.EOF.Error() {
|
||||
c.JSON(c.Writer.Status(), gin.H{"error": "A JSON formatted body is required for this endpoint."})
|
||||
return
|
||||
}
|
||||
tracked.Abort(c)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Set the access request control headers on all of the requests.
|
||||
func (m *Middleware) SetAccessControlHeaders() gin.HandlerFunc {
|
||||
origins := config.Get().AllowedOrigins
|
||||
location := config.Get().PanelLocation
|
||||
return func(c *gin.Context) {
|
||||
c.Header("Access-Control-Allow-Credentials", "true")
|
||||
c.Header("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS")
|
||||
c.Header("Access-Control-Allow-Headers", "Accept, Accept-Encoding, Authorization, Cache-Control, Content-Type, Content-Length, Origin, X-Real-IP, X-CSRF-Token")
|
||||
|
||||
o := c.GetHeader("Origin")
|
||||
if o != location {
|
||||
for _, origin := range origins {
|
||||
if origin != "*" && o != origin {
|
||||
continue
|
||||
}
|
||||
c.Header("Access-Control-Allow-Origin", origin)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
}
|
||||
c.Header("Access-Control-Allow-Origin", location)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// Authenticates the request token against the given permission string, ensuring that
|
||||
// if it is a server permission, the token has control over that server. If it is a global
|
||||
// token, this will ensure that the request is using a properly signed global token.
|
||||
func (m *Middleware) RequireAuthorization() gin.HandlerFunc {
|
||||
token := config.Get().AuthenticationToken
|
||||
return func(c *gin.Context) {
|
||||
auth := strings.SplitN(c.GetHeader("Authorization"), " ", 2)
|
||||
if len(auth) != 2 || auth[0] != "Bearer" {
|
||||
c.Header("WWW-Authenticate", "Bearer")
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
|
||||
"error": "The required authorization heads were not present in the request.",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// All requests to Wings must be authorized with the authentication token present in
|
||||
// the Wings configuration file. Remeber, all requests to Wings come from the Panel
|
||||
// backend, or using a signed JWT for temporary authentication.
|
||||
if auth[1] == token {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
|
||||
"error": "You are not authorized to access this endpoint.",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Middleware) WithServerManager() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Set("servermanager", m.serverManager)
|
||||
}
|
||||
}
|
||||
|
||||
func ExtractServerManager(c *gin.Context) server.Manager {
|
||||
if s, ok := c.Get("servermanager"); ok {
|
||||
if srvs, ok := s.(server.Manager); ok {
|
||||
return srvs
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ensure that the requested server exists in this setup. Returns a 404 if we cannot
|
||||
// locate it.
|
||||
func (m *Middleware) ServerExists() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
u, err := uuid.Parse(c.Param("server"))
|
||||
if err == nil {
|
||||
if s := m.serverManager.Get(u.String()); s != nil {
|
||||
c.Set("server", s)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
}
|
||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
|
||||
"error": "The resource you requested does not exist.",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the server instance from the gin context. If there is no server set in the
|
||||
// context (e.g. calling from a controller not protected by ServerExists) this function
|
||||
// will panic.
|
||||
// ExtractServer returns the server instance from the gin context. If there is
|
||||
// no server set in the context (e.g. calling from a controller not protected
|
||||
// by ServerExists) this function will panic.
|
||||
//
|
||||
// This function is deprecated. Use middleware.ExtractServer.
|
||||
func ExtractServer(c *gin.Context) *server.Server {
|
||||
if s, ok := c.Get("server"); ok {
|
||||
return s.(*server.Server)
|
||||
}
|
||||
panic(errors.New("cannot extract server, missing on gin context"))
|
||||
return middleware.ExtractServer(c)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user