Merge branch 'develop' of https://github.com/pterodactyl/wings into develop

This commit is contained in:
Dane Everitt 2020-12-06 10:53:57 -08:00
commit 83f0d2c953
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
7 changed files with 99 additions and 58 deletions

2
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,2 @@
github: [DaneEveritt]
custom: ["https://paypal.me/PterodactylSoftware"]

View File

@ -1,47 +0,0 @@
os: linux
dist: xenial
language: go
go:
- 1.13.x
go_import_path: "github.com/pterodactyl/wings"
services:
- docker
install:
- mkdir -p $GOPATH/bin
# Install used tools
- go get github.com/mitchellh/gox
- go get github.com/haya14busa/goverage
- go get github.com/schrej/godacov
- go mod download
script:
- make cross-build
- goverage -v -coverprofile=coverage.out ./...
- godacov -t $CODACY_TOKEN -r ./coverage.out -c $TRAVIS_COMMIT
deploy:
provider: releases
api_key:
secure: HQ8AvnSsOW2aDUKv25sU83SswK9rReGeFi68SotLGPdWyFBWJbp/JEHhw9swSqvhLPykx5QqLnRPG4nomOp2i5dVTXgM/7C3wQ2ULymkJDZqDJEAxjm1IuNsjXgcFqp0zcNXL3g0moaorHS2XZpzbgaewlCyYoEb+3SZUGzOCPIjSFvoIBaAYx6kRn+pyWo1I0mQChno2i7SGvAoZwh/hZIO6L5FZe5PcpBs/SxkZ+/shsGMk7CIyNMhG6CQTE1tlr+ZenluXjtliZfc4XwkHG/9MICNl8ihUrnN6YfdvJZXLQvolZQ0QJ5Eyb04jQd1yzKR1hcLx2S42IAWxaWTy5QxSN8QyG5wBRNg567ib5FEqY4M1nyQnWQbUbaiYloYBp14aR1L9DQw8+xmXnlgnTUPq1w+cOpQLeY/RENCalgHe7NoI3lClC2b7/c1j+O7RA68yYUFUod0y7ZXcCwsJkbRk7xgyDEAGs+rq8wLknj6f8y8cfNm179lRARwblnmo9uA43Tlee8DBSziSvJy/mYMzdIQeb+PHuznXjr4fze7x+zvronkiD/JH8MjJl3SWaE7DGtc5jz4+aRxU3rMbHwToEOY6u5pIsvz5PRFYWBvKX2+VoxmdR+m1qhAxsg0wtbA0CTnqgHNGMIFDWVTDQSy8LvJt+usUn1RtrYyyiI=
file_glob: true
file: build/*
on:
tags: true
branch: master
notifications:
email: false
webhooks:
urls:
- https://misc.schrej.net/travistodiscord/pterodev.php
on_success: change
on_failure: always
on_error: always
on_cancel: always
on_start: never

View File

@ -38,15 +38,16 @@ func (a *Allocations) Bindings() nat.PortMap {
continue
}
binding := []nat.PortBinding{
{
HostIP: ip,
HostPort: strconv.Itoa(port),
},
binding := nat.PortBinding{
HostIP: ip,
HostPort: strconv.Itoa(port),
}
out[nat.Port(fmt.Sprintf("%d/tcp", port))] = binding
out[nat.Port(fmt.Sprintf("%d/udp", port))] = binding
tcp := nat.Port(fmt.Sprintf("%d/tcp", port))
udp := nat.Port(fmt.Sprintf("%d/udp", port))
out[tcp] = append(out[tcp], binding)
out[udp] = append(out[udp], binding)
}
}

View File

@ -87,6 +87,7 @@ func Configure() *gin.Engine {
files.POST("/delete", postServerDeleteFiles)
files.POST("/compress", postServerCompressFiles)
files.POST("/decompress", postServerDecompressFiles)
files.POST("/chmod", postServerChmodFile)
}
backup := server.Group("/backup")

View File

@ -2,6 +2,7 @@ package router
import (
"context"
"github.com/apex/log"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/router/tokens"
@ -365,6 +366,68 @@ func postServerDecompressFiles(c *gin.Context) {
c.Status(http.StatusNoContent)
}
type chmodFile struct {
File string `json:"file"`
Mode string `json:"mode"`
}
func postServerChmodFile(c *gin.Context) {
s := GetServer(c.Param("server"))
var data struct {
Root string `json:"root"`
Files []chmodFile `json:"files"`
}
if err := c.BindJSON(&data); err != nil {
log.Debug(err.Error())
return
}
if len(data.Files) == 0 {
c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{
"error": "No files to chmod were provided.",
})
return
}
g, ctx := errgroup.WithContext(context.Background())
// Loop over the array of files passed in and perform the move or rename action against each.
for _, p := range data.Files {
g.Go(func() error {
select {
case <-ctx.Done():
return ctx.Err()
default:
mode, err := strconv.ParseUint(p.Mode, 8, 32)
if err != nil {
return err
}
if err := s.Filesystem().Chmod(path.Join(data.Root, p.File), os.FileMode(mode)); err != nil {
// Return nil if the error is an is not exists.
// NOTE: os.IsNotExist() does not work if the error is wrapped.
if errors.Is(err, os.ErrNotExist) {
return nil
}
return err
}
return nil
}
})
}
if err := g.Wait(); err != nil {
TrackedServerError(err, s).AbortFilesystemError(c)
return
}
c.Status(http.StatusNoContent)
}
func postServerUploadFiles(c *gin.Context) {
token := tokens.UploadPayload{}
if err := tokens.ParseToken([]byte(c.Query("token")), &token); err != nil {

View File

@ -227,6 +227,23 @@ func (fs *Filesystem) Chown(path string) error {
})
}
func (fs *Filesystem) Chmod(path string, mode os.FileMode) error {
cleaned, err := fs.SafePath(path)
if err != nil {
return err
}
if fs.isTest {
return nil
}
if err := os.Chmod(cleaned, mode); err != nil {
return err
}
return nil
}
// Begin looping up to 50 times to try and create a unique copy file name. This will take
// an input of "file.txt" and generate "file copy.txt". If that name is already taken, it will
// then try to write "file copy 2.txt" and so on, until reaching 50 loops. At that point we

View File

@ -4,6 +4,7 @@ import (
"encoding/json"
"github.com/gabriel-vasile/mimetype"
"os"
"strconv"
"time"
)
@ -18,16 +19,19 @@ func (s *Stat) MarshalJSON() ([]byte, error) {
Created string `json:"created"`
Modified string `json:"modified"`
Mode string `json:"mode"`
ModeBits string `json:"mode_bits"`
Size int64 `json:"size"`
Directory bool `json:"directory"`
File bool `json:"file"`
Symlink bool `json:"symlink"`
Mime string `json:"mime"`
}{
Name: s.Info.Name(),
Created: s.CTime().Format(time.RFC3339),
Modified: s.Info.ModTime().Format(time.RFC3339),
Mode: s.Info.Mode().String(),
Name: s.Info.Name(),
Created: s.CTime().Format(time.RFC3339),
Modified: s.Info.ModTime().Format(time.RFC3339),
Mode: s.Info.Mode().String(),
// Using `&os.ModePerm` on the file's mode will cause the mode to only have the permission values, and nothing else.
ModeBits: strconv.FormatUint(uint64(s.Info.Mode()&os.ModePerm), 8),
Size: s.Info.Size(),
Directory: s.Info.IsDir(),
File: !s.Info.IsDir(),