forked from Alex/Pterodactyl-Panel
Compare commits
304 Commits
develop
...
dane/sanct
Author | SHA1 | Date | |
---|---|---|---|
|
9fe1527f10 | ||
|
baf8a9fb2c | ||
|
436e686037 | ||
|
cec96062e3 | ||
|
7169b481b1 | ||
|
b19ce4df7c | ||
|
5a1cceb9d2 | ||
|
3a83a2d5ac | ||
|
815ce0e451 | ||
|
3d14974d64 | ||
|
1bc1b87422 | ||
|
9e0ec8fca8 | ||
|
fdd90b3be7 | ||
|
bbf2f33c5e | ||
|
5c81f820d8 | ||
|
cf500a1a54 | ||
|
2203a4d87e | ||
|
bc1db626e7 | ||
|
74426a97f4 | ||
|
4d1a7e6637 | ||
|
e1089e0b73 | ||
|
e8474271b3 | ||
|
47b895a98a | ||
|
622d292f39 | ||
|
b47d262ee0 | ||
|
dfff8ad667 | ||
|
374910d73a | ||
|
1a3451fb0d | ||
|
d60e8a193b | ||
|
4b32828423 | ||
|
0ab124f026 | ||
|
94198f3bfd | ||
|
f44833ca9c | ||
|
178a886d3b | ||
|
c6dccc568d | ||
|
3d3df30903 | ||
|
38ddcfb0d9 | ||
|
b9ab6e2c33 | ||
|
07617bcd27 | ||
|
c46131e7ad | ||
|
a39802cb4e | ||
|
d9740fff65 | ||
|
174cca9e49 | ||
|
d9d79d8c95 | ||
|
d2864410ed | ||
|
4d77d486ec | ||
|
833b47abc5 | ||
|
346271a9a3 | ||
|
89a0244cf2 | ||
|
1d9927d7f8 | ||
|
98cb7370f0 | ||
|
2b8565fd1a | ||
|
455be4bb52 | ||
|
98ed8e431b | ||
|
27ed07e81f | ||
|
fffe3a7f8b | ||
|
0313bdb1cb | ||
|
030bc2d8ef | ||
|
11fc88c849 | ||
|
bf9dfa87da | ||
|
f1be653486 | ||
|
b8b481b57b | ||
|
7f290c6e52 | ||
|
e56aef31bc | ||
|
ca4046e818 | ||
|
25feeaa9f5 | ||
|
58f0bbbb9b | ||
|
3c2a6e1136 | ||
|
01242a805d | ||
|
6acb989965 | ||
|
b25a0c4cbc | ||
|
544d1f5746 | ||
|
31847a8566 | ||
|
14940d666b | ||
|
88bcb69a8a | ||
|
631b4ae2a8 | ||
|
0828d00857 | ||
|
426d955643 | ||
|
27c93365e9 | ||
|
1d290919b7 | ||
|
7b3c71f6a7 | ||
|
26438fa034 | ||
|
be011906e6 | ||
|
361596e051 | ||
|
23de3d68f3 | ||
|
3b1a0e22a7 | ||
|
d2d62b7463 | ||
|
84b207eddb | ||
|
d32b3a0473 | ||
|
6879ca4054 | ||
|
7524bbe8ee | ||
|
30f09a4098 | ||
|
08c780c388 | ||
|
64110d84af | ||
|
790f109e66 | ||
|
f9114e2de0 | ||
|
9d64c6751b | ||
|
28bc86e23b | ||
|
59f2ea37d8 | ||
|
3c21770c25 | ||
|
31c2ef5279 | ||
|
42a3e740ba | ||
|
28146f5bb6 | ||
|
cdd07fa275 | ||
|
f137192113 | ||
|
c09cfd4c76 | ||
|
bc4e28578d | ||
|
7ad32293f3 | ||
|
11bafe42b4 | ||
|
779b0eca67 | ||
|
c0e9f1adee | ||
|
8f8d66584d | ||
|
2d412e66ac | ||
|
ef5380e59d | ||
|
e86f9a5ed9 | ||
|
ea4bcf0b9c | ||
|
2963b77b41 | ||
|
7776436d18 | ||
|
8d5dbbb57b | ||
|
63a466c79a | ||
|
3bf34024c7 | ||
|
f4442d0b1c | ||
|
96788f9269 | ||
|
01464b6da5 | ||
|
7dacf90718 | ||
|
c49e8b1a07 | ||
|
98c54cba3a | ||
|
3a3caee715 | ||
|
556885f682 | ||
|
01c03b6b77 | ||
|
a45fc525a9 | ||
|
8aa9641ec2 | ||
|
bca2338863 | ||
|
ae88a01bea | ||
|
a3b59f24af | ||
|
8a24c1a142 | ||
|
7b38f05019 | ||
|
984a774811 | ||
|
c521d37ddd | ||
|
49de31bf4c | ||
|
2e046ae258 | ||
|
7e8cb52d88 | ||
|
59e5017fd8 | ||
|
08546e6076 | ||
|
e9546c70bd | ||
|
5d1568cf84 | ||
|
5fe86f164e | ||
|
264c3865b2 | ||
|
7d80b5fee7 | ||
|
f78aaea6a3 | ||
|
00c42225e8 | ||
|
350ef1aba5 | ||
|
ffdf27e606 | ||
|
f6e71e7e76 | ||
|
ee5a661e46 | ||
|
542fd61049 | ||
|
8c8de6ac62 | ||
|
d57060dad9 | ||
|
ffbf7daea6 | ||
|
ff4a64bfff | ||
|
46759ba967 | ||
|
b8788d1af1 | ||
|
c053ca7c44 | ||
|
dc003a6ada | ||
|
224943cc85 | ||
|
10fc7e88e0 | ||
|
9b08b6b595 | ||
|
d43e70c97a | ||
|
93be6db530 | ||
|
3971c4499d | ||
|
f790404845 | ||
|
3c2094890a | ||
|
5f56ff0fed | ||
|
b7ee2195d7 | ||
|
60b630354e | ||
|
a87fef37ec | ||
|
8e07bb4bc2 | ||
|
22807f1ff4 | ||
|
f3e7aab27c | ||
|
72be2808f3 | ||
|
9184cbdf11 | ||
|
7bbe9e8e89 | ||
|
1c8143ad9d | ||
|
be1b05e0ec | ||
|
2a0c99163b | ||
|
2b5cc99abd | ||
|
72983e8385 | ||
|
4e1c07d36e | ||
|
b856ab17bd | ||
|
31c26a2de4 | ||
|
18bdde8b81 | ||
|
da3c7fa455 | ||
|
eb29f6fc04 | ||
|
5737b5dc5d | ||
|
409c081275 | ||
|
8a79589317 | ||
|
f9bb791a7d | ||
|
8feb87de7c | ||
|
e01d859b53 | ||
|
1e61fd161c | ||
|
9d005b5fd2 | ||
|
9532ecf867 | ||
|
e123367f40 | ||
|
79d80e8c22 | ||
|
95d3f4c9e0 | ||
|
b1c7b91313 | ||
|
a71392d632 | ||
|
4dab137b51 | ||
|
e2c8a2fdea | ||
|
ba41fb5095 | ||
|
d648ee5c93 | ||
|
c40e4bd2c0 | ||
|
166221be9b | ||
|
6bb4f6cd01 | ||
|
17f8715e41 | ||
|
3b0eb0d8ae | ||
|
abd33c2384 | ||
|
52b2463281 | ||
|
1800800308 | ||
|
ef9bdf5cd5 | ||
|
0c7e787d44 | ||
|
9ec6068f45 | ||
|
a91cb578d7 | ||
|
d323662ad5 | ||
|
0759ecb1e1 | ||
|
c7d905fece | ||
|
ee3b8e6432 | ||
|
e70351cbad | ||
|
11b7197c49 | ||
|
52ce5e9a57 | ||
|
93a333e1bb | ||
|
e1b33c9346 | ||
|
48882e6f2c | ||
|
0d2fbfddc0 | ||
|
bbd14c41c8 | ||
|
a43ef62435 | ||
|
cf006c9d36 | ||
|
20234b308c | ||
|
0e366f69ee | ||
|
58cfa98b9c | ||
|
5946210e18 | ||
|
2352ef0369 | ||
|
9eed88b430 | ||
|
56c098a316 | ||
|
946f907b68 | ||
|
12c68961db | ||
|
545cc3bbd2 | ||
|
b45592466e | ||
|
63daa7b14f | ||
|
d81aef68b5 | ||
|
e7021dfc39 | ||
|
b4ec1fb45d | ||
|
a038b0733d | ||
|
96eb232fc0 | ||
|
915666d827 | ||
|
727cf8d753 | ||
|
231b8b40d6 | ||
|
ae6b8cba19 | ||
|
935f99ab91 | ||
|
92840d3630 | ||
|
b95f28fbd9 | ||
|
59de9576c9 | ||
|
8f1a5bf0ab | ||
|
ed73f6a020 | ||
|
95c55e7d28 | ||
|
0ddf806100 | ||
|
5636c25838 | ||
|
0511f75747 | ||
|
b1d30c1bde | ||
|
ce40194147 | ||
|
052a6d4ce5 | ||
|
b17bb7c24b | ||
|
03474ccfcf | ||
|
04799fa44b | ||
|
f72402b5fa | ||
|
88ac1ce1fd | ||
|
6c85be72fa | ||
|
359769244f | ||
|
193086548f | ||
|
9d92053865 | ||
|
9c7b49e2b9 | ||
|
b6abeb0994 | ||
|
f67e340d33 | ||
|
318c9f741b | ||
|
0381fe1bd9 | ||
|
dc0fdee030 | ||
|
7369167e28 | ||
|
333c9312d4 | ||
|
108bf6e3f7 | ||
|
1cdf9bc18f | ||
|
1f850fac61 | ||
|
19176fb1b6 | ||
|
d2f3d8178b | ||
|
1dff1f1810 | ||
|
e7aeeace26 | ||
|
df6f5c3a09 | ||
|
dd0cd5bcb9 | ||
|
3cdd348352 | ||
|
e5c30cb6f3 | ||
|
434d204c49 | ||
|
a1115ff096 | ||
|
6c53738070 | ||
|
c22ab762de | ||
|
9ee3275b11 |
@ -1,11 +0,0 @@
|
||||
module.exports = {
|
||||
twin: {
|
||||
preset: 'styled-components',
|
||||
autoCssProp: true,
|
||||
},
|
||||
styledComponents: {
|
||||
pure: true,
|
||||
displayName: false,
|
||||
fileName: false,
|
||||
},
|
||||
};
|
@ -8,7 +8,7 @@ indent_size = 4
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[.*yml]
|
||||
[*.yml]
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
|
@ -8,7 +8,6 @@ APP_DELETE_MINUTES=10
|
||||
APP_ENVIRONMENT_ONLY=true
|
||||
LOG_CHANNEL=daily
|
||||
APP_LOCALE=en
|
||||
APP_URL=http://panel.example.com
|
||||
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
@ -31,7 +30,7 @@ MAILGUN_ENDPOINT=api.mailgun.net
|
||||
# mail servers such as Gmail to reject your mail.
|
||||
#
|
||||
# @see: https://github.com/pterodactyl/panel/pull/3110
|
||||
# SERVER_NAME=panel.example.com
|
||||
# SERVER_NAME=panel.yourdomain.com
|
||||
|
||||
QUEUE_HIGH=high
|
||||
QUEUE_STANDARD=standard
|
||||
|
@ -1,4 +1,6 @@
|
||||
public
|
||||
node_modules
|
||||
resources/views
|
||||
babel.config.js
|
||||
tailwind.config.js
|
||||
webpack.config.js
|
||||
|
4
.github/FUNDING.yml
vendored
4
.github/FUNDING.yml
vendored
@ -1,2 +1,2 @@
|
||||
github: [DaneEveritt]
|
||||
custom: ["https://paypal.me/PterodactylSoftware"]
|
||||
github: [ DaneEveritt ]
|
||||
custom: [ "https://paypal.me/PterodactylSoftware" ]
|
||||
|
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,4 +1,4 @@
|
||||
blank_issues_enabled: false
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Installation Help
|
||||
url: https://discord.gg/pterodactyl
|
||||
|
2
.github/docker/README.md
vendored
2
.github/docker/README.md
vendored
@ -33,7 +33,7 @@ Note: If your `APP_URL` starts with `https://` you need to provide an `LETSENCRY
|
||||
| ------------------- | ------------------------------------------------------------------------------ | -------- |
|
||||
| `APP_URL` | The URL the panel will be reachable with (including protocol) | yes |
|
||||
| `APP_TIMEZONE` | The timezone to use for the panel | yes |
|
||||
| `LE_EMAIL` | The email used for letsencrypt certificate generation | yes |
|
||||
| `LETSENCRYPT_EMAIL` | The email used for letsencrypt certificate generation | yes |
|
||||
| `DB_HOST` | The host of the mysql instance | yes |
|
||||
| `DB_PORT` | The port of the mysql instance | yes |
|
||||
| `DB_DATABASE` | The name of the mysql database | yes |
|
||||
|
12
.github/docker/entrypoint.sh
vendored
12
.github/docker/entrypoint.sh
vendored
@ -30,7 +30,7 @@ else
|
||||
fi
|
||||
|
||||
echo "Checking if https is required."
|
||||
if [ -f /etc/nginx/http.d/panel.conf ]; then
|
||||
if [ -f /etc/nginx/conf.d/default.conf ]; then
|
||||
echo "Using nginx config already in place."
|
||||
if [ $LE_EMAIL ]; then
|
||||
echo "Checking for cert update"
|
||||
@ -42,22 +42,20 @@ else
|
||||
echo "Checking if letsencrypt email is set."
|
||||
if [ -z $LE_EMAIL ]; then
|
||||
echo "No letsencrypt email is set using http config."
|
||||
cp .github/docker/default.conf /etc/nginx/http.d/panel.conf
|
||||
cp .github/docker/default.conf /etc/nginx/conf.d/default.conf
|
||||
else
|
||||
echo "writing ssl config"
|
||||
cp .github/docker/default_ssl.conf /etc/nginx/http.d/panel.conf
|
||||
cp .github/docker/default_ssl.conf /etc/nginx/conf.d/default.conf
|
||||
echo "updating ssl config for domain"
|
||||
sed -i "s|<domain>|$(echo $APP_URL | sed 's~http[s]*://~~g')|g" /etc/nginx/http.d/panel.conf
|
||||
sed -i "s|<domain>|$(echo $APP_URL | sed 's~http[s]*://~~g')|g" /etc/nginx/conf.d/default.conf
|
||||
echo "generating certs"
|
||||
certbot certonly -d $(echo $APP_URL | sed 's~http[s]*://~~g') --standalone -m $LE_EMAIL --agree-tos -n
|
||||
fi
|
||||
echo "Removing the default nginx config"
|
||||
rm -rf /etc/nginx/http.d/default.conf
|
||||
fi
|
||||
|
||||
## check for DB up before starting the panel
|
||||
echo "Checking database status."
|
||||
until nc -z -v -w30 $DB_HOST $DB_PORT
|
||||
until nc -z -v -w30 $DB_HOST 3306
|
||||
do
|
||||
echo "Waiting for database connection..."
|
||||
# wait for 1 seconds before check again
|
||||
|
4
.github/workflows/docker.yml
vendored
4
.github/workflows/docker.yml
vendored
@ -8,7 +8,7 @@ on:
|
||||
jobs:
|
||||
push_to_registry:
|
||||
name: Push Image to GitHub Packages
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
# Always run against a tag, even if the commit into the tag has [docker skip]
|
||||
# within the commit message.
|
||||
if: "!contains(github.ref, 'develop') || (!contains(github.event.head_commit.message, 'skip docker') && !contains(github.event.head_commit.message, 'docker skip'))"
|
||||
@ -36,7 +36,6 @@ jobs:
|
||||
if: "!contains(github.ref, 'develop')"
|
||||
with:
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: ${{ steps.docker_meta.outputs.tags }}
|
||||
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||
- name: Release Development Build
|
||||
@ -44,6 +43,5 @@ jobs:
|
||||
if: "contains(github.ref, 'develop')"
|
||||
with:
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: ${{ steps.docker_meta.outputs.tags }}
|
||||
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||
|
21
.github/workflows/release.yml
vendored
21
.github/workflows/release.yml
vendored
@ -7,11 +7,13 @@ jobs:
|
||||
release:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '12'
|
||||
|
||||
node-version: '14'
|
||||
cache: 'yarn'
|
||||
- name: Create release branch and bump version
|
||||
env:
|
||||
REF: ${{ github.ref }}
|
||||
@ -25,17 +27,14 @@ jobs:
|
||||
git add config/app.php
|
||||
git commit -m "bump version for release"
|
||||
git push
|
||||
|
||||
- name: Build assets
|
||||
run: |
|
||||
yarn install
|
||||
yarn run build:production
|
||||
|
||||
- name: Create release archive
|
||||
run: |
|
||||
rm -rf node_modules/ test/ codecov.yml CODE_OF_CONDUCT.md CONTRIBUTING.md phpunit.dusk.xml phpunit.xml Vagrantfile
|
||||
tar -czf panel.tar.gz * .env.example .babel-plugin-macrosrc.js
|
||||
|
||||
rm -rf node_modules/ test/ codecov.yml CODE_OF_CONDUCT.md CONTRIBUTING.md phpunit.dusk.xml phpunit.xml
|
||||
tar -czf panel.tar.gz * .env.example .eslintignore .eslintrc.yml .yarnclean
|
||||
- name: Extract changelog
|
||||
id: extract_changelog
|
||||
env:
|
||||
@ -43,13 +42,11 @@ jobs:
|
||||
run: |
|
||||
sed -n "/^## ${REF:10}/,/^## /{/^## /b;p}" CHANGELOG.md > ./RELEASE_CHANGELOG
|
||||
echo ::set-output name=version_name::`sed -nr "s/^## (${REF:10} .*)$/\1/p" CHANGELOG.md`
|
||||
|
||||
- name: Create checksum and add to changelog
|
||||
run: |
|
||||
SUM=`sha256sum panel.tar.gz`
|
||||
echo -e "\n#### SHA256 Checksum\n\n\`\`\`\n$SUM\n\`\`\`\n" >> ./RELEASE_CHANGELOG
|
||||
echo $SUM > checksum.txt
|
||||
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
@ -61,7 +58,6 @@ jobs:
|
||||
body_path: ./RELEASE_CHANGELOG
|
||||
draft: true
|
||||
prerelease: ${{ contains(github.ref, 'beta') || contains(github.ref, 'alpha') }}
|
||||
|
||||
- name: Upload binary
|
||||
id: upload-release-archive
|
||||
uses: actions/upload-release-asset@v1
|
||||
@ -72,7 +68,6 @@ jobs:
|
||||
asset_path: panel.tar.gz
|
||||
asset_name: panel.tar.gz
|
||||
asset_content_type: application/gzip
|
||||
|
||||
- name: Upload checksum
|
||||
id: upload-release-checksum
|
||||
uses: actions/upload-release-asset@v1
|
||||
|
36
.github/workflows/tests.yml
vendored
36
.github/workflows/tests.yml
vendored
@ -25,35 +25,43 @@ jobs:
|
||||
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
name: "php-${{ matrix.php }} (${{ matrix.database }})"
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: get cache directory
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Get cache directory
|
||||
id: composer-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
- uses: actions/cache@v2
|
||||
- name: Cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.php_cs.cache
|
||||
${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-cache-${{ matrix.php }}-${{ hashFiles('**.composer.lock') }}
|
||||
- uses: shivammathur/setup-php@v2
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cache-${{ matrix.php }}-
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
extensions: bcmath, cli, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip
|
||||
tools: composer:v2
|
||||
coverage: none
|
||||
- run: cp .env.ci .env
|
||||
- run: composer install --prefer-dist --no-interaction --no-progress
|
||||
- run: vendor/bin/php-cs-fixer fix --dry-run --diff --diff-format=udiff --config .php-cs-fixer.dist.php
|
||||
- name: Configure .env
|
||||
run: cp .env.ci .env
|
||||
- name: composer install
|
||||
run: composer install --prefer-dist --no-interaction --no-progress
|
||||
- name: Run cs-fixer
|
||||
run: vendor/bin/php-cs-fixer fix --dry-run --diff --diff-format=udiff --config .php-cs-fixer.dist.php
|
||||
continue-on-error: true
|
||||
- name: execute unit tests
|
||||
run: vendor/bin/phpunit --bootstrap vendor/autoload.php tests/Unit
|
||||
- name: Execute Unit Tests
|
||||
run: php artisan test tests/Unit
|
||||
if: ${{ always() }}
|
||||
env:
|
||||
DB_CONNECTION: testing
|
||||
TESTING_DB_HOST: UNIT_NO_DB
|
||||
- name: execute integration tests
|
||||
run: vendor/bin/phpunit tests/Integration
|
||||
env:
|
||||
TESTING_DB_PORT: ${{ job.services.database.ports[3306] }}
|
||||
TESTING_DB_USERNAME: root
|
||||
- name: Execute Integration Tests
|
||||
run: php artisan test tests/Integration
|
||||
env:
|
||||
TESTING_DB_PORT: ${{ job.services.database.ports[3306] }}
|
||||
TESTING_DB_USERNAME: root
|
||||
|
106
.gitignore
vendored
106
.gitignore
vendored
@ -1,40 +1,82 @@
|
||||
#------------------#
|
||||
# IDEs and Editors #
|
||||
#------------------#
|
||||
|
||||
# Jetbrains
|
||||
/.idea
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
# Visual Studio Code
|
||||
/.vscode
|
||||
|
||||
# Sublime Text
|
||||
*.sublime-*
|
||||
|
||||
#-------------------#
|
||||
# Tools #
|
||||
#-------------------#
|
||||
|
||||
# Vagrant
|
||||
/.vagrant
|
||||
|
||||
#-------------------#
|
||||
# Languages #
|
||||
#-------------------#
|
||||
|
||||
# Node.js
|
||||
/.npm
|
||||
/node_modules
|
||||
npm-debug.log
|
||||
|
||||
.cache
|
||||
.eslintcache
|
||||
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/releases
|
||||
!.yarn/plugins
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
.pnp.*
|
||||
.yarn-integrity
|
||||
yarn-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# PHP
|
||||
/vendor
|
||||
*.DS_Store*
|
||||
.php-cs-fixer.cache
|
||||
.phpunit.result.cache
|
||||
|
||||
#-------------------#
|
||||
# Operating Systems #
|
||||
#-------------------#
|
||||
|
||||
# External Drives
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
|
||||
# Linux
|
||||
*~
|
||||
|
||||
# Mac OS
|
||||
/.DS_Store
|
||||
*.DS_Store
|
||||
|
||||
# VIM
|
||||
.*.sw[a-p]
|
||||
|
||||
#-------------------#
|
||||
# Project Files #
|
||||
#-------------------#
|
||||
|
||||
# Environment Files
|
||||
!.env.ci
|
||||
!.env.dusk
|
||||
!.env.example
|
||||
.env*
|
||||
.vagrant/*
|
||||
.vscode/*
|
||||
storage/framework/*
|
||||
/.idea
|
||||
/nbproject
|
||||
|
||||
node_modules
|
||||
*.log
|
||||
_ide_helper.php
|
||||
_ide_helper_models.php
|
||||
_ide_helper.php
|
||||
.phpstorm.meta.php
|
||||
.php_cs.cache
|
||||
.yarn
|
||||
public/assets/manifest.json
|
||||
|
||||
# For local development with docker
|
||||
# Remove if we ever put the Dockerfile in the repo
|
||||
.dockerignore
|
||||
#Dockerfile
|
||||
docker-compose.yml
|
||||
|
||||
# for image related files
|
||||
misc
|
||||
.phpstorm.meta.php
|
||||
.php_cs.cache
|
||||
|
||||
coverage.xml
|
||||
|
||||
# Vagrant
|
||||
*.log
|
||||
resources/lang/locales.js
|
||||
resources/assets/pterodactyl/scripts/helpers/ziggy.js
|
||||
resources/assets/scripts/helpers/ziggy.js
|
||||
.phpunit.result.cache
|
||||
|
@ -3,15 +3,7 @@
|
||||
use PhpCsFixer\Config;
|
||||
use PhpCsFixer\Finder;
|
||||
|
||||
$finder = (new Finder())
|
||||
->in(__DIR__)
|
||||
->exclude([
|
||||
'vendor',
|
||||
'node_modules',
|
||||
'storage',
|
||||
'bootstrap/cache',
|
||||
])
|
||||
->notName(['_ide_helper*']);
|
||||
$finder = (new Finder())->in(__DIR__)->exclude(['vendor', 'node_modules', 'storage', 'bootstrap/cache']);
|
||||
|
||||
return (new Config())
|
||||
->setRiskyAllowed(true)
|
||||
@ -29,7 +21,7 @@ return (new Config())
|
||||
'no_unreachable_default_argument_value' => true,
|
||||
'no_useless_return' => true,
|
||||
'ordered_imports' => [
|
||||
'sortAlgorithm' => 'length',
|
||||
'sort_algorithm' => 'length',
|
||||
],
|
||||
'phpdoc_align' => [
|
||||
'align' => 'left',
|
||||
|
55
.yarn/releases/yarn-berry.cjs
vendored
Executable file
55
.yarn/releases/yarn-berry.cjs
vendored
Executable file
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
@types/react-native
|
4
.yarnrc.yml
Normal file
4
.yarnrc.yml
Normal file
@ -0,0 +1,4 @@
|
||||
nodeLinker: 'node-modules'
|
||||
pnpIgnorePatterns:
|
||||
- './public/**/*'
|
||||
yarnPath: '.yarn/releases/yarn-berry.cjs'
|
55
CHANGELOG.md
55
CHANGELOG.md
@ -3,61 +3,6 @@ This file is a running track of new features and fixes to each version of the pa
|
||||
|
||||
This project follows [Semantic Versioning](http://semver.org) guidelines.
|
||||
|
||||
## v1.6.6
|
||||
### Fixed
|
||||
* **[security]** Fixes a CSRF vulnerability for both the administrative test email endpoint and node auto-deployment token generation endpoint. [GHSA-wwgq-9jhf-qgw6](https://github.com/pterodactyl/panel/security/advisories/GHSA-wwgq-9jhf-qgw6)
|
||||
|
||||
### Changed
|
||||
* Updates Minecraft eggs to include latest Java 17 yolk by default.
|
||||
|
||||
## v1.6.5
|
||||
### Fixed
|
||||
* Fixes broken application API endpoints due to changes introduced with session management in 1.6.4.
|
||||
|
||||
## v1.6.4
|
||||
_This release should not be used, please use `1.6.5`. It has been pulled from our releases._
|
||||
|
||||
### Fixed
|
||||
* Fixes a session management bug that would cause a user who signs out of one browser to be unintentionally logged out of other browser sessions when using the client API.
|
||||
|
||||
## v1.6.3
|
||||
### Fixed
|
||||
* **[Security]** Changes logout endpoint to be a POST request with CSRF-token validation to prevent a malicious actor from triggering a user logout.
|
||||
* Fixes Wings receiving the wrong server suspension state when syncing servers.
|
||||
|
||||
### Added
|
||||
* Adds additional throttling to login and password reset endpoints.
|
||||
* Adds server uptime display when viewing a server console.
|
||||
|
||||
## v1.6.2
|
||||
### Fixed
|
||||
* **[Security]** Fixes an authentication bypass vulerability that could allow a malicious actor to login as another user in the Panel without knowing that user's email or password.
|
||||
|
||||
## v1.6.1
|
||||
### Fixed
|
||||
* Fixes server build modifications not being properly persisted to the database when edited.
|
||||
* Correctly exposes the `oom_disabled` field in the `build` limits block for a server build so that Wings can pick it up.
|
||||
*
|
||||
## v1.6.0
|
||||
### Fixed
|
||||
* Fixes array merging logic for server transfers that would cause a 500 error to occur in some scenarios.
|
||||
* Fixes user password updates not correctly logging the user out and returning a failure message even upon successful update.
|
||||
* Fixes the count of used backups when browsing a paginated backup list for a server.
|
||||
* Fixes an error being triggered when API endpoints are called with no `User-Agent` header and an audit log is generated for the action.
|
||||
* Fixes state management on the frontend not properly resetting the loading indicator when adding subusers to a server.
|
||||
* Fixes extraneous API calls being made to Wings for the server file listing when not on a file manager screen.
|
||||
|
||||
### Added
|
||||
* Adds foreign key relationship on the `mount_node`, `mount_server` and `egg_mount` tables.
|
||||
* Adds environment variable `PER_SCHEDULE_TASK_LIMIT` to allow manual overrides for the number of tasks that can exist on a single schedule. This is currently defaulted to `10`.
|
||||
* OOM killer can now be configured at the time of server creation.
|
||||
|
||||
### Changed
|
||||
* Server updates are not dependent on a successful call to Wings occurring — if the API call fails internally the error will be logged but the server update will still be persisted.
|
||||
|
||||
### Removed
|
||||
* Removed `WingsServerRepository::update()` function — if you were previously using this to modify server elements on Wings please replace calls to it with `::sync()` after updating Wings.
|
||||
|
||||
## v1.5.1
|
||||
### Fixed
|
||||
* Fixes Docker image 404ing instead of being able to access the Panel.
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Build the assets that are needed for the frontend. This build stage is then discarded
|
||||
# since we won't need NodeJS anymore in the future. This Docker image ships a final production
|
||||
# level distribution of Pterodactyl.
|
||||
FROM --platform=$TARGETOS/$TARGETARCH mhart/alpine-node:14
|
||||
FROM mhart/alpine-node:14
|
||||
WORKDIR /app
|
||||
COPY . ./
|
||||
RUN yarn install --frozen-lockfile \
|
||||
@ -10,7 +10,7 @@ RUN yarn install --frozen-lockfile \
|
||||
|
||||
# Stage 1:
|
||||
# Build the actual container with all of the needed PHP dependencies that will run the application.
|
||||
FROM --platform=$TARGETOS/$TARGETARCH php:7.4-fpm-alpine
|
||||
FROM php:7.4-fpm-alpine
|
||||
WORKDIR /app
|
||||
COPY . ./
|
||||
COPY --from=0 /app/public/assets ./public/assets
|
||||
|
@ -32,12 +32,10 @@ I would like to extend my sincere thanks to the following sponsors for helping f
|
||||
| [**Spill Hosting**](https://spillhosting.no/) | Spill Hosting is a Norwegian hosting service, which aims for inexpensive services on quality servers. Premium i9-9900K processors will run your game like a dream. |
|
||||
| [**DeinServerHost**](https://deinserverhost.de/) | DeinServerHost offers Dedicated, vps and Gameservers for many popular Games like Minecraft and Rust in Germany since 2013. |
|
||||
| [**HostBend**](https://hostbend.com/) | HostBend offers a variety of solutions for developers, students, and others who have a tight budget but don't want to compromise quality and support. |
|
||||
| [**Capitol Hosting Solutions**](https://chs.gg/) | CHS is *the* budget friendly hosting company for Australian and American gamers, offering a variety of plans from Web Hosting to Game Servers; Custom Solutions too! |
|
||||
| [**Capitol Hosting Solutions**](https://capitolsolutions.cloud/) | CHS is *the* budget friendly hosting company for Australian and American gamers, offering a variety of plans from Web Hosting to Game Servers; Custom Solutions too! |
|
||||
| [**ByteAnia**](https://byteania.com/?utm_source=pterodactyl) | ByteAnia offers the best performing and most affordable **Ryzen 5000 Series hosting** on the market for *unbeatable prices*! |
|
||||
| [**Aussie Server Hosts**](https://aussieserverhosts.com/) | No frills Australian Owned and operated High Performance Server hosting for some of the most demanding games serving Australia and New Zealand. |
|
||||
| [**VibeGAMES**](https://vibegames.net/) | VibeGAMES is a game server provider that specializes in DDOS protection for the games we offer. We have multiple locations in the US, Brazil, France, Germany, Singapore, Australia and South Africa.|
|
||||
| [**RocketNode**](https://rocketnode.net) | RocketNode is a VPS and Game Server provider that offers the best performing VPS and Game hosting Solutions at affordable prices! |
|
||||
| [**HostEZ**](https://hostez.io) | Providing North America Valheim, Minecraft and other popular games with low latency, high uptime and maximum availability. EZ! |
|
||||
|
||||
## Documentation
|
||||
* [Panel Documentation](https://pterodactyl.io/panel/1.0/getting_started.html)
|
||||
|
11
SECURITY.md
11
SECURITY.md
@ -5,13 +5,18 @@ The following versions of Pterodactyl are receiving active support and maintenan
|
||||
|
||||
| Panel | Daemon | Supported |
|
||||
| ----- | ------------ | ------------------ |
|
||||
| 1.6.x | wings@1.5.x | :white_check_mark: |
|
||||
| 1.4.x | wings@1.4.x | :white_check_mark: |
|
||||
| 1.3.x | wings@1.3.x | :x: |
|
||||
| 1.2.x | wings@1.2.x | :x: |
|
||||
| 1.1.x | wings@1.1.x | :x: |
|
||||
| 1.0.x | wings@1.0.x | :x: |
|
||||
| 0.7.x | daemon@0.6.x | :x: |
|
||||
|
||||
| 0.6.x | daemon@0.5.x | :x: |
|
||||
| 0.5.x | daemon@0.4.x | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please reach out directly to any project team member on Discord when reporting a security vulnerability, or you can send an email to `dane@pterodactyl.io`.
|
||||
Please reach out directly to any project team member on Discord when reporting a security vulnerability, or you can send an email to `dane [ät] pterodactyl.io`.
|
||||
|
||||
We make every effort to respond as soon as possible, although it may take a day or two for us to sync internally and determine the severity of the report and its impact. Please, _do not_ use a public facing channel or GitHub issues to report sensitive security issues.
|
||||
|
||||
|
@ -12,7 +12,6 @@ namespace Pterodactyl\Console\Commands\Environment;
|
||||
use DateTimeZone;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Contracts\Console\Kernel;
|
||||
use Illuminate\Validation\Factory as ValidatorFactory;
|
||||
use Pterodactyl\Traits\Commands\EnvironmentWriterTrait;
|
||||
use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
||||
|
||||
@ -79,13 +78,12 @@ class AppSettingsCommand extends Command
|
||||
/**
|
||||
* AppSettingsCommand constructor.
|
||||
*/
|
||||
public function __construct(ConfigRepository $config, Kernel $command, ValidatorFactory $validator)
|
||||
public function __construct(ConfigRepository $config, Kernel $command)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->config = $config;
|
||||
$this->command = $command;
|
||||
$this->validator = $validator;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,18 +103,6 @@ class AppSettingsCommand extends Command
|
||||
$this->config->get('pterodactyl.service.author', 'unknown@unknown.com')
|
||||
);
|
||||
|
||||
$validator = $this->validator->make(
|
||||
['email' => $this->variables['APP_SERVICE_AUTHOR']],
|
||||
['email' => 'email']
|
||||
);
|
||||
|
||||
if ($validator->fails()) {
|
||||
foreach ($validator->errors()->all() as $error) {
|
||||
$this->output->error($error);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->output->comment(trans('command/messages.environment.app.app_url_help'));
|
||||
$this->variables['APP_URL'] = $this->option('url') ?? $this->ask(
|
||||
trans('command/messages.environment.app.app_url'),
|
||||
|
@ -70,7 +70,6 @@ class InfoCommand extends Command
|
||||
['Queue Driver', $this->config->get('queue.default')],
|
||||
['Session Driver', $this->config->get('session.driver')],
|
||||
['Filesystem Driver', $this->config->get('filesystems.default')],
|
||||
['Default Theme', $this->config->get('themes.active')],
|
||||
['Proxies', $this->config->get('trustedproxies.proxies')],
|
||||
], 'compact');
|
||||
|
||||
|
@ -57,7 +57,7 @@ class UpgradeCommand extends Command
|
||||
$userDetails = posix_getpwuid(fileowner('public'));
|
||||
$user = $userDetails['name'] ?? 'www-data';
|
||||
|
||||
if (!$this->confirm("Your webserver user has been detected as <fg=blue>[{$user}]:</> is this correct?", true)) {
|
||||
if (!$this->confirm("Your webserver user has been detected as [{$user}]: is this correct?", true)) {
|
||||
$user = $this->anticipate(
|
||||
'Please enter the name of the user running your webserver process. This varies from system to system, but is generally "www-data", "nginx", or "apache".',
|
||||
[
|
||||
@ -73,7 +73,7 @@ class UpgradeCommand extends Command
|
||||
$groupDetails = posix_getgrgid(filegroup('public'));
|
||||
$group = $groupDetails['name'] ?? 'www-data';
|
||||
|
||||
if (!$this->confirm("Your webserver group has been detected as <fg=blue>[{$group}]:</> is this correct?", true)) {
|
||||
if (!$this->confirm("Your webserver group has been detected as [{$group}]: is this correct?", true)) {
|
||||
$group = $this->anticipate(
|
||||
'Please enter the name of the group running your webserver process. Normally this is the same as your user.',
|
||||
[
|
||||
@ -86,7 +86,6 @@ class UpgradeCommand extends Command
|
||||
}
|
||||
|
||||
if (!$this->confirm('Are you sure you want to run the upgrade process for your Panel?')) {
|
||||
$this->warn('Upgrade process terminated by user.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -174,8 +173,8 @@ class UpgradeCommand extends Command
|
||||
$this->call('up');
|
||||
});
|
||||
|
||||
$this->newLine(2);
|
||||
$this->info('Panel has been successfully upgraded. Please ensure you also update any Wings instances: https://pterodactyl.io/wings/1.0/upgrading.html');
|
||||
$this->newLine();
|
||||
$this->info('Finished running upgrade.');
|
||||
}
|
||||
|
||||
protected function withProgress(ProgressBar $bar, Closure $callback)
|
||||
|
@ -50,8 +50,6 @@ class MakeUserCommand extends Command
|
||||
$root_admin = $this->option('admin') ?? $this->confirm(trans('command/messages.user.ask_admin'));
|
||||
$email = $this->option('email') ?? $this->ask(trans('command/messages.user.ask_email'));
|
||||
$username = $this->option('username') ?? $this->ask(trans('command/messages.user.ask_username'));
|
||||
$name_first = $this->option('name-first') ?? $this->ask(trans('command/messages.user.ask_name_first'));
|
||||
$name_last = $this->option('name-last') ?? $this->ask(trans('command/messages.user.ask_name_last'));
|
||||
|
||||
if (is_null($password = $this->option('password')) && !$this->option('no-password')) {
|
||||
$this->warn(trans('command/messages.user.ask_password_help'));
|
||||
@ -59,7 +57,7 @@ class MakeUserCommand extends Command
|
||||
$password = $this->secret(trans('command/messages.user.ask_password'));
|
||||
}
|
||||
|
||||
$user = $this->creationService->handle(compact('email', 'username', 'name_first', 'name_last', 'password', 'root_admin'));
|
||||
$user = $this->creationService->handle(compact('email', 'username', 'password', 'root_admin'));
|
||||
$this->table(['Field', 'Value'], [
|
||||
['UUID', $user->uuid],
|
||||
['Email', $user->email],
|
||||
|
@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Contracts\Http;
|
||||
|
||||
interface ClientPermissionsRequest
|
||||
{
|
||||
/**
|
||||
* Returns the permissions string indicating which permission should be used to
|
||||
* validate that the authenticated user has permission to perform this action aganist
|
||||
* the given resource (server).
|
||||
*/
|
||||
public function permission(): string;
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Contracts\Repository;
|
||||
|
||||
use Pterodactyl\Models\User;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
interface ApiKeyRepositoryInterface extends RepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Get all of the account API keys that exist for a specific user.
|
||||
*/
|
||||
public function getAccountKeys(User $user): Collection;
|
||||
|
||||
/**
|
||||
* Get all of the application API keys that exist for a specific user.
|
||||
*/
|
||||
public function getApplicationKeys(User $user): Collection;
|
||||
|
||||
/**
|
||||
* Delete an account API key from the panel for a specific user.
|
||||
*/
|
||||
public function deleteAccountKey(User $user, string $identifier): int;
|
||||
|
||||
/**
|
||||
* Delete an application API key from the panel for a specific user.
|
||||
*/
|
||||
public function deleteApplicationKey(User $user, string $identifier): int;
|
||||
}
|
@ -7,6 +7,7 @@ use Throwable;
|
||||
use PDOException;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\Response;
|
||||
use Swift_TransportException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
@ -59,6 +60,16 @@ class Handler extends ExceptionHandler
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Maps specific internal exceptions to a valid HTTP status code.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $statusCodeMap = [
|
||||
AuthenticationException::class => Response::HTTP_UNAUTHORIZED,
|
||||
ValidationException::class => Response::HTTP_UNPROCESSABLE_ENTITY,
|
||||
];
|
||||
|
||||
/**
|
||||
* Registers the exception handling callbacks for the application. This
|
||||
* will capture specific exception types that we do not want to include
|
||||
@ -191,7 +202,7 @@ class Handler extends ExceptionHandler
|
||||
'code' => class_basename($exception),
|
||||
'status' => method_exists($exception, 'getStatusCode')
|
||||
? strval($exception->getStatusCode())
|
||||
: ($exception instanceof ValidationException ? '422' : '500'),
|
||||
: strval(self::$statusCodeMap[get_class($exception)] ?? 500),
|
||||
'detail' => $exception instanceof HttpExceptionInterface
|
||||
? $exception->getMessage()
|
||||
: 'An unexpected error was encountered while processing this request, please try again.',
|
||||
@ -212,6 +223,7 @@ class Handler extends ExceptionHandler
|
||||
'file' => str_replace(Application::getInstance()->basePath(), '', $exception->getFile()),
|
||||
],
|
||||
'meta' => [
|
||||
'class' => get_class($exception),
|
||||
'trace' => explode("\n", $exception->getTraceAsString()),
|
||||
],
|
||||
]);
|
||||
|
21
app/Exceptions/Http/QueryValueOutOfRangeHttpException.php
Normal file
21
app/Exceptions/Http/QueryValueOutOfRangeHttpException.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Exceptions\Http;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
class QueryValueOutOfRangeHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* QueryValueOutOfRangeHttpException constructor.
|
||||
*/
|
||||
public function __construct(string $name, int $min, int $max, \Throwable $previous = null)
|
||||
{
|
||||
parent::__construct(
|
||||
Response::HTTP_BAD_REQUEST,
|
||||
'\"' . $name . '\" query parameter must be between ' . $min . ' and ' . $max,
|
||||
$previous,
|
||||
);
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Exceptions\Transformer;
|
||||
|
||||
use Pterodactyl\Exceptions\PterodactylException;
|
||||
|
||||
class InvalidTransformerLevelException extends PterodactylException
|
||||
{
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Extensions\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class Theme extends Facade
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'extensions.themes';
|
||||
}
|
||||
}
|
23
app/Extensions/Laravel/Sanctum/NewAccessToken.php
Normal file
23
app/Extensions/Laravel/Sanctum/NewAccessToken.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Extensions\Laravel\Sanctum;
|
||||
|
||||
use Pterodactyl\Models\PersonalAccessToken;
|
||||
use Laravel\Sanctum\NewAccessToken as SanctumAccessToken;
|
||||
|
||||
/**
|
||||
* @property \Pterodactyl\Models\PersonalAccessToken $accessToken
|
||||
*/
|
||||
class NewAccessToken extends SanctumAccessToken
|
||||
{
|
||||
/**
|
||||
* NewAccessToken constructor.
|
||||
*
|
||||
* @noinspection PhpMissingParentConstructorInspection
|
||||
*/
|
||||
public function __construct(PersonalAccessToken $accessToken, string $plainTextToken)
|
||||
{
|
||||
$this->accessToken = $accessToken;
|
||||
$this->plainTextToken = $plainTextToken;
|
||||
}
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
|
||||
namespace Pterodactyl\Extensions\Spatie\Fractalistic;
|
||||
|
||||
use League\Fractal\TransformerAbstract;
|
||||
use Spatie\Fractal\Fractal as SpatieFractal;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use Pterodactyl\Extensions\League\Fractal\Serializers\PterodactylSerializer;
|
||||
@ -33,12 +33,9 @@ class Fractal extends SpatieFractal
|
||||
|
||||
// If the resource name is not set attempt to pull it off the transformer
|
||||
// itself and set it automatically.
|
||||
if (
|
||||
is_null($this->resourceName)
|
||||
&& $this->transformer instanceof TransformerAbstract
|
||||
&& method_exists($this->transformer, 'getResourceName')
|
||||
) {
|
||||
$this->resourceName = $this->transformer->getResourceName();
|
||||
$class = is_string($this->transformer) ? new $this->transformer() : $this->transformer;
|
||||
if (is_null($this->resourceName) && $class instanceof Transformer) {
|
||||
$this->resourceName = $class->getResourceName();
|
||||
}
|
||||
|
||||
return parent::createData();
|
||||
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Extensions\Themes;
|
||||
|
||||
class Theme
|
||||
{
|
||||
public function js($path)
|
||||
{
|
||||
return sprintf('<script src="%s"></script>' . PHP_EOL, $this->getUrl($path));
|
||||
}
|
||||
|
||||
public function css($path)
|
||||
{
|
||||
return sprintf('<link media="all" type="text/css" rel="stylesheet" href="%s"/>' . PHP_EOL, $this->getUrl($path));
|
||||
}
|
||||
|
||||
protected function getUrl($path)
|
||||
{
|
||||
return '/themes/pterodactyl/' . ltrim($path, '/');
|
||||
}
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Pterodactyl\Models\ApiKey;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Services\Api\KeyCreationService;
|
||||
use Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface;
|
||||
use Pterodactyl\Http\Requests\Admin\Api\StoreApplicationApiKeyRequest;
|
||||
|
||||
class ApiController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
private $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Api\KeyCreationService
|
||||
*/
|
||||
private $keyCreationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* ApplicationApiController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
ApiKeyRepositoryInterface $repository,
|
||||
KeyCreationService $keyCreationService
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->keyCreationService = $keyCreationService;
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render view showing all of a user's application API keys.
|
||||
*/
|
||||
public function index(Request $request): View
|
||||
{
|
||||
return view('admin.api.index', [
|
||||
'keys' => $this->repository->getApplicationKeys($request->user()),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render view allowing an admin to create a new application API key.
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function create(): View
|
||||
{
|
||||
$resources = AdminAcl::getResourceList();
|
||||
sort($resources);
|
||||
|
||||
return view('admin.api.new', [
|
||||
'resources' => $resources,
|
||||
'permissions' => [
|
||||
'r' => AdminAcl::READ,
|
||||
'rw' => AdminAcl::READ | AdminAcl::WRITE,
|
||||
'n' => AdminAcl::NONE,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the new key and redirect the user back to the application key listing.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
*/
|
||||
public function store(StoreApplicationApiKeyRequest $request): RedirectResponse
|
||||
{
|
||||
$this->keyCreationService->setKeyType(ApiKey::TYPE_APPLICATION)->handle([
|
||||
'memo' => $request->input('memo'),
|
||||
'user_id' => $request->user()->id,
|
||||
], $request->getKeyPermissions());
|
||||
|
||||
$this->alert->success('A new application API key has been generated for your account.')->flash();
|
||||
|
||||
return redirect()->route('admin.api.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an application API key from the database.
|
||||
*/
|
||||
public function delete(Request $request, string $identifier): Response
|
||||
{
|
||||
$this->repository->deleteApplicationKey($request->user(), $identifier);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
}
|
@ -4,28 +4,14 @@ namespace Pterodactyl\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Services\Helpers\SoftwareVersionService;
|
||||
|
||||
class BaseController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Helpers\SoftwareVersionService
|
||||
*/
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* BaseController constructor.
|
||||
*/
|
||||
public function __construct(SoftwareVersionService $version)
|
||||
{
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the admin index view.
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.index', ['version' => $this->version]);
|
||||
return view('templates/base.core');
|
||||
}
|
||||
}
|
||||
|
@ -1,170 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin;
|
||||
|
||||
use Exception;
|
||||
use PDOException;
|
||||
use Illuminate\View\View;
|
||||
use Pterodactyl\Models\DatabaseHost;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Services\Databases\Hosts\HostUpdateService;
|
||||
use Pterodactyl\Http\Requests\Admin\DatabaseHostFormRequest;
|
||||
use Pterodactyl\Services\Databases\Hosts\HostCreationService;
|
||||
use Pterodactyl\Services\Databases\Hosts\HostDeletionService;
|
||||
use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
||||
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
||||
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
||||
|
||||
class DatabaseController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
private $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Databases\Hosts\HostCreationService
|
||||
*/
|
||||
private $creationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface
|
||||
*/
|
||||
private $databaseRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Databases\Hosts\HostDeletionService
|
||||
*/
|
||||
private $deletionService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
|
||||
*/
|
||||
private $locationRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Databases\Hosts\HostUpdateService
|
||||
*/
|
||||
private $updateService;
|
||||
|
||||
/**
|
||||
* DatabaseController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
DatabaseHostRepositoryInterface $repository,
|
||||
DatabaseRepositoryInterface $databaseRepository,
|
||||
HostCreationService $creationService,
|
||||
HostDeletionService $deletionService,
|
||||
HostUpdateService $updateService,
|
||||
LocationRepositoryInterface $locationRepository
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->creationService = $creationService;
|
||||
$this->databaseRepository = $databaseRepository;
|
||||
$this->deletionService = $deletionService;
|
||||
$this->repository = $repository;
|
||||
$this->locationRepository = $locationRepository;
|
||||
$this->updateService = $updateService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display database host index.
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.databases.index', [
|
||||
'locations' => $this->locationRepository->getAllWithNodes(),
|
||||
'hosts' => $this->repository->getWithViewDetails(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display database host to user.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function view(int $host): View
|
||||
{
|
||||
return view('admin.databases.view', [
|
||||
'locations' => $this->locationRepository->getAllWithNodes(),
|
||||
'host' => $this->repository->find($host),
|
||||
'databases' => $this->databaseRepository->getDatabasesForHost($host),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to create a new database host.
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function create(DatabaseHostFormRequest $request): RedirectResponse
|
||||
{
|
||||
try {
|
||||
$host = $this->creationService->handle($request->normalize());
|
||||
} catch (Exception $exception) {
|
||||
if ($exception instanceof PDOException || $exception->getPrevious() instanceof PDOException) {
|
||||
$this->alert->danger(
|
||||
sprintf('There was an error while trying to connect to the host or while executing a query: "%s"', $exception->getMessage())
|
||||
)->flash();
|
||||
|
||||
return redirect()->route('admin.databases')->withInput($request->validated());
|
||||
} else {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
$this->alert->success('Successfully created a new database host on the system.')->flash();
|
||||
|
||||
return redirect()->route('admin.databases.view', $host->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle updating database host.
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function update(DatabaseHostFormRequest $request, DatabaseHost $host): RedirectResponse
|
||||
{
|
||||
$redirect = redirect()->route('admin.databases.view', $host->id);
|
||||
|
||||
try {
|
||||
$this->updateService->handle($host->id, $request->normalize());
|
||||
$this->alert->success('Database host was updated successfully.')->flash();
|
||||
} catch (Exception $exception) {
|
||||
// Catch any SQL related exceptions and display them back to the user, otherwise just
|
||||
// throw the exception like normal and move on with it.
|
||||
if ($exception instanceof PDOException || $exception->getPrevious() instanceof PDOException) {
|
||||
$this->alert->danger(
|
||||
sprintf('There was an error while trying to connect to the host or while executing a query: "%s"', $exception->getMessage())
|
||||
)->flash();
|
||||
|
||||
return $redirect->withInput($request->normalize());
|
||||
} else {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
return $redirect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to delete a database host.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Service\HasActiveServersException
|
||||
*/
|
||||
public function delete(int $host): RedirectResponse
|
||||
{
|
||||
$this->deletionService->handle($host);
|
||||
$this->alert->success('The requested database host has been deleted from the system.')->flash();
|
||||
|
||||
return redirect()->route('admin.databases');
|
||||
}
|
||||
}
|
@ -1,148 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin;
|
||||
|
||||
use Pterodactyl\Models\Location;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Exceptions\DisplayException;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Http\Requests\Admin\LocationFormRequest;
|
||||
use Pterodactyl\Services\Locations\LocationUpdateService;
|
||||
use Pterodactyl\Services\Locations\LocationCreationService;
|
||||
use Pterodactyl\Services\Locations\LocationDeletionService;
|
||||
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
||||
|
||||
class LocationController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
protected $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Locations\LocationCreationService
|
||||
*/
|
||||
protected $creationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Locations\LocationDeletionService
|
||||
*/
|
||||
protected $deletionService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Locations\LocationUpdateService
|
||||
*/
|
||||
protected $updateService;
|
||||
|
||||
/**
|
||||
* LocationController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
LocationCreationService $creationService,
|
||||
LocationDeletionService $deletionService,
|
||||
LocationRepositoryInterface $repository,
|
||||
LocationUpdateService $updateService
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->creationService = $creationService;
|
||||
$this->deletionService = $deletionService;
|
||||
$this->repository = $repository;
|
||||
$this->updateService = $updateService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the location overview page.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('admin.locations.index', [
|
||||
'locations' => $this->repository->getAllWithDetails(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the location view page.
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function view($id)
|
||||
{
|
||||
return view('admin.locations.view', [
|
||||
'location' => $this->repository->getWithNodes($id),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to create new location.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function create(LocationFormRequest $request)
|
||||
{
|
||||
$location = $this->creationService->handle($request->normalize());
|
||||
$this->alert->success('Location was created successfully.')->flash();
|
||||
|
||||
return redirect()->route('admin.locations.view', $location->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to update or delete location.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function update(LocationFormRequest $request, Location $location)
|
||||
{
|
||||
if ($request->input('action') === 'delete') {
|
||||
return $this->delete($location);
|
||||
}
|
||||
|
||||
$this->updateService->handle($location->id, $request->normalize());
|
||||
$this->alert->success('Location was updated successfully.')->flash();
|
||||
|
||||
return redirect()->route('admin.locations.view', $location->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a location from the system.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
*/
|
||||
public function delete(Location $location)
|
||||
{
|
||||
try {
|
||||
$this->deletionService->handle($location->id);
|
||||
|
||||
return redirect()->route('admin.locations');
|
||||
} catch (DisplayException $ex) {
|
||||
$this->alert->danger($ex->getMessage())->flash();
|
||||
}
|
||||
|
||||
return redirect()->route('admin.locations.view', $location->id);
|
||||
}
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin;
|
||||
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\Nest;
|
||||
use Pterodactyl\Models\Mount;
|
||||
use Pterodactyl\Models\Location;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Http\Requests\Admin\MountFormRequest;
|
||||
use Pterodactyl\Repositories\Eloquent\MountRepository;
|
||||
use Pterodactyl\Contracts\Repository\NestRepositoryInterface;
|
||||
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
||||
|
||||
class MountController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
protected $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\NestRepositoryInterface
|
||||
*/
|
||||
protected $nestRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
|
||||
*/
|
||||
protected $locationRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\MountRepository
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* MountController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
NestRepositoryInterface $nestRepository,
|
||||
LocationRepositoryInterface $locationRepository,
|
||||
MountRepository $repository
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->nestRepository = $nestRepository;
|
||||
$this->locationRepository = $locationRepository;
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mount overview page.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('admin.mounts.index', [
|
||||
'mounts' => $this->repository->getAllWithDetails(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mount view page.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function view($id)
|
||||
{
|
||||
$nests = Nest::query()->with('eggs')->get();
|
||||
$locations = Location::query()->with('nodes')->get();
|
||||
|
||||
return view('admin.mounts.view', [
|
||||
'mount' => $this->repository->getWithRelations($id),
|
||||
'nests' => $nests,
|
||||
'locations' => $locations,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to create new mount.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function create(MountFormRequest $request)
|
||||
{
|
||||
$model = (new Mount())->fill($request->validated());
|
||||
$model->forceFill(['uuid' => Uuid::uuid4()->toString()]);
|
||||
|
||||
$model->saveOrFail();
|
||||
$mount = $model->fresh();
|
||||
|
||||
$this->alert->success('Mount was created successfully.')->flash();
|
||||
|
||||
return redirect()->route('admin.mounts.view', $mount->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to update or delete location.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function update(MountFormRequest $request, Mount $mount)
|
||||
{
|
||||
if ($request->input('action') === 'delete') {
|
||||
return $this->delete($mount);
|
||||
}
|
||||
|
||||
$mount->forceFill($request->validated())->save();
|
||||
|
||||
$this->alert->success('Mount was updated successfully.')->flash();
|
||||
|
||||
return redirect()->route('admin.mounts.view', $mount->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a location from the system.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(Mount $mount)
|
||||
{
|
||||
$mount->delete();
|
||||
|
||||
return redirect()->route('admin.mounts');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds eggs to the mount's many to many relation.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function addEggs(Request $request, Mount $mount)
|
||||
{
|
||||
$validatedData = $request->validate([
|
||||
'eggs' => 'required|exists:eggs,id',
|
||||
]);
|
||||
|
||||
$eggs = $validatedData['eggs'] ?? [];
|
||||
if (count($eggs) > 0) {
|
||||
$mount->eggs()->attach($eggs);
|
||||
}
|
||||
|
||||
$this->alert->success('Mount was updated successfully.')->flash();
|
||||
|
||||
return redirect()->route('admin.mounts.view', $mount->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds nodes to the mount's many to many relation.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function addNodes(Request $request, Mount $mount)
|
||||
{
|
||||
$data = $request->validate(['nodes' => 'required|exists:nodes,id']);
|
||||
|
||||
$nodes = $data['nodes'] ?? [];
|
||||
if (count($nodes) > 0) {
|
||||
$mount->nodes()->attach($nodes);
|
||||
}
|
||||
|
||||
$this->alert->success('Mount was updated successfully.')->flash();
|
||||
|
||||
return redirect()->route('admin.mounts.view', $mount->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an egg from the mount's many to many relation.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function deleteEgg(Mount $mount, int $egg_id)
|
||||
{
|
||||
$mount->eggs()->detach($egg_id);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an node from the mount's many to many relation.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function deleteNode(Mount $mount, int $node_id)
|
||||
{
|
||||
$mount->nodes()->detach($node_id);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Nests;
|
||||
|
||||
use Javascript;
|
||||
use Illuminate\View\View;
|
||||
use Pterodactyl\Models\Egg;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Services\Eggs\EggUpdateService;
|
||||
use Pterodactyl\Services\Eggs\EggCreationService;
|
||||
use Pterodactyl\Services\Eggs\EggDeletionService;
|
||||
use Pterodactyl\Http\Requests\Admin\Egg\EggFormRequest;
|
||||
use Pterodactyl\Contracts\Repository\EggRepositoryInterface;
|
||||
use Pterodactyl\Contracts\Repository\NestRepositoryInterface;
|
||||
|
||||
class EggController extends Controller
|
||||
{
|
||||
protected $alert;
|
||||
|
||||
protected $creationService;
|
||||
|
||||
protected $deletionService;
|
||||
|
||||
protected $nestRepository;
|
||||
|
||||
protected $repository;
|
||||
|
||||
protected $updateService;
|
||||
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
EggCreationService $creationService,
|
||||
EggDeletionService $deletionService,
|
||||
EggRepositoryInterface $repository,
|
||||
EggUpdateService $updateService,
|
||||
NestRepositoryInterface $nestRepository
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->creationService = $creationService;
|
||||
$this->deletionService = $deletionService;
|
||||
$this->nestRepository = $nestRepository;
|
||||
$this->repository = $repository;
|
||||
$this->updateService = $updateService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a request to display the Egg creation page.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function create(): View
|
||||
{
|
||||
$nests = $this->nestRepository->getWithEggs();
|
||||
Javascript::put(['nests' => $nests->keyBy('id')]);
|
||||
|
||||
return view('admin.eggs.new', ['nests' => $nests]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to store a new Egg.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Egg\NoParentConfigurationFoundException
|
||||
*/
|
||||
public function store(EggFormRequest $request): RedirectResponse
|
||||
{
|
||||
$data = $request->normalize();
|
||||
if (!empty($data['docker_images']) && !is_array($data['docker_images'])) {
|
||||
$data['docker_images'] = array_map(function ($value) {
|
||||
return trim($value);
|
||||
}, explode("\n", $data['docker_images']));
|
||||
}
|
||||
|
||||
$egg = $this->creationService->handle($data);
|
||||
$this->alert->success(trans('admin/nests.eggs.notices.egg_created'))->flash();
|
||||
|
||||
return redirect()->route('admin.nests.egg.view', $egg->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to view a single Egg.
|
||||
*/
|
||||
public function view(Egg $egg): View
|
||||
{
|
||||
return view('admin.eggs.view', ['egg' => $egg]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to update an Egg.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Egg\NoParentConfigurationFoundException
|
||||
*/
|
||||
public function update(EggFormRequest $request, Egg $egg): RedirectResponse
|
||||
{
|
||||
$data = $request->normalize();
|
||||
if (!empty($data['docker_images']) && !is_array($data['docker_images'])) {
|
||||
$data['docker_images'] = array_map(function ($value) {
|
||||
return trim($value);
|
||||
}, explode("\n", $data['docker_images']));
|
||||
}
|
||||
|
||||
$this->updateService->handle($egg, $data);
|
||||
$this->alert->success(trans('admin/nests.eggs.notices.updated'))->flash();
|
||||
|
||||
return redirect()->route('admin.nests.egg.view', $egg->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to destroy an egg.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Service\Egg\HasChildrenException
|
||||
* @throws \Pterodactyl\Exceptions\Service\HasActiveServersException
|
||||
*/
|
||||
public function destroy(Egg $egg): RedirectResponse
|
||||
{
|
||||
$this->deletionService->handle($egg->id);
|
||||
$this->alert->success(trans('admin/nests.eggs.notices.deleted'))->flash();
|
||||
|
||||
return redirect()->route('admin.nests.view', $egg->nest_id);
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Nests;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Pterodactyl\Models\Egg;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Services\Eggs\Scripts\InstallScriptService;
|
||||
use Pterodactyl\Contracts\Repository\EggRepositoryInterface;
|
||||
use Pterodactyl\Http\Requests\Admin\Egg\EggScriptFormRequest;
|
||||
|
||||
class EggScriptController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
protected $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Eggs\Scripts\InstallScriptService
|
||||
*/
|
||||
protected $installScriptService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\EggRepositoryInterface
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* EggScriptController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
EggRepositoryInterface $repository,
|
||||
InstallScriptService $installScriptService
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->installScriptService = $installScriptService;
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle requests to render installation script for an Egg.
|
||||
*/
|
||||
public function index(int $egg): View
|
||||
{
|
||||
$egg = $this->repository->getWithCopyAttributes($egg);
|
||||
$copy = $this->repository->findWhere([
|
||||
['copy_script_from', '=', null],
|
||||
['nest_id', '=', $egg->nest_id],
|
||||
['id', '!=', $egg],
|
||||
]);
|
||||
|
||||
$rely = $this->repository->findWhere([
|
||||
['copy_script_from', '=', $egg->id],
|
||||
]);
|
||||
|
||||
return view('admin.eggs.scripts', [
|
||||
'copyFromOptions' => $copy,
|
||||
'relyOnScript' => $rely,
|
||||
'egg' => $egg,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a request to update the installation script for an Egg.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Egg\InvalidCopyFromException
|
||||
*/
|
||||
public function update(EggScriptFormRequest $request, Egg $egg): RedirectResponse
|
||||
{
|
||||
$this->installScriptService->handle($egg, $request->normalize());
|
||||
$this->alert->success(trans('admin/nests.eggs.notices.script_updated'))->flash();
|
||||
|
||||
return redirect()->route('admin.nests.egg.scripts', $egg);
|
||||
}
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Nests;
|
||||
|
||||
use Pterodactyl\Models\Egg;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Pterodactyl\Services\Eggs\Sharing\EggExporterService;
|
||||
use Pterodactyl\Services\Eggs\Sharing\EggImporterService;
|
||||
use Pterodactyl\Http\Requests\Admin\Egg\EggImportFormRequest;
|
||||
use Pterodactyl\Services\Eggs\Sharing\EggUpdateImporterService;
|
||||
|
||||
class EggShareController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
protected $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Eggs\Sharing\EggExporterService
|
||||
*/
|
||||
protected $exporterService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Eggs\Sharing\EggImporterService
|
||||
*/
|
||||
protected $importerService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Eggs\Sharing\EggUpdateImporterService
|
||||
*/
|
||||
protected $updateImporterService;
|
||||
|
||||
/**
|
||||
* OptionShareController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
EggExporterService $exporterService,
|
||||
EggImporterService $importerService,
|
||||
EggUpdateImporterService $updateImporterService
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->exporterService = $exporterService;
|
||||
$this->importerService = $importerService;
|
||||
$this->updateImporterService = $updateImporterService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function export(Egg $egg): Response
|
||||
{
|
||||
$filename = trim(preg_replace('/[^\w]/', '-', kebab_case($egg->name)), '-');
|
||||
|
||||
return response($this->exporterService->handle($egg->id), 200, [
|
||||
'Content-Transfer-Encoding' => 'binary',
|
||||
'Content-Description' => 'File Transfer',
|
||||
'Content-Disposition' => 'attachment; filename=egg-' . $filename . '.json',
|
||||
'Content-Type' => 'application/json',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a new service option using an XML file.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Egg\BadJsonFormatException
|
||||
* @throws \Pterodactyl\Exceptions\Service\InvalidFileUploadException
|
||||
*/
|
||||
public function import(EggImportFormRequest $request): RedirectResponse
|
||||
{
|
||||
$egg = $this->importerService->handle($request->file('import_file'), $request->input('import_to_nest'));
|
||||
$this->alert->success(trans('admin/nests.eggs.notices.imported'))->flash();
|
||||
|
||||
return redirect()->route('admin.nests.egg.view', ['egg' => $egg->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing Egg using a new imported file.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Egg\BadJsonFormatException
|
||||
* @throws \Pterodactyl\Exceptions\Service\InvalidFileUploadException
|
||||
*/
|
||||
public function update(EggImportFormRequest $request, Egg $egg): RedirectResponse
|
||||
{
|
||||
$this->updateImporterService->handle($egg, $request->file('import_file'));
|
||||
$this->alert->success(trans('admin/nests.eggs.notices.updated_via_import'))->flash();
|
||||
|
||||
return redirect()->route('admin.nests.egg.view', ['egg' => $egg]);
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Nests;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Pterodactyl\Models\Egg;
|
||||
use Pterodactyl\Models\EggVariable;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Contracts\Repository\EggRepositoryInterface;
|
||||
use Pterodactyl\Services\Eggs\Variables\VariableUpdateService;
|
||||
use Pterodactyl\Http\Requests\Admin\Egg\EggVariableFormRequest;
|
||||
use Pterodactyl\Services\Eggs\Variables\VariableCreationService;
|
||||
use Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface;
|
||||
|
||||
class EggVariableController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
protected $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Eggs\Variables\VariableCreationService
|
||||
*/
|
||||
protected $creationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\EggRepositoryInterface
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Eggs\Variables\VariableUpdateService
|
||||
*/
|
||||
protected $updateService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface
|
||||
*/
|
||||
protected $variableRepository;
|
||||
|
||||
/**
|
||||
* EggVariableController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
VariableCreationService $creationService,
|
||||
VariableUpdateService $updateService,
|
||||
EggRepositoryInterface $repository,
|
||||
EggVariableRepositoryInterface $variableRepository
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->creationService = $creationService;
|
||||
$this->repository = $repository;
|
||||
$this->updateService = $updateService;
|
||||
$this->variableRepository = $variableRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to view the variables attached to an Egg.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function view(int $egg): View
|
||||
{
|
||||
$egg = $this->repository->getWithVariables($egg);
|
||||
|
||||
return view('admin.eggs.variables', ['egg' => $egg]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a request to create a new Egg variable.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Egg\Variable\BadValidationRuleException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException
|
||||
*/
|
||||
public function store(EggVariableFormRequest $request, Egg $egg): RedirectResponse
|
||||
{
|
||||
$this->creationService->handle($egg->id, $request->normalize());
|
||||
$this->alert->success(trans('admin/nests.variables.notices.variable_created'))->flash();
|
||||
|
||||
return redirect()->route('admin.nests.egg.variables', $egg->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a request to update an existing Egg variable.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException
|
||||
*/
|
||||
public function update(EggVariableFormRequest $request, Egg $egg, EggVariable $variable): RedirectResponse
|
||||
{
|
||||
$this->updateService->handle($variable, $request->normalize());
|
||||
$this->alert->success(trans('admin/nests.variables.notices.variable_updated', [
|
||||
'variable' => $variable->name,
|
||||
]))->flash();
|
||||
|
||||
return redirect()->route('admin.nests.egg.variables', $egg->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a request to delete an existing Egg variable from the Panel.
|
||||
*/
|
||||
public function destroy(int $egg, EggVariable $variable): RedirectResponse
|
||||
{
|
||||
$this->variableRepository->delete($variable->id);
|
||||
$this->alert->success(trans('admin/nests.variables.notices.variable_deleted', [
|
||||
'variable' => $variable->name,
|
||||
]))->flash();
|
||||
|
||||
return redirect()->route('admin.nests.egg.variables', $egg);
|
||||
}
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Nests;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Services\Nests\NestUpdateService;
|
||||
use Pterodactyl\Services\Nests\NestCreationService;
|
||||
use Pterodactyl\Services\Nests\NestDeletionService;
|
||||
use Pterodactyl\Contracts\Repository\NestRepositoryInterface;
|
||||
use Pterodactyl\Http\Requests\Admin\Nest\StoreNestFormRequest;
|
||||
|
||||
class NestController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
protected $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Nests\NestCreationService
|
||||
*/
|
||||
protected $nestCreationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Nests\NestDeletionService
|
||||
*/
|
||||
protected $nestDeletionService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\NestRepositoryInterface
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Nests\NestUpdateService
|
||||
*/
|
||||
protected $nestUpdateService;
|
||||
|
||||
/**
|
||||
* NestController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
NestCreationService $nestCreationService,
|
||||
NestDeletionService $nestDeletionService,
|
||||
NestRepositoryInterface $repository,
|
||||
NestUpdateService $nestUpdateService
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->nestDeletionService = $nestDeletionService;
|
||||
$this->nestCreationService = $nestCreationService;
|
||||
$this->nestUpdateService = $nestUpdateService;
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render nest listing page.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.nests.index', [
|
||||
'nests' => $this->repository->getWithCounts(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render nest creation page.
|
||||
*/
|
||||
public function create(): View
|
||||
{
|
||||
return view('admin.nests.new');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the storage of a new nest.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
*/
|
||||
public function store(StoreNestFormRequest $request): RedirectResponse
|
||||
{
|
||||
$nest = $this->nestCreationService->handle($request->normalize());
|
||||
$this->alert->success(trans('admin/nests.notices.created', ['name' => $nest->name]))->flash();
|
||||
|
||||
return redirect()->route('admin.nests.view', $nest->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return details about a nest including all of the eggs and servers per egg.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function view(int $nest): View
|
||||
{
|
||||
return view('admin.nests.view', [
|
||||
'nest' => $this->repository->getWithEggServers($nest),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to update a nest.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function update(StoreNestFormRequest $request, int $nest): RedirectResponse
|
||||
{
|
||||
$this->nestUpdateService->handle($nest, $request->normalize());
|
||||
$this->alert->success(trans('admin/nests.notices.updated'))->flash();
|
||||
|
||||
return redirect()->route('admin.nests.view', $nest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to delete a nest.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Service\HasActiveServersException
|
||||
*/
|
||||
public function destroy(int $nest): RedirectResponse
|
||||
{
|
||||
$this->nestDeletionService->handle($nest);
|
||||
$this->alert->success(trans('admin/nests.notices.deleted'))->flash();
|
||||
|
||||
return redirect()->route('admin.nests');
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\Node;
|
||||
use Pterodactyl\Models\ApiKey;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\Encryption\Encrypter;
|
||||
use Pterodactyl\Services\Api\KeyCreationService;
|
||||
use Pterodactyl\Repositories\Eloquent\ApiKeyRepository;
|
||||
|
||||
class NodeAutoDeployController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Api\KeyCreationService
|
||||
*/
|
||||
private $keyCreationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ApiKeyRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Encryption\Encrypter
|
||||
*/
|
||||
private $encrypter;
|
||||
|
||||
/**
|
||||
* NodeAutoDeployController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
ApiKeyRepository $repository,
|
||||
Encrypter $encrypter,
|
||||
KeyCreationService $keyCreationService
|
||||
) {
|
||||
$this->keyCreationService = $keyCreationService;
|
||||
$this->repository = $repository;
|
||||
$this->encrypter = $encrypter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new API key for the logged in user with only permission to read
|
||||
* nodes, and returns that as the deployment key for a node.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
*/
|
||||
public function __invoke(Request $request, Node $node)
|
||||
{
|
||||
/** @var \Pterodactyl\Models\ApiKey|null $key */
|
||||
$key = $this->repository->getApplicationKeys($request->user())
|
||||
->filter(function (ApiKey $key) {
|
||||
foreach ($key->getAttributes() as $permission => $value) {
|
||||
if ($permission === 'r_nodes' && $value === 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
})
|
||||
->first();
|
||||
|
||||
// We couldn't find a key that exists for this user with only permission for
|
||||
// reading nodes. Go ahead and create it now.
|
||||
if (!$key) {
|
||||
$key = $this->keyCreationService->setKeyType(ApiKey::TYPE_APPLICATION)->handle([
|
||||
'user_id' => $request->user()->id,
|
||||
'memo' => 'Automatically generated node deployment key.',
|
||||
'allowed_ips' => [],
|
||||
], ['r_nodes' => 1]);
|
||||
}
|
||||
|
||||
return JsonResponse::create([
|
||||
'node' => $node->id,
|
||||
'token' => $key->identifier . $this->encrypter->decrypt($key->token),
|
||||
]);
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Nodes;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\Node;
|
||||
use Spatie\QueryBuilder\QueryBuilder;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
||||
|
||||
class NodeController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\NodeRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* NodeController constructor.
|
||||
*/
|
||||
public function __construct(NodeRepository $repository, Factory $view)
|
||||
{
|
||||
$this->view = $view;
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a listing of nodes on the system.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$nodes = QueryBuilder::for(
|
||||
Node::query()->with('location')->withCount('servers')
|
||||
)
|
||||
->allowedFilters(['uuid', 'name'])
|
||||
->allowedSorts(['id'])
|
||||
->paginate(25);
|
||||
|
||||
return $this->view->make('admin.nodes.index', ['nodes' => $nodes]);
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Nodes;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\Node;
|
||||
use Illuminate\Support\Collection;
|
||||
use Pterodactyl\Models\Allocation;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||
use Pterodactyl\Traits\Controllers\JavascriptInjection;
|
||||
use Pterodactyl\Services\Helpers\SoftwareVersionService;
|
||||
use Pterodactyl\Repositories\Eloquent\LocationRepository;
|
||||
use Pterodactyl\Repositories\Eloquent\AllocationRepository;
|
||||
|
||||
class NodeViewController extends Controller
|
||||
{
|
||||
use JavascriptInjection;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\NodeRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Helpers\SoftwareVersionService
|
||||
*/
|
||||
private $versionService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\LocationRepository
|
||||
*/
|
||||
private $locationRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\AllocationRepository
|
||||
*/
|
||||
private $allocationRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
||||
*/
|
||||
private $serverRepository;
|
||||
|
||||
/**
|
||||
* NodeViewController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AllocationRepository $allocationRepository,
|
||||
LocationRepository $locationRepository,
|
||||
NodeRepository $repository,
|
||||
ServerRepository $serverRepository,
|
||||
SoftwareVersionService $versionService,
|
||||
Factory $view
|
||||
) {
|
||||
$this->repository = $repository;
|
||||
$this->view = $view;
|
||||
$this->versionService = $versionService;
|
||||
$this->locationRepository = $locationRepository;
|
||||
$this->allocationRepository = $allocationRepository;
|
||||
$this->serverRepository = $serverRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns index view for a specific node on the system.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request, Node $node)
|
||||
{
|
||||
$node = $this->repository->loadLocationAndServerCount($node);
|
||||
|
||||
return $this->view->make('admin.nodes.view.index', [
|
||||
'node' => $node,
|
||||
'stats' => $this->repository->getUsageStats($node),
|
||||
'version' => $this->versionService,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the settings page for a specific node.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function settings(Request $request, Node $node)
|
||||
{
|
||||
return $this->view->make('admin.nodes.view.settings', [
|
||||
'node' => $node,
|
||||
'locations' => $this->locationRepository->all(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the node configuration page for a specific node.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function configuration(Request $request, Node $node)
|
||||
{
|
||||
return $this->view->make('admin.nodes.view.configuration', compact('node'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the node allocation management page.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function allocations(Request $request, Node $node)
|
||||
{
|
||||
$node = $this->repository->loadNodeAllocations($node);
|
||||
|
||||
$this->plainInject(['node' => Collection::wrap($node)->only(['id'])]);
|
||||
|
||||
return $this->view->make('admin.nodes.view.allocation', [
|
||||
'node' => $node,
|
||||
'allocations' => Allocation::query()->where('node_id', $node->id)
|
||||
->groupBy('ip')
|
||||
->orderByRaw('INET_ATON(ip) ASC')
|
||||
->get(['ip']),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a listing of servers that exist for this specific node.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function servers(Request $request, Node $node)
|
||||
{
|
||||
$this->plainInject([
|
||||
'node' => Collection::wrap($node->makeVisible(['daemon_token_id', 'daemon_token']))
|
||||
->only(['scheme', 'fqdn', 'daemonListen', 'daemon_token_id', 'daemon_token']),
|
||||
]);
|
||||
|
||||
return $this->view->make('admin.nodes.view.servers', [
|
||||
'node' => $node,
|
||||
'servers' => $this->serverRepository->loadAllServersForNode($node->id, 25),
|
||||
]);
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Nodes;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\Node;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Repositories\Wings\DaemonConfigurationRepository;
|
||||
|
||||
class SystemInformationController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Wings\DaemonConfigurationRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* SystemInformationController constructor.
|
||||
*/
|
||||
public function __construct(DaemonConfigurationRepository $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns system information from the Daemon.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||
*/
|
||||
public function __invoke(Request $request, Node $node)
|
||||
{
|
||||
$data = $this->repository->setNode($node)->getSystemInformation();
|
||||
|
||||
return JsonResponse::create([
|
||||
'version' => $data['version'] ?? '',
|
||||
'system' => [
|
||||
'type' => Str::title($data['os'] ?? 'Unknown'),
|
||||
'arch' => $data['architecture'] ?? '--',
|
||||
'release' => $data['kernel_version'] ?? '--',
|
||||
'cpus' => $data['cpu_count'] ?? 0,
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
@ -1,278 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\Node;
|
||||
use Illuminate\Http\Response;
|
||||
use Pterodactyl\Models\Allocation;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Services\Nodes\NodeUpdateService;
|
||||
use Illuminate\Cache\Repository as CacheRepository;
|
||||
use Pterodactyl\Services\Nodes\NodeCreationService;
|
||||
use Pterodactyl\Services\Nodes\NodeDeletionService;
|
||||
use Pterodactyl\Services\Allocations\AssignmentService;
|
||||
use Pterodactyl\Services\Helpers\SoftwareVersionService;
|
||||
use Pterodactyl\Http\Requests\Admin\Node\NodeFormRequest;
|
||||
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
|
||||
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||
use Pterodactyl\Http\Requests\Admin\Node\AllocationFormRequest;
|
||||
use Pterodactyl\Services\Allocations\AllocationDeletionService;
|
||||
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
||||
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
|
||||
use Pterodactyl\Http\Requests\Admin\Node\AllocationAliasFormRequest;
|
||||
|
||||
class NodesController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Allocations\AllocationDeletionService
|
||||
*/
|
||||
protected $allocationDeletionService;
|
||||
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
protected $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\AllocationRepositoryInterface
|
||||
*/
|
||||
protected $allocationRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Allocations\AssignmentService
|
||||
*/
|
||||
protected $assignmentService;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Cache\Repository
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Nodes\NodeCreationService
|
||||
*/
|
||||
protected $creationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Nodes\NodeDeletionService
|
||||
*/
|
||||
protected $deletionService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
|
||||
*/
|
||||
protected $locationRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\NodeRepositoryInterface
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
||||
*/
|
||||
protected $serverRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Nodes\NodeUpdateService
|
||||
*/
|
||||
protected $updateService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Helpers\SoftwareVersionService
|
||||
*/
|
||||
protected $versionService;
|
||||
|
||||
/**
|
||||
* NodesController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
AllocationDeletionService $allocationDeletionService,
|
||||
AllocationRepositoryInterface $allocationRepository,
|
||||
AssignmentService $assignmentService,
|
||||
CacheRepository $cache,
|
||||
NodeCreationService $creationService,
|
||||
NodeDeletionService $deletionService,
|
||||
LocationRepositoryInterface $locationRepository,
|
||||
NodeRepositoryInterface $repository,
|
||||
ServerRepositoryInterface $serverRepository,
|
||||
NodeUpdateService $updateService,
|
||||
SoftwareVersionService $versionService
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->allocationDeletionService = $allocationDeletionService;
|
||||
$this->allocationRepository = $allocationRepository;
|
||||
$this->assignmentService = $assignmentService;
|
||||
$this->cache = $cache;
|
||||
$this->creationService = $creationService;
|
||||
$this->deletionService = $deletionService;
|
||||
$this->locationRepository = $locationRepository;
|
||||
$this->repository = $repository;
|
||||
$this->serverRepository = $serverRepository;
|
||||
$this->updateService = $updateService;
|
||||
$this->versionService = $versionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays create new node page.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$locations = $this->locationRepository->all();
|
||||
if (count($locations) < 1) {
|
||||
$this->alert->warning(trans('admin/node.notices.location_required'))->flash();
|
||||
|
||||
return redirect()->route('admin.locations');
|
||||
}
|
||||
|
||||
return view('admin.nodes.new', ['locations' => $locations]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Post controller to create a new node on the system.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
*/
|
||||
public function store(NodeFormRequest $request)
|
||||
{
|
||||
$node = $this->creationService->handle($request->normalize());
|
||||
$this->alert->info(trans('admin/node.notices.node_created'))->flash();
|
||||
|
||||
return redirect()->route('admin.nodes.view.allocation', $node->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates settings for a node.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function updateSettings(NodeFormRequest $request, Node $node)
|
||||
{
|
||||
$this->updateService->handle($node, $request->normalize(), $request->input('reset_secret') === 'on');
|
||||
$this->alert->success(trans('admin/node.notices.node_updated'))->flash();
|
||||
|
||||
return redirect()->route('admin.nodes.view.settings', $node->id)->withInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a single allocation from a node.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Service\Allocation\ServerUsingAllocationException
|
||||
*/
|
||||
public function allocationRemoveSingle(int $node, Allocation $allocation): Response
|
||||
{
|
||||
$this->allocationDeletionService->handle($allocation);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes multiple individual allocations from a node.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Service\Allocation\ServerUsingAllocationException
|
||||
*/
|
||||
public function allocationRemoveMultiple(Request $request, int $node): Response
|
||||
{
|
||||
$allocations = $request->input('allocations');
|
||||
foreach ($allocations as $rawAllocation) {
|
||||
$allocation = new Allocation();
|
||||
$allocation->id = $rawAllocation['id'];
|
||||
$this->allocationRemoveSingle($node, $allocation);
|
||||
}
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all allocations for a specific IP at once on a node.
|
||||
*
|
||||
* @param int $node
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function allocationRemoveBlock(Request $request, $node)
|
||||
{
|
||||
$this->allocationRepository->deleteWhere([
|
||||
['node_id', '=', $node],
|
||||
['server_id', '=', null],
|
||||
['ip', '=', $request->input('ip')],
|
||||
]);
|
||||
|
||||
$this->alert->success(trans('admin/node.notices.unallocated_deleted', ['ip' => $request->input('ip')]))
|
||||
->flash();
|
||||
|
||||
return redirect()->route('admin.nodes.view.allocation', $node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an alias for a specific allocation on a node.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function allocationSetAlias(AllocationAliasFormRequest $request)
|
||||
{
|
||||
$this->allocationRepository->update($request->input('allocation_id'), [
|
||||
'ip_alias' => (empty($request->input('alias'))) ? null : $request->input('alias'),
|
||||
]);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new allocations on a node.
|
||||
*
|
||||
* @param int|\Pterodactyl\Models\Node $node
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Service\Allocation\CidrOutOfRangeException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Allocation\InvalidPortMappingException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Allocation\PortOutOfRangeException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Allocation\TooManyPortsInRangeException
|
||||
*/
|
||||
public function createAllocation(AllocationFormRequest $request, Node $node)
|
||||
{
|
||||
$this->assignmentService->handle($node, $request->normalize());
|
||||
$this->alert->success(trans('admin/node.notices.allocations_added'))->flash();
|
||||
|
||||
return redirect()->route('admin.nodes.view.allocation', $node->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a node from the system.
|
||||
*
|
||||
* @param $node
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
*/
|
||||
public function delete($node)
|
||||
{
|
||||
$this->deletionService->handle($node);
|
||||
$this->alert->success(trans('admin/node.notices.node_deleted'))->flash();
|
||||
|
||||
return redirect()->route('admin.nodes');
|
||||
}
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Servers;
|
||||
|
||||
use JavaScript;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Repositories\Eloquent\NestRepository;
|
||||
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
||||
use Pterodactyl\Http\Requests\Admin\ServerFormRequest;
|
||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||
use Pterodactyl\Services\Servers\ServerCreationService;
|
||||
use Pterodactyl\Repositories\Eloquent\LocationRepository;
|
||||
|
||||
class CreateServerController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\NodeRepository
|
||||
*/
|
||||
private $nodeRepository;
|
||||
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
private $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\NestRepository
|
||||
*/
|
||||
private $nestRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\LocationRepository
|
||||
*/
|
||||
private $locationRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\ServerCreationService
|
||||
*/
|
||||
private $creationService;
|
||||
|
||||
/**
|
||||
* CreateServerController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
NestRepository $nestRepository,
|
||||
LocationRepository $locationRepository,
|
||||
NodeRepository $nodeRepository,
|
||||
ServerRepository $repository,
|
||||
ServerCreationService $creationService
|
||||
) {
|
||||
$this->repository = $repository;
|
||||
$this->nodeRepository = $nodeRepository;
|
||||
$this->alert = $alert;
|
||||
$this->nestRepository = $nestRepository;
|
||||
$this->locationRepository = $locationRepository;
|
||||
$this->creationService = $creationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the create server page.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$nodes = $this->nodeRepository->all();
|
||||
if (count($nodes) < 1) {
|
||||
$this->alert->warning(trans('admin/server.alerts.node_required'))->flash();
|
||||
|
||||
return redirect()->route('admin.nodes');
|
||||
}
|
||||
|
||||
$nests = $this->nestRepository->getWithEggs();
|
||||
|
||||
Javascript::put([
|
||||
'nodeData' => $this->nodeRepository->getNodesForServerCreation(),
|
||||
'nests' => $nests->map(function ($item) {
|
||||
return array_merge($item->toArray(), [
|
||||
'eggs' => $item->eggs->keyBy('id')->toArray(),
|
||||
]);
|
||||
})->keyBy('id'),
|
||||
]);
|
||||
|
||||
return view('admin.servers.new', [
|
||||
'locations' => $this->locationRepository->all(),
|
||||
'nests' => $nests,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new server on the remote system.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableAllocationException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableNodeException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function store(ServerFormRequest $request)
|
||||
{
|
||||
$data = $request->except(['_token']);
|
||||
if (!empty($data['custom_image'])) {
|
||||
$data['image'] = $data['custom_image'];
|
||||
unset($data['custom_image']);
|
||||
}
|
||||
|
||||
$server = $this->creationService->handle($data);
|
||||
|
||||
$this->alert->success(
|
||||
trans('admin/server.alerts.server_created')
|
||||
)->flash();
|
||||
|
||||
return RedirectResponse::create('/admin/servers/view/' . $server->id);
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Servers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Spatie\QueryBuilder\QueryBuilder;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Spatie\QueryBuilder\AllowedFilter;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Models\Filters\AdminServerFilter;
|
||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||
|
||||
class ServerController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* ServerController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
Factory $view,
|
||||
ServerRepository $repository
|
||||
) {
|
||||
$this->view = $view;
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all of the servers that exist on the system using a paginated result set. If
|
||||
* a query is passed along in the request it is also passed to the repository function.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$servers = QueryBuilder::for(Server::query()->with('node', 'user', 'allocation'))
|
||||
->allowedFilters([
|
||||
AllowedFilter::exact('owner_id'),
|
||||
AllowedFilter::custom('*', new AdminServerFilter()),
|
||||
])
|
||||
->paginate(config()->get('pterodactyl.paginate.admin.servers'));
|
||||
|
||||
return $this->view->make('admin.servers.index', ['servers' => $servers]);
|
||||
}
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Servers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Models\ServerTransfer;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Services\Servers\TransferService;
|
||||
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||
use Pterodactyl\Repositories\Eloquent\LocationRepository;
|
||||
use Pterodactyl\Repositories\Wings\DaemonConfigurationRepository;
|
||||
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
|
||||
|
||||
class ServerTransferController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
private $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\AllocationRepositoryInterface
|
||||
*/
|
||||
private $allocationRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\LocationRepository
|
||||
*/
|
||||
private $locationRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\NodeRepository
|
||||
*/
|
||||
private $nodeRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\TransferService
|
||||
*/
|
||||
private $transferService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Wings\DaemonConfigurationRepository
|
||||
*/
|
||||
private $daemonConfigurationRepository;
|
||||
|
||||
/**
|
||||
* ServerTransferController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
AllocationRepositoryInterface $allocationRepository,
|
||||
ServerRepository $repository,
|
||||
LocationRepository $locationRepository,
|
||||
NodeRepository $nodeRepository,
|
||||
TransferService $transferService,
|
||||
DaemonConfigurationRepository $daemonConfigurationRepository
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->allocationRepository = $allocationRepository;
|
||||
$this->repository = $repository;
|
||||
$this->locationRepository = $locationRepository;
|
||||
$this->nodeRepository = $nodeRepository;
|
||||
$this->transferService = $transferService;
|
||||
$this->daemonConfigurationRepository = $daemonConfigurationRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a transfer of a server to a new node.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function transfer(Request $request, Server $server)
|
||||
{
|
||||
$validatedData = $request->validate([
|
||||
'node_id' => 'required|exists:nodes,id',
|
||||
'allocation_id' => 'required|bail|unique:servers|exists:allocations,id',
|
||||
'allocation_additional' => 'nullable',
|
||||
]);
|
||||
|
||||
$node_id = $validatedData['node_id'];
|
||||
$allocation_id = intval($validatedData['allocation_id']);
|
||||
$additional_allocations = array_map('intval', $validatedData['allocation_additional'] ?? []);
|
||||
|
||||
// Check if the node is viable for the transfer.
|
||||
$node = $this->nodeRepository->getNodeWithResourceUsage($node_id);
|
||||
if ($node->isViable($server->memory, $server->disk)) {
|
||||
// Check if the selected daemon is online.
|
||||
$this->daemonConfigurationRepository->setNode($node)->getSystemInformation();
|
||||
|
||||
// Create a new ServerTransfer entry.
|
||||
$transfer = new ServerTransfer();
|
||||
|
||||
$transfer->server_id = $server->id;
|
||||
$transfer->old_node = $server->node_id;
|
||||
$transfer->new_node = $node_id;
|
||||
$transfer->old_allocation = $server->allocation_id;
|
||||
$transfer->new_allocation = $allocation_id;
|
||||
$transfer->old_additional_allocations = $server->allocations->where('id', '!=', $server->allocation_id)->pluck('id');
|
||||
$transfer->new_additional_allocations = $additional_allocations;
|
||||
|
||||
$transfer->save();
|
||||
|
||||
// Add the allocations to the server so they cannot be automatically assigned while the transfer is in progress.
|
||||
$this->assignAllocationsToServer($server, $node_id, $allocation_id, $additional_allocations);
|
||||
|
||||
// Request an archive from the server's current daemon. (this also checks if the daemon is online)
|
||||
$this->transferService->requestArchive($server);
|
||||
|
||||
$this->alert->success(trans('admin/server.alerts.transfer_started'))->flash();
|
||||
} else {
|
||||
$this->alert->danger(trans('admin/server.alerts.transfer_not_viable'))->flash();
|
||||
}
|
||||
|
||||
return redirect()->route('admin.servers.view.manage', $server->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the specified allocations to the specified server.
|
||||
*/
|
||||
private function assignAllocationsToServer(Server $server, int $node_id, int $allocation_id, array $additional_allocations)
|
||||
{
|
||||
$allocations = $additional_allocations;
|
||||
array_push($allocations, $allocation_id);
|
||||
|
||||
$unassigned = $this->allocationRepository->getUnassignedAllocationIds($node_id);
|
||||
|
||||
$updateIds = [];
|
||||
foreach ($allocations as $allocation) {
|
||||
if (!in_array($allocation, $unassigned)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$updateIds[] = $allocation;
|
||||
}
|
||||
|
||||
if (!empty($updateIds)) {
|
||||
$this->allocationRepository->updateWhereIn('id', $updateIds, ['server_id' => $server->id]);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,218 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Servers;
|
||||
|
||||
use JavaScript;
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\Nest;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Pterodactyl\Exceptions\DisplayException;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Services\Servers\EnvironmentService;
|
||||
use Pterodactyl\Repositories\Eloquent\NestRepository;
|
||||
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
||||
use Pterodactyl\Repositories\Eloquent\MountRepository;
|
||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||
use Pterodactyl\Traits\Controllers\JavascriptInjection;
|
||||
use Pterodactyl\Repositories\Eloquent\LocationRepository;
|
||||
use Pterodactyl\Repositories\Eloquent\DatabaseHostRepository;
|
||||
|
||||
class ServerViewController extends Controller
|
||||
{
|
||||
use JavascriptInjection;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\DatabaseHostRepository
|
||||
*/
|
||||
private $databaseHostRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\MountRepository
|
||||
*/
|
||||
protected $mountRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\NestRepository
|
||||
*/
|
||||
private $nestRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\LocationRepository
|
||||
*/
|
||||
private $locationRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\NodeRepository
|
||||
*/
|
||||
private $nodeRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\EnvironmentService
|
||||
*/
|
||||
private $environmentService;
|
||||
|
||||
/**
|
||||
* ServerViewController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
Factory $view,
|
||||
DatabaseHostRepository $databaseHostRepository,
|
||||
LocationRepository $locationRepository,
|
||||
MountRepository $mountRepository,
|
||||
NestRepository $nestRepository,
|
||||
NodeRepository $nodeRepository,
|
||||
ServerRepository $repository,
|
||||
EnvironmentService $environmentService
|
||||
) {
|
||||
$this->view = $view;
|
||||
$this->databaseHostRepository = $databaseHostRepository;
|
||||
$this->locationRepository = $locationRepository;
|
||||
$this->mountRepository = $mountRepository;
|
||||
$this->nestRepository = $nestRepository;
|
||||
$this->nodeRepository = $nodeRepository;
|
||||
$this->repository = $repository;
|
||||
$this->environmentService = $environmentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index view for a server.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request, Server $server)
|
||||
{
|
||||
return $this->view->make('admin.servers.view.index', compact('server'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server details page.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function details(Request $request, Server $server)
|
||||
{
|
||||
return $this->view->make('admin.servers.view.details', compact('server'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view of server build settings.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function build(Request $request, Server $server)
|
||||
{
|
||||
$allocations = $server->node->allocations->toBase();
|
||||
|
||||
return $this->view->make('admin.servers.view.build', [
|
||||
'server' => $server,
|
||||
'assigned' => $allocations->where('server_id', $server->id)->sortBy('port')->sortBy('ip'),
|
||||
'unassigned' => $allocations->where('server_id', null)->sortBy('port')->sortBy('ip'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server startup management page.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function startup(Request $request, Server $server)
|
||||
{
|
||||
$nests = $this->nestRepository->getWithEggs();
|
||||
$variables = $this->environmentService->handle($server);
|
||||
|
||||
$this->plainInject([
|
||||
'server' => $server,
|
||||
'server_variables' => $variables,
|
||||
'nests' => $nests->map(function (Nest $item) {
|
||||
return array_merge($item->toArray(), [
|
||||
'eggs' => $item->eggs->keyBy('id')->toArray(),
|
||||
]);
|
||||
})->keyBy('id'),
|
||||
]);
|
||||
|
||||
return $this->view->make('admin.servers.view.startup', compact('server', 'nests'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all of the databases that exist for the server.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function database(Request $request, Server $server)
|
||||
{
|
||||
return $this->view->make('admin.servers.view.database', [
|
||||
'hosts' => $this->databaseHostRepository->all(),
|
||||
'server' => $server,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all of the mounts that exist for the server.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function mounts(Request $request, Server $server)
|
||||
{
|
||||
$server->load('mounts');
|
||||
|
||||
return $this->view->make('admin.servers.view.mounts', [
|
||||
'mounts' => $this->mountRepository->getMountListForServer($server),
|
||||
'server' => $server,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base server management page, or an exception if the server
|
||||
* is in a state that cannot be recovered from.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
*/
|
||||
public function manage(Request $request, Server $server)
|
||||
{
|
||||
if ($server->status === Server::STATUS_INSTALL_FAILED) {
|
||||
throw new DisplayException('This server is in a failed install state and cannot be recovered. Please delete and re-create the server.');
|
||||
}
|
||||
|
||||
// Check if the panel doesn't have at least 2 nodes configured.
|
||||
$nodes = $this->nodeRepository->all();
|
||||
$canTransfer = false;
|
||||
if (count($nodes) >= 2) {
|
||||
$canTransfer = true;
|
||||
}
|
||||
|
||||
Javascript::put([
|
||||
'nodeData' => $this->nodeRepository->getNodesForServerCreation(),
|
||||
]);
|
||||
|
||||
return $this->view->make('admin.servers.view.manage', [
|
||||
'server' => $server,
|
||||
'locations' => $this->locationRepository->all(),
|
||||
'canTransfer' => $canTransfer,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server deletion page.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function delete(Request $request, Server $server)
|
||||
{
|
||||
return $this->view->make('admin.servers.view.delete', compact('server'));
|
||||
}
|
||||
}
|
@ -1,422 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\User;
|
||||
use Pterodactyl\Models\Mount;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Models\MountServer;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Exceptions\DisplayException;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Pterodactyl\Services\Servers\SuspensionService;
|
||||
use Pterodactyl\Repositories\Eloquent\MountRepository;
|
||||
use Pterodactyl\Services\Servers\ServerDeletionService;
|
||||
use Pterodactyl\Services\Servers\ReinstallServerService;
|
||||
use Pterodactyl\Exceptions\Model\DataValidationException;
|
||||
use Pterodactyl\Repositories\Wings\DaemonServerRepository;
|
||||
use Pterodactyl\Services\Servers\BuildModificationService;
|
||||
use Pterodactyl\Services\Databases\DatabasePasswordService;
|
||||
use Pterodactyl\Services\Servers\DetailsModificationService;
|
||||
use Pterodactyl\Services\Servers\StartupModificationService;
|
||||
use Pterodactyl\Contracts\Repository\NestRepositoryInterface;
|
||||
use Pterodactyl\Repositories\Eloquent\DatabaseHostRepository;
|
||||
use Pterodactyl\Services\Databases\DatabaseManagementService;
|
||||
use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
||||
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||
use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
||||
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
|
||||
use Pterodactyl\Services\Servers\ServerConfigurationStructureService;
|
||||
use Pterodactyl\Http\Requests\Admin\Servers\Databases\StoreServerDatabaseRequest;
|
||||
|
||||
class ServersController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
protected $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\AllocationRepositoryInterface
|
||||
*/
|
||||
protected $allocationRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\BuildModificationService
|
||||
*/
|
||||
protected $buildModificationService;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Config\Repository
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Wings\DaemonServerRepository
|
||||
*/
|
||||
private $daemonServerRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface
|
||||
*/
|
||||
protected $databaseRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Databases\DatabaseManagementService
|
||||
*/
|
||||
protected $databaseManagementService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Databases\DatabasePasswordService
|
||||
*/
|
||||
protected $databasePasswordService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface
|
||||
*/
|
||||
protected $databaseHostRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\ServerDeletionService
|
||||
*/
|
||||
protected $deletionService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\DetailsModificationService
|
||||
*/
|
||||
protected $detailsModificationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\MountRepository
|
||||
*/
|
||||
protected $mountRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\NestRepositoryInterface
|
||||
*/
|
||||
protected $nestRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\ReinstallServerService
|
||||
*/
|
||||
protected $reinstallService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\ServerConfigurationStructureService
|
||||
*/
|
||||
private $serverConfigurationStructureService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\StartupModificationService
|
||||
*/
|
||||
private $startupModificationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\SuspensionService
|
||||
*/
|
||||
protected $suspensionService;
|
||||
|
||||
/**
|
||||
* ServersController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
AllocationRepositoryInterface $allocationRepository,
|
||||
BuildModificationService $buildModificationService,
|
||||
ConfigRepository $config,
|
||||
DaemonServerRepository $daemonServerRepository,
|
||||
DatabaseManagementService $databaseManagementService,
|
||||
DatabasePasswordService $databasePasswordService,
|
||||
DatabaseRepositoryInterface $databaseRepository,
|
||||
DatabaseHostRepository $databaseHostRepository,
|
||||
ServerDeletionService $deletionService,
|
||||
DetailsModificationService $detailsModificationService,
|
||||
ReinstallServerService $reinstallService,
|
||||
ServerRepositoryInterface $repository,
|
||||
MountRepository $mountRepository,
|
||||
NestRepositoryInterface $nestRepository,
|
||||
ServerConfigurationStructureService $serverConfigurationStructureService,
|
||||
StartupModificationService $startupModificationService,
|
||||
SuspensionService $suspensionService
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->allocationRepository = $allocationRepository;
|
||||
$this->buildModificationService = $buildModificationService;
|
||||
$this->config = $config;
|
||||
$this->daemonServerRepository = $daemonServerRepository;
|
||||
$this->databaseHostRepository = $databaseHostRepository;
|
||||
$this->databaseManagementService = $databaseManagementService;
|
||||
$this->databasePasswordService = $databasePasswordService;
|
||||
$this->databaseRepository = $databaseRepository;
|
||||
$this->detailsModificationService = $detailsModificationService;
|
||||
$this->deletionService = $deletionService;
|
||||
$this->nestRepository = $nestRepository;
|
||||
$this->reinstallService = $reinstallService;
|
||||
$this->repository = $repository;
|
||||
$this->mountRepository = $mountRepository;
|
||||
$this->serverConfigurationStructureService = $serverConfigurationStructureService;
|
||||
$this->startupModificationService = $startupModificationService;
|
||||
$this->suspensionService = $suspensionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the details for a server.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function setDetails(Request $request, Server $server)
|
||||
{
|
||||
$this->detailsModificationService->handle($server, $request->only([
|
||||
'owner_id', 'external_id', 'name', 'description',
|
||||
]));
|
||||
|
||||
$this->alert->success(trans('admin/server.alerts.details_updated'))->flash();
|
||||
|
||||
return redirect()->route('admin.servers.view.details', $server->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the install status for a server.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function toggleInstall(Server $server)
|
||||
{
|
||||
if ($server->status === Server::STATUS_INSTALL_FAILED) {
|
||||
throw new DisplayException(trans('admin/server.exceptions.marked_as_failed'));
|
||||
}
|
||||
|
||||
$this->repository->update($server->id, [
|
||||
'status' => $server->isInstalled() ? Server::STATUS_INSTALLING : null,
|
||||
], true, true);
|
||||
|
||||
$this->alert->success(trans('admin/server.alerts.install_toggled'))->flash();
|
||||
|
||||
return redirect()->route('admin.servers.view.manage', $server->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinstalls the server with the currently assigned service.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function reinstallServer(Server $server)
|
||||
{
|
||||
$this->reinstallService->handle($server);
|
||||
$this->alert->success(trans('admin/server.alerts.server_reinstalled'))->flash();
|
||||
|
||||
return redirect()->route('admin.servers.view.manage', $server->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage the suspension status for a server.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function manageSuspension(Request $request, Server $server)
|
||||
{
|
||||
$this->suspensionService->toggle($server, $request->input('action'));
|
||||
$this->alert->success(trans('admin/server.alerts.suspension_toggled', [
|
||||
'status' => $request->input('action') . 'ed',
|
||||
]))->flash();
|
||||
|
||||
return redirect()->route('admin.servers.view.manage', $server->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the build configuration for a server.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function updateBuild(Request $request, Server $server)
|
||||
{
|
||||
try {
|
||||
$this->buildModificationService->handle($server, $request->only([
|
||||
'allocation_id', 'add_allocations', 'remove_allocations',
|
||||
'memory', 'swap', 'io', 'cpu', 'threads', 'disk',
|
||||
'database_limit', 'allocation_limit', 'backup_limit', 'oom_disabled',
|
||||
]));
|
||||
} catch (DataValidationException $exception) {
|
||||
throw new ValidationException($exception->validator);
|
||||
}
|
||||
|
||||
$this->alert->success(trans('admin/server.alerts.build_updated'))->flash();
|
||||
|
||||
return redirect()->route('admin.servers.view.build', $server->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the server deletion process.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function delete(Request $request, Server $server)
|
||||
{
|
||||
$this->deletionService->withForce($request->filled('force_delete'))->handle($server);
|
||||
$this->alert->success(trans('admin/server.alerts.server_deleted'))->flash();
|
||||
|
||||
return redirect()->route('admin.servers');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the startup command as well as variables.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function saveStartup(Request $request, Server $server)
|
||||
{
|
||||
$data = $request->except('_token');
|
||||
if (!empty($data['custom_docker_image'])) {
|
||||
$data['docker_image'] = $data['custom_docker_image'];
|
||||
unset($data['custom_docker_image']);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->startupModificationService
|
||||
->setUserLevel(User::USER_LEVEL_ADMIN)
|
||||
->handle($server, $data);
|
||||
} catch (DataValidationException $exception) {
|
||||
throw new ValidationException($exception->validator);
|
||||
}
|
||||
|
||||
$this->alert->success(trans('admin/server.alerts.startup_changed'))->flash();
|
||||
|
||||
return redirect()->route('admin.servers.view.startup', $server->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new database assigned to a specific server.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function newDatabase(StoreServerDatabaseRequest $request, Server $server)
|
||||
{
|
||||
$this->databaseManagementService->create($server, [
|
||||
'database' => DatabaseManagementService::generateUniqueDatabaseName($request->input('database'), $server->id),
|
||||
'remote' => $request->input('remote'),
|
||||
'database_host_id' => $request->input('database_host_id'),
|
||||
'max_connections' => $request->input('max_connections'),
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.servers.view.database', $server->id)->withInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the database password for a specific database on this server.
|
||||
*
|
||||
* @param int $server
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function resetDatabasePassword(Request $request, $server)
|
||||
{
|
||||
$database = $this->databaseRepository->findFirstWhere([
|
||||
['server_id', '=', $server],
|
||||
['id', '=', $request->input('database')],
|
||||
]);
|
||||
|
||||
$this->databasePasswordService->handle($database);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a database from a server.
|
||||
*
|
||||
* @param int $server
|
||||
* @param int $database
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
*/
|
||||
public function deleteDatabase($server, $database)
|
||||
{
|
||||
$database = $this->databaseRepository->findFirstWhere([
|
||||
['server_id', '=', $server],
|
||||
['id', '=', $database],
|
||||
]);
|
||||
|
||||
$this->databaseManagementService->delete($database);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mount to a server.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function addMount(Server $server, Mount $mount)
|
||||
{
|
||||
$mountServer = (new MountServer())->forceFill([
|
||||
'mount_id' => $mount->id,
|
||||
'server_id' => $server->id,
|
||||
]);
|
||||
|
||||
$mountServer->saveOrFail();
|
||||
|
||||
$this->alert->success('Mount was added successfully.')->flash();
|
||||
|
||||
return redirect()->route('admin.servers.view.mounts', $server->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a mount from a server.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function deleteMount(Server $server, Mount $mount)
|
||||
{
|
||||
MountServer::where('mount_id', $mount->id)->where('server_id', $server->id)->delete();
|
||||
|
||||
$this->alert->success('Mount was removed successfully.')->flash();
|
||||
|
||||
return redirect()->route('admin.servers.view.mounts', $server->id);
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Settings;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Illuminate\Contracts\Console\Kernel;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
||||
use Pterodactyl\Contracts\Repository\SettingsRepositoryInterface;
|
||||
use Pterodactyl\Http\Requests\Admin\Settings\AdvancedSettingsFormRequest;
|
||||
|
||||
class AdvancedController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
private $alert;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Config\Repository
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Console\Kernel
|
||||
*/
|
||||
private $kernel;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\SettingsRepositoryInterface
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* AdvancedController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
ConfigRepository $config,
|
||||
Kernel $kernel,
|
||||
SettingsRepositoryInterface $settings
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->config = $config;
|
||||
$this->kernel = $kernel;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render advanced Panel settings UI.
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
$showRecaptchaWarning = false;
|
||||
if (
|
||||
$this->config->get('recaptcha._shipped_secret_key') === $this->config->get('recaptcha.secret_key')
|
||||
|| $this->config->get('recaptcha._shipped_website_key') === $this->config->get('recaptcha.website_key')
|
||||
) {
|
||||
$showRecaptchaWarning = true;
|
||||
}
|
||||
|
||||
return view('admin.settings.advanced', [
|
||||
'showRecaptchaWarning' => $showRecaptchaWarning,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function update(AdvancedSettingsFormRequest $request): RedirectResponse
|
||||
{
|
||||
foreach ($request->normalize() as $key => $value) {
|
||||
$this->settings->set('settings::' . $key, $value);
|
||||
}
|
||||
|
||||
$this->kernel->call('queue:restart');
|
||||
$this->alert->success('Advanced settings have been updated successfully and the queue worker was restarted to apply these changes.')->flash();
|
||||
|
||||
return redirect()->route('admin.settings.advanced');
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Settings;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Illuminate\Contracts\Console\Kernel;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Traits\Helpers\AvailableLanguages;
|
||||
use Pterodactyl\Services\Helpers\SoftwareVersionService;
|
||||
use Pterodactyl\Contracts\Repository\SettingsRepositoryInterface;
|
||||
use Pterodactyl\Http\Requests\Admin\Settings\BaseSettingsFormRequest;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
use AvailableLanguages;
|
||||
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
private $alert;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Console\Kernel
|
||||
*/
|
||||
private $kernel;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\SettingsRepositoryInterface
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Helpers\SoftwareVersionService
|
||||
*/
|
||||
private $versionService;
|
||||
|
||||
/**
|
||||
* IndexController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
Kernel $kernel,
|
||||
SettingsRepositoryInterface $settings,
|
||||
SoftwareVersionService $versionService
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->kernel = $kernel;
|
||||
$this->settings = $settings;
|
||||
$this->versionService = $versionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the UI for basic Panel settings.
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.settings.index', [
|
||||
'version' => $this->versionService,
|
||||
'languages' => $this->getAvailableLanguages(true),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle settings update.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function update(BaseSettingsFormRequest $request): RedirectResponse
|
||||
{
|
||||
foreach ($request->normalize() as $key => $value) {
|
||||
$this->settings->set('settings::' . $key, $value);
|
||||
}
|
||||
|
||||
$this->kernel->call('queue:restart');
|
||||
$this->alert->success('Panel settings have been updated successfully and the queue worker was restarted to apply these changes.')->flash();
|
||||
|
||||
return redirect()->route('admin.settings');
|
||||
}
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Settings;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Illuminate\Contracts\Console\Kernel;
|
||||
use Pterodactyl\Notifications\MailTested;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
use Pterodactyl\Exceptions\DisplayException;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\Encryption\Encrypter;
|
||||
use Pterodactyl\Providers\SettingsServiceProvider;
|
||||
use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
||||
use Pterodactyl\Contracts\Repository\SettingsRepositoryInterface;
|
||||
use Pterodactyl\Http\Requests\Admin\Settings\MailSettingsFormRequest;
|
||||
|
||||
class MailController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
private $alert;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Config\Repository
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Encryption\Encrypter
|
||||
*/
|
||||
private $encrypter;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Console\Kernel
|
||||
*/
|
||||
private $kernel;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\SettingsRepositoryInterface
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* MailController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
ConfigRepository $config,
|
||||
Encrypter $encrypter,
|
||||
Kernel $kernel,
|
||||
SettingsRepositoryInterface $settings
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->config = $config;
|
||||
$this->encrypter = $encrypter;
|
||||
$this->kernel = $kernel;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render UI for editing mail settings. This UI should only display if
|
||||
* the server is configured to send mail using SMTP.
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.settings.mail', [
|
||||
'disabled' => $this->config->get('mail.driver') !== 'smtp',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle request to update SMTP mail settings.
|
||||
*
|
||||
* @throws DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function update(MailSettingsFormRequest $request): Response
|
||||
{
|
||||
if ($this->config->get('mail.driver') !== 'smtp') {
|
||||
throw new DisplayException('This feature is only available if SMTP is the selected email driver for the Panel.');
|
||||
}
|
||||
|
||||
$values = $request->normalize();
|
||||
if (array_get($values, 'mail:password') === '!e') {
|
||||
$values['mail:password'] = '';
|
||||
}
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
if (in_array($key, SettingsServiceProvider::getEncryptedKeys()) && !empty($value)) {
|
||||
$value = $this->encrypter->encrypt($value);
|
||||
}
|
||||
|
||||
$this->settings->set('settings::' . $key, $value);
|
||||
}
|
||||
|
||||
$this->kernel->call('queue:restart');
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit a request to send a test mail message.
|
||||
*/
|
||||
public function test(Request $request): Response
|
||||
{
|
||||
try {
|
||||
Notification::route('mail', $request->user()->email)
|
||||
->notify(new MailTested($request->user()));
|
||||
} catch (Exception $exception) {
|
||||
return response($exception->getMessage(), 500);
|
||||
}
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
}
|
@ -1,196 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\User;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Spatie\QueryBuilder\QueryBuilder;
|
||||
use Pterodactyl\Exceptions\DisplayException;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\Translation\Translator;
|
||||
use Pterodactyl\Services\Users\UserUpdateService;
|
||||
use Pterodactyl\Traits\Helpers\AvailableLanguages;
|
||||
use Pterodactyl\Services\Users\UserCreationService;
|
||||
use Pterodactyl\Services\Users\UserDeletionService;
|
||||
use Pterodactyl\Http\Requests\Admin\UserFormRequest;
|
||||
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
use AvailableLanguages;
|
||||
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
protected $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Users\UserCreationService
|
||||
*/
|
||||
protected $creationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Users\UserDeletionService
|
||||
*/
|
||||
protected $deletionService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Translation\Translator
|
||||
*/
|
||||
protected $translator;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Users\UserUpdateService
|
||||
*/
|
||||
protected $updateService;
|
||||
|
||||
/**
|
||||
* UserController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
UserCreationService $creationService,
|
||||
UserDeletionService $deletionService,
|
||||
Translator $translator,
|
||||
UserUpdateService $updateService,
|
||||
UserRepositoryInterface $repository
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->creationService = $creationService;
|
||||
$this->deletionService = $deletionService;
|
||||
$this->repository = $repository;
|
||||
$this->translator = $translator;
|
||||
$this->updateService = $updateService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display user index page.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$users = QueryBuilder::for(
|
||||
User::query()->select('users.*')
|
||||
->selectRaw('COUNT(DISTINCT(subusers.id)) as subuser_of_count')
|
||||
->selectRaw('COUNT(DISTINCT(servers.id)) as servers_count')
|
||||
->leftJoin('subusers', 'subusers.user_id', '=', 'users.id')
|
||||
->leftJoin('servers', 'servers.owner_id', '=', 'users.id')
|
||||
->groupBy('users.id')
|
||||
)
|
||||
->allowedFilters(['username', 'email', 'uuid'])
|
||||
->allowedSorts(['id', 'uuid'])
|
||||
->paginate(50);
|
||||
|
||||
return view('admin.users.index', ['users' => $users]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display new user page.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('admin.users.new', [
|
||||
'languages' => $this->getAvailableLanguages(true),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display user view page.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function view(User $user)
|
||||
{
|
||||
return view('admin.users.view', [
|
||||
'user' => $user,
|
||||
'languages' => $this->getAvailableLanguages(true),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a user from the system.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
*/
|
||||
public function delete(Request $request, User $user)
|
||||
{
|
||||
if ($request->user()->id === $user->id) {
|
||||
throw new DisplayException($this->translator->trans('admin/user.exceptions.user_has_servers'));
|
||||
}
|
||||
|
||||
$this->deletionService->handle($user);
|
||||
|
||||
return redirect()->route('admin.users');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a user.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function store(UserFormRequest $request)
|
||||
{
|
||||
$user = $this->creationService->handle($request->normalize());
|
||||
$this->alert->success($this->translator->get('admin/user.notices.account_created'))->flash();
|
||||
|
||||
return redirect()->route('admin.users.view', $user->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a user on the system.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function update(UserFormRequest $request, User $user)
|
||||
{
|
||||
$this->updateService
|
||||
->setUserLevel(User::USER_LEVEL_ADMIN)
|
||||
->handle($user, $request->normalize());
|
||||
|
||||
$this->alert->success(trans('admin/user.notices.account_updated'))->flash();
|
||||
|
||||
return redirect()->route('admin.users.view', $user->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON response of users on the system.
|
||||
*
|
||||
* @return \Illuminate\Support\Collection|\Pterodactyl\Models\Model
|
||||
*/
|
||||
public function json(Request $request)
|
||||
{
|
||||
$users = QueryBuilder::for(User::query())->allowedFilters(['email'])->paginate(25);
|
||||
|
||||
// Handle single user requests.
|
||||
if ($request->query('user_id')) {
|
||||
$user = User::query()->findOrFail($request->input('user_id'));
|
||||
$user->md5 = md5(strtolower($user->email));
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
return $users->map(function ($item) {
|
||||
$item->md5 = md5(strtolower($item->email));
|
||||
|
||||
return $item;
|
||||
});
|
||||
}
|
||||
}
|
@ -3,25 +3,17 @@
|
||||
namespace Pterodactyl\Http\Controllers\Api\Application;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Webmozart\Assert\Assert;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Container\Container;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Extensions\Spatie\Fractalistic\Fractal;
|
||||
use Pterodactyl\Transformers\Api\Application\BaseTransformer;
|
||||
|
||||
abstract class ApplicationApiController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Http\Request
|
||||
*/
|
||||
protected $request;
|
||||
protected Request $request;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Extensions\Spatie\Fractalistic\Fractal
|
||||
*/
|
||||
protected $fractal;
|
||||
protected Fractal $fractal;
|
||||
|
||||
/**
|
||||
* ApplicationApiController constructor.
|
||||
@ -53,19 +45,11 @@ abstract class ApplicationApiController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of an application transformer.
|
||||
*
|
||||
* @return \Pterodactyl\Transformers\Api\Application\BaseTransformer
|
||||
* Return a HTTP/201 response for the API.
|
||||
*/
|
||||
public function getTransformer(string $abstract)
|
||||
protected function returnAccepted(): Response
|
||||
{
|
||||
/** @var \Pterodactyl\Transformers\Api\Application\BaseTransformer $transformer */
|
||||
$transformer = Container::getInstance()->make($abstract);
|
||||
$transformer->setKey($this->request->attributes->get('api_key'));
|
||||
|
||||
Assert::isInstanceOf($transformer, BaseTransformer::class);
|
||||
|
||||
return $transformer;
|
||||
return new Response('', Response::HTTP_ACCEPTED);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Application\Databases;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Models\DatabaseHost;
|
||||
use Spatie\QueryBuilder\QueryBuilder;
|
||||
use Pterodactyl\Services\Databases\Hosts\HostUpdateService;
|
||||
use Pterodactyl\Services\Databases\Hosts\HostCreationService;
|
||||
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
|
||||
use Pterodactyl\Transformers\Api\Application\DatabaseHostTransformer;
|
||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Databases\GetDatabaseRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Databases\GetDatabasesRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Databases\StoreDatabaseRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Databases\DeleteDatabaseRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Databases\UpdateDatabaseRequest;
|
||||
|
||||
class DatabaseController extends ApplicationApiController
|
||||
{
|
||||
private HostCreationService $creationService;
|
||||
private HostUpdateService $updateService;
|
||||
|
||||
/**
|
||||
* DatabaseController constructor.
|
||||
*/
|
||||
public function __construct(HostCreationService $creationService, HostUpdateService $updateService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->creationService = $creationService;
|
||||
$this->updateService = $updateService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all database hosts.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetDatabasesRequest $request): array
|
||||
{
|
||||
$perPage = $request->query('per_page', 10);
|
||||
if ($perPage < 1 || $perPage > 100) {
|
||||
throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
|
||||
}
|
||||
|
||||
$databases = QueryBuilder::for(DatabaseHost::query())
|
||||
->allowedFilters(['name', 'host'])
|
||||
->allowedSorts(['id', 'name', 'host'])
|
||||
->paginate($perPage);
|
||||
|
||||
return $this->fractal->collection($databases)
|
||||
->transformWith(DatabaseHostTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single database host.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function view(GetDatabaseRequest $request, DatabaseHost $databaseHost): array
|
||||
{
|
||||
return $this->fractal->item($databaseHost)
|
||||
->transformWith(DatabaseHostTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new database host.
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function store(StoreDatabaseRequest $request): JsonResponse
|
||||
{
|
||||
$databaseHost = $this->creationService->handle($request->validated());
|
||||
|
||||
return $this->fractal->item($databaseHost)
|
||||
->transformWith(DatabaseHostTransformer::class)
|
||||
->respond(JsonResponse::HTTP_CREATED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a database host.
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function update(UpdateDatabaseRequest $request, DatabaseHost $databaseHost): array
|
||||
{
|
||||
$databaseHost = $this->updateService->handle($databaseHost->id, $request->validated());
|
||||
|
||||
return $this->fractal->item($databaseHost)
|
||||
->transformWith(DatabaseHostTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a database host.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(DeleteDatabaseRequest $request, DatabaseHost $databaseHost): Response
|
||||
{
|
||||
$databaseHost->delete();
|
||||
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
110
app/Http/Controllers/Api/Application/Eggs/EggController.php
Normal file
110
app/Http/Controllers/Api/Application/Eggs/EggController.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Application\Eggs;
|
||||
|
||||
use Pterodactyl\Models\Egg;
|
||||
use Pterodactyl\Models\Nest;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Spatie\QueryBuilder\QueryBuilder;
|
||||
use Pterodactyl\Contracts\Repository\EggRepositoryInterface;
|
||||
use Pterodactyl\Transformers\Api\Application\EggTransformer;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Eggs\GetEggRequest;
|
||||
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Eggs\GetEggsRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Eggs\StoreEggRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Eggs\DeleteEggRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Eggs\UpdateEggRequest;
|
||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
|
||||
class EggController extends ApplicationApiController
|
||||
{
|
||||
private EggRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* EggController constructor.
|
||||
*/
|
||||
public function __construct(EggRepositoryInterface $repository)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of all eggs on a given nest.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetEggsRequest $request, Nest $nest): array
|
||||
{
|
||||
$perPage = $request->query('per_page', 10);
|
||||
if ($perPage > 100) {
|
||||
throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
|
||||
}
|
||||
|
||||
$eggs = QueryBuilder::for(Egg::query())
|
||||
->where('nest_id', '=', $nest->id)
|
||||
->allowedFilters(['id', 'name', 'author'])
|
||||
->allowedSorts(['id', 'name', 'author']);
|
||||
if ($perPage > 0) {
|
||||
$eggs = $eggs->paginate($perPage);
|
||||
}
|
||||
|
||||
return $this->fractal->collection($eggs)
|
||||
->transformWith(EggTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single egg.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function view(GetEggRequest $request, Egg $egg): array
|
||||
{
|
||||
return $this->fractal->item($egg)
|
||||
->transformWith(EggTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new egg.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function store(StoreEggRequest $request): JsonResponse
|
||||
{
|
||||
$egg = Egg::query()->create($request->validated());
|
||||
|
||||
return $this->fractal->item($egg)
|
||||
->transformWith(EggTransformer::class)
|
||||
->respond(JsonResponse::HTTP_CREATED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an egg.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function update(UpdateEggRequest $request, Egg $egg): array
|
||||
{
|
||||
$egg->update($request->validated());
|
||||
|
||||
return $this->fractal->item($egg)
|
||||
->transformWith(EggTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an egg.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(DeleteEggRequest $request, Egg $egg): Response
|
||||
{
|
||||
$egg->delete();
|
||||
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
@ -9,8 +9,8 @@ use Spatie\QueryBuilder\QueryBuilder;
|
||||
use Pterodactyl\Services\Locations\LocationUpdateService;
|
||||
use Pterodactyl\Services\Locations\LocationCreationService;
|
||||
use Pterodactyl\Services\Locations\LocationDeletionService;
|
||||
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
||||
use Pterodactyl\Transformers\Api\Application\LocationTransformer;
|
||||
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
|
||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Locations\GetLocationRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Locations\GetLocationsRequest;
|
||||
@ -20,25 +20,9 @@ use Pterodactyl\Http\Requests\Api\Application\Locations\UpdateLocationRequest;
|
||||
|
||||
class LocationController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Locations\LocationCreationService
|
||||
*/
|
||||
private $creationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Locations\LocationDeletionService
|
||||
*/
|
||||
private $deletionService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Locations\LocationUpdateService
|
||||
*/
|
||||
private $updateService;
|
||||
private LocationCreationService $creationService;
|
||||
private LocationDeletionService $deletionService;
|
||||
private LocationUpdateService $updateService;
|
||||
|
||||
/**
|
||||
* LocationController constructor.
|
||||
@ -46,39 +30,46 @@ class LocationController extends ApplicationApiController
|
||||
public function __construct(
|
||||
LocationCreationService $creationService,
|
||||
LocationDeletionService $deletionService,
|
||||
LocationRepositoryInterface $repository,
|
||||
LocationUpdateService $updateService
|
||||
) {
|
||||
parent::__construct();
|
||||
|
||||
$this->creationService = $creationService;
|
||||
$this->deletionService = $deletionService;
|
||||
$this->repository = $repository;
|
||||
$this->updateService = $updateService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all of the locations currently registered on the Panel.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetLocationsRequest $request): array
|
||||
{
|
||||
$perPage = $request->query('per_page', 10);
|
||||
if ($perPage < 1 || $perPage > 100) {
|
||||
throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
|
||||
}
|
||||
|
||||
$locations = QueryBuilder::for(Location::query())
|
||||
->allowedFilters(['short', 'long'])
|
||||
->allowedSorts(['id'])
|
||||
->paginate($request->query('per_page') ?? 50);
|
||||
->allowedSorts(['id', 'short', 'long'])
|
||||
->paginate($perPage);
|
||||
|
||||
return $this->fractal->collection($locations)
|
||||
->transformWith($this->getTransformer(LocationTransformer::class))
|
||||
->transformWith(LocationTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a single location.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function view(GetLocationRequest $request): array
|
||||
public function view(GetLocationRequest $request, Location $location): array
|
||||
{
|
||||
return $this->fractal->item($request->getModel(Location::class))
|
||||
->transformWith($this->getTransformer(LocationTransformer::class))
|
||||
return $this->fractal->item($location)
|
||||
->transformWith(LocationTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -87,13 +78,14 @@ class LocationController extends ApplicationApiController
|
||||
* new location attached.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function store(StoreLocationRequest $request): JsonResponse
|
||||
{
|
||||
$location = $this->creationService->handle($request->validated());
|
||||
|
||||
return $this->fractal->item($location)
|
||||
->transformWith($this->getTransformer(LocationTransformer::class))
|
||||
->transformWith(LocationTransformer::class)
|
||||
->addMeta([
|
||||
'resource' => route('api.application.locations.view', [
|
||||
'location' => $location->id,
|
||||
@ -107,13 +99,14 @@ class LocationController extends ApplicationApiController
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function update(UpdateLocationRequest $request): array
|
||||
public function update(UpdateLocationRequest $request, Location $location): array
|
||||
{
|
||||
$location = $this->updateService->handle($request->getModel(Location::class), $request->validated());
|
||||
$location = $this->updateService->handle($location, $request->validated());
|
||||
|
||||
return $this->fractal->item($location)
|
||||
->transformWith($this->getTransformer(LocationTransformer::class))
|
||||
->transformWith(LocationTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -122,10 +115,10 @@ class LocationController extends ApplicationApiController
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Service\Location\HasActiveNodesException
|
||||
*/
|
||||
public function delete(DeleteLocationRequest $request): Response
|
||||
public function delete(DeleteLocationRequest $request, Location $location): Response
|
||||
{
|
||||
$this->deletionService->handle($request->getModel(Location::class));
|
||||
$this->deletionService->handle($location);
|
||||
|
||||
return response('', 204);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
179
app/Http/Controllers/Api/Application/Mounts/MountController.php
Normal file
179
app/Http/Controllers/Api/Application/Mounts/MountController.php
Normal file
@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Application\Mounts;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
use Pterodactyl\Models\Mount;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Spatie\QueryBuilder\QueryBuilder;
|
||||
use Pterodactyl\Transformers\Api\Application\MountTransformer;
|
||||
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Mounts\GetMountRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Mounts\GetMountsRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Mounts\MountEggsRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Mounts\MountNodesRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Mounts\StoreMountRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Mounts\DeleteMountRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Mounts\UpdateMountRequest;
|
||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
|
||||
class MountController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* MountController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all mount.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetMountsRequest $request): array
|
||||
{
|
||||
$perPage = $request->query('per_page', 10);
|
||||
if ($perPage < 1 || $perPage > 100) {
|
||||
throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
|
||||
}
|
||||
|
||||
$mounts = QueryBuilder::for(Mount::query())
|
||||
->allowedFilters(['id', 'name', 'source', 'target'])
|
||||
->allowedSorts(['id', 'name', 'source', 'target'])
|
||||
->paginate($perPage);
|
||||
|
||||
return $this->fractal->collection($mounts)
|
||||
->transformWith(MountTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single mount.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function view(GetMountRequest $request, Mount $mount): array
|
||||
{
|
||||
return $this->fractal->item($mount)
|
||||
->transformWith(MountTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new mount.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function store(StoreMountRequest $request): JsonResponse
|
||||
{
|
||||
$mount = Mount::query()->create($request->validated());
|
||||
|
||||
return $this->fractal->item($mount)
|
||||
->transformWith(MountTransformer::class)
|
||||
->respond(JsonResponse::HTTP_CREATED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a mount.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function update(UpdateMountRequest $request, Mount $mount): array
|
||||
{
|
||||
$mount->update($request->validated());
|
||||
|
||||
return $this->fractal->item($mount)
|
||||
->transformWith(MountTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a mount.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(DeleteMountRequest $request, Mount $mount): Response
|
||||
{
|
||||
$mount->delete();
|
||||
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches eggs to a mount.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function addEggs(MountEggsRequest $request, Mount $mount): array
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
$eggs = $data['eggs'] ?? [];
|
||||
if (count($eggs) > 0) {
|
||||
$mount->eggs()->syncWithoutDetaching($eggs);
|
||||
}
|
||||
|
||||
return $this->fractal->item($mount)
|
||||
->transformWith(MountTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches nodes to a mount.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function addNodes(MountNodesRequest $request, Mount $mount): array
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
$nodes = $data['nodes'] ?? [];
|
||||
if (count($nodes) > 0) {
|
||||
$mount->nodes()->syncWithoutDetaching($nodes);
|
||||
}
|
||||
|
||||
return $this->fractal->item($mount)
|
||||
->transformWith(MountTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches eggs from a mount.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function deleteEggs(MountEggsRequest $request, Mount $mount): array
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
$eggs = $data['eggs'] ?? [];
|
||||
if (count($eggs) > 0) {
|
||||
$mount->eggs()->detach($eggs);
|
||||
}
|
||||
|
||||
return $this->fractal->item($mount)
|
||||
->transformWith(MountTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches nodes from a mount.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function deleteNodes(MountNodesRequest $request, Mount $mount): array
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
$nodes = $data['nodes'] ?? [];
|
||||
if (count($nodes) > 0) {
|
||||
$mount->nodes()->detach($nodes);
|
||||
}
|
||||
|
||||
return $this->fractal->item($mount)
|
||||
->transformWith(MountTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Application\Nests;
|
||||
|
||||
use Pterodactyl\Models\Egg;
|
||||
use Pterodactyl\Models\Nest;
|
||||
use Pterodactyl\Contracts\Repository\EggRepositoryInterface;
|
||||
use Pterodactyl\Transformers\Api\Application\EggTransformer;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Nests\Eggs\GetEggRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Nests\Eggs\GetEggsRequest;
|
||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
|
||||
class EggController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\EggRepositoryInterface
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* EggController constructor.
|
||||
*/
|
||||
public function __construct(EggRepositoryInterface $repository)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all eggs that exist for a given nest.
|
||||
*/
|
||||
public function index(GetEggsRequest $request): array
|
||||
{
|
||||
$eggs = $this->repository->findWhere([
|
||||
['nest_id', '=', $request->getModel(Nest::class)->id],
|
||||
]);
|
||||
|
||||
return $this->fractal->collection($eggs)
|
||||
->transformWith($this->getTransformer(EggTransformer::class))
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a single egg that exists on the specified nest.
|
||||
*/
|
||||
public function view(GetEggRequest $request): array
|
||||
{
|
||||
return $this->fractal->item($request->getModel(Egg::class))
|
||||
->transformWith($this->getTransformer(EggTransformer::class))
|
||||
->toArray();
|
||||
}
|
||||
}
|
@ -3,47 +3,122 @@
|
||||
namespace Pterodactyl\Http\Controllers\Api\Application\Nests;
|
||||
|
||||
use Pterodactyl\Models\Nest;
|
||||
use Illuminate\Http\Response;
|
||||
use Spatie\QueryBuilder\QueryBuilder;
|
||||
use Pterodactyl\Services\Nests\NestUpdateService;
|
||||
use Pterodactyl\Services\Nests\NestCreationService;
|
||||
use Pterodactyl\Services\Nests\NestDeletionService;
|
||||
use Pterodactyl\Contracts\Repository\NestRepositoryInterface;
|
||||
use Pterodactyl\Transformers\Api\Application\NestTransformer;
|
||||
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Nests\GetNestRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Nests\GetNestsRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Nests\StoreNestRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Nests\DeleteNestRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Nests\UpdateNestRequest;
|
||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
|
||||
class NestController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\NestRepositoryInterface
|
||||
*/
|
||||
private $repository;
|
||||
private NestRepositoryInterface $repository;
|
||||
protected NestCreationService $nestCreationService;
|
||||
protected NestDeletionService $nestDeletionService;
|
||||
protected NestUpdateService $nestUpdateService;
|
||||
|
||||
/**
|
||||
* NestController constructor.
|
||||
*/
|
||||
public function __construct(NestRepositoryInterface $repository)
|
||||
{
|
||||
public function __construct(
|
||||
NestRepositoryInterface $repository,
|
||||
NestCreationService $nestCreationService,
|
||||
NestDeletionService $nestDeletionService,
|
||||
NestUpdateService $nestUpdateService
|
||||
) {
|
||||
parent::__construct();
|
||||
|
||||
$this->repository = $repository;
|
||||
|
||||
$this->nestCreationService = $nestCreationService;
|
||||
$this->nestDeletionService = $nestDeletionService;
|
||||
$this->nestUpdateService = $nestUpdateService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all Nests that exist on the Panel.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetNestsRequest $request): array
|
||||
{
|
||||
$nests = $this->repository->paginated($request->query('per_page') ?? 50);
|
||||
$perPage = $request->query('per_page', 10);
|
||||
if ($perPage > 100) {
|
||||
throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
|
||||
}
|
||||
|
||||
$nests = QueryBuilder::for(Nest::query())
|
||||
->allowedFilters(['id', 'name', 'author'])
|
||||
->allowedSorts(['id', 'name', 'author']);
|
||||
if ($perPage > 0) {
|
||||
$nests = $nests->paginate($perPage);
|
||||
}
|
||||
|
||||
return $this->fractal->collection($nests)
|
||||
->transformWith($this->getTransformer(NestTransformer::class))
|
||||
->transformWith(NestTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return information about a single Nest model.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function view(GetNestsRequest $request): array
|
||||
public function view(GetNestRequest $request, Nest $nest): array
|
||||
{
|
||||
return $this->fractal->item($request->getModel(Nest::class))
|
||||
->transformWith($this->getTransformer(NestTransformer::class))
|
||||
return $this->fractal->item($nest)
|
||||
->transformWith(NestTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new nest.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
*/
|
||||
public function store(StoreNestRequest $request): array
|
||||
{
|
||||
$nest = $this->nestCreationService->handle($request->validated());
|
||||
|
||||
return $this->fractal->item($nest)
|
||||
->transformWith(NestTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing nest.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function update(UpdateNestRequest $request, Nest $nest): array
|
||||
{
|
||||
$this->nestUpdateService->handle($nest->id, $request->validated());
|
||||
|
||||
return $this->fractal->item($nest)
|
||||
->transformWith(NestTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an existing nest.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Service\HasActiveServersException
|
||||
*/
|
||||
public function delete(DeleteNestRequest $request, Nest $nest): Response
|
||||
{
|
||||
$this->nestDeletionService->handle($nest->id);
|
||||
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,11 @@
|
||||
namespace Pterodactyl\Http\Controllers\Api\Application\Nodes;
|
||||
|
||||
use Pterodactyl\Models\Node;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Response;
|
||||
use Pterodactyl\Models\Allocation;
|
||||
use Pterodactyl\Services\Allocations\AssignmentService;
|
||||
use Pterodactyl\Services\Allocations\AllocationDeletionService;
|
||||
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
|
||||
use Pterodactyl\Transformers\Api\Application\AllocationTransformer;
|
||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Allocations\GetAllocationsRequest;
|
||||
@ -15,15 +16,8 @@ use Pterodactyl\Http\Requests\Api\Application\Allocations\DeleteAllocationReques
|
||||
|
||||
class AllocationController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Allocations\AssignmentService
|
||||
*/
|
||||
private $assignmentService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Allocations\AllocationDeletionService
|
||||
*/
|
||||
private $deletionService;
|
||||
private AssignmentService $assignmentService;
|
||||
private AllocationDeletionService $deletionService;
|
||||
|
||||
/**
|
||||
* AllocationController constructor.
|
||||
@ -40,13 +34,20 @@ class AllocationController extends ApplicationApiController
|
||||
|
||||
/**
|
||||
* Return all of the allocations that exist for a given node.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetAllocationsRequest $request, Node $node): array
|
||||
{
|
||||
$allocations = $node->allocations()->paginate($request->query('per_page') ?? 50);
|
||||
$perPage = $request->query('per_page', 10);
|
||||
if ($perPage < 1 || $perPage > 100) {
|
||||
throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
|
||||
}
|
||||
|
||||
$allocations = $node->allocations()->paginate($perPage);
|
||||
|
||||
return $this->fractal->collection($allocations)
|
||||
->transformWith($this->getTransformer(AllocationTransformer::class))
|
||||
->transformWith(AllocationTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -59,11 +60,11 @@ class AllocationController extends ApplicationApiController
|
||||
* @throws \Pterodactyl\Exceptions\Service\Allocation\PortOutOfRangeException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Allocation\TooManyPortsInRangeException
|
||||
*/
|
||||
public function store(StoreAllocationRequest $request, Node $node): JsonResponse
|
||||
public function store(StoreAllocationRequest $request, Node $node): Response
|
||||
{
|
||||
$this->assignmentService->handle($node, $request->validated());
|
||||
|
||||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,10 +72,10 @@ class AllocationController extends ApplicationApiController
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Service\Allocation\ServerUsingAllocationException
|
||||
*/
|
||||
public function delete(DeleteAllocationRequest $request, Node $node, Allocation $allocation): JsonResponse
|
||||
public function delete(DeleteAllocationRequest $request, Node $node, Allocation $allocation): Response
|
||||
{
|
||||
$this->deletionService->handle($allocation);
|
||||
|
||||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
@ -14,10 +14,14 @@ class NodeConfigurationController extends ApplicationApiController
|
||||
* to remote machines so long as an API key is provided to the machine to make the request
|
||||
* with, and the node is known.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function __invoke(GetNodeRequest $request, Node $node)
|
||||
public function __invoke(GetNodeRequest $request, Node $node): string
|
||||
{
|
||||
return JsonResponse::create($node->getConfiguration());
|
||||
if ($request->query('format') === 'yaml') {
|
||||
return $node->getYamlConfiguration();
|
||||
}
|
||||
|
||||
return new JsonResponse($node->getConfiguration());
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Pterodactyl\Http\Controllers\Api\Application\Nodes;
|
||||
|
||||
use Pterodactyl\Models\Node;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Spatie\QueryBuilder\QueryBuilder;
|
||||
use Pterodactyl\Services\Nodes\NodeUpdateService;
|
||||
@ -10,6 +11,7 @@ use Pterodactyl\Services\Nodes\NodeCreationService;
|
||||
use Pterodactyl\Services\Nodes\NodeDeletionService;
|
||||
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
|
||||
use Pterodactyl\Transformers\Api\Application\NodeTransformer;
|
||||
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Nodes\GetNodeRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Nodes\GetNodesRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Nodes\StoreNodeRequest;
|
||||
@ -19,34 +21,19 @@ use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
|
||||
class NodeController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Nodes\NodeCreationService
|
||||
*/
|
||||
private $creationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Nodes\NodeDeletionService
|
||||
*/
|
||||
private $deletionService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\NodeRepositoryInterface
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Nodes\NodeUpdateService
|
||||
*/
|
||||
private $updateService;
|
||||
private NodeRepositoryInterface $repository;
|
||||
private NodeCreationService $creationService;
|
||||
private NodeDeletionService $deletionService;
|
||||
private NodeUpdateService $updateService;
|
||||
|
||||
/**
|
||||
* NodeController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
NodeRepositoryInterface $repository,
|
||||
NodeCreationService $creationService,
|
||||
NodeDeletionService $deletionService,
|
||||
NodeUpdateService $updateService,
|
||||
NodeRepositoryInterface $repository
|
||||
NodeUpdateService $updateService
|
||||
) {
|
||||
parent::__construct();
|
||||
|
||||
@ -58,26 +45,35 @@ class NodeController extends ApplicationApiController
|
||||
|
||||
/**
|
||||
* Return all of the nodes currently available on the Panel.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetNodesRequest $request): array
|
||||
{
|
||||
$perPage = $request->query('per_page', 10);
|
||||
if ($perPage < 1 || $perPage > 100) {
|
||||
throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
|
||||
}
|
||||
|
||||
$nodes = QueryBuilder::for(Node::query())
|
||||
->allowedFilters(['uuid', 'name', 'fqdn', 'daemon_token_id'])
|
||||
->allowedSorts(['id', 'uuid', 'memory', 'disk'])
|
||||
->paginate($request->query('per_page') ?? 50);
|
||||
->allowedFilters(['id', 'uuid', 'name', 'fqdn', 'daemon_token_id'])
|
||||
->allowedSorts(['id', 'uuid', 'name', 'location_id', 'fqdn', 'memory', 'disk'])
|
||||
->paginate($perPage);
|
||||
|
||||
return $this->fractal->collection($nodes)
|
||||
->transformWith($this->getTransformer(NodeTransformer::class))
|
||||
->transformWith(NodeTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return data for a single instance of a node.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function view(GetNodeRequest $request, Node $node): array
|
||||
{
|
||||
return $this->fractal->item($node)
|
||||
->transformWith($this->getTransformer(NodeTransformer::class))
|
||||
->transformWith(NodeTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -86,13 +82,14 @@ class NodeController extends ApplicationApiController
|
||||
* status response on success.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function store(StoreNodeRequest $request): JsonResponse
|
||||
{
|
||||
$node = $this->creationService->handle($request->validated());
|
||||
|
||||
return $this->fractal->item($node)
|
||||
->transformWith($this->getTransformer(NodeTransformer::class))
|
||||
->transformWith(NodeTransformer::class)
|
||||
->addMeta([
|
||||
'resource' => route('api.application.nodes.view', [
|
||||
'node' => $node->id,
|
||||
@ -111,11 +108,11 @@ class NodeController extends ApplicationApiController
|
||||
$node = $this->updateService->handle(
|
||||
$node,
|
||||
$request->validated(),
|
||||
$request->input('reset_secret') === true
|
||||
false,
|
||||
);
|
||||
|
||||
return $this->fractal->item($node)
|
||||
->transformWith($this->getTransformer(NodeTransformer::class))
|
||||
->transformWith(NodeTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -125,10 +122,10 @@ class NodeController extends ApplicationApiController
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Service\HasActiveServersException
|
||||
*/
|
||||
public function delete(DeleteNodeRequest $request, Node $node): JsonResponse
|
||||
public function delete(DeleteNodeRequest $request, Node $node): Response
|
||||
{
|
||||
$this->deletionService->handle($node);
|
||||
|
||||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,7 @@ use Pterodactyl\Http\Requests\Api\Application\Nodes\GetDeployableNodesRequest;
|
||||
|
||||
class NodeDeploymentController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Deployment\FindViableNodesService
|
||||
*/
|
||||
private $viableNodesService;
|
||||
private FindViableNodesService $viableNodesService;
|
||||
|
||||
/**
|
||||
* NodeDeploymentController constructor.
|
||||
@ -29,6 +26,7 @@ class NodeDeploymentController extends ApplicationApiController
|
||||
* similarly to the server creation process, but allows you to pass the deployment object
|
||||
* to this endpoint and get back a list of all Nodes satisfying the requirements.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableNodeException
|
||||
*/
|
||||
public function __invoke(GetDeployableNodesRequest $request): array
|
||||
@ -40,7 +38,7 @@ class NodeDeploymentController extends ApplicationApiController
|
||||
->handle($request->query('per_page'), $request->query('page'));
|
||||
|
||||
return $this->fractal->collection($nodes)
|
||||
->transformWith($this->getTransformer(NodeTransformer::class))
|
||||
->transformWith(NodeTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Application\Nodes;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\Node;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Cache\Repository as Cache;
|
||||
use Pterodactyl\Repositories\Wings\DaemonConfigurationRepository;
|
||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
|
||||
class NodeInformationController extends ApplicationApiController
|
||||
{
|
||||
private Cache $cache;
|
||||
private DaemonConfigurationRepository $repository;
|
||||
|
||||
public function __construct(Cache $cache, DaemonConfigurationRepository $repository)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->cache = $cache;
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns system information from the node.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||
*/
|
||||
public function __invoke(Request $request, Node $node)
|
||||
{
|
||||
$data = $this->cache
|
||||
->tags(['nodes'])
|
||||
->remember($node->uuid, Carbon::now()->addSeconds(30), function () use ($node) {
|
||||
return $this->repository->setNode($node)->getSystemInformation();
|
||||
});
|
||||
|
||||
return new JsonResponse([
|
||||
'version' => $data['version'] ?? null,
|
||||
'system' => [
|
||||
'type' => Str::title($data['os'] ?? 'Unknown'),
|
||||
'arch' => $data['architecture'] ?? null,
|
||||
'release' => $data['kernel_version'] ?? null,
|
||||
'cpus' => $data['cpu_count'] ?? null,
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
104
app/Http/Controllers/Api/Application/Roles/RoleController.php
Normal file
104
app/Http/Controllers/Api/Application/Roles/RoleController.php
Normal file
@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Application\Roles;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Models\AdminRole;
|
||||
use Spatie\QueryBuilder\QueryBuilder;
|
||||
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
|
||||
use Pterodactyl\Transformers\Api\Application\AdminRoleTransformer;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Roles\GetRoleRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Roles\GetRolesRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Roles\StoreRoleRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Roles\DeleteRoleRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Roles\UpdateRoleRequest;
|
||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
|
||||
class RoleController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* RoleController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all roles.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetRolesRequest $request): array
|
||||
{
|
||||
$perPage = $request->query('per_page', 10);
|
||||
if ($perPage < 1 || $perPage > 100) {
|
||||
throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
|
||||
}
|
||||
|
||||
$roles = QueryBuilder::for(AdminRole::query())
|
||||
->allowedFilters(['id', 'name'])
|
||||
->allowedSorts(['id', 'name'])
|
||||
->paginate($perPage);
|
||||
|
||||
return $this->fractal->collection($roles)
|
||||
->transformWith(AdminRoleTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single role.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function view(GetRoleRequest $request, AdminRole $role): array
|
||||
{
|
||||
return $this->fractal->item($role)
|
||||
->transformWith(AdminRoleTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new role.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function store(StoreRoleRequest $request): JsonResponse
|
||||
{
|
||||
$data = array_merge($request->validated(), [
|
||||
'sort_id' => 99,
|
||||
]);
|
||||
$role = AdminRole::query()->create($data);
|
||||
|
||||
return $this->fractal->item($role)
|
||||
->transformWith(AdminRoleTransformer::class)
|
||||
->respond(JsonResponse::HTTP_CREATED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a role.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function update(UpdateRoleRequest $request, AdminRole $role): array
|
||||
{
|
||||
$role->update($request->validated());
|
||||
|
||||
return $this->fractal->item($role)
|
||||
->transformWith(AdminRoleTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a role.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(DeleteRoleRequest $request, AdminRole $role): Response
|
||||
{
|
||||
$role->delete();
|
||||
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
@ -18,20 +18,9 @@ use Pterodactyl\Http\Requests\Api\Application\Servers\Databases\StoreServerDatab
|
||||
|
||||
class DatabaseController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Databases\DatabaseManagementService
|
||||
*/
|
||||
private $databaseManagementService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Databases\DatabasePasswordService
|
||||
*/
|
||||
private $databasePasswordService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface
|
||||
*/
|
||||
private $repository;
|
||||
private DatabaseManagementService $databaseManagementService;
|
||||
private DatabasePasswordService $databasePasswordService;
|
||||
private DatabaseRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* DatabaseController constructor.
|
||||
@ -51,21 +40,25 @@ class DatabaseController extends ApplicationApiController
|
||||
/**
|
||||
* Return a listing of all databases currently available to a single
|
||||
* server.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetServerDatabasesRequest $request, Server $server): array
|
||||
{
|
||||
return $this->fractal->collection($server->databases)
|
||||
->transformWith($this->getTransformer(ServerDatabaseTransformer::class))
|
||||
->transformWith(ServerDatabaseTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a single server database.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function view(GetServerDatabaseRequest $request, Server $server, Database $database): array
|
||||
{
|
||||
return $this->fractal->item($database)
|
||||
->transformWith($this->getTransformer(ServerDatabaseTransformer::class))
|
||||
->transformWith(ServerDatabaseTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -74,11 +67,11 @@ class DatabaseController extends ApplicationApiController
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function resetPassword(ServerDatabaseWriteRequest $request, Server $server, Database $database): JsonResponse
|
||||
public function resetPassword(ServerDatabaseWriteRequest $request, Server $server, Database $database): Response
|
||||
{
|
||||
$this->databasePasswordService->handle($database);
|
||||
|
||||
return JsonResponse::create([], JsonResponse::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,7 +86,7 @@ class DatabaseController extends ApplicationApiController
|
||||
]));
|
||||
|
||||
return $this->fractal->item($database)
|
||||
->transformWith($this->getTransformer(ServerDatabaseTransformer::class))
|
||||
->transformWith(ServerDatabaseTransformer::class)
|
||||
->addMeta([
|
||||
'resource' => route('api.application.servers.databases.view', [
|
||||
'server' => $server->id,
|
||||
@ -106,12 +99,12 @@ class DatabaseController extends ApplicationApiController
|
||||
/**
|
||||
* Handle a request to delete a specific server database from the Panel.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(ServerDatabaseWriteRequest $request): Response
|
||||
public function delete(ServerDatabaseWriteRequest $request, Database $database): Response
|
||||
{
|
||||
$this->databaseManagementService->delete($request->getModel(Database::class));
|
||||
$this->databaseManagementService->delete($database);
|
||||
|
||||
return response('', 204);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Application\Servers;
|
||||
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Transformers\Api\Application\ServerTransformer;
|
||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Servers\GetExternalServerRequest;
|
||||
@ -10,11 +11,15 @@ class ExternalServerController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* Retrieve a specific server from the database using its external ID.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetExternalServerRequest $request): array
|
||||
public function index(GetExternalServerRequest $request, string $external_id): array
|
||||
{
|
||||
return $this->fractal->item($request->getServerModel())
|
||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
||||
$server = Server::query()->where('external_id', $external_id)->firstOrFail();
|
||||
|
||||
return $this->fractal->item($server)
|
||||
->transformWith(ServerTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ use Illuminate\Http\JsonResponse;
|
||||
use Spatie\QueryBuilder\QueryBuilder;
|
||||
use Pterodactyl\Services\Servers\ServerCreationService;
|
||||
use Pterodactyl\Services\Servers\ServerDeletionService;
|
||||
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||
use Pterodactyl\Transformers\Api\Application\ServerTransformer;
|
||||
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Servers\GetServerRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Servers\GetServersRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Servers\ServerWriteRequest;
|
||||
@ -18,48 +18,41 @@ use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
|
||||
class ServerController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\ServerCreationService
|
||||
*/
|
||||
private $creationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\ServerDeletionService
|
||||
*/
|
||||
private $deletionService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
||||
*/
|
||||
private $repository;
|
||||
private ServerCreationService $creationService;
|
||||
private ServerDeletionService $deletionService;
|
||||
|
||||
/**
|
||||
* ServerController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
ServerCreationService $creationService,
|
||||
ServerDeletionService $deletionService,
|
||||
ServerRepositoryInterface $repository
|
||||
ServerDeletionService $deletionService
|
||||
) {
|
||||
parent::__construct();
|
||||
|
||||
$this->creationService = $creationService;
|
||||
$this->deletionService = $deletionService;
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all of the servers that currently exist on the Panel.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetServersRequest $request): array
|
||||
{
|
||||
$perPage = $request->query('per_page', 10);
|
||||
if ($perPage < 1 || $perPage > 100) {
|
||||
throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
|
||||
}
|
||||
|
||||
$servers = QueryBuilder::for(Server::query())
|
||||
->allowedFilters(['uuid', 'uuidShort', 'name', 'image', 'external_id'])
|
||||
->allowedSorts(['id', 'uuid'])
|
||||
->paginate($request->query('per_page') ?? 50);
|
||||
->allowedFilters(['id', 'uuid', 'uuidShort', 'name', 'owner_id', 'node_id', 'external_id'])
|
||||
->allowedSorts(['id', 'uuid', 'uuidShort', 'name', 'owner_id', 'node_id', 'status'])
|
||||
->paginate($perPage);
|
||||
|
||||
return $this->fractal->collection($servers)
|
||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
||||
->transformWith(ServerTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -69,7 +62,6 @@ class ServerController extends ApplicationApiController
|
||||
* @throws \Throwable
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableAllocationException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableNodeException
|
||||
@ -79,22 +71,27 @@ class ServerController extends ApplicationApiController
|
||||
$server = $this->creationService->handle($request->validated(), $request->getDeploymentObject());
|
||||
|
||||
return $this->fractal->item($server)
|
||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
||||
->respond(201);
|
||||
->transformWith(ServerTransformer::class)
|
||||
->respond(Response::HTTP_CREATED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a single server transformed for the application API.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function view(GetServerRequest $request): array
|
||||
public function view(GetServerRequest $request, Server $server): array
|
||||
{
|
||||
return $this->fractal->item($request->getModel(Server::class))
|
||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
||||
return $this->fractal->item($server)
|
||||
->transformWith(ServerTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function delete(ServerWriteRequest $request, Server $server, string $force = ''): Response
|
||||
{
|
||||
|
@ -12,15 +12,8 @@ use Pterodactyl\Http\Requests\Api\Application\Servers\UpdateServerBuildConfigura
|
||||
|
||||
class ServerDetailsController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\BuildModificationService
|
||||
*/
|
||||
private $buildModificationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\DetailsModificationService
|
||||
*/
|
||||
private $detailsModificationService;
|
||||
private BuildModificationService $buildModificationService;
|
||||
private DetailsModificationService $detailsModificationService;
|
||||
|
||||
/**
|
||||
* ServerDetailsController constructor.
|
||||
@ -38,35 +31,31 @@ class ServerDetailsController extends ApplicationApiController
|
||||
/**
|
||||
* Update the details for a specific server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function details(UpdateServerDetailsRequest $request): array
|
||||
public function details(UpdateServerDetailsRequest $request, Server $server): array
|
||||
{
|
||||
$server = $this->detailsModificationService->returnUpdatedModel()->handle(
|
||||
$request->getModel(Server::class),
|
||||
$server,
|
||||
$request->validated()
|
||||
);
|
||||
|
||||
return $this->fractal->item($server)
|
||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
||||
->transformWith(ServerTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the build details for a specific server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function build(UpdateServerBuildConfigurationRequest $request, Server $server): array
|
||||
{
|
||||
$server = $this->buildModificationService->handle($server, $request->validated());
|
||||
|
||||
return $this->fractal->item($server)
|
||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
||||
->transformWith(ServerTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
@ -11,15 +11,8 @@ use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
|
||||
class ServerManagementController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\ReinstallServerService
|
||||
*/
|
||||
private $reinstallServerService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\SuspensionService
|
||||
*/
|
||||
private $suspensionService;
|
||||
private ReinstallServerService $reinstallServerService;
|
||||
private SuspensionService $suspensionService;
|
||||
|
||||
/**
|
||||
* SuspensionController constructor.
|
||||
@ -61,9 +54,7 @@ class ServerManagementController extends ApplicationApiController
|
||||
/**
|
||||
* Mark a server as needing to be reinstalled.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function reinstall(ServerWriteRequest $request, Server $server): Response
|
||||
{
|
||||
|
@ -11,10 +11,7 @@ use Pterodactyl\Http\Requests\Api\Application\Servers\UpdateServerStartupRequest
|
||||
|
||||
class StartupController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\StartupModificationService
|
||||
*/
|
||||
private $modificationService;
|
||||
private StartupModificationService $modificationService;
|
||||
|
||||
/**
|
||||
* StartupController constructor.
|
||||
@ -29,19 +26,16 @@ class StartupController extends ApplicationApiController
|
||||
/**
|
||||
* Update the startup and environment settings for a specific server.
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function index(UpdateServerStartupRequest $request): array
|
||||
public function index(UpdateServerStartupRequest $request, Server $server): array
|
||||
{
|
||||
$server = $this->modificationService
|
||||
->setUserLevel(User::USER_LEVEL_ADMIN)
|
||||
->handle($request->getModel(Server::class), $request->validated());
|
||||
->handle($server, $request->validated());
|
||||
|
||||
return $this->fractal->item($server)
|
||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
||||
->transformWith(ServerTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Application\Users;
|
||||
|
||||
use Pterodactyl\Models\User;
|
||||
use Pterodactyl\Transformers\Api\Application\UserTransformer;
|
||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Users\GetExternalUserRequest;
|
||||
@ -10,11 +11,15 @@ class ExternalUserController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* Retrieve a specific user from the database using their external ID.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetExternalUserRequest $request): array
|
||||
public function index(GetExternalUserRequest $request, string $external_id): array
|
||||
{
|
||||
return $this->fractal->item($request->getUserModel())
|
||||
->transformWith($this->getTransformer(UserTransformer::class))
|
||||
$user = User::query()->where('external_id', $external_id)->firstOrFail();
|
||||
|
||||
return $this->fractal->item($user)
|
||||
->transformWith(UserTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ use Pterodactyl\Services\Users\UserCreationService;
|
||||
use Pterodactyl\Services\Users\UserDeletionService;
|
||||
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
|
||||
use Pterodactyl\Transformers\Api\Application\UserTransformer;
|
||||
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Users\GetUserRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Users\GetUsersRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Users\StoreUserRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Application\Users\DeleteUserRequest;
|
||||
@ -19,25 +21,10 @@ use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
|
||||
class UserController extends ApplicationApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Users\UserCreationService
|
||||
*/
|
||||
private $creationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Users\UserDeletionService
|
||||
*/
|
||||
private $deletionService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Users\UserUpdateService
|
||||
*/
|
||||
private $updateService;
|
||||
private UserRepositoryInterface $repository;
|
||||
private UserCreationService $creationService;
|
||||
private UserDeletionService $deletionService;
|
||||
private UserUpdateService $updateService;
|
||||
|
||||
/**
|
||||
* UserController constructor.
|
||||
@ -50,9 +37,9 @@ class UserController extends ApplicationApiController
|
||||
) {
|
||||
parent::__construct();
|
||||
|
||||
$this->repository = $repository;
|
||||
$this->creationService = $creationService;
|
||||
$this->deletionService = $deletionService;
|
||||
$this->repository = $repository;
|
||||
$this->updateService = $updateService;
|
||||
}
|
||||
|
||||
@ -60,27 +47,36 @@ class UserController extends ApplicationApiController
|
||||
* Handle request to list all users on the panel. Returns a JSON-API representation
|
||||
* of a collection of users including any defined relations passed in
|
||||
* the request.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetUsersRequest $request): array
|
||||
{
|
||||
$perPage = $request->query('per_page', 10);
|
||||
if ($perPage < 1 || $perPage > 100) {
|
||||
throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
|
||||
}
|
||||
|
||||
$users = QueryBuilder::for(User::query())
|
||||
->allowedFilters(['email', 'uuid', 'username', 'external_id'])
|
||||
->allowedSorts(['id', 'uuid'])
|
||||
->paginate($request->query('per_page') ?? 50);
|
||||
->allowedFilters(['id', 'uuid', 'username', 'email', 'external_id'])
|
||||
->allowedSorts(['id', 'uuid', 'username', 'email', 'admin_role_id'])
|
||||
->paginate($perPage);
|
||||
|
||||
return $this->fractal->collection($users)
|
||||
->transformWith($this->getTransformer(UserTransformer::class))
|
||||
->transformWith(UserTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a request to view a single user. Includes any relations that
|
||||
* were defined in the request.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function view(GetUsersRequest $request, User $user): array
|
||||
public function view(GetUserRequest $request, User $user): array
|
||||
{
|
||||
return $this->fractal->item($user)
|
||||
->transformWith($this->getTransformer(UserTransformer::class))
|
||||
->transformWith(UserTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -94,16 +90,16 @@ class UserController extends ApplicationApiController
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function update(UpdateUserRequest $request, User $user): array
|
||||
{
|
||||
$this->updateService->setUserLevel(User::USER_LEVEL_ADMIN);
|
||||
$user = $this->updateService->handle($user, $request->validated());
|
||||
|
||||
$response = $this->fractal->item($user)
|
||||
->transformWith($this->getTransformer(UserTransformer::class));
|
||||
|
||||
return $response->toArray();
|
||||
return $this->fractal->item($user)
|
||||
->transformWith(UserTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,7 +114,7 @@ class UserController extends ApplicationApiController
|
||||
$user = $this->creationService->handle($request->validated());
|
||||
|
||||
return $this->fractal->item($user)
|
||||
->transformWith($this->getTransformer(UserTransformer::class))
|
||||
->transformWith(UserTransformer::class)
|
||||
->addMeta([
|
||||
'resource' => route('api.application.users.view', [
|
||||
'user' => $user->id,
|
||||
@ -133,10 +129,10 @@ class UserController extends ApplicationApiController
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
*/
|
||||
public function delete(DeleteUserRequest $request, User $user): JsonResponse
|
||||
public function delete(DeleteUserRequest $request, User $user): Response
|
||||
{
|
||||
$this->deletionService->handle($user);
|
||||
|
||||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
29
app/Http/Controllers/Api/Application/VersionController.php
Normal file
29
app/Http/Controllers/Api/Application/VersionController.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Application;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Services\Helpers\SoftwareVersionService;
|
||||
|
||||
class VersionController extends ApplicationApiController
|
||||
{
|
||||
private SoftwareVersionService $softwareVersionService;
|
||||
|
||||
/**
|
||||
* VersionController constructor.
|
||||
*/
|
||||
public function __construct(SoftwareVersionService $softwareVersionService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->softwareVersionService = $softwareVersionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns version information.
|
||||
*/
|
||||
public function __invoke(): JsonResponse
|
||||
{
|
||||
return new JsonResponse($this->softwareVersionService->getVersionData());
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ namespace Pterodactyl\Http\Controllers\Api\Client;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Auth\AuthManager;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Services\Users\UserUpdateService;
|
||||
use Pterodactyl\Transformers\Api\Client\AccountTransformer;
|
||||
use Pterodactyl\Http\Requests\Api\Client\Account\UpdateEmailRequest;
|
||||
@ -13,31 +12,29 @@ use Pterodactyl\Http\Requests\Api\Client\Account\UpdatePasswordRequest;
|
||||
|
||||
class AccountController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Users\UserUpdateService
|
||||
*/
|
||||
private $updateService;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Auth\SessionGuard
|
||||
*/
|
||||
private $sessionGuard;
|
||||
private AuthManager $authManager;
|
||||
private UserUpdateService $updateService;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
*/
|
||||
public function __construct(AuthManager $sessionGuard, UserUpdateService $updateService)
|
||||
public function __construct(AuthManager $authManager, UserUpdateService $updateService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->authManager = $authManager;
|
||||
$this->updateService = $updateService;
|
||||
$this->sessionGuard = $sessionGuard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get's information about the currently authenticated user.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(Request $request): array
|
||||
{
|
||||
return $this->fractal->item($request->user())
|
||||
->transformWith($this->getTransformer(AccountTransformer::class))
|
||||
->transformWith(AccountTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -47,31 +44,26 @@ class AccountController extends ClientApiController
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function updateEmail(UpdateEmailRequest $request): JsonResponse
|
||||
public function updateEmail(UpdateEmailRequest $request): Response
|
||||
{
|
||||
$this->updateService->handle($request->user(), $request->validated());
|
||||
|
||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the authenticated user's password. All existing sessions will be logged
|
||||
* out immediately.
|
||||
*
|
||||
* @throws \Throwable
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function updatePassword(UpdatePasswordRequest $request): JsonResponse
|
||||
public function updatePassword(UpdatePasswordRequest $request): Response
|
||||
{
|
||||
$user = $this->updateService->handle($request->user(), $request->validated());
|
||||
$this->updateService->handle($request->user(), $request->validated());
|
||||
|
||||
// If you do not update the user in the session you'll end up working with a
|
||||
// cached copy of the user that does not include the updated password. Do this
|
||||
// to correctly store the new user details in the guard and allow the logout
|
||||
// other devices functionality to work.
|
||||
$this->sessionGuard->setUser($user);
|
||||
$this->authManager->logoutOtherDevices($request->input('password'));
|
||||
|
||||
$this->sessionGuard->logoutOtherDevices($request->input('password'));
|
||||
|
||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
@ -2,106 +2,57 @@
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Client;
|
||||
|
||||
use Pterodactyl\Models\ApiKey;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Response;
|
||||
use Pterodactyl\Exceptions\DisplayException;
|
||||
use Illuminate\Contracts\Encryption\Encrypter;
|
||||
use Pterodactyl\Services\Api\KeyCreationService;
|
||||
use Pterodactyl\Repositories\Eloquent\ApiKeyRepository;
|
||||
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
|
||||
use Pterodactyl\Transformers\Api\Client\ApiKeyTransformer;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Pterodactyl\Http\Requests\Api\Client\AccountApiRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Client\Account\StoreApiKeyRequest;
|
||||
use Pterodactyl\Transformers\Api\Client\PersonalAccessTokenTransformer;
|
||||
|
||||
class ApiKeyController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Api\KeyCreationService
|
||||
*/
|
||||
private $keyCreationService;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Encryption\Encrypter
|
||||
*/
|
||||
private $encrypter;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ApiKeyRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* ApiKeyController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
Encrypter $encrypter,
|
||||
KeyCreationService $keyCreationService,
|
||||
ApiKeyRepository $repository
|
||||
) {
|
||||
parent::__construct();
|
||||
|
||||
$this->encrypter = $encrypter;
|
||||
$this->keyCreationService = $keyCreationService;
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all of the API keys that exist for the given client.
|
||||
*
|
||||
* @return array
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(ClientApiRequest $request)
|
||||
public function index(AccountApiRequest $request): array
|
||||
{
|
||||
return $this->fractal->collection($request->user()->apiKeys)
|
||||
->transformWith($this->getTransformer(ApiKeyTransformer::class))
|
||||
return $this->fractal->collection($request->user()->tokens)
|
||||
->transformWith(PersonalAccessTokenTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a new API key for a user's account.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function store(StoreApiKeyRequest $request)
|
||||
public function store(StoreApiKeyRequest $request): array
|
||||
{
|
||||
if ($request->user()->apiKeys->count() >= 5) {
|
||||
if ($request->user()->tokens->count() >= 10) {
|
||||
throw new DisplayException('You have reached the account limit for number of API keys.');
|
||||
}
|
||||
|
||||
$key = $this->keyCreationService->setKeyType(ApiKey::TYPE_ACCOUNT)->handle([
|
||||
'user_id' => $request->user()->id,
|
||||
'memo' => $request->input('description'),
|
||||
'allowed_ips' => $request->input('allowed_ips') ?? [],
|
||||
]);
|
||||
// TODO: this should accept an array of different scopes to apply as permissions
|
||||
// for the token. Right now it allows any account level permission.
|
||||
$token = $request->user()->createToken($request->input('description'));
|
||||
|
||||
return $this->fractal->item($key)
|
||||
->transformWith($this->getTransformer(ApiKeyTransformer::class))
|
||||
return $this->fractal->item($token->accessToken)
|
||||
->transformWith(PersonalAccessTokenTransformer::class)
|
||||
->addMeta([
|
||||
'secret_token' => $this->encrypter->decrypt($key->token),
|
||||
'secret_token' => $token->plainTextToken,
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a given API key.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function delete(ClientApiRequest $request, string $identifier)
|
||||
public function delete(AccountApiRequest $request, string $id): Response
|
||||
{
|
||||
$response = $this->repository->deleteWhere([
|
||||
'key_type' => ApiKey::TYPE_ACCOUNT,
|
||||
'user_id' => $request->user()->id,
|
||||
'identifier' => $identifier,
|
||||
]);
|
||||
$request->user()->tokens()->where('token_id', $id)->delete();
|
||||
|
||||
if (!$response) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
return JsonResponse::create([], JsonResponse::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,7 @@
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Client;
|
||||
|
||||
use Webmozart\Assert\Assert;
|
||||
use Illuminate\Container\Container;
|
||||
use Pterodactyl\Transformers\Daemon\BaseDaemonTransformer;
|
||||
use Pterodactyl\Transformers\Api\Client\BaseClientTransformer;
|
||||
use Pterodactyl\Transformers\Api\Transformer;
|
||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||
|
||||
abstract class ClientApiController extends ApplicationApiController
|
||||
@ -15,7 +12,7 @@ abstract class ClientApiController extends ApplicationApiController
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getIncludesForTransformer(BaseClientTransformer $transformer, array $merge = [])
|
||||
protected function getIncludesForTransformer(Transformer $transformer, array $merge = []): array
|
||||
{
|
||||
$filtered = array_filter($this->parseIncludes(), function ($datum) use ($transformer) {
|
||||
return in_array($datum, $transformer->getAvailableIncludes());
|
||||
@ -29,7 +26,7 @@ abstract class ClientApiController extends ApplicationApiController
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function parseIncludes()
|
||||
protected function parseIncludes(): array
|
||||
{
|
||||
$includes = $this->request->query('include') ?? [];
|
||||
|
||||
@ -41,26 +38,4 @@ abstract class ClientApiController extends ApplicationApiController
|
||||
return trim($item);
|
||||
}, explode(',', $includes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of an application transformer.
|
||||
*
|
||||
* @return \Pterodactyl\Transformers\Api\Client\BaseClientTransformer
|
||||
*/
|
||||
public function getTransformer(string $abstract)
|
||||
{
|
||||
/** @var \Pterodactyl\Transformers\Api\Client\BaseClientTransformer $transformer */
|
||||
$transformer = Container::getInstance()->make($abstract);
|
||||
Assert::isInstanceOfAny($transformer, [
|
||||
BaseClientTransformer::class,
|
||||
BaseDaemonTransformer::class,
|
||||
]);
|
||||
|
||||
if ($transformer instanceof BaseClientTransformer) {
|
||||
$transformer->setKey($this->request->attributes->get('api_key'));
|
||||
$transformer->setUser($this->request->user());
|
||||
}
|
||||
|
||||
return $transformer;
|
||||
}
|
||||
}
|
||||
|
@ -13,10 +13,7 @@ use Pterodactyl\Http\Requests\Api\Client\GetServersRequest;
|
||||
|
||||
class ClientController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
||||
*/
|
||||
private $repository;
|
||||
private ServerRepository $repository;
|
||||
|
||||
/**
|
||||
* ClientController constructor.
|
||||
@ -31,15 +28,16 @@ class ClientController extends ClientApiController
|
||||
/**
|
||||
* Return all of the servers available to the client making the API
|
||||
* request, including servers the user has access to as a subuser.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetServersRequest $request): array
|
||||
{
|
||||
$user = $request->user();
|
||||
$transformer = $this->getTransformer(ServerTransformer::class);
|
||||
|
||||
// Start the query builder and ensure we eager load any requested relationships from the request.
|
||||
$builder = QueryBuilder::for(
|
||||
Server::query()->with($this->getIncludesForTransformer($transformer, ['node']))
|
||||
Server::query()->with($this->getIncludesForTransformer(new ServerTransformer(), ['node']))
|
||||
)->allowedFilters([
|
||||
'uuid',
|
||||
'name',
|
||||
@ -70,15 +68,13 @@ class ClientController extends ClientApiController
|
||||
|
||||
$servers = $builder->paginate(min($request->query('per_page', 50), 100))->appends($request->query());
|
||||
|
||||
return $this->fractal->transformWith($transformer)->collection($servers)->toArray();
|
||||
return $this->fractal->transformWith(new ServerTransformer())->collection($servers)->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all of the subuser permissions available on the system.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function permissions()
|
||||
public function permissions(): array
|
||||
{
|
||||
return [
|
||||
'object' => 'system_permissions',
|
||||
|
57
app/Http/Controllers/Api/Client/SSHKeyController.php
Normal file
57
app/Http/Controllers/Api/Client/SSHKeyController.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Client;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Models\UserSSHKey;
|
||||
use Pterodactyl\Exceptions\DisplayException;
|
||||
use Pterodactyl\Transformers\Api\Client\UserSSHKeyTransformer;
|
||||
use Pterodactyl\Http\Requests\Api\Client\Account\StoreSSHKeyRequest;
|
||||
|
||||
class SSHKeyController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* ?
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(Request $request): \Pterodactyl\Extensions\Spatie\Fractalistic\Fractal
|
||||
{
|
||||
return $this->fractal->collection(UserSSHKey::query()->where('user_id', '=', $request->user()->id)->get())
|
||||
->transformWith(UserSSHKeyTransformer::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* ?
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
*/
|
||||
public function store(StoreSSHKeyRequest $request): JsonResponse
|
||||
{
|
||||
if ($request->user()->sshKeys->count() >= 5) {
|
||||
throw new DisplayException('You have reached the account limit for number of SSH keys.');
|
||||
}
|
||||
|
||||
$data = array_merge($request->validated(), [
|
||||
'user_id' => $request->user()->id,
|
||||
]);
|
||||
$key = UserSSHKey::query()->create($data);
|
||||
|
||||
return $this->fractal->item($key)
|
||||
->transformWith(UserSSHKeyTransformer::class)
|
||||
->respond(JsonResponse::HTTP_CREATED);
|
||||
}
|
||||
|
||||
/**
|
||||
* ?
|
||||
*/
|
||||
public function delete(Request $request, UserSSHKey $sshKey): Response
|
||||
{
|
||||
$sshKey->delete();
|
||||
|
||||
return new Response('', Response::HTTP_NO_CONTENT);
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Pterodactyl\Models\Backup;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Models\AuditLog;
|
||||
@ -51,6 +52,7 @@ class BackupController extends ClientApiController
|
||||
* result set.
|
||||
*
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(Request $request, Server $server): array
|
||||
{
|
||||
@ -61,7 +63,7 @@ class BackupController extends ClientApiController
|
||||
$limit = min($request->query('per_page') ?? 20, 50);
|
||||
|
||||
return $this->fractal->collection($server->backups()->paginate($limit))
|
||||
->transformWith($this->getTransformer(BackupTransformer::class))
|
||||
->transformWith(BackupTransformer::class)
|
||||
->addMeta([
|
||||
'backup_count' => $this->repository->getNonFailedBackups($server)->count(),
|
||||
])
|
||||
@ -98,7 +100,7 @@ class BackupController extends ClientApiController
|
||||
});
|
||||
|
||||
return $this->fractal->item($backup)
|
||||
->transformWith($this->getTransformer(BackupTransformer::class))
|
||||
->transformWith(BackupTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -124,7 +126,7 @@ class BackupController extends ClientApiController
|
||||
$backup->refresh();
|
||||
|
||||
return $this->fractal->item($backup)
|
||||
->transformWith($this->getTransformer(BackupTransformer::class))
|
||||
->transformWith(BackupTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -140,7 +142,7 @@ class BackupController extends ClientApiController
|
||||
}
|
||||
|
||||
return $this->fractal->item($backup)
|
||||
->transformWith($this->getTransformer(BackupTransformer::class))
|
||||
->transformWith(BackupTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -150,7 +152,7 @@ class BackupController extends ClientApiController
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function delete(Request $request, Server $server, Backup $backup): JsonResponse
|
||||
public function delete(Request $request, Server $server, Backup $backup): Response
|
||||
{
|
||||
if (!$request->user()->can(Permission::ACTION_BACKUP_DELETE, $server)) {
|
||||
throw new AuthorizationException();
|
||||
@ -162,7 +164,7 @@ class BackupController extends ClientApiController
|
||||
$this->deleteBackupService->handle($backup);
|
||||
});
|
||||
|
||||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -205,7 +207,7 @@ class BackupController extends ClientApiController
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function restore(Request $request, Server $server, Backup $backup): JsonResponse
|
||||
public function restore(Request $request, Server $server, Backup $backup): Response
|
||||
{
|
||||
if (!$request->user()->can(Permission::ACTION_BACKUP_RESTORE, $server)) {
|
||||
throw new AuthorizationException();
|
||||
@ -237,6 +239,6 @@ class BackupController extends ClientApiController
|
||||
$this->daemonRepository->setServer($server)->restore($backup, $url ?? null, $request->input('truncate'));
|
||||
});
|
||||
|
||||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
@ -14,10 +14,7 @@ use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
|
||||
|
||||
class CommandController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Wings\DaemonCommandRepository
|
||||
*/
|
||||
private $repository;
|
||||
private DaemonCommandRepository $repository;
|
||||
|
||||
/**
|
||||
* CommandController constructor.
|
||||
|
@ -18,25 +18,10 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Databases\RotatePasswordRequest
|
||||
|
||||
class DatabaseController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Databases\DeployServerDatabaseService
|
||||
*/
|
||||
private $deployDatabaseService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\DatabaseRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Databases\DatabaseManagementService
|
||||
*/
|
||||
private $managementService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Databases\DatabasePasswordService
|
||||
*/
|
||||
private $passwordService;
|
||||
private DeployServerDatabaseService $deployDatabaseService;
|
||||
private DatabaseRepository $repository;
|
||||
private DatabaseManagementService $managementService;
|
||||
private DatabasePasswordService $passwordService;
|
||||
|
||||
/**
|
||||
* DatabaseController constructor.
|
||||
@ -57,11 +42,13 @@ class DatabaseController extends ClientApiController
|
||||
|
||||
/**
|
||||
* Return all of the databases that belong to the given server.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetDatabasesRequest $request, Server $server): array
|
||||
{
|
||||
return $this->fractal->collection($server->databases)
|
||||
->transformWith($this->getTransformer(DatabaseTransformer::class))
|
||||
->transformWith(DatabaseTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -78,7 +65,7 @@ class DatabaseController extends ClientApiController
|
||||
|
||||
return $this->fractal->item($database)
|
||||
->parseIncludes(['password'])
|
||||
->transformWith($this->getTransformer(DatabaseTransformer::class))
|
||||
->transformWith(DatabaseTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -86,30 +73,28 @@ class DatabaseController extends ClientApiController
|
||||
* Rotates the password for the given server model and returns a fresh instance to
|
||||
* the caller.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function rotatePassword(RotatePasswordRequest $request, Server $server, Database $database)
|
||||
public function rotatePassword(RotatePasswordRequest $request, Server $server, Database $database): array
|
||||
{
|
||||
$this->passwordService->handle($database);
|
||||
$database->refresh();
|
||||
|
||||
return $this->fractal->item($database)
|
||||
->parseIncludes(['password'])
|
||||
->transformWith($this->getTransformer(DatabaseTransformer::class))
|
||||
->transformWith(DatabaseTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a database from the server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(DeleteDatabaseRequest $request, Server $server, Database $database): Response
|
||||
{
|
||||
$this->managementService->delete($database);
|
||||
|
||||
return Response::create('', Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ use Carbon\CarbonImmutable;
|
||||
use Illuminate\Http\Response;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Models\AuditLog;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Services\Nodes\NodeJWTService;
|
||||
use Illuminate\Contracts\Routing\ResponseFactory;
|
||||
use Pterodactyl\Repositories\Wings\DaemonFileRepository;
|
||||
@ -26,28 +25,17 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Files\WriteFileContentRequest;
|
||||
|
||||
class FileController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Wings\DaemonFileRepository
|
||||
*/
|
||||
private $fileRepository;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Routing\ResponseFactory
|
||||
*/
|
||||
private $responseFactory;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Nodes\NodeJWTService
|
||||
*/
|
||||
private $jwtService;
|
||||
private DaemonFileRepository $fileRepository;
|
||||
private ResponseFactory $responseFactory;
|
||||
private NodeJWTService $jwtService;
|
||||
|
||||
/**
|
||||
* FileController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
DaemonFileRepository $fileRepository,
|
||||
ResponseFactory $responseFactory,
|
||||
NodeJWTService $jwtService,
|
||||
DaemonFileRepository $fileRepository
|
||||
NodeJWTService $jwtService
|
||||
) {
|
||||
parent::__construct();
|
||||
|
||||
@ -60,6 +48,7 @@ class FileController extends ClientApiController
|
||||
* Returns a listing of files in a given directory.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function directory(ListFilesRequest $request, Server $server): array
|
||||
{
|
||||
@ -68,7 +57,7 @@ class FileController extends ClientApiController
|
||||
->getDirectory($request->get('directory') ?? '/');
|
||||
|
||||
return $this->fractal->collection($contents)
|
||||
->transformWith($this->getTransformer(FileObjectTransformer::class))
|
||||
->transformWith(FileObjectTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -91,11 +80,9 @@ class FileController extends ClientApiController
|
||||
* Generates a one-time token with a link that the user can use to
|
||||
* download a given file.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function download(GetFileContentsRequest $request, Server $server)
|
||||
public function download(GetFileContentsRequest $request, Server $server): array
|
||||
{
|
||||
$token = $server->audit(AuditLog::SERVER__FILESYSTEM_DOWNLOAD, function (AuditLog $audit, Server $server) use ($request) {
|
||||
$audit->metadata = ['file' => $request->get('file')];
|
||||
@ -124,9 +111,9 @@ class FileController extends ClientApiController
|
||||
/**
|
||||
* Writes the contents of the specified file to the server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function write(WriteFileContentRequest $request, Server $server): JsonResponse
|
||||
public function write(WriteFileContentRequest $request, Server $server): Response
|
||||
{
|
||||
$server->audit(AuditLog::SERVER__FILESYSTEM_WRITE, function (AuditLog $audit, Server $server) use ($request) {
|
||||
$audit->subaction = 'write_content';
|
||||
@ -137,7 +124,7 @@ class FileController extends ClientApiController
|
||||
->putContent($request->get('file'), $request->getContent());
|
||||
});
|
||||
|
||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,7 +132,7 @@ class FileController extends ClientApiController
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function create(CreateFolderRequest $request, Server $server): JsonResponse
|
||||
public function create(CreateFolderRequest $request, Server $server): Response
|
||||
{
|
||||
$server->audit(AuditLog::SERVER__FILESYSTEM_WRITE, function (AuditLog $audit, Server $server) use ($request) {
|
||||
$audit->subaction = 'create_folder';
|
||||
@ -156,7 +143,7 @@ class FileController extends ClientApiController
|
||||
->createDirectory($request->input('name'), $request->input('root', '/'));
|
||||
});
|
||||
|
||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,7 +151,7 @@ class FileController extends ClientApiController
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function rename(RenameFileRequest $request, Server $server): JsonResponse
|
||||
public function rename(RenameFileRequest $request, Server $server): Response
|
||||
{
|
||||
$server->audit(AuditLog::SERVER__FILESYSTEM_RENAME, function (AuditLog $audit, Server $server) use ($request) {
|
||||
$audit->metadata = ['root' => $request->input('root'), 'files' => $request->input('files')];
|
||||
@ -174,15 +161,15 @@ class FileController extends ClientApiController
|
||||
->renameFiles($request->input('root'), $request->input('files'));
|
||||
});
|
||||
|
||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a file on the server.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function copy(CopyFileRequest $request, Server $server): JsonResponse
|
||||
public function copy(CopyFileRequest $request, Server $server): Response
|
||||
{
|
||||
$server->audit(AuditLog::SERVER__FILESYSTEM_WRITE, function (AuditLog $audit, Server $server) use ($request) {
|
||||
$audit->subaction = 'copy_file';
|
||||
@ -193,11 +180,11 @@ class FileController extends ClientApiController
|
||||
->copyFile($request->input('location'));
|
||||
});
|
||||
|
||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function compress(CompressFilesRequest $request, Server $server): array
|
||||
{
|
||||
@ -215,14 +202,14 @@ class FileController extends ClientApiController
|
||||
});
|
||||
|
||||
return $this->fractal->item($file)
|
||||
->transformWith($this->getTransformer(FileObjectTransformer::class))
|
||||
->transformWith(FileObjectTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function decompress(DecompressFilesRequest $request, Server $server): JsonResponse
|
||||
public function decompress(DecompressFilesRequest $request, Server $server): Response
|
||||
{
|
||||
$file = $server->audit(AuditLog::SERVER__FILESYSTEM_DECOMPRESS, function (AuditLog $audit, Server $server) use ($request) {
|
||||
// Allow up to five minutes for this request to process before timing out.
|
||||
@ -234,15 +221,15 @@ class FileController extends ClientApiController
|
||||
->decompressFile($request->input('root'), $request->input('file'));
|
||||
});
|
||||
|
||||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes files or folders for the server in the given root directory.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function delete(DeleteFileRequest $request, Server $server): JsonResponse
|
||||
public function delete(DeleteFileRequest $request, Server $server): Response
|
||||
{
|
||||
$server->audit(AuditLog::SERVER__FILESYSTEM_DELETE, function (AuditLog $audit, Server $server) use ($request) {
|
||||
$audit->metadata = ['root' => $request->input('root'), 'files' => $request->input('files')];
|
||||
@ -254,40 +241,46 @@ class FileController extends ClientApiController
|
||||
);
|
||||
});
|
||||
|
||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates file permissions for file(s) in the given root directory.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function chmod(ChmodFilesRequest $request, Server $server): JsonResponse
|
||||
public function chmod(ChmodFilesRequest $request, Server $server): Response
|
||||
{
|
||||
$this->fileRepository->setServer($server)
|
||||
->chmodFiles(
|
||||
$request->input('root'),
|
||||
$request->input('files')
|
||||
);
|
||||
$server->audit(AuditLog::SERVER__FILESYSTEM_CHMOD, function (AuditLog $audit, Server $server) use ($request) {
|
||||
$audit->metadata = ['directory' => $request->input('root'), 'files' => $request->input('files')];
|
||||
|
||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||
$this->fileRepository->setServer($server)
|
||||
->chmodFiles(
|
||||
$request->input('root'),
|
||||
$request->input('files'),
|
||||
);
|
||||
});
|
||||
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that a file be downloaded from a remote location by Wings.
|
||||
*
|
||||
* @param $request
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function pull(PullFileRequest $request, Server $server): JsonResponse
|
||||
public function pull(PullFileRequest $request, Server $server): Response
|
||||
{
|
||||
$server->audit(AuditLog::SERVER__FILESYSTEM_PULL, function (AuditLog $audit, Server $server) use ($request) {
|
||||
$audit->metadata = ['directory' => $request->input('directory'), 'url' => $request->input('url')];
|
||||
$audit->metadata = ['directory' => $request->input('root'), 'url' => $request->input('url')];
|
||||
|
||||
$this->fileRepository->setServer($server)->pull($request->input('url'), $request->input('directory'));
|
||||
$this->fileRepository->setServer($server)
|
||||
->pull(
|
||||
$request->input('root'),
|
||||
$request->input('url'),
|
||||
);
|
||||
});
|
||||
|
||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
@ -12,17 +12,13 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Files\UploadFileRequest;
|
||||
|
||||
class FileUploadController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Nodes\NodeJWTService
|
||||
*/
|
||||
private $jwtService;
|
||||
private NodeJWTService $jwtService;
|
||||
|
||||
/**
|
||||
* FileUploadController constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
NodeJWTService $jwtService
|
||||
) {
|
||||
public function __construct(NodeJWTService $jwtService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->jwtService = $jwtService;
|
||||
@ -30,10 +26,8 @@ class FileUploadController extends ClientApiController
|
||||
|
||||
/**
|
||||
* Returns a url where files can be uploaded to.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function __invoke(UploadFileRequest $request, Server $server)
|
||||
public function __invoke(UploadFileRequest $request, Server $server): JsonResponse
|
||||
{
|
||||
return new JsonResponse([
|
||||
'object' => 'signed_url',
|
||||
@ -45,13 +39,11 @@ class FileUploadController extends ClientApiController
|
||||
|
||||
/**
|
||||
* Returns a url where files can be uploaded to.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getUploadUrl(Server $server, User $user)
|
||||
protected function getUploadUrl(Server $server, User $user): string
|
||||
{
|
||||
$token = $this->jwtService
|
||||
->setExpiresAt(CarbonImmutable::now()->addMinutes(15))
|
||||
->setExpiresAt(CarbonImmutable::now()->addMinutes(15)->toDateTimeImmutable())
|
||||
->setClaims([
|
||||
'server_uuid' => $server->uuid,
|
||||
])
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Models\Allocation;
|
||||
use Pterodactyl\Exceptions\DisplayException;
|
||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||
@ -19,20 +19,9 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Network\SetPrimaryAllocationReq
|
||||
|
||||
class NetworkAllocationController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\AllocationRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
||||
*/
|
||||
private $serverRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Allocations\FindAssignableAllocationService
|
||||
*/
|
||||
private $assignableAllocationService;
|
||||
private AllocationRepository $repository;
|
||||
private ServerRepository $serverRepository;
|
||||
private FindAssignableAllocationService $assignableAllocationService;
|
||||
|
||||
/**
|
||||
* NetworkController constructor.
|
||||
@ -50,13 +39,15 @@ class NetworkAllocationController extends ClientApiController
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all of the allocations available to a server and wether or
|
||||
* Lists all of the allocations available to a server and whether or
|
||||
* not they are currently assigned as the primary for this server.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetNetworkRequest $request, Server $server): array
|
||||
{
|
||||
return $this->fractal->collection($server->allocations)
|
||||
->transformWith($this->getTransformer(AllocationTransformer::class))
|
||||
->transformWith(AllocationTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -65,6 +56,7 @@ class NetworkAllocationController extends ClientApiController
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function update(UpdateAllocationRequest $request, Server $server, Allocation $allocation): array
|
||||
{
|
||||
@ -73,7 +65,7 @@ class NetworkAllocationController extends ClientApiController
|
||||
]);
|
||||
|
||||
return $this->fractal->item($allocation)
|
||||
->transformWith($this->getTransformer(AllocationTransformer::class))
|
||||
->transformWith(AllocationTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -82,21 +74,22 @@ class NetworkAllocationController extends ClientApiController
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function setPrimary(SetPrimaryAllocationRequest $request, Server $server, Allocation $allocation): array
|
||||
{
|
||||
$this->serverRepository->update($server->id, ['allocation_id' => $allocation->id]);
|
||||
|
||||
return $this->fractal->item($allocation)
|
||||
->transformWith($this->getTransformer(AllocationTransformer::class))
|
||||
->transformWith(AllocationTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the notes for the allocation for a server.
|
||||
*s.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function store(NewAllocationRequest $request, Server $server): array
|
||||
{
|
||||
@ -107,18 +100,16 @@ class NetworkAllocationController extends ClientApiController
|
||||
$allocation = $this->assignableAllocationService->handle($server);
|
||||
|
||||
return $this->fractal->item($allocation)
|
||||
->transformWith($this->getTransformer(AllocationTransformer::class))
|
||||
->transformWith(AllocationTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an allocation from a server.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
*/
|
||||
public function delete(DeleteAllocationRequest $request, Server $server, Allocation $allocation)
|
||||
public function delete(DeleteAllocationRequest $request, Server $server, Allocation $allocation): Response
|
||||
{
|
||||
if ($allocation->id === $server->allocation_id) {
|
||||
throw new DisplayException('You cannot delete the primary allocation for this server.');
|
||||
@ -129,6 +120,6 @@ class NetworkAllocationController extends ClientApiController
|
||||
'server_id' => null,
|
||||
]);
|
||||
|
||||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,7 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\SendPowerRequest;
|
||||
|
||||
class PowerController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Wings\DaemonPowerRepository
|
||||
*/
|
||||
private $repository;
|
||||
private DaemonPowerRepository $repository;
|
||||
|
||||
/**
|
||||
* PowerController constructor.
|
||||
|
@ -12,9 +12,8 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\GetServerRequest;
|
||||
|
||||
class ResourceUtilizationController extends ClientApiController
|
||||
{
|
||||
private DaemonServerRepository $repository;
|
||||
|
||||
private Repository $cache;
|
||||
private DaemonServerRepository $repository;
|
||||
|
||||
/**
|
||||
* ResourceUtilizationController constructor.
|
||||
@ -33,6 +32,7 @@ class ResourceUtilizationController extends ClientApiController
|
||||
* a flood of unnecessary API calls.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function __invoke(GetServerRequest $request, Server $server): array
|
||||
{
|
||||
@ -42,7 +42,7 @@ class ResourceUtilizationController extends ClientApiController
|
||||
});
|
||||
|
||||
return $this->fractal->item($stats)
|
||||
->transformWith($this->getTransformer(StatsTransformer::class))
|
||||
->transformWith(StatsTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
@ -8,14 +8,13 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Models\Schedule;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Helpers\Utilities;
|
||||
use Pterodactyl\Exceptions\DisplayException;
|
||||
use Pterodactyl\Repositories\Eloquent\ScheduleRepository;
|
||||
use Pterodactyl\Services\Schedules\ProcessScheduleService;
|
||||
use Pterodactyl\Transformers\Api\Client\ScheduleTransformer;
|
||||
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\ViewScheduleRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\StoreScheduleRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\DeleteScheduleRequest;
|
||||
@ -24,15 +23,8 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\TriggerScheduleReques
|
||||
|
||||
class ScheduleController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ScheduleRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Schedules\ProcessScheduleService
|
||||
*/
|
||||
private $service;
|
||||
private ScheduleRepository $repository;
|
||||
private ProcessScheduleService $service;
|
||||
|
||||
/**
|
||||
* ScheduleController constructor.
|
||||
@ -48,27 +40,26 @@ class ScheduleController extends ClientApiController
|
||||
/**
|
||||
* Returns all of the schedules belonging to a given server.
|
||||
*
|
||||
* @return array
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(ViewScheduleRequest $request, Server $server)
|
||||
public function index(ViewScheduleRequest $request, Server $server): array
|
||||
{
|
||||
$schedules = $server->schedule;
|
||||
$schedules->loadMissing('tasks');
|
||||
|
||||
return $this->fractal->collection($schedules)
|
||||
->transformWith($this->getTransformer(ScheduleTransformer::class))
|
||||
->transformWith(ScheduleTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a new schedule for a server.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function store(StoreScheduleRequest $request, Server $server)
|
||||
public function store(StoreScheduleRequest $request, Server $server): array
|
||||
{
|
||||
/** @var \Pterodactyl\Models\Schedule $model */
|
||||
$model = $this->repository->create([
|
||||
@ -85,38 +76,33 @@ class ScheduleController extends ClientApiController
|
||||
]);
|
||||
|
||||
return $this->fractal->item($model)
|
||||
->transformWith($this->getTransformer(ScheduleTransformer::class))
|
||||
->transformWith(ScheduleTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific schedule for the server.
|
||||
*
|
||||
* @return array
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function view(ViewScheduleRequest $request, Server $server, Schedule $schedule)
|
||||
public function view(ViewScheduleRequest $request, Server $server, Schedule $schedule): array
|
||||
{
|
||||
if ($schedule->server_id !== $server->id) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
$schedule->loadMissing('tasks');
|
||||
|
||||
return $this->fractal->item($schedule)
|
||||
->transformWith($this->getTransformer(ScheduleTransformer::class))
|
||||
->transformWith(ScheduleTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a given schedule with the new data provided.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function update(UpdateScheduleRequest $request, Server $server, Schedule $schedule)
|
||||
public function update(UpdateScheduleRequest $request, Server $server, Schedule $schedule): array
|
||||
{
|
||||
$active = (bool) $request->input('is_active');
|
||||
|
||||
@ -143,7 +129,7 @@ class ScheduleController extends ClientApiController
|
||||
$this->repository->update($schedule->id, $data);
|
||||
|
||||
return $this->fractal->item($schedule->refresh())
|
||||
->transformWith($this->getTransformer(ScheduleTransformer::class))
|
||||
->transformWith(ScheduleTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -151,27 +137,27 @@ class ScheduleController extends ClientApiController
|
||||
* Executes a given schedule immediately rather than waiting on it's normally scheduled time
|
||||
* to pass. This does not care about the schedule state.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function execute(TriggerScheduleRequest $request, Server $server, Schedule $schedule)
|
||||
public function execute(TriggerScheduleRequest $request, Server $server, Schedule $schedule): Response
|
||||
{
|
||||
if (!$schedule->is_active) {
|
||||
throw new BadRequestHttpException('Cannot trigger schedule exception for a schedule that is not currently active.');
|
||||
}
|
||||
|
||||
$this->service->handle($schedule, true);
|
||||
|
||||
return new JsonResponse([], JsonResponse::HTTP_ACCEPTED);
|
||||
return $this->returnAccepted();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a schedule and it's associated tasks.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function delete(DeleteScheduleRequest $request, Server $server, Schedule $schedule)
|
||||
public function delete(DeleteScheduleRequest $request, Server $server, Schedule $schedule): Response
|
||||
{
|
||||
$this->repository->delete($schedule->id);
|
||||
|
||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,23 +6,19 @@ use Pterodactyl\Models\Task;
|
||||
use Illuminate\Http\Response;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Models\Schedule;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Models\Permission;
|
||||
use Pterodactyl\Repositories\Eloquent\TaskRepository;
|
||||
use Pterodactyl\Exceptions\Http\HttpForbiddenException;
|
||||
use Pterodactyl\Transformers\Api\Client\TaskTransformer;
|
||||
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
|
||||
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
||||
use Pterodactyl\Exceptions\Service\ServiceLimitExceededException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\StoreTaskRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\DeleteScheduleRequest;
|
||||
use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\UpdateScheduleRequest;
|
||||
|
||||
class ScheduleTaskController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\TaskRepository
|
||||
*/
|
||||
private $repository;
|
||||
private TaskRepository $repository;
|
||||
|
||||
/**
|
||||
* ScheduleTaskController constructor.
|
||||
@ -37,13 +33,12 @@ class ScheduleTaskController extends ClientApiController
|
||||
/**
|
||||
* Create a new task for a given schedule and store it in the database.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\HttpForbiddenException
|
||||
* @throws \Pterodactyl\Exceptions\Http\HttpForbiddenException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Service\ServiceLimitExceededException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function store(StoreTaskRequest $request, Server $server, Schedule $schedule)
|
||||
public function store(StoreTaskRequest $request, Server $server, Schedule $schedule): array
|
||||
{
|
||||
$limit = config('pterodactyl.client_features.schedules.per_schedule_task_limit', 10);
|
||||
if ($schedule->tasks()->count() >= $limit) {
|
||||
@ -68,20 +63,19 @@ class ScheduleTaskController extends ClientApiController
|
||||
]);
|
||||
|
||||
return $this->fractal->item($task)
|
||||
->transformWith($this->getTransformer(TaskTransformer::class))
|
||||
->transformWith(TaskTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a given task for a server.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\HttpForbiddenException
|
||||
* @throws \Pterodactyl\Exceptions\Http\HttpForbiddenException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function update(StoreTaskRequest $request, Server $server, Schedule $schedule, Task $task)
|
||||
public function update(StoreTaskRequest $request, Server $server, Schedule $schedule, Task $task): array
|
||||
{
|
||||
if ($schedule->id !== $task->schedule_id || $server->id !== $schedule->server_id) {
|
||||
throw new NotFoundHttpException();
|
||||
@ -99,7 +93,7 @@ class ScheduleTaskController extends ClientApiController
|
||||
]);
|
||||
|
||||
return $this->fractal->item($task->refresh())
|
||||
->transformWith($this->getTransformer(TaskTransformer::class))
|
||||
->transformWith(TaskTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -107,26 +101,20 @@ class ScheduleTaskController extends ClientApiController
|
||||
* Delete a given task for a schedule. If there are subsequent tasks stored in the database
|
||||
* for this schedule their sequence IDs are decremented properly.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* This uses the UpdateScheduleRequest intentionally -- there is no permission specific
|
||||
* to deleting a given task on a schedule, so we'll assume if you have permission to edit
|
||||
* a schedule that you can then remove a task from said schedule.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(ClientApiRequest $request, Server $server, Schedule $schedule, Task $task)
|
||||
public function delete(DeleteScheduleRequest $request, Server $server, Schedule $schedule, Task $task): Response
|
||||
{
|
||||
if ($task->schedule_id !== $schedule->id || $schedule->server_id !== $server->id) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
if (!$request->user()->can(Permission::ACTION_SCHEDULE_UPDATE, $server)) {
|
||||
throw new HttpForbiddenException('You do not have permission to perform this action.');
|
||||
}
|
||||
|
||||
$schedule->tasks()->where('sequence_id', '>', $task->sequence_id)->update([
|
||||
'sequence_id' => $schedule->tasks()->getConnection()->raw('(sequence_id - 1)'),
|
||||
]);
|
||||
|
||||
$task->delete();
|
||||
|
||||
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
@ -11,15 +11,8 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\GetServerRequest;
|
||||
|
||||
class ServerController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\SubuserRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\GetUserPermissionsService
|
||||
*/
|
||||
private $permissionsService;
|
||||
private SubuserRepository $repository;
|
||||
private GetUserPermissionsService $permissionsService;
|
||||
|
||||
/**
|
||||
* ServerController constructor.
|
||||
@ -35,11 +28,13 @@ class ServerController extends ClientApiController
|
||||
/**
|
||||
* Transform an individual server into a response that can be consumed by a
|
||||
* client using the API.
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetServerRequest $request, Server $server): array
|
||||
{
|
||||
return $this->fractal->item($server)
|
||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
||||
->transformWith(ServerTransformer::class)
|
||||
->addMeta([
|
||||
'is_server_owner' => $request->user()->id === $server->owner_id,
|
||||
'user_permissions' => $this->permissionsService->handle($server, $request->user()),
|
||||
|
@ -4,7 +4,6 @@ namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||
use Pterodactyl\Services\Servers\ReinstallServerService;
|
||||
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
||||
@ -15,15 +14,8 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Settings\ReinstallServerRequest
|
||||
|
||||
class SettingsController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\ReinstallServerService
|
||||
*/
|
||||
private $reinstallServerService;
|
||||
private ServerRepository $repository;
|
||||
private ReinstallServerService $reinstallServerService;
|
||||
|
||||
/**
|
||||
* SettingsController constructor.
|
||||
@ -41,42 +33,36 @@ class SettingsController extends ClientApiController
|
||||
/**
|
||||
* Renames a server.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function rename(RenameServerRequest $request, Server $server)
|
||||
public function rename(RenameServerRequest $request, Server $server): Response
|
||||
{
|
||||
$this->repository->update($server->id, [
|
||||
'name' => $request->input('name'),
|
||||
]);
|
||||
|
||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinstalls the server on the daemon.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function reinstall(ReinstallServerRequest $request, Server $server)
|
||||
public function reinstall(ReinstallServerRequest $request, Server $server): Response
|
||||
{
|
||||
$this->reinstallServerService->handle($server);
|
||||
|
||||
return new JsonResponse([], Response::HTTP_ACCEPTED);
|
||||
return $this->returnAccepted();
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the Docker image in use by the server.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function dockerImage(SetDockerImageRequest $request, Server $server)
|
||||
public function dockerImage(SetDockerImageRequest $request, Server $server): Response
|
||||
{
|
||||
if (!in_array($server->image, $server->egg->docker_images)) {
|
||||
throw new BadRequestHttpException('This server\'s Docker image has been manually set by an administrator and cannot be updated.');
|
||||
@ -84,6 +70,6 @@ class SettingsController extends ClientApiController
|
||||
|
||||
$server->forceFill(['image' => $request->input('docker_image')])->saveOrFail();
|
||||
|
||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
@ -14,20 +14,9 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Startup\UpdateStartupVariableRe
|
||||
|
||||
class StartupController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\VariableValidatorService
|
||||
*/
|
||||
private $service;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\ServerVariableRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\StartupCommandService
|
||||
*/
|
||||
private $startupCommandService;
|
||||
private VariableValidatorService $service;
|
||||
private ServerVariableRepository $repository;
|
||||
private StartupCommandService $startupCommandService;
|
||||
|
||||
/**
|
||||
* StartupController constructor.
|
||||
@ -44,16 +33,16 @@ class StartupController extends ClientApiController
|
||||
/**
|
||||
* Returns the startup information for the server including all of the variables.
|
||||
*
|
||||
* @return array
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetStartupRequest $request, Server $server)
|
||||
public function index(GetStartupRequest $request, Server $server): array
|
||||
{
|
||||
$startup = $this->startupCommandService->handle($server, false);
|
||||
|
||||
return $this->fractal->collection(
|
||||
$server->variables()->where('user_viewable', true)->get()
|
||||
)
|
||||
->transformWith($this->getTransformer(EggVariableTransformer::class))
|
||||
->transformWith(EggVariableTransformer::class)
|
||||
->addMeta([
|
||||
'startup_command' => $startup,
|
||||
'docker_images' => $server->egg->docker_images,
|
||||
@ -65,13 +54,12 @@ class StartupController extends ClientApiController
|
||||
/**
|
||||
* Updates a single variable for a server.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function update(UpdateStartupVariableRequest $request, Server $server)
|
||||
public function update(UpdateStartupVariableRequest $request, Server $server): array
|
||||
{
|
||||
/** @var \Pterodactyl\Models\EggVariable $variable */
|
||||
$variable = $server->variables()->where('env_variable', $request->input('key'))->first();
|
||||
@ -98,7 +86,7 @@ class StartupController extends ClientApiController
|
||||
$startup = $this->startupCommandService->handle($server, false);
|
||||
|
||||
return $this->fractal->item($variable)
|
||||
->transformWith($this->getTransformer(EggVariableTransformer::class))
|
||||
->transformWith(EggVariableTransformer::class)
|
||||
->addMeta([
|
||||
'startup_command' => $startup,
|
||||
'raw_startup_command' => $server->startup,
|
||||
|
@ -3,8 +3,9 @@
|
||||
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Models\Subuser;
|
||||
use Pterodactyl\Models\Permission;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Pterodactyl\Repositories\Eloquent\SubuserRepository;
|
||||
@ -20,20 +21,9 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Subusers\UpdateSubuserRequest;
|
||||
|
||||
class SubuserController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Eloquent\SubuserRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Subusers\SubuserCreationService
|
||||
*/
|
||||
private $creationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Repositories\Wings\DaemonServerRepository
|
||||
*/
|
||||
private $serverRepository;
|
||||
private SubuserRepository $repository;
|
||||
private SubuserCreationService $creationService;
|
||||
private DaemonServerRepository $serverRepository;
|
||||
|
||||
/**
|
||||
* SubuserController constructor.
|
||||
@ -53,40 +43,36 @@ class SubuserController extends ClientApiController
|
||||
/**
|
||||
* Return the users associated with this server instance.
|
||||
*
|
||||
* @return array
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function index(GetSubuserRequest $request, Server $server)
|
||||
public function index(GetSubuserRequest $request, Server $server): array
|
||||
{
|
||||
return $this->fractal->collection($server->subusers)
|
||||
->transformWith($this->getTransformer(SubuserTransformer::class))
|
||||
->transformWith(SubuserTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single subuser associated with this server instance.
|
||||
*
|
||||
* @return array
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function view(GetSubuserRequest $request)
|
||||
public function view(GetSubuserRequest $request, Server $server, Subuser $subuser): array
|
||||
{
|
||||
$subuser = $request->attributes->get('subuser');
|
||||
|
||||
return $this->fractal->item($subuser)
|
||||
->transformWith($this->getTransformer(SubuserTransformer::class))
|
||||
->transformWith(SubuserTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new subuser for the given server.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Subuser\ServerSubuserExistsException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Subuser\UserIsServerOwnerException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function store(StoreSubuserRequest $request, Server $server)
|
||||
public function store(StoreSubuserRequest $request, Server $server): array
|
||||
{
|
||||
$response = $this->creationService->handle(
|
||||
$server,
|
||||
@ -95,7 +81,7 @@ class SubuserController extends ClientApiController
|
||||
);
|
||||
|
||||
return $this->fractal->item($response)
|
||||
->transformWith($this->getTransformer(SubuserTransformer::class))
|
||||
->transformWith(SubuserTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@ -104,12 +90,10 @@ class SubuserController extends ClientApiController
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function update(UpdateSubuserRequest $request, Server $server): array
|
||||
public function update(UpdateSubuserRequest $request, Server $server, Subuser $subuser): array
|
||||
{
|
||||
/** @var \Pterodactyl\Models\Subuser $subuser */
|
||||
$subuser = $request->attributes->get('subuser');
|
||||
|
||||
$permissions = $this->getDefaultPermissions($request);
|
||||
$current = $subuser->permissions;
|
||||
|
||||
@ -133,20 +117,15 @@ class SubuserController extends ClientApiController
|
||||
}
|
||||
|
||||
return $this->fractal->item($subuser->refresh())
|
||||
->transformWith($this->getTransformer(SubuserTransformer::class))
|
||||
->transformWith(SubuserTransformer::class)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a subusers from a server's assignment.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function delete(DeleteSubuserRequest $request, Server $server)
|
||||
public function delete(DeleteSubuserRequest $request, Server $server, Subuser $subuser): Response
|
||||
{
|
||||
/** @var \Pterodactyl\Models\Subuser $subuser */
|
||||
$subuser = $request->attributes->get('subuser');
|
||||
|
||||
$this->repository->delete($subuser->id);
|
||||
|
||||
try {
|
||||
@ -156,7 +135,7 @@ class SubuserController extends ClientApiController
|
||||
Log::warning($exception, ['user_id' => $subuser->user_id, 'server_id' => $server->id]);
|
||||
}
|
||||
|
||||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,24 +5,16 @@ namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
|
||||
use Carbon\CarbonImmutable;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Pterodactyl\Models\Permission;
|
||||
use Pterodactyl\Services\Nodes\NodeJWTService;
|
||||
use Pterodactyl\Exceptions\Http\HttpForbiddenException;
|
||||
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
|
||||
use Pterodactyl\Services\Servers\GetUserPermissionsService;
|
||||
use Pterodactyl\Http\Requests\Api\Client\WebsocketTokenRequest;
|
||||
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
||||
|
||||
class WebsocketController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Nodes\NodeJWTService
|
||||
*/
|
||||
private $jwtService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Servers\GetUserPermissionsService
|
||||
*/
|
||||
private $permissionsService;
|
||||
private NodeJWTService $jwtService;
|
||||
private GetUserPermissionsService $permissionsService;
|
||||
|
||||
/**
|
||||
* WebsocketController constructor.
|
||||
@ -40,19 +32,12 @@ class WebsocketController extends ClientApiController
|
||||
/**
|
||||
* Generates a one-time token that is sent along in every websocket call to the Daemon.
|
||||
* This is a signed JWT that the Daemon then uses the verify the user's identity, and
|
||||
* allows us to continually renew this token and avoid users mainitaining sessions wrongly,
|
||||
* allows us to continually renew this token and avoid users maintaining sessions wrongly,
|
||||
* as well as ensure that user's only perform actions they're allowed to.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function __invoke(ClientApiRequest $request, Server $server)
|
||||
public function __invoke(WebsocketTokenRequest $request, Server $server): JsonResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
if ($user->cannot(Permission::ACTION_WEBSOCKET_CONNECT, $server)) {
|
||||
throw new HttpForbiddenException('You do not have permission to connect to this server\'s websocket.');
|
||||
}
|
||||
|
||||
$permissions = $this->permissionsService->handle($server, $user);
|
||||
$permissions = $this->permissionsService->handle($server, $request->user());
|
||||
|
||||
$node = $server->node;
|
||||
if (!is_null($server->transfer)) {
|
||||
@ -68,13 +53,13 @@ class WebsocketController extends ClientApiController
|
||||
}
|
||||
|
||||
$token = $this->jwtService
|
||||
->setExpiresAt(CarbonImmutable::now()->addMinutes(10))
|
||||
->setExpiresAt(CarbonImmutable::now()->addMinutes(10)->toDateTimeImmutable())
|
||||
->setClaims([
|
||||
'user_id' => $request->user()->id,
|
||||
'server_uuid' => $server->uuid,
|
||||
'permissions' => $permissions,
|
||||
])
|
||||
->handle($node, $user->id . $server->uuid);
|
||||
->handle($node, $request->user()->id . $server->uuid);
|
||||
|
||||
$socket = str_replace(['https://', 'http://'], ['wss://', 'ws://'], $node->getConnectionAddress());
|
||||
|
||||
|
@ -14,20 +14,9 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
|
||||
class TwoFactorController extends ClientApiController
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Users\TwoFactorSetupService
|
||||
*/
|
||||
private $setupService;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Validation\Factory
|
||||
*/
|
||||
private $validation;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Users\ToggleTwoFactorService
|
||||
*/
|
||||
private $toggleTwoFactorService;
|
||||
private ToggleTwoFactorService $toggleTwoFactorService;
|
||||
private TwoFactorSetupService $setupService;
|
||||
private Factory $validation;
|
||||
|
||||
/**
|
||||
* TwoFactorController constructor.
|
||||
@ -39,9 +28,9 @@ class TwoFactorController extends ClientApiController
|
||||
) {
|
||||
parent::__construct();
|
||||
|
||||
$this->toggleTwoFactorService = $toggleTwoFactorService;
|
||||
$this->setupService = $setupService;
|
||||
$this->validation = $validation;
|
||||
$this->toggleTwoFactorService = $toggleTwoFactorService;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,12 +38,10 @@ class TwoFactorController extends ClientApiController
|
||||
* it on their account. If two-factor is already enabled this endpoint
|
||||
* will return a 400 error.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
if ($request->user()->use_totp) {
|
||||
throw new BadRequestHttpException('Two-factor authentication is already enabled on this account.');
|
||||
@ -68,8 +55,6 @@ class TwoFactorController extends ClientApiController
|
||||
/**
|
||||
* Updates a user's account to have two-factor enabled.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Throwable
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
|
||||
@ -77,7 +62,7 @@ class TwoFactorController extends ClientApiController
|
||||
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
|
||||
* @throws \Pterodactyl\Exceptions\Service\User\TwoFactorAuthenticationTokenInvalid
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$validator = $this->validation->make($request->all(), [
|
||||
'code' => 'required|string',
|
||||
@ -100,10 +85,8 @@ class TwoFactorController extends ClientApiController
|
||||
/**
|
||||
* Disables two-factor authentication on an account if the password provided
|
||||
* is valid.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function delete(Request $request)
|
||||
public function delete(Request $request): Response
|
||||
{
|
||||
if (!password_verify($request->input('password') ?? '', $request->user()->password)) {
|
||||
throw new BadRequestHttpException('The password provided was not valid.');
|
||||
@ -117,6 +100,6 @@ class TwoFactorController extends ClientApiController
|
||||
'use_totp' => false,
|
||||
]);
|
||||
|
||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
||||
return $this->returnNoContent();
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user