Remove more unused files, fix issue with CORS on /api/system, fix issue with GET /api/servers/:server/archive
This commit is contained in:
parent
718b126baf
commit
f5a804210f
|
@ -1,34 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gbrlsnchs/jwt/v3"
|
|
||||||
"github.com/pterodactyl/wings/config"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var alg *jwt.HMACSHA
|
|
||||||
|
|
||||||
// ArchiveTokenPayload represents an Archive Token Payload.
|
|
||||||
type ArchiveTokenPayload struct {
|
|
||||||
jwt.Payload
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseArchiveJWT(token []byte) (*ArchiveTokenPayload, error) {
|
|
||||||
var payload ArchiveTokenPayload
|
|
||||||
if alg == nil {
|
|
||||||
alg = jwt.NewHS256([]byte(config.Get().AuthenticationToken))
|
|
||||||
}
|
|
||||||
|
|
||||||
now := time.Now()
|
|
||||||
verifyOptions := jwt.ValidatePayload(
|
|
||||||
&payload.Payload,
|
|
||||||
jwt.ExpirationTimeValidator(now),
|
|
||||||
)
|
|
||||||
|
|
||||||
_, err := jwt.Verify(token, alg, &payload, verifyOptions)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &payload, nil
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gbrlsnchs/jwt/v3"
|
|
||||||
cache2 "github.com/patrickmn/go-cache"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type JWTokens struct {
|
|
||||||
cache *cache2.Cache
|
|
||||||
mutex *sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
var _tokens *JWTokens
|
|
||||||
|
|
||||||
type DownloadBackupPayload struct {
|
|
||||||
jwt.Payload
|
|
||||||
ServerUuid string `json:"server_uuid"`
|
|
||||||
BackupUuid string `json:"backup_uuid"`
|
|
||||||
UniqueId string `json:"unique_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTokenStore() *JWTokens {
|
|
||||||
if _tokens == nil {
|
|
||||||
_tokens = &JWTokens{
|
|
||||||
cache: cache2.New(time.Minute*60, time.Minute*5),
|
|
||||||
mutex: &sync.Mutex{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _tokens
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determines if a given JWT unique token is valid.
|
|
||||||
func (tokens *JWTokens) IsValidToken(token string) bool {
|
|
||||||
tokens.mutex.Lock()
|
|
||||||
defer tokens.mutex.Unlock()
|
|
||||||
|
|
||||||
_, exists := tokens.cache.Get(token)
|
|
||||||
|
|
||||||
if !exists {
|
|
||||||
_tokens.cache.Add(token, "", time.Minute*60)
|
|
||||||
}
|
|
||||||
|
|
||||||
return !exists
|
|
||||||
}
|
|
|
@ -1,20 +1,31 @@
|
||||||
package router
|
package router
|
||||||
|
|
||||||
import "github.com/gin-gonic/gin"
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
// Configures the routing infrastructure for this daemon instance.
|
// Configures the routing infrastructure for this daemon instance.
|
||||||
func Configure() *gin.Engine {
|
func Configure() *gin.Engine {
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
router.Use(SetAccessControlHeaders)
|
router.Use(SetAccessControlHeaders)
|
||||||
|
|
||||||
|
router.OPTIONS("/api/system", func(c *gin.Context) {
|
||||||
|
c.Status(200)
|
||||||
|
})
|
||||||
|
|
||||||
// These routes use signed URLs to validate access to the resource being requested.
|
// These routes use signed URLs to validate access to the resource being requested.
|
||||||
router.GET("/download/backup", getDownloadBackup)
|
router.GET("/download/backup", getDownloadBackup)
|
||||||
|
|
||||||
// This route is special is sits above all of the other requests because we are
|
// This route is special it sits above all of the other requests because we are
|
||||||
// using a JWT to authorize access to it, therefore it needs to be publically
|
// using a JWT to authorize access to it, therefore it needs to be publicly
|
||||||
// accessible.
|
// accessible.
|
||||||
router.GET("/api/servers/:server/ws", getServerWebsocket)
|
router.GET("/api/servers/:server/ws", getServerWebsocket)
|
||||||
|
|
||||||
|
// This request is called by another daemon when a server is going to be transferred out.
|
||||||
|
// This request does not need the AuthorizationMiddleware as the panel should never call it
|
||||||
|
// and requests are authenticated through a JWT the panel issues to the other daemon.
|
||||||
|
router.GET("/api/servers/:server/archive", getServerArchive)
|
||||||
|
|
||||||
// All of the routes beyond this mount will use an authorization middleware
|
// All of the routes beyond this mount will use an authorization middleware
|
||||||
// and will not be accessible without the correct Authorization header provided.
|
// and will not be accessible without the correct Authorization header provided.
|
||||||
protected := router.Use(AuthorizationMiddleware)
|
protected := router.Use(AuthorizationMiddleware)
|
||||||
|
@ -39,7 +50,8 @@ func Configure() *gin.Engine {
|
||||||
server.POST("/reinstall", postServerReinstall)
|
server.POST("/reinstall", postServerReinstall)
|
||||||
server.POST("/backup", postServerBackup)
|
server.POST("/backup", postServerBackup)
|
||||||
|
|
||||||
server.GET("/archive", getServerArchive)
|
// This archive request causes the archive to start being created
|
||||||
|
// this should only be triggered by the panel.
|
||||||
server.POST("/archive", postServerArchive)
|
server.POST("/archive", postServerArchive)
|
||||||
|
|
||||||
files := server.Group("/files")
|
files := server.Group("/files")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/pterodactyl/wings/installer"
|
"github.com/pterodactyl/wings/installer"
|
||||||
"github.com/pterodactyl/wings/server"
|
"github.com/pterodactyl/wings/server"
|
||||||
|
@ -30,10 +31,10 @@ func getAllServers(c *gin.Context) {
|
||||||
// Creates a new server on the wings daemon and begins the installation process
|
// Creates a new server on the wings daemon and begins the installation process
|
||||||
// for it.
|
// for it.
|
||||||
func postCreateServer(c *gin.Context) {
|
func postCreateServer(c *gin.Context) {
|
||||||
var data []byte
|
buf := bytes.Buffer{}
|
||||||
c.Bind(&data)
|
buf.ReadFrom(c.Request.Body)
|
||||||
|
|
||||||
install, err := installer.New(data)
|
install, err := installer.New(buf.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
TrackedError(err).
|
TrackedError(err).
|
||||||
SetMessage("Failed to validate the data provided in the request.").
|
SetMessage("Failed to validate the data provided in the request.").
|
||||||
|
@ -61,4 +62,4 @@ func postCreateServer(c *gin.Context) {
|
||||||
}(install)
|
}(install)
|
||||||
|
|
||||||
c.Status(http.StatusAccepted)
|
c.Status(http.StatusAccepted)
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,14 +37,14 @@ func getServerArchive(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
token := tokens.TransferPayload{}
|
token := tokens.TransferPayload{}
|
||||||
if err := tokens.ParseToken([]byte(c.Query("token")), &token); err != nil {
|
if err := tokens.ParseToken([]byte(auth[1]), &token); err != nil {
|
||||||
TrackedError(err).AbortWithServerError(c)
|
TrackedError(err).AbortWithServerError(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if token.Subject != c.Param("server") {
|
if token.Subject != c.Param("server") {
|
||||||
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
|
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
|
||||||
"error": "You are not authorized to access this endpoint.",
|
"error": "( ..•˘___˘• .. )",
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,6 @@ func getServerArchive(c *gin.Context) {
|
||||||
st, err := s.Archiver.Stat()
|
st, err := s.Archiver.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
// zap.S().Errorw("failed to stat archive for reading", zap.String("server", s.Uuid), zap.Error(err))
|
|
||||||
TrackedServerError(err, s).SetMessage("failed to stat archive").AbortWithServerError(c)
|
TrackedServerError(err, s).SetMessage("failed to stat archive").AbortWithServerError(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -65,7 +64,6 @@ func getServerArchive(c *gin.Context) {
|
||||||
|
|
||||||
checksum, err := s.Archiver.Checksum()
|
checksum, err := s.Archiver.Checksum()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// zap.S().Errorw("failed to calculate checksum", zap.String("server", s.Uuid), zap.Error(err))
|
|
||||||
TrackedServerError(err, s).SetMessage("failed to calculate checksum").AbortWithServerError(c)
|
TrackedServerError(err, s).SetMessage("failed to calculate checksum").AbortWithServerError(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -75,7 +73,6 @@ func getServerArchive(c *gin.Context) {
|
||||||
tserr := TrackedServerError(err, s)
|
tserr := TrackedServerError(err, s)
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
tserr.SetMessage("failed to open archive for reading")
|
tserr.SetMessage("failed to open archive for reading")
|
||||||
// zap.S().Errorw("failed to open archive for reading", zap.String("server", s.Uuid), zap.Error(err))
|
|
||||||
} else {
|
} else {
|
||||||
tserr.SetMessage("failed to open archive")
|
tserr.SetMessage("failed to open archive")
|
||||||
}
|
}
|
||||||
|
@ -271,8 +268,6 @@ func postTransfer(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
zap.S().Debug(string(serverData))
|
|
||||||
|
|
||||||
// Create a new server installer (note this does not execute the install script)
|
// Create a new server installer (note this does not execute the install script)
|
||||||
i, err := installer.New(serverData)
|
i, err := installer.New(serverData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -287,8 +282,19 @@ func postTransfer(c *gin.Context) {
|
||||||
i.Execute()
|
i.Execute()
|
||||||
|
|
||||||
// Un-archive the archive. That sounds weird..
|
// Un-archive the archive. That sounds weird..
|
||||||
archiver.NewTarGz().Unarchive(archivePath, i.Server().Filesystem.Path())
|
if err := archiver.NewTarGz().Unarchive(archivePath, i.Server().Filesystem.Path()); err != nil {
|
||||||
|
zap.S().Errorw("failed to extract archive", zap.String("server", serverID), zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// We mark the process as being successful here as if we fail to send a transfer success,
|
||||||
|
// then a transfer failure won't probably be successful either.
|
||||||
|
//
|
||||||
|
// It may be useful to retry sending the transfer success every so often just in case of a small
|
||||||
|
// hiccup or the fix of whatever error causing the success request to fail.
|
||||||
|
hasError = false
|
||||||
|
|
||||||
|
// Notify the panel that the transfer succeeded.
|
||||||
rerr, err := api.NewRequester().SendTransferSuccess(serverID)
|
rerr, err := api.NewRequester().SendTransferSuccess(serverID)
|
||||||
if rerr != nil || err != nil {
|
if rerr != nil || err != nil {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -301,7 +307,6 @@ func postTransfer(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
zap.S().Debugw("successfully notified panel about transfer success", zap.String("server", serverID))
|
zap.S().Debugw("successfully notified panel about transfer success", zap.String("server", serverID))
|
||||||
hasError = false
|
|
||||||
}(buf.Bytes())
|
}(buf.Bytes())
|
||||||
|
|
||||||
c.Status(http.StatusAccepted)
|
c.Status(http.StatusAccepted)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user