break everything
- upgrade dependencies - run gofmt and goimports to organize code - fix typos - other small tweaks
This commit is contained in:
@@ -2,11 +2,8 @@ package downloader
|
||||
|
||||
import (
|
||||
"context"
|
||||
"emperror.dev/errors"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -17,11 +14,16 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"emperror.dev/errors"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/pterodactyl/wings/server"
|
||||
)
|
||||
|
||||
var client = &http.Client{
|
||||
Timeout: time.Hour * 12,
|
||||
// Disallow any redirect on a HTTP call. This is a security requirement: do not modify
|
||||
// Disallow any redirect on an HTTP call. This is a security requirement: do not modify
|
||||
// this logic without first ensuring that the new target location IS NOT within the current
|
||||
// instance's local network.
|
||||
//
|
||||
@@ -36,9 +38,9 @@ var client = &http.Client{
|
||||
}
|
||||
|
||||
var instance = &Downloader{
|
||||
// Tracks all of the active downloads.
|
||||
// Tracks all the active downloads.
|
||||
downloadCache: make(map[string]*Download),
|
||||
// Tracks all of the downloads active for a given server instance. This is
|
||||
// Tracks all the downloads active for a given server instance. This is
|
||||
// primarily used to make things quicker and keep the code a little more
|
||||
// legible throughout here.
|
||||
serverCache: make(map[string][]string),
|
||||
@@ -196,7 +198,7 @@ func (dl *Download) Cancel() {
|
||||
|
||||
// Checks if the given download belongs to the provided server.
|
||||
func (dl *Download) BelongsTo(s *server.Server) bool {
|
||||
return dl.server.Id() == s.Id()
|
||||
return dl.server.ID() == s.ID()
|
||||
}
|
||||
|
||||
// Returns the current progress of the download as a float value between 0 and 1 where
|
||||
@@ -277,7 +279,7 @@ type Downloader struct {
|
||||
func (d *Downloader) track(dl *Download) {
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
sid := dl.server.Id()
|
||||
sid := dl.server.ID()
|
||||
if _, ok := d.downloadCache[dl.Identifier]; !ok {
|
||||
d.downloadCache[dl.Identifier] = dl
|
||||
if _, ok := d.serverCache[sid]; !ok {
|
||||
@@ -299,22 +301,22 @@ func (d *Downloader) find(dlid string) *Download {
|
||||
|
||||
// Remove the given download reference from the cache storing them. This also updates
|
||||
// the slice of active downloads for a given server to not include this download.
|
||||
func (d *Downloader) remove(dlid string) {
|
||||
func (d *Downloader) remove(dlID string) {
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
if _, ok := d.downloadCache[dlid]; !ok {
|
||||
if _, ok := d.downloadCache[dlID]; !ok {
|
||||
return
|
||||
}
|
||||
sid := d.downloadCache[dlid].server.Id()
|
||||
delete(d.downloadCache, dlid)
|
||||
if tracked, ok := d.serverCache[sid]; ok {
|
||||
sID := d.downloadCache[dlID].server.ID()
|
||||
delete(d.downloadCache, dlID)
|
||||
if tracked, ok := d.serverCache[sID]; ok {
|
||||
var out []string
|
||||
for _, k := range tracked {
|
||||
if k != dlid {
|
||||
if k != dlID {
|
||||
out = append(out, k)
|
||||
}
|
||||
}
|
||||
d.serverCache[sid] = out
|
||||
d.serverCache[sID] = out
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/apex/log"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/pterodactyl/wings/server"
|
||||
"github.com/pterodactyl/wings/server/filesystem"
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@ package router
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/pterodactyl/wings/router/middleware"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
)
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/apex/log"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/pterodactyl/wings/config"
|
||||
"github.com/pterodactyl/wings/remote"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
@@ -62,7 +63,7 @@ func (re *RequestError) Abort(c *gin.Context, status int) {
|
||||
// server triggered this error.
|
||||
if s, ok := c.Get("server"); ok {
|
||||
if s, ok := s.(*server.Server); ok {
|
||||
event = event.WithField("server_id", s.Id())
|
||||
event = event.WithField("server_id", s.ID())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,14 +263,14 @@ func ServerExists() gin.HandlerFunc {
|
||||
if c.Param("server") != "" {
|
||||
manager := ExtractManager(c)
|
||||
s = manager.Find(func(s *server.Server) bool {
|
||||
return c.Param("server") == s.Id()
|
||||
return c.Param("server") == s.ID()
|
||||
})
|
||||
}
|
||||
if s == nil {
|
||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": "The requested resource does not exist on this instance."})
|
||||
return
|
||||
}
|
||||
c.Set("logger", ExtractLogger(c).WithField("server_id", s.Id()))
|
||||
c.Set("logger", ExtractLogger(c).WithField("server_id", s.ID()))
|
||||
c.Set("server", s)
|
||||
c.Next()
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package router
|
||||
import (
|
||||
"github.com/apex/log"
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/pterodactyl/wings/remote"
|
||||
"github.com/pterodactyl/wings/router/middleware"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/pterodactyl/wings/router/middleware"
|
||||
"github.com/pterodactyl/wings/router/tokens"
|
||||
"github.com/pterodactyl/wings/server/backup"
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"emperror.dev/errors"
|
||||
"github.com/apex/log"
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/pterodactyl/wings/router/downloader"
|
||||
"github.com/pterodactyl/wings/router/middleware"
|
||||
"github.com/pterodactyl/wings/router/tokens"
|
||||
@@ -195,7 +196,7 @@ func deleteServer(c *gin.Context) {
|
||||
s.Websockets().CancelAll()
|
||||
|
||||
// Remove any pending remote file downloads for the server.
|
||||
for _, dl := range downloader.ByServer(s.Id()) {
|
||||
for _, dl := range downloader.ByServer(s.ID()) {
|
||||
dl.Cancel()
|
||||
}
|
||||
|
||||
@@ -220,7 +221,7 @@ func deleteServer(c *gin.Context) {
|
||||
}(s.Filesystem().Path())
|
||||
|
||||
middleware.ExtractManager(c).Remove(func(server *server.Server) bool {
|
||||
return server.Id() == s.Id()
|
||||
return server.ID() == s.ID()
|
||||
})
|
||||
|
||||
// Deallocate the reference to this server.
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"emperror.dev/errors"
|
||||
"github.com/apex/log"
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/pterodactyl/wings/router/middleware"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
"github.com/pterodactyl/wings/server/backup"
|
||||
@@ -42,7 +43,7 @@ func postServerBackup(c *gin.Context) {
|
||||
// Attach the server ID and the request ID to the adapter log context for easier
|
||||
// parsing in the logs.
|
||||
adapter.WithLogContext(map[string]interface{}{
|
||||
"server": s.Id(),
|
||||
"server": s.ID(),
|
||||
"request_id": c.GetString("request_id"),
|
||||
})
|
||||
|
||||
|
||||
@@ -16,12 +16,13 @@ import (
|
||||
"emperror.dev/errors"
|
||||
"github.com/apex/log"
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/pterodactyl/wings/router/downloader"
|
||||
"github.com/pterodactyl/wings/router/middleware"
|
||||
"github.com/pterodactyl/wings/router/tokens"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
"github.com/pterodactyl/wings/server/filesystem"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
// getServerFileContents returns the contents of a file on the server.
|
||||
@@ -245,7 +246,7 @@ func postServerWriteFile(c *gin.Context) {
|
||||
func getServerPullingFiles(c *gin.Context) {
|
||||
s := ExtractServer(c)
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"downloads": downloader.ByServer(s.Id()),
|
||||
"downloads": downloader.ByServer(s.ID()),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -277,7 +278,7 @@ func postServerPullRemoteFile(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
// Do not allow more than three simultaneous remote file downloads at one time.
|
||||
if len(downloader.ByServer(s.Id())) >= 3 {
|
||||
if len(downloader.ByServer(s.ID())) >= 3 {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
|
||||
"error": "This server has reached its limit of 3 simultaneous remote file downloads at once. Please wait for one to complete before trying again.",
|
||||
})
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
ws "github.com/gorilla/websocket"
|
||||
|
||||
"github.com/pterodactyl/wings/router/middleware"
|
||||
"github.com/pterodactyl/wings/router/websocket"
|
||||
)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/pterodactyl/wings/config"
|
||||
"github.com/pterodactyl/wings/installer"
|
||||
"github.com/pterodactyl/wings/router/middleware"
|
||||
@@ -78,18 +79,18 @@ func postCreateServer(c *gin.Context) {
|
||||
}
|
||||
|
||||
if i.Server().Config().StartOnCompletion {
|
||||
log.WithField("server_id", i.Server().Id()).Debug("starting server after successful installation")
|
||||
log.WithField("server_id", i.Server().ID()).Debug("starting server after successful installation")
|
||||
if err := i.Server().HandlePowerAction(server.PowerActionStart, 30); err != nil {
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
log.WithFields(log.Fields{"server_id": i.Server().Id(), "action": "start"}).
|
||||
log.WithFields(log.Fields{"server_id": i.Server().ID(), "action": "start"}).
|
||||
Warn("could not acquire a lock while attempting to perform a power action")
|
||||
} else {
|
||||
log.WithFields(log.Fields{"server_id": i.Server().Id(), "action": "start", "error": err}).
|
||||
log.WithFields(log.Fields{"server_id": i.Server().ID(), "action": "start", "error": err}).
|
||||
Error("encountered error processing a server power action in the background")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.WithField("server_id", i.Server().Id()).
|
||||
log.WithField("server_id", i.Server().ID()).
|
||||
Debug("skipping automatic start after successful server installation")
|
||||
}
|
||||
}(install)
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/juju/ratelimit"
|
||||
"github.com/mholt/archiver/v3"
|
||||
"github.com/mitchellh/colorstring"
|
||||
|
||||
"github.com/pterodactyl/wings/config"
|
||||
"github.com/pterodactyl/wings/installer"
|
||||
"github.com/pterodactyl/wings/remote"
|
||||
@@ -75,14 +76,14 @@ func getServerArchive(c *gin.Context) {
|
||||
}
|
||||
|
||||
s := ExtractServer(c)
|
||||
if token.Subject != s.Id() {
|
||||
if token.Subject != s.ID() {
|
||||
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
|
||||
"error": "Missing required token subject, or subject is not valid for the requested server.",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
archivePath := getArchivePath(s.Id())
|
||||
archivePath := getArchivePath(s.ID())
|
||||
|
||||
// Stat the archive file.
|
||||
st, err := os.Lstat(archivePath)
|
||||
@@ -123,7 +124,7 @@ func getServerArchive(c *gin.Context) {
|
||||
c.Header("X-Checksum", checksum)
|
||||
c.Header("X-Mime-Type", "application/tar+gzip")
|
||||
c.Header("Content-Length", strconv.Itoa(int(st.Size())))
|
||||
c.Header("Content-Disposition", "attachment; filename="+strconv.Quote(s.Id()+".tar.gz"))
|
||||
c.Header("Content-Disposition", "attachment; filename="+strconv.Quote(s.ID()+".tar.gz"))
|
||||
c.Header("Content-Type", "application/octet-stream")
|
||||
|
||||
_, _ = bufio.NewReader(f).WriteTo(c.Writer)
|
||||
@@ -134,7 +135,7 @@ func postServerArchive(c *gin.Context) {
|
||||
manager := middleware.ExtractManager(c)
|
||||
|
||||
go func(s *server.Server) {
|
||||
l := log.WithField("server", s.Id())
|
||||
l := log.WithField("server", s.ID())
|
||||
|
||||
// This function automatically adds the Source Node prefix and Timestamp to the log
|
||||
// output before sending it over the websocket.
|
||||
@@ -157,7 +158,7 @@ func postServerArchive(c *gin.Context) {
|
||||
s.Events().Publish(server.TransferStatusEvent, "failure")
|
||||
|
||||
sendTransferLog("Attempting to notify panel of archive failure..")
|
||||
if err := manager.Client().SetArchiveStatus(s.Context(), s.Id(), false); err != nil {
|
||||
if err := manager.Client().SetArchiveStatus(s.Context(), s.ID(), false); err != nil {
|
||||
if !remote.IsRequestError(err) {
|
||||
sendTransferLog("Failed to notify panel of archive failure: " + err.Error())
|
||||
l.WithField("error", err).Error("failed to notify panel of failed archive status")
|
||||
@@ -190,7 +191,7 @@ func postServerArchive(c *gin.Context) {
|
||||
}
|
||||
|
||||
// Attempt to get an archive of the server.
|
||||
if err := a.Create(getArchivePath(s.Id())); err != nil {
|
||||
if err := a.Create(getArchivePath(s.ID())); err != nil {
|
||||
sendTransferLog("An error occurred while archiving the server: " + err.Error())
|
||||
l.WithField("error", err).Error("failed to get transfer archive for server")
|
||||
return
|
||||
@@ -199,7 +200,7 @@ func postServerArchive(c *gin.Context) {
|
||||
sendTransferLog("Successfully created archive, attempting to notify panel..")
|
||||
l.Info("successfully created server transfer archive, notifying panel..")
|
||||
|
||||
if err := manager.Client().SetArchiveStatus(s.Context(), s.Id(), true); err != nil {
|
||||
if err := manager.Client().SetArchiveStatus(s.Context(), s.ID(), true); err != nil {
|
||||
if !remote.IsRequestError(err) {
|
||||
sendTransferLog("Failed to notify panel of archive success: " + err.Error())
|
||||
l.WithField("error", err).Error("failed to notify panel of successful archive status")
|
||||
@@ -360,7 +361,7 @@ func postTransfer(c *gin.Context) {
|
||||
sendTransferLog("Server transfer failed, check Wings logs for additional information.")
|
||||
s.Events().Publish(server.TransferStatusEvent, "failure")
|
||||
manager.Remove(func(match *server.Server) bool {
|
||||
return match.Id() == s.Id()
|
||||
return match.ID() == s.ID()
|
||||
})
|
||||
|
||||
// If the transfer status was successful but the request failed, act like the transfer failed.
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package tokens
|
||||
|
||||
import (
|
||||
"github.com/gbrlsnchs/jwt/v3"
|
||||
"github.com/pterodactyl/wings/config"
|
||||
"time"
|
||||
|
||||
"github.com/gbrlsnchs/jwt/v3"
|
||||
|
||||
"github.com/pterodactyl/wings/config"
|
||||
)
|
||||
|
||||
type TokenData interface {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package tokens
|
||||
|
||||
import (
|
||||
"github.com/patrickmn/go-cache"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/patrickmn/go-cache"
|
||||
)
|
||||
|
||||
type TokenStore struct {
|
||||
|
||||
@@ -2,11 +2,12 @@ package tokens
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/apex/log"
|
||||
"github.com/gbrlsnchs/jwt/v3"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/gbrlsnchs/jwt/v3"
|
||||
)
|
||||
|
||||
// The time at which Wings was booted. No JWT's created before this time are allowed to
|
||||
|
||||
@@ -2,9 +2,10 @@ package websocket
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/pterodactyl/wings/events"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Checks the time to expiration on the JWT every 30 seconds until the token has
|
||||
|
||||
@@ -2,22 +2,24 @@ package websocket
|
||||
|
||||
import (
|
||||
"context"
|
||||
"emperror.dev/errors"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"emperror.dev/errors"
|
||||
"github.com/apex/log"
|
||||
"github.com/gbrlsnchs/jwt/v3"
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/websocket"
|
||||
|
||||
"github.com/pterodactyl/wings/config"
|
||||
"github.com/pterodactyl/wings/environment"
|
||||
"github.com/pterodactyl/wings/environment/docker"
|
||||
"github.com/pterodactyl/wings/router/tokens"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -55,11 +57,10 @@ func IsJwtError(err error) bool {
|
||||
errors.Is(err, jwt.ErrExpValidation)
|
||||
}
|
||||
|
||||
// Parses a JWT into a websocket token payload.
|
||||
// NewTokenPayload parses a JWT into a websocket token payload.
|
||||
func NewTokenPayload(token []byte) (*tokens.WebsocketPayload, error) {
|
||||
payload := tokens.WebsocketPayload{}
|
||||
err := tokens.ParseToken(token, &payload)
|
||||
if err != nil {
|
||||
var payload tokens.WebsocketPayload
|
||||
if err := tokens.ParseToken(token, &payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -180,7 +181,7 @@ func (h *Handler) unsafeSendJson(v interface{}) error {
|
||||
return h.Connection.WriteJSON(v)
|
||||
}
|
||||
|
||||
// Checks if the JWT is still valid.
|
||||
// TokenValid checks if the JWT is still valid.
|
||||
func (h *Handler) TokenValid() error {
|
||||
j := h.GetJwt()
|
||||
if j == nil {
|
||||
@@ -199,14 +200,14 @@ func (h *Handler) TokenValid() error {
|
||||
return ErrJwtNoConnectPerm
|
||||
}
|
||||
|
||||
if h.server.Id() != j.GetServerUuid() {
|
||||
if h.server.ID() != j.GetServerUuid() {
|
||||
return ErrJwtUuidMismatch
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sends an error back to the connected websocket instance by checking the permissions
|
||||
// SendErrorJson sends an error back to the connected websocket instance by checking the permissions
|
||||
// of the token. If the user has the "receive-errors" grant we will send back the actual
|
||||
// error message, otherwise we just send back a standard error message.
|
||||
func (h *Handler) SendErrorJson(msg Message, err error, shouldLog ...bool) error {
|
||||
@@ -236,7 +237,7 @@ func (h *Handler) SendErrorJson(msg Message, err error, shouldLog ...bool) error
|
||||
return h.unsafeSendJson(wsm)
|
||||
}
|
||||
|
||||
// Converts an error message into a more readable representation and returns a UUID
|
||||
// GetErrorMessage converts an error message into a more readable representation and returns a UUID
|
||||
// that can be cross-referenced to find the specific error that triggered.
|
||||
func (h *Handler) GetErrorMessage(msg string) (string, uuid.UUID) {
|
||||
u := uuid.Must(uuid.NewRandom())
|
||||
@@ -246,13 +247,7 @@ func (h *Handler) GetErrorMessage(msg string) (string, uuid.UUID) {
|
||||
return m, u
|
||||
}
|
||||
|
||||
// Sets the JWT for the websocket in a race-safe manner.
|
||||
func (h *Handler) setJwt(token *tokens.WebsocketPayload) {
|
||||
h.Lock()
|
||||
h.jwt = token
|
||||
h.Unlock()
|
||||
}
|
||||
|
||||
// GetJwt returns the JWT for the websocket in a race-safe manner.
|
||||
func (h *Handler) GetJwt() *tokens.WebsocketPayload {
|
||||
h.RLock()
|
||||
defer h.RUnlock()
|
||||
@@ -260,7 +255,14 @@ func (h *Handler) GetJwt() *tokens.WebsocketPayload {
|
||||
return h.jwt
|
||||
}
|
||||
|
||||
// Handle the inbound socket request and route it to the proper server action.
|
||||
// setJwt sets the JWT for the websocket in a race-safe manner.
|
||||
func (h *Handler) setJwt(token *tokens.WebsocketPayload) {
|
||||
h.Lock()
|
||||
h.jwt = token
|
||||
h.Unlock()
|
||||
}
|
||||
|
||||
// HandleInbound handles an inbound socket request and route it to the proper action.
|
||||
func (h *Handler) HandleInbound(m Message) error {
|
||||
if m.Event != AuthenticationEvent {
|
||||
if err := h.TokenValid(); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user