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 |
734 changed files with 31570 additions and 37919 deletions
|
@ -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
|
charset = utf-8
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
[.*yml]
|
[*.yml]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
[*.md]
|
[*.md]
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
public
|
public
|
||||||
node_modules
|
node_modules
|
||||||
resources/views
|
resources/views
|
||||||
|
babel.config.js
|
||||||
|
tailwind.config.js
|
||||||
webpack.config.js
|
webpack.config.js
|
||||||
|
|
4
.github/FUNDING.yml
vendored
4
.github/FUNDING.yml
vendored
|
@ -1,2 +1,2 @@
|
||||||
github: [DaneEveritt]
|
github: [ DaneEveritt ]
|
||||||
custom: ["https://paypal.me/PterodactylSoftware"]
|
custom: [ "https://paypal.me/PterodactylSoftware" ]
|
||||||
|
|
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
|
@ -8,7 +8,7 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
push_to_registry:
|
push_to_registry:
|
||||||
name: Push Image to GitHub Packages
|
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]
|
# Always run against a tag, even if the commit into the tag has [docker skip]
|
||||||
# within the commit message.
|
# 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'))"
|
if: "!contains(github.ref, 'develop') || (!contains(github.event.head_commit.message, 'skip docker') && !contains(github.event.head_commit.message, 'docker skip'))"
|
||||||
|
|
21
.github/workflows/release.yml
vendored
21
.github/workflows/release.yml
vendored
|
@ -7,11 +7,13 @@ jobs:
|
||||||
release:
|
release:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- name: Checkout
|
||||||
- uses: actions/setup-node@v1
|
uses: actions/checkout@v2
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: '12'
|
node-version: '14'
|
||||||
|
cache: 'yarn'
|
||||||
- name: Create release branch and bump version
|
- name: Create release branch and bump version
|
||||||
env:
|
env:
|
||||||
REF: ${{ github.ref }}
|
REF: ${{ github.ref }}
|
||||||
|
@ -25,17 +27,14 @@ jobs:
|
||||||
git add config/app.php
|
git add config/app.php
|
||||||
git commit -m "bump version for release"
|
git commit -m "bump version for release"
|
||||||
git push
|
git push
|
||||||
|
|
||||||
- name: Build assets
|
- name: Build assets
|
||||||
run: |
|
run: |
|
||||||
yarn install
|
yarn install
|
||||||
yarn run build:production
|
yarn run build:production
|
||||||
|
|
||||||
- name: Create release archive
|
- name: Create release archive
|
||||||
run: |
|
run: |
|
||||||
rm -rf node_modules/ test/ codecov.yml CODE_OF_CONDUCT.md CONTRIBUTING.md phpunit.dusk.xml phpunit.xml Vagrantfile
|
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 .babel-plugin-macrosrc.js
|
tar -czf panel.tar.gz * .env.example .eslintignore .eslintrc.yml .yarnclean
|
||||||
|
|
||||||
- name: Extract changelog
|
- name: Extract changelog
|
||||||
id: extract_changelog
|
id: extract_changelog
|
||||||
env:
|
env:
|
||||||
|
@ -43,13 +42,11 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
sed -n "/^## ${REF:10}/,/^## /{/^## /b;p}" CHANGELOG.md > ./RELEASE_CHANGELOG
|
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`
|
echo ::set-output name=version_name::`sed -nr "s/^## (${REF:10} .*)$/\1/p" CHANGELOG.md`
|
||||||
|
|
||||||
- name: Create checksum and add to changelog
|
- name: Create checksum and add to changelog
|
||||||
run: |
|
run: |
|
||||||
SUM=`sha256sum panel.tar.gz`
|
SUM=`sha256sum panel.tar.gz`
|
||||||
echo -e "\n#### SHA256 Checksum\n\n\`\`\`\n$SUM\n\`\`\`\n" >> ./RELEASE_CHANGELOG
|
echo -e "\n#### SHA256 Checksum\n\n\`\`\`\n$SUM\n\`\`\`\n" >> ./RELEASE_CHANGELOG
|
||||||
echo $SUM > checksum.txt
|
echo $SUM > checksum.txt
|
||||||
|
|
||||||
- name: Create Release
|
- name: Create Release
|
||||||
id: create_release
|
id: create_release
|
||||||
uses: actions/create-release@v1
|
uses: actions/create-release@v1
|
||||||
|
@ -61,7 +58,6 @@ jobs:
|
||||||
body_path: ./RELEASE_CHANGELOG
|
body_path: ./RELEASE_CHANGELOG
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: ${{ contains(github.ref, 'beta') || contains(github.ref, 'alpha') }}
|
prerelease: ${{ contains(github.ref, 'beta') || contains(github.ref, 'alpha') }}
|
||||||
|
|
||||||
- name: Upload binary
|
- name: Upload binary
|
||||||
id: upload-release-archive
|
id: upload-release-archive
|
||||||
uses: actions/upload-release-asset@v1
|
uses: actions/upload-release-asset@v1
|
||||||
|
@ -72,7 +68,6 @@ jobs:
|
||||||
asset_path: panel.tar.gz
|
asset_path: panel.tar.gz
|
||||||
asset_name: panel.tar.gz
|
asset_name: panel.tar.gz
|
||||||
asset_content_type: application/gzip
|
asset_content_type: application/gzip
|
||||||
|
|
||||||
- name: Upload checksum
|
- name: Upload checksum
|
||||||
id: upload-release-checksum
|
id: upload-release-checksum
|
||||||
uses: actions/upload-release-asset@v1
|
uses: actions/upload-release-asset@v1
|
||||||
|
|
77
.github/workflows/tests.yml
vendored
77
.github/workflows/tests.yml
vendored
|
@ -1,45 +1,37 @@
|
||||||
name: run tests
|
name: Run Tests
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches-ignore:
|
branches:
|
||||||
- master
|
- 'develop'
|
||||||
- "release/**"
|
- 'v2'
|
||||||
pull_request:
|
pull_request:
|
||||||
jobs:
|
jobs:
|
||||||
tests:
|
tests:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
if: "!contains(github.event.head_commit.message, 'skip ci') && !contains(github.event.head_commit.message, 'ci skip')"
|
if: "!contains(github.event.head_commit.message, 'skip ci') && !contains(github.event.head_commit.message, 'ci skip')"
|
||||||
services:
|
|
||||||
mariadb:
|
|
||||||
image: mariadb:10.2
|
|
||||||
env:
|
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
|
||||||
MYSQL_DATABASE: panel_test
|
|
||||||
ports:
|
|
||||||
- 3306
|
|
||||||
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
|
||||||
mysql:
|
|
||||||
image: mysql:8
|
|
||||||
env:
|
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
|
||||||
MYSQL_DATABASE: panel_test
|
|
||||||
ports:
|
|
||||||
- 3306
|
|
||||||
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
php: [ 7.4, 8.0 ]
|
php: [ 7.4, 8.0 ]
|
||||||
database: [ mysql, mariadb ]
|
database: [ 'mariadb:10.2', 'mysql:8' ]
|
||||||
name: "php-${{ matrix.php }} (engine: ${{ matrix.database }})"
|
services:
|
||||||
|
database:
|
||||||
|
image: ${{ matrix.database }}
|
||||||
|
env:
|
||||||
|
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||||
|
MYSQL_DATABASE: panel_test
|
||||||
|
ports:
|
||||||
|
- 3306
|
||||||
|
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||||
|
name: "php-${{ matrix.php }} (${{ matrix.database }})"
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: get cache directory
|
- name: Get cache directory
|
||||||
id: composer-cache
|
id: composer-cache
|
||||||
run: |
|
run: |
|
||||||
echo "::set-output name=dir::$(composer config cache-files-dir)"
|
echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||||
- name: cache dependencies
|
- name: Cache
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
@ -48,35 +40,28 @@ jobs:
|
||||||
key: ${{ runner.os }}-cache-${{ matrix.php }}-${{ hashFiles('**.composer.lock') }}
|
key: ${{ runner.os }}-cache-${{ matrix.php }}-${{ hashFiles('**.composer.lock') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-cache-${{ matrix.php }}-
|
${{ runner.os }}-cache-${{ matrix.php }}-
|
||||||
- name: setup
|
- name: Setup PHP
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: ${{ matrix.php }}
|
php-version: ${{ matrix.php }}
|
||||||
extensions: cli, openssl, gd, mysql, pdo, mbstring, tokenizer, bcmath, xml, curl, zip
|
extensions: bcmath, cli, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip
|
||||||
tools: composer:v2
|
tools: composer:v2
|
||||||
coverage: none
|
coverage: none
|
||||||
- name: configure
|
- name: Configure .env
|
||||||
run: cp .env.ci .env
|
run: cp .env.ci .env
|
||||||
- name: install dependencies
|
- name: composer install
|
||||||
run: composer install --prefer-dist --no-interaction --no-progress
|
run: composer install --prefer-dist --no-interaction --no-progress
|
||||||
- name: run cs-fixer
|
- name: Run cs-fixer
|
||||||
run: vendor/bin/php-cs-fixer fix --dry-run --diff --diff-format=udiff --config .php_cs.dist
|
run: vendor/bin/php-cs-fixer fix --dry-run --diff --diff-format=udiff --config .php-cs-fixer.dist.php
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
- name: execute unit tests
|
- name: Execute Unit Tests
|
||||||
run: vendor/bin/phpunit --bootstrap bootstrap/app.php tests/Unit
|
run: php artisan test tests/Unit
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
env:
|
env:
|
||||||
DB_CONNECTION: testing
|
TESTING_DB_PORT: ${{ job.services.database.ports[3306] }}
|
||||||
TESTING_DB_HOST: UNIT_NO_DB
|
|
||||||
- name: execute integration tests (mysql)
|
|
||||||
run: vendor/bin/phpunit tests/Integration
|
|
||||||
if: "${{ matrix.database }} == 'mysql'"
|
|
||||||
env:
|
|
||||||
TESTING_DB_PORT: ${{ job.services.mysql.ports[3306] }}
|
|
||||||
TESTING_DB_USERNAME: root
|
TESTING_DB_USERNAME: root
|
||||||
- name: execute integration tests (mariadb)
|
- name: Execute Integration Tests
|
||||||
run: vendor/bin/phpunit tests/Integration
|
run: php artisan test tests/Integration
|
||||||
if: "${{ matrix.database }} == 'mariadb'"
|
|
||||||
env:
|
env:
|
||||||
TESTING_DB_PORT: ${{ job.services.mariadb.ports[3306] }}
|
TESTING_DB_PORT: ${{ job.services.database.ports[3306] }}
|
||||||
TESTING_DB_USERNAME: root
|
TESTING_DB_USERNAME: root
|
||||||
|
|
104
.gitignore
vendored
104
.gitignore
vendored
|
@ -1,38 +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
|
/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.ci
|
||||||
!.env.dusk
|
!.env.dusk
|
||||||
!.env.example
|
!.env.example
|
||||||
.env*
|
.env*
|
||||||
.vagrant/*
|
|
||||||
.vscode/*
|
|
||||||
storage/framework/*
|
|
||||||
/.idea
|
|
||||||
/nbproject
|
|
||||||
|
|
||||||
node_modules
|
|
||||||
*.log
|
*.log
|
||||||
|
_ide_helper_models.php
|
||||||
_ide_helper.php
|
_ide_helper.php
|
||||||
.phpstorm.meta.php
|
.phpstorm.meta.php
|
||||||
.php_cs.cache
|
|
||||||
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
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ return (new Config())
|
||||||
'no_unreachable_default_argument_value' => true,
|
'no_unreachable_default_argument_value' => true,
|
||||||
'no_useless_return' => true,
|
'no_useless_return' => true,
|
||||||
'ordered_imports' => [
|
'ordered_imports' => [
|
||||||
'sortAlgorithm' => 'length',
|
'sort_algorithm' => 'length',
|
||||||
],
|
],
|
||||||
'phpdoc_align' => [
|
'phpdoc_align' => [
|
||||||
'align' => 'left',
|
'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'
|
|
@ -70,7 +70,6 @@ class InfoCommand extends Command
|
||||||
['Queue Driver', $this->config->get('queue.default')],
|
['Queue Driver', $this->config->get('queue.default')],
|
||||||
['Session Driver', $this->config->get('session.driver')],
|
['Session Driver', $this->config->get('session.driver')],
|
||||||
['Filesystem Driver', $this->config->get('filesystems.default')],
|
['Filesystem Driver', $this->config->get('filesystems.default')],
|
||||||
['Default Theme', $this->config->get('themes.active')],
|
|
||||||
['Proxies', $this->config->get('trustedproxies.proxies')],
|
['Proxies', $this->config->get('trustedproxies.proxies')],
|
||||||
], 'compact');
|
], 'compact');
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,6 @@ class MakeUserCommand extends Command
|
||||||
$root_admin = $this->option('admin') ?? $this->confirm(trans('command/messages.user.ask_admin'));
|
$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'));
|
$email = $this->option('email') ?? $this->ask(trans('command/messages.user.ask_email'));
|
||||||
$username = $this->option('username') ?? $this->ask(trans('command/messages.user.ask_username'));
|
$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')) {
|
if (is_null($password = $this->option('password')) && !$this->option('no-password')) {
|
||||||
$this->warn(trans('command/messages.user.ask_password_help'));
|
$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'));
|
$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'], [
|
$this->table(['Field', 'Value'], [
|
||||||
['UUID', $user->uuid],
|
['UUID', $user->uuid],
|
||||||
['Email', $user->email],
|
['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 PDOException;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use Swift_TransportException;
|
use Swift_TransportException;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
@ -59,6 +60,16 @@ class Handler extends ExceptionHandler
|
||||||
'password_confirmation',
|
'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
|
* Registers the exception handling callbacks for the application. This
|
||||||
* will capture specific exception types that we do not want to include
|
* will capture specific exception types that we do not want to include
|
||||||
|
@ -191,7 +202,7 @@ class Handler extends ExceptionHandler
|
||||||
'code' => class_basename($exception),
|
'code' => class_basename($exception),
|
||||||
'status' => method_exists($exception, 'getStatusCode')
|
'status' => method_exists($exception, 'getStatusCode')
|
||||||
? strval($exception->getStatusCode())
|
? strval($exception->getStatusCode())
|
||||||
: ($exception instanceof ValidationException ? '422' : '500'),
|
: strval(self::$statusCodeMap[get_class($exception)] ?? 500),
|
||||||
'detail' => $exception instanceof HttpExceptionInterface
|
'detail' => $exception instanceof HttpExceptionInterface
|
||||||
? $exception->getMessage()
|
? $exception->getMessage()
|
||||||
: 'An unexpected error was encountered while processing this request, please try again.',
|
: '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()),
|
'file' => str_replace(Application::getInstance()->basePath(), '', $exception->getFile()),
|
||||||
],
|
],
|
||||||
'meta' => [
|
'meta' => [
|
||||||
|
'class' => get_class($exception),
|
||||||
'trace' => explode("\n", $exception->getTraceAsString()),
|
'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;
|
namespace Pterodactyl\Extensions\Spatie\Fractalistic;
|
||||||
|
|
||||||
use League\Fractal\TransformerAbstract;
|
|
||||||
use Spatie\Fractal\Fractal as SpatieFractal;
|
use Spatie\Fractal\Fractal as SpatieFractal;
|
||||||
|
use Pterodactyl\Transformers\Api\Transformer;
|
||||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
use Pterodactyl\Extensions\League\Fractal\Serializers\PterodactylSerializer;
|
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
|
// If the resource name is not set attempt to pull it off the transformer
|
||||||
// itself and set it automatically.
|
// itself and set it automatically.
|
||||||
if (
|
$class = is_string($this->transformer) ? new $this->transformer() : $this->transformer;
|
||||||
is_null($this->resourceName)
|
if (is_null($this->resourceName) && $class instanceof Transformer) {
|
||||||
&& $this->transformer instanceof TransformerAbstract
|
$this->resourceName = $class->getResourceName();
|
||||||
&& method_exists($this->transformer, 'getResourceName')
|
|
||||||
) {
|
|
||||||
$this->resourceName = $this->transformer->getResourceName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::createData();
|
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 Illuminate\View\View;
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
use Pterodactyl\Services\Helpers\SoftwareVersionService;
|
|
||||||
|
|
||||||
class BaseController extends Controller
|
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.
|
* Return the admin index view.
|
||||||
*/
|
*/
|
||||||
public function 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;
|
namespace Pterodactyl\Http\Controllers\Api\Application;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Webmozart\Assert\Assert;
|
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Container\Container;
|
use Illuminate\Container\Container;
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
use Pterodactyl\Extensions\Spatie\Fractalistic\Fractal;
|
use Pterodactyl\Extensions\Spatie\Fractalistic\Fractal;
|
||||||
use Pterodactyl\Transformers\Api\Application\BaseTransformer;
|
|
||||||
|
|
||||||
abstract class ApplicationApiController extends Controller
|
abstract class ApplicationApiController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
protected Request $request;
|
||||||
* @var \Illuminate\Http\Request
|
|
||||||
*/
|
|
||||||
protected $request;
|
|
||||||
|
|
||||||
/**
|
protected Fractal $fractal;
|
||||||
* @var \Pterodactyl\Extensions\Spatie\Fractalistic\Fractal
|
|
||||||
*/
|
|
||||||
protected $fractal;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ApplicationApiController constructor.
|
* ApplicationApiController constructor.
|
||||||
|
@ -53,19 +45,11 @@ abstract class ApplicationApiController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance of an application transformer.
|
* Return a HTTP/201 response for the API.
|
||||||
*
|
|
||||||
* @return \Pterodactyl\Transformers\Api\Application\BaseTransformer
|
|
||||||
*/
|
*/
|
||||||
public function getTransformer(string $abstract)
|
protected function returnAccepted(): Response
|
||||||
{
|
{
|
||||||
/** @var \Pterodactyl\Transformers\Api\Application\BaseTransformer $transformer */
|
return new Response('', Response::HTTP_ACCEPTED);
|
||||||
$transformer = Container::getInstance()->make($abstract);
|
|
||||||
$transformer->setKey($this->request->attributes->get('api_key'));
|
|
||||||
|
|
||||||
Assert::isInstanceOf($transformer, BaseTransformer::class);
|
|
||||||
|
|
||||||
return $transformer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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\LocationUpdateService;
|
||||||
use Pterodactyl\Services\Locations\LocationCreationService;
|
use Pterodactyl\Services\Locations\LocationCreationService;
|
||||||
use Pterodactyl\Services\Locations\LocationDeletionService;
|
use Pterodactyl\Services\Locations\LocationDeletionService;
|
||||||
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
|
||||||
use Pterodactyl\Transformers\Api\Application\LocationTransformer;
|
use Pterodactyl\Transformers\Api\Application\LocationTransformer;
|
||||||
|
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
|
||||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Locations\GetLocationRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Locations\GetLocationRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Locations\GetLocationsRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Locations\GetLocationsRequest;
|
||||||
|
@ -20,25 +20,9 @@ use Pterodactyl\Http\Requests\Api\Application\Locations\UpdateLocationRequest;
|
||||||
|
|
||||||
class LocationController extends ApplicationApiController
|
class LocationController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private LocationCreationService $creationService;
|
||||||
* @var \Pterodactyl\Services\Locations\LocationCreationService
|
private LocationDeletionService $deletionService;
|
||||||
*/
|
private LocationUpdateService $updateService;
|
||||||
private $creationService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Locations\LocationDeletionService
|
|
||||||
*/
|
|
||||||
private $deletionService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Locations\LocationUpdateService
|
|
||||||
*/
|
|
||||||
private $updateService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LocationController constructor.
|
* LocationController constructor.
|
||||||
|
@ -46,39 +30,46 @@ class LocationController extends ApplicationApiController
|
||||||
public function __construct(
|
public function __construct(
|
||||||
LocationCreationService $creationService,
|
LocationCreationService $creationService,
|
||||||
LocationDeletionService $deletionService,
|
LocationDeletionService $deletionService,
|
||||||
LocationRepositoryInterface $repository,
|
|
||||||
LocationUpdateService $updateService
|
LocationUpdateService $updateService
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->creationService = $creationService;
|
$this->creationService = $creationService;
|
||||||
$this->deletionService = $deletionService;
|
$this->deletionService = $deletionService;
|
||||||
$this->repository = $repository;
|
|
||||||
$this->updateService = $updateService;
|
$this->updateService = $updateService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all of the locations currently registered on the Panel.
|
* Return all of the locations currently registered on the Panel.
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function index(GetLocationsRequest $request): array
|
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())
|
$locations = QueryBuilder::for(Location::query())
|
||||||
->allowedFilters(['short', 'long'])
|
->allowedFilters(['short', 'long'])
|
||||||
->allowedSorts(['id'])
|
->allowedSorts(['id', 'short', 'long'])
|
||||||
->paginate($request->query('per_page') ?? 50);
|
->paginate($perPage);
|
||||||
|
|
||||||
return $this->fractal->collection($locations)
|
return $this->fractal->collection($locations)
|
||||||
->transformWith($this->getTransformer(LocationTransformer::class))
|
->transformWith(LocationTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a single location.
|
* 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))
|
return $this->fractal->item($location)
|
||||||
->transformWith($this->getTransformer(LocationTransformer::class))
|
->transformWith(LocationTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,13 +78,14 @@ class LocationController extends ApplicationApiController
|
||||||
* new location attached.
|
* new location attached.
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function store(StoreLocationRequest $request): JsonResponse
|
public function store(StoreLocationRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$location = $this->creationService->handle($request->validated());
|
$location = $this->creationService->handle($request->validated());
|
||||||
|
|
||||||
return $this->fractal->item($location)
|
return $this->fractal->item($location)
|
||||||
->transformWith($this->getTransformer(LocationTransformer::class))
|
->transformWith(LocationTransformer::class)
|
||||||
->addMeta([
|
->addMeta([
|
||||||
'resource' => route('api.application.locations.view', [
|
'resource' => route('api.application.locations.view', [
|
||||||
'location' => $location->id,
|
'location' => $location->id,
|
||||||
|
@ -107,13 +99,14 @@ class LocationController extends ApplicationApiController
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @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)
|
return $this->fractal->item($location)
|
||||||
->transformWith($this->getTransformer(LocationTransformer::class))
|
->transformWith(LocationTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,10 +115,10 @@ class LocationController extends ApplicationApiController
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Service\Location\HasActiveNodesException
|
* @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;
|
namespace Pterodactyl\Http\Controllers\Api\Application\Nests;
|
||||||
|
|
||||||
use Pterodactyl\Models\Nest;
|
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\Contracts\Repository\NestRepositoryInterface;
|
||||||
use Pterodactyl\Transformers\Api\Application\NestTransformer;
|
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\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;
|
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
|
||||||
class NestController extends ApplicationApiController
|
class NestController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private NestRepositoryInterface $repository;
|
||||||
* @var \Pterodactyl\Contracts\Repository\NestRepositoryInterface
|
protected NestCreationService $nestCreationService;
|
||||||
*/
|
protected NestDeletionService $nestDeletionService;
|
||||||
private $repository;
|
protected NestUpdateService $nestUpdateService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NestController constructor.
|
* NestController constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(NestRepositoryInterface $repository)
|
public function __construct(
|
||||||
{
|
NestRepositoryInterface $repository,
|
||||||
|
NestCreationService $nestCreationService,
|
||||||
|
NestDeletionService $nestDeletionService,
|
||||||
|
NestUpdateService $nestUpdateService
|
||||||
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
|
|
||||||
|
$this->nestCreationService = $nestCreationService;
|
||||||
|
$this->nestDeletionService = $nestDeletionService;
|
||||||
|
$this->nestUpdateService = $nestUpdateService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all Nests that exist on the Panel.
|
* Return all Nests that exist on the Panel.
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function index(GetNestsRequest $request): array
|
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)
|
return $this->fractal->collection($nests)
|
||||||
->transformWith($this->getTransformer(NestTransformer::class))
|
->transformWith(NestTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return information about a single Nest model.
|
* 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))
|
return $this->fractal->item($nest)
|
||||||
->transformWith($this->getTransformer(NestTransformer::class))
|
->transformWith(NestTransformer::class)
|
||||||
->toArray();
|
->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;
|
namespace Pterodactyl\Http\Controllers\Api\Application\Nodes;
|
||||||
|
|
||||||
use Pterodactyl\Models\Node;
|
use Pterodactyl\Models\Node;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\Response;
|
||||||
use Pterodactyl\Models\Allocation;
|
use Pterodactyl\Models\Allocation;
|
||||||
use Pterodactyl\Services\Allocations\AssignmentService;
|
use Pterodactyl\Services\Allocations\AssignmentService;
|
||||||
use Pterodactyl\Services\Allocations\AllocationDeletionService;
|
use Pterodactyl\Services\Allocations\AllocationDeletionService;
|
||||||
|
use Pterodactyl\Exceptions\Http\QueryValueOutOfRangeHttpException;
|
||||||
use Pterodactyl\Transformers\Api\Application\AllocationTransformer;
|
use Pterodactyl\Transformers\Api\Application\AllocationTransformer;
|
||||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Allocations\GetAllocationsRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Allocations\GetAllocationsRequest;
|
||||||
|
@ -15,15 +16,8 @@ use Pterodactyl\Http\Requests\Api\Application\Allocations\DeleteAllocationReques
|
||||||
|
|
||||||
class AllocationController extends ApplicationApiController
|
class AllocationController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private AssignmentService $assignmentService;
|
||||||
* @var \Pterodactyl\Services\Allocations\AssignmentService
|
private AllocationDeletionService $deletionService;
|
||||||
*/
|
|
||||||
private $assignmentService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Allocations\AllocationDeletionService
|
|
||||||
*/
|
|
||||||
private $deletionService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AllocationController constructor.
|
* AllocationController constructor.
|
||||||
|
@ -40,13 +34,20 @@ class AllocationController extends ApplicationApiController
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all of the allocations that exist for a given node.
|
* Return all of the allocations that exist for a given node.
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function index(GetAllocationsRequest $request, Node $node): array
|
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)
|
return $this->fractal->collection($allocations)
|
||||||
->transformWith($this->getTransformer(AllocationTransformer::class))
|
->transformWith(AllocationTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,11 +60,11 @@ class AllocationController extends ApplicationApiController
|
||||||
* @throws \Pterodactyl\Exceptions\Service\Allocation\PortOutOfRangeException
|
* @throws \Pterodactyl\Exceptions\Service\Allocation\PortOutOfRangeException
|
||||||
* @throws \Pterodactyl\Exceptions\Service\Allocation\TooManyPortsInRangeException
|
* @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());
|
$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
|
* @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);
|
$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
|
* to remote machines so long as an API key is provided to the machine to make the request
|
||||||
* with, and the node is known.
|
* 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;
|
namespace Pterodactyl\Http\Controllers\Api\Application\Nodes;
|
||||||
|
|
||||||
use Pterodactyl\Models\Node;
|
use Pterodactyl\Models\Node;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Spatie\QueryBuilder\QueryBuilder;
|
use Spatie\QueryBuilder\QueryBuilder;
|
||||||
use Pterodactyl\Services\Nodes\NodeUpdateService;
|
use Pterodactyl\Services\Nodes\NodeUpdateService;
|
||||||
|
@ -10,6 +11,7 @@ use Pterodactyl\Services\Nodes\NodeCreationService;
|
||||||
use Pterodactyl\Services\Nodes\NodeDeletionService;
|
use Pterodactyl\Services\Nodes\NodeDeletionService;
|
||||||
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
|
||||||
use Pterodactyl\Transformers\Api\Application\NodeTransformer;
|
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\GetNodeRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Nodes\GetNodesRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Nodes\GetNodesRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Nodes\StoreNodeRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Nodes\StoreNodeRequest;
|
||||||
|
@ -19,34 +21,19 @@ use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
|
||||||
class NodeController extends ApplicationApiController
|
class NodeController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private NodeRepositoryInterface $repository;
|
||||||
* @var \Pterodactyl\Services\Nodes\NodeCreationService
|
private NodeCreationService $creationService;
|
||||||
*/
|
private NodeDeletionService $deletionService;
|
||||||
private $creationService;
|
private NodeUpdateService $updateService;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Nodes\NodeDeletionService
|
|
||||||
*/
|
|
||||||
private $deletionService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\NodeRepositoryInterface
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Nodes\NodeUpdateService
|
|
||||||
*/
|
|
||||||
private $updateService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NodeController constructor.
|
* NodeController constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
NodeRepositoryInterface $repository,
|
||||||
NodeCreationService $creationService,
|
NodeCreationService $creationService,
|
||||||
NodeDeletionService $deletionService,
|
NodeDeletionService $deletionService,
|
||||||
NodeUpdateService $updateService,
|
NodeUpdateService $updateService
|
||||||
NodeRepositoryInterface $repository
|
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
@ -58,26 +45,35 @@ class NodeController extends ApplicationApiController
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all of the nodes currently available on the Panel.
|
* Return all of the nodes currently available on the Panel.
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function index(GetNodesRequest $request): array
|
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())
|
$nodes = QueryBuilder::for(Node::query())
|
||||||
->allowedFilters(['uuid', 'name', 'fqdn', 'daemon_token_id'])
|
->allowedFilters(['id', 'uuid', 'name', 'fqdn', 'daemon_token_id'])
|
||||||
->allowedSorts(['id', 'uuid', 'memory', 'disk'])
|
->allowedSorts(['id', 'uuid', 'name', 'location_id', 'fqdn', 'memory', 'disk'])
|
||||||
->paginate($request->query('per_page') ?? 50);
|
->paginate($perPage);
|
||||||
|
|
||||||
return $this->fractal->collection($nodes)
|
return $this->fractal->collection($nodes)
|
||||||
->transformWith($this->getTransformer(NodeTransformer::class))
|
->transformWith(NodeTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return data for a single instance of a node.
|
* Return data for a single instance of a node.
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function view(GetNodeRequest $request, Node $node): array
|
public function view(GetNodeRequest $request, Node $node): array
|
||||||
{
|
{
|
||||||
return $this->fractal->item($node)
|
return $this->fractal->item($node)
|
||||||
->transformWith($this->getTransformer(NodeTransformer::class))
|
->transformWith(NodeTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,13 +82,14 @@ class NodeController extends ApplicationApiController
|
||||||
* status response on success.
|
* status response on success.
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function store(StoreNodeRequest $request): JsonResponse
|
public function store(StoreNodeRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$node = $this->creationService->handle($request->validated());
|
$node = $this->creationService->handle($request->validated());
|
||||||
|
|
||||||
return $this->fractal->item($node)
|
return $this->fractal->item($node)
|
||||||
->transformWith($this->getTransformer(NodeTransformer::class))
|
->transformWith(NodeTransformer::class)
|
||||||
->addMeta([
|
->addMeta([
|
||||||
'resource' => route('api.application.nodes.view', [
|
'resource' => route('api.application.nodes.view', [
|
||||||
'node' => $node->id,
|
'node' => $node->id,
|
||||||
|
@ -111,11 +108,11 @@ class NodeController extends ApplicationApiController
|
||||||
$node = $this->updateService->handle(
|
$node = $this->updateService->handle(
|
||||||
$node,
|
$node,
|
||||||
$request->validated(),
|
$request->validated(),
|
||||||
$request->input('reset_secret') === true
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->fractal->item($node)
|
return $this->fractal->item($node)
|
||||||
->transformWith($this->getTransformer(NodeTransformer::class))
|
->transformWith(NodeTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,10 +122,10 @@ class NodeController extends ApplicationApiController
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Service\HasActiveServersException
|
* @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);
|
$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
|
class NodeDeploymentController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private FindViableNodesService $viableNodesService;
|
||||||
* @var \Pterodactyl\Services\Deployment\FindViableNodesService
|
|
||||||
*/
|
|
||||||
private $viableNodesService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NodeDeploymentController constructor.
|
* NodeDeploymentController constructor.
|
||||||
|
@ -29,6 +26,7 @@ class NodeDeploymentController extends ApplicationApiController
|
||||||
* similarly to the server creation process, but allows you to pass the deployment object
|
* 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.
|
* 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
|
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableNodeException
|
||||||
*/
|
*/
|
||||||
public function __invoke(GetDeployableNodesRequest $request): array
|
public function __invoke(GetDeployableNodesRequest $request): array
|
||||||
|
@ -40,7 +38,7 @@ class NodeDeploymentController extends ApplicationApiController
|
||||||
->handle($request->query('per_page'), $request->query('page'));
|
->handle($request->query('per_page'), $request->query('page'));
|
||||||
|
|
||||||
return $this->fractal->collection($nodes)
|
return $this->fractal->collection($nodes)
|
||||||
->transformWith($this->getTransformer(NodeTransformer::class))
|
->transformWith(NodeTransformer::class)
|
||||||
->toArray();
|
->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
|
class DatabaseController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private DatabaseManagementService $databaseManagementService;
|
||||||
* @var \Pterodactyl\Services\Databases\DatabaseManagementService
|
private DatabasePasswordService $databasePasswordService;
|
||||||
*/
|
private DatabaseRepositoryInterface $repository;
|
||||||
private $databaseManagementService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Databases\DatabasePasswordService
|
|
||||||
*/
|
|
||||||
private $databasePasswordService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DatabaseController constructor.
|
* DatabaseController constructor.
|
||||||
|
@ -51,21 +40,25 @@ class DatabaseController extends ApplicationApiController
|
||||||
/**
|
/**
|
||||||
* Return a listing of all databases currently available to a single
|
* Return a listing of all databases currently available to a single
|
||||||
* server.
|
* server.
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function index(GetServerDatabasesRequest $request, Server $server): array
|
public function index(GetServerDatabasesRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
return $this->fractal->collection($server->databases)
|
return $this->fractal->collection($server->databases)
|
||||||
->transformWith($this->getTransformer(ServerDatabaseTransformer::class))
|
->transformWith(ServerDatabaseTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a single server database.
|
* Return a single server database.
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function view(GetServerDatabaseRequest $request, Server $server, Database $database): array
|
public function view(GetServerDatabaseRequest $request, Server $server, Database $database): array
|
||||||
{
|
{
|
||||||
return $this->fractal->item($database)
|
return $this->fractal->item($database)
|
||||||
->transformWith($this->getTransformer(ServerDatabaseTransformer::class))
|
->transformWith(ServerDatabaseTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,11 +67,11 @@ class DatabaseController extends ApplicationApiController
|
||||||
*
|
*
|
||||||
* @throws \Throwable
|
* @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);
|
$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)
|
return $this->fractal->item($database)
|
||||||
->transformWith($this->getTransformer(ServerDatabaseTransformer::class))
|
->transformWith(ServerDatabaseTransformer::class)
|
||||||
->addMeta([
|
->addMeta([
|
||||||
'resource' => route('api.application.servers.databases.view', [
|
'resource' => route('api.application.servers.databases.view', [
|
||||||
'server' => $server->id,
|
'server' => $server->id,
|
||||||
|
@ -106,12 +99,12 @@ class DatabaseController extends ApplicationApiController
|
||||||
/**
|
/**
|
||||||
* Handle a request to delete a specific server database from the Panel.
|
* 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;
|
namespace Pterodactyl\Http\Controllers\Api\Application\Servers;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Server;
|
||||||
use Pterodactyl\Transformers\Api\Application\ServerTransformer;
|
use Pterodactyl\Transformers\Api\Application\ServerTransformer;
|
||||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Servers\GetExternalServerRequest;
|
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.
|
* 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())
|
$server = Server::query()->where('external_id', $external_id)->firstOrFail();
|
||||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
|
||||||
|
return $this->fractal->item($server)
|
||||||
|
->transformWith(ServerTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ use Illuminate\Http\JsonResponse;
|
||||||
use Spatie\QueryBuilder\QueryBuilder;
|
use Spatie\QueryBuilder\QueryBuilder;
|
||||||
use Pterodactyl\Services\Servers\ServerCreationService;
|
use Pterodactyl\Services\Servers\ServerCreationService;
|
||||||
use Pterodactyl\Services\Servers\ServerDeletionService;
|
use Pterodactyl\Services\Servers\ServerDeletionService;
|
||||||
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
|
||||||
use Pterodactyl\Transformers\Api\Application\ServerTransformer;
|
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\GetServerRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Servers\GetServersRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Servers\GetServersRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Servers\ServerWriteRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Servers\ServerWriteRequest;
|
||||||
|
@ -18,48 +18,41 @@ use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
|
||||||
class ServerController extends ApplicationApiController
|
class ServerController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private ServerCreationService $creationService;
|
||||||
* @var \Pterodactyl\Services\Servers\ServerCreationService
|
private ServerDeletionService $deletionService;
|
||||||
*/
|
|
||||||
private $creationService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Servers\ServerDeletionService
|
|
||||||
*/
|
|
||||||
private $deletionService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServerController constructor.
|
* ServerController constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ServerCreationService $creationService,
|
ServerCreationService $creationService,
|
||||||
ServerDeletionService $deletionService,
|
ServerDeletionService $deletionService
|
||||||
ServerRepositoryInterface $repository
|
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->creationService = $creationService;
|
$this->creationService = $creationService;
|
||||||
$this->deletionService = $deletionService;
|
$this->deletionService = $deletionService;
|
||||||
$this->repository = $repository;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all of the servers that currently exist on the Panel.
|
* Return all of the servers that currently exist on the Panel.
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function index(GetServersRequest $request): array
|
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())
|
$servers = QueryBuilder::for(Server::query())
|
||||||
->allowedFilters(['uuid', 'uuidShort', 'name', 'image', 'external_id'])
|
->allowedFilters(['id', 'uuid', 'uuidShort', 'name', 'owner_id', 'node_id', 'external_id'])
|
||||||
->allowedSorts(['id', 'uuid'])
|
->allowedSorts(['id', 'uuid', 'uuidShort', 'name', 'owner_id', 'node_id', 'status'])
|
||||||
->paginate($request->query('per_page') ?? 50);
|
->paginate($perPage);
|
||||||
|
|
||||||
return $this->fractal->collection($servers)
|
return $this->fractal->collection($servers)
|
||||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
->transformWith(ServerTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +62,6 @@ class ServerController extends ApplicationApiController
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
* @throws \Illuminate\Validation\ValidationException
|
* @throws \Illuminate\Validation\ValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableAllocationException
|
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableAllocationException
|
||||||
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableNodeException
|
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableNodeException
|
||||||
|
@ -79,22 +71,27 @@ class ServerController extends ApplicationApiController
|
||||||
$server = $this->creationService->handle($request->validated(), $request->getDeploymentObject());
|
$server = $this->creationService->handle($request->validated(), $request->getDeploymentObject());
|
||||||
|
|
||||||
return $this->fractal->item($server)
|
return $this->fractal->item($server)
|
||||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
->transformWith(ServerTransformer::class)
|
||||||
->respond(201);
|
->respond(Response::HTTP_CREATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a single server transformed for the application API.
|
* 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))
|
return $this->fractal->item($server)
|
||||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
->transformWith(ServerTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Deletes a server.
|
||||||
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function delete(ServerWriteRequest $request, Server $server, string $force = ''): Response
|
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
|
class ServerDetailsController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private BuildModificationService $buildModificationService;
|
||||||
* @var \Pterodactyl\Services\Servers\BuildModificationService
|
private DetailsModificationService $detailsModificationService;
|
||||||
*/
|
|
||||||
private $buildModificationService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Servers\DetailsModificationService
|
|
||||||
*/
|
|
||||||
private $detailsModificationService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServerDetailsController constructor.
|
* ServerDetailsController constructor.
|
||||||
|
@ -38,35 +31,31 @@ class ServerDetailsController extends ApplicationApiController
|
||||||
/**
|
/**
|
||||||
* Update the details for a specific server.
|
* Update the details for a specific server.
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Throwable
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function details(UpdateServerDetailsRequest $request): array
|
public function details(UpdateServerDetailsRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
$server = $this->detailsModificationService->returnUpdatedModel()->handle(
|
$server = $this->detailsModificationService->returnUpdatedModel()->handle(
|
||||||
$request->getModel(Server::class),
|
$server,
|
||||||
$request->validated()
|
$request->validated()
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->fractal->item($server)
|
return $this->fractal->item($server)
|
||||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
->transformWith(ServerTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the build details for a specific server.
|
* Update the build details for a specific server.
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Throwable
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function build(UpdateServerBuildConfigurationRequest $request, Server $server): array
|
public function build(UpdateServerBuildConfigurationRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
$server = $this->buildModificationService->handle($server, $request->validated());
|
$server = $this->buildModificationService->handle($server, $request->validated());
|
||||||
|
|
||||||
return $this->fractal->item($server)
|
return $this->fractal->item($server)
|
||||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
->transformWith(ServerTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,15 +11,8 @@ use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
|
||||||
class ServerManagementController extends ApplicationApiController
|
class ServerManagementController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private ReinstallServerService $reinstallServerService;
|
||||||
* @var \Pterodactyl\Services\Servers\ReinstallServerService
|
private SuspensionService $suspensionService;
|
||||||
*/
|
|
||||||
private $reinstallServerService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Servers\SuspensionService
|
|
||||||
*/
|
|
||||||
private $suspensionService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SuspensionController constructor.
|
* SuspensionController constructor.
|
||||||
|
@ -61,9 +54,7 @@ class ServerManagementController extends ApplicationApiController
|
||||||
/**
|
/**
|
||||||
* Mark a server as needing to be reinstalled.
|
* Mark a server as needing to be reinstalled.
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Throwable
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function reinstall(ServerWriteRequest $request, Server $server): Response
|
public function reinstall(ServerWriteRequest $request, Server $server): Response
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,10 +11,7 @@ use Pterodactyl\Http\Requests\Api\Application\Servers\UpdateServerStartupRequest
|
||||||
|
|
||||||
class StartupController extends ApplicationApiController
|
class StartupController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private StartupModificationService $modificationService;
|
||||||
* @var \Pterodactyl\Services\Servers\StartupModificationService
|
|
||||||
*/
|
|
||||||
private $modificationService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StartupController constructor.
|
* StartupController constructor.
|
||||||
|
@ -29,19 +26,16 @@ class StartupController extends ApplicationApiController
|
||||||
/**
|
/**
|
||||||
* Update the startup and environment settings for a specific server.
|
* Update the startup and environment settings for a specific server.
|
||||||
*
|
*
|
||||||
* @throws \Illuminate\Validation\ValidationException
|
* @throws \Throwable
|
||||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function index(UpdateServerStartupRequest $request): array
|
public function index(UpdateServerStartupRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
$server = $this->modificationService
|
$server = $this->modificationService
|
||||||
->setUserLevel(User::USER_LEVEL_ADMIN)
|
->setUserLevel(User::USER_LEVEL_ADMIN)
|
||||||
->handle($request->getModel(Server::class), $request->validated());
|
->handle($server, $request->validated());
|
||||||
|
|
||||||
return $this->fractal->item($server)
|
return $this->fractal->item($server)
|
||||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
->transformWith(ServerTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Api\Application\Users;
|
namespace Pterodactyl\Http\Controllers\Api\Application\Users;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\User;
|
||||||
use Pterodactyl\Transformers\Api\Application\UserTransformer;
|
use Pterodactyl\Transformers\Api\Application\UserTransformer;
|
||||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Users\GetExternalUserRequest;
|
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.
|
* 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())
|
$user = User::query()->where('external_id', $external_id)->firstOrFail();
|
||||||
->transformWith($this->getTransformer(UserTransformer::class))
|
|
||||||
|
return $this->fractal->item($user)
|
||||||
|
->transformWith(UserTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ use Pterodactyl\Services\Users\UserCreationService;
|
||||||
use Pterodactyl\Services\Users\UserDeletionService;
|
use Pterodactyl\Services\Users\UserDeletionService;
|
||||||
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
|
||||||
use Pterodactyl\Transformers\Api\Application\UserTransformer;
|
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\GetUsersRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Users\StoreUserRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Users\StoreUserRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Users\DeleteUserRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Users\DeleteUserRequest;
|
||||||
|
@ -19,25 +21,10 @@ use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
|
||||||
class UserController extends ApplicationApiController
|
class UserController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private UserRepositoryInterface $repository;
|
||||||
* @var \Pterodactyl\Services\Users\UserCreationService
|
private UserCreationService $creationService;
|
||||||
*/
|
private UserDeletionService $deletionService;
|
||||||
private $creationService;
|
private UserUpdateService $updateService;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Users\UserDeletionService
|
|
||||||
*/
|
|
||||||
private $deletionService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Users\UserUpdateService
|
|
||||||
*/
|
|
||||||
private $updateService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UserController constructor.
|
* UserController constructor.
|
||||||
|
@ -50,9 +37,9 @@ class UserController extends ApplicationApiController
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->repository = $repository;
|
||||||
$this->creationService = $creationService;
|
$this->creationService = $creationService;
|
||||||
$this->deletionService = $deletionService;
|
$this->deletionService = $deletionService;
|
||||||
$this->repository = $repository;
|
|
||||||
$this->updateService = $updateService;
|
$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
|
* 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
|
* of a collection of users including any defined relations passed in
|
||||||
* the request.
|
* the request.
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function index(GetUsersRequest $request): array
|
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())
|
$users = QueryBuilder::for(User::query())
|
||||||
->allowedFilters(['email', 'uuid', 'username', 'external_id'])
|
->allowedFilters(['id', 'uuid', 'username', 'email', 'external_id'])
|
||||||
->allowedSorts(['id', 'uuid'])
|
->allowedSorts(['id', 'uuid', 'username', 'email', 'admin_role_id'])
|
||||||
->paginate($request->query('per_page') ?? 50);
|
->paginate($perPage);
|
||||||
|
|
||||||
return $this->fractal->collection($users)
|
return $this->fractal->collection($users)
|
||||||
->transformWith($this->getTransformer(UserTransformer::class))
|
->transformWith(UserTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a request to view a single user. Includes any relations that
|
* Handle a request to view a single user. Includes any relations that
|
||||||
* were defined in the request.
|
* 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)
|
return $this->fractal->item($user)
|
||||||
->transformWith($this->getTransformer(UserTransformer::class))
|
->transformWith(UserTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,16 +90,16 @@ class UserController extends ApplicationApiController
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function update(UpdateUserRequest $request, User $user): array
|
public function update(UpdateUserRequest $request, User $user): array
|
||||||
{
|
{
|
||||||
$this->updateService->setUserLevel(User::USER_LEVEL_ADMIN);
|
$this->updateService->setUserLevel(User::USER_LEVEL_ADMIN);
|
||||||
$user = $this->updateService->handle($user, $request->validated());
|
$user = $this->updateService->handle($user, $request->validated());
|
||||||
|
|
||||||
$response = $this->fractal->item($user)
|
return $this->fractal->item($user)
|
||||||
->transformWith($this->getTransformer(UserTransformer::class));
|
->transformWith(UserTransformer::class)
|
||||||
|
->toArray();
|
||||||
return $response->toArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,7 +114,7 @@ class UserController extends ApplicationApiController
|
||||||
$user = $this->creationService->handle($request->validated());
|
$user = $this->creationService->handle($request->validated());
|
||||||
|
|
||||||
return $this->fractal->item($user)
|
return $this->fractal->item($user)
|
||||||
->transformWith($this->getTransformer(UserTransformer::class))
|
->transformWith(UserTransformer::class)
|
||||||
->addMeta([
|
->addMeta([
|
||||||
'resource' => route('api.application.users.view', [
|
'resource' => route('api.application.users.view', [
|
||||||
'user' => $user->id,
|
'user' => $user->id,
|
||||||
|
@ -133,10 +129,10 @@ class UserController extends ApplicationApiController
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
*/
|
*/
|
||||||
public function delete(DeleteUserRequest $request, User $user): JsonResponse
|
public function delete(DeleteUserRequest $request, User $user): Response
|
||||||
{
|
{
|
||||||
$this->deletionService->handle($user);
|
$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\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Auth\AuthManager;
|
use Illuminate\Auth\AuthManager;
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
use Pterodactyl\Services\Users\UserUpdateService;
|
use Pterodactyl\Services\Users\UserUpdateService;
|
||||||
use Pterodactyl\Transformers\Api\Client\AccountTransformer;
|
use Pterodactyl\Transformers\Api\Client\AccountTransformer;
|
||||||
use Pterodactyl\Http\Requests\Api\Client\Account\UpdateEmailRequest;
|
use Pterodactyl\Http\Requests\Api\Client\Account\UpdateEmailRequest;
|
||||||
|
@ -13,31 +12,29 @@ use Pterodactyl\Http\Requests\Api\Client\Account\UpdatePasswordRequest;
|
||||||
|
|
||||||
class AccountController extends ClientApiController
|
class AccountController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private AuthManager $authManager;
|
||||||
* @var \Pterodactyl\Services\Users\UserUpdateService
|
private UserUpdateService $updateService;
|
||||||
*/
|
|
||||||
private $updateService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Auth\SessionGuard
|
|
||||||
*/
|
|
||||||
private $sessionGuard;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(AuthManager $sessionGuard, UserUpdateService $updateService)
|
public function __construct(AuthManager $authManager, UserUpdateService $updateService)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->authManager = $authManager;
|
||||||
$this->updateService = $updateService;
|
$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
|
public function index(Request $request): array
|
||||||
{
|
{
|
||||||
return $this->fractal->item($request->user())
|
return $this->fractal->item($request->user())
|
||||||
->transformWith($this->getTransformer(AccountTransformer::class))
|
->transformWith(AccountTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,11 +44,11 @@ class AccountController extends ClientApiController
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function updateEmail(UpdateEmailRequest $request): JsonResponse
|
public function updateEmail(UpdateEmailRequest $request): Response
|
||||||
{
|
{
|
||||||
$this->updateService->handle($request->user(), $request->validated());
|
$this->updateService->handle($request->user(), $request->validated());
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return $this->returnNoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,12 +58,12 @@ class AccountController extends ClientApiController
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function updatePassword(UpdatePasswordRequest $request): JsonResponse
|
public function updatePassword(UpdatePasswordRequest $request): Response
|
||||||
{
|
{
|
||||||
$this->updateService->handle($request->user(), $request->validated());
|
$this->updateService->handle($request->user(), $request->validated());
|
||||||
|
|
||||||
$this->sessionGuard->logoutOtherDevices($request->input('password'));
|
$this->authManager->logoutOtherDevices($request->input('password'));
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return $this->returnNoContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,106 +2,57 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Api\Client;
|
namespace Pterodactyl\Http\Controllers\Api\Client;
|
||||||
|
|
||||||
use Pterodactyl\Models\ApiKey;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
use Illuminate\Contracts\Encryption\Encrypter;
|
use Pterodactyl\Http\Requests\Api\Client\AccountApiRequest;
|
||||||
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\Account\StoreApiKeyRequest;
|
use Pterodactyl\Http\Requests\Api\Client\Account\StoreApiKeyRequest;
|
||||||
|
use Pterodactyl\Transformers\Api\Client\PersonalAccessTokenTransformer;
|
||||||
|
|
||||||
class ApiKeyController extends ClientApiController
|
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.
|
* 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)
|
return $this->fractal->collection($request->user()->tokens)
|
||||||
->transformWith($this->getTransformer(ApiKeyTransformer::class))
|
->transformWith(PersonalAccessTokenTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a new API key for a user's account.
|
* Store a new API key for a user's account.
|
||||||
*
|
*
|
||||||
* @return array
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @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.');
|
throw new DisplayException('You have reached the account limit for number of API keys.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$key = $this->keyCreationService->setKeyType(ApiKey::TYPE_ACCOUNT)->handle([
|
// TODO: this should accept an array of different scopes to apply as permissions
|
||||||
'user_id' => $request->user()->id,
|
// for the token. Right now it allows any account level permission.
|
||||||
'memo' => $request->input('description'),
|
$token = $request->user()->createToken($request->input('description'));
|
||||||
'allowed_ips' => $request->input('allowed_ips') ?? [],
|
|
||||||
]);
|
|
||||||
|
|
||||||
return $this->fractal->item($key)
|
return $this->fractal->item($token->accessToken)
|
||||||
->transformWith($this->getTransformer(ApiKeyTransformer::class))
|
->transformWith(PersonalAccessTokenTransformer::class)
|
||||||
->addMeta([
|
->addMeta([
|
||||||
'secret_token' => $this->encrypter->decrypt($key->token),
|
'secret_token' => $token->plainTextToken,
|
||||||
])
|
])
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a given API key.
|
* 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([
|
$request->user()->tokens()->where('token_id', $id)->delete();
|
||||||
'key_type' => ApiKey::TYPE_ACCOUNT,
|
|
||||||
'user_id' => $request->user()->id,
|
|
||||||
'identifier' => $identifier,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!$response) {
|
return $this->returnNoContent();
|
||||||
throw new NotFoundHttpException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return JsonResponse::create([], JsonResponse::HTTP_NO_CONTENT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,7 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Api\Client;
|
namespace Pterodactyl\Http\Controllers\Api\Client;
|
||||||
|
|
||||||
use Webmozart\Assert\Assert;
|
use Pterodactyl\Transformers\Api\Transformer;
|
||||||
use Illuminate\Container\Container;
|
|
||||||
use Pterodactyl\Transformers\Daemon\BaseDaemonTransformer;
|
|
||||||
use Pterodactyl\Transformers\Api\Client\BaseClientTransformer;
|
|
||||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
|
||||||
abstract class ClientApiController extends ApplicationApiController
|
abstract class ClientApiController extends ApplicationApiController
|
||||||
|
@ -15,7 +12,7 @@ abstract class ClientApiController extends ApplicationApiController
|
||||||
*
|
*
|
||||||
* @return string[]
|
* @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) {
|
$filtered = array_filter($this->parseIncludes(), function ($datum) use ($transformer) {
|
||||||
return in_array($datum, $transformer->getAvailableIncludes());
|
return in_array($datum, $transformer->getAvailableIncludes());
|
||||||
|
@ -29,7 +26,7 @@ abstract class ClientApiController extends ApplicationApiController
|
||||||
*
|
*
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
protected function parseIncludes()
|
protected function parseIncludes(): array
|
||||||
{
|
{
|
||||||
$includes = $this->request->query('include') ?? [];
|
$includes = $this->request->query('include') ?? [];
|
||||||
|
|
||||||
|
@ -41,26 +38,4 @@ abstract class ClientApiController extends ApplicationApiController
|
||||||
return trim($item);
|
return trim($item);
|
||||||
}, explode(',', $includes));
|
}, 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
|
class ClientController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private ServerRepository $repository;
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClientController constructor.
|
* ClientController constructor.
|
||||||
|
@ -31,15 +28,16 @@ class ClientController extends ClientApiController
|
||||||
/**
|
/**
|
||||||
* Return all of the servers available to the client making the API
|
* Return all of the servers available to the client making the API
|
||||||
* request, including servers the user has access to as a subuser.
|
* request, including servers the user has access to as a subuser.
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function index(GetServersRequest $request): array
|
public function index(GetServersRequest $request): array
|
||||||
{
|
{
|
||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
$transformer = $this->getTransformer(ServerTransformer::class);
|
|
||||||
|
|
||||||
// Start the query builder and ensure we eager load any requested relationships from the request.
|
// Start the query builder and ensure we eager load any requested relationships from the request.
|
||||||
$builder = QueryBuilder::for(
|
$builder = QueryBuilder::for(
|
||||||
Server::query()->with($this->getIncludesForTransformer($transformer, ['node']))
|
Server::query()->with($this->getIncludesForTransformer(new ServerTransformer(), ['node']))
|
||||||
)->allowedFilters([
|
)->allowedFilters([
|
||||||
'uuid',
|
'uuid',
|
||||||
'name',
|
'name',
|
||||||
|
@ -70,15 +68,13 @@ class ClientController extends ClientApiController
|
||||||
|
|
||||||
$servers = $builder->paginate(min($request->query('per_page', 50), 100))->appends($request->query());
|
$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.
|
* Returns all of the subuser permissions available on the system.
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function permissions()
|
public function permissions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'object' => 'system_permissions',
|
'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;
|
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use Pterodactyl\Models\Backup;
|
use Pterodactyl\Models\Backup;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Pterodactyl\Models\AuditLog;
|
use Pterodactyl\Models\AuditLog;
|
||||||
|
@ -11,8 +12,8 @@ use Pterodactyl\Models\Permission;
|
||||||
use Illuminate\Auth\Access\AuthorizationException;
|
use Illuminate\Auth\Access\AuthorizationException;
|
||||||
use Pterodactyl\Services\Backups\DeleteBackupService;
|
use Pterodactyl\Services\Backups\DeleteBackupService;
|
||||||
use Pterodactyl\Services\Backups\DownloadLinkService;
|
use Pterodactyl\Services\Backups\DownloadLinkService;
|
||||||
use Pterodactyl\Services\Backups\InitiateBackupService;
|
|
||||||
use Pterodactyl\Repositories\Eloquent\BackupRepository;
|
use Pterodactyl\Repositories\Eloquent\BackupRepository;
|
||||||
|
use Pterodactyl\Services\Backups\InitiateBackupService;
|
||||||
use Pterodactyl\Repositories\Wings\DaemonBackupRepository;
|
use Pterodactyl\Repositories\Wings\DaemonBackupRepository;
|
||||||
use Pterodactyl\Transformers\Api\Client\BackupTransformer;
|
use Pterodactyl\Transformers\Api\Client\BackupTransformer;
|
||||||
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
||||||
|
@ -51,6 +52,7 @@ class BackupController extends ClientApiController
|
||||||
* result set.
|
* result set.
|
||||||
*
|
*
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function index(Request $request, Server $server): array
|
public function index(Request $request, Server $server): array
|
||||||
{
|
{
|
||||||
|
@ -61,7 +63,7 @@ class BackupController extends ClientApiController
|
||||||
$limit = min($request->query('per_page') ?? 20, 50);
|
$limit = min($request->query('per_page') ?? 20, 50);
|
||||||
|
|
||||||
return $this->fractal->collection($server->backups()->paginate($limit))
|
return $this->fractal->collection($server->backups()->paginate($limit))
|
||||||
->transformWith($this->getTransformer(BackupTransformer::class))
|
->transformWith(BackupTransformer::class)
|
||||||
->addMeta([
|
->addMeta([
|
||||||
'backup_count' => $this->repository->getNonFailedBackups($server)->count(),
|
'backup_count' => $this->repository->getNonFailedBackups($server)->count(),
|
||||||
])
|
])
|
||||||
|
@ -98,7 +100,7 @@ class BackupController extends ClientApiController
|
||||||
});
|
});
|
||||||
|
|
||||||
return $this->fractal->item($backup)
|
return $this->fractal->item($backup)
|
||||||
->transformWith($this->getTransformer(BackupTransformer::class))
|
->transformWith(BackupTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +126,7 @@ class BackupController extends ClientApiController
|
||||||
$backup->refresh();
|
$backup->refresh();
|
||||||
|
|
||||||
return $this->fractal->item($backup)
|
return $this->fractal->item($backup)
|
||||||
->transformWith($this->getTransformer(BackupTransformer::class))
|
->transformWith(BackupTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +142,7 @@ class BackupController extends ClientApiController
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->fractal->item($backup)
|
return $this->fractal->item($backup)
|
||||||
->transformWith($this->getTransformer(BackupTransformer::class))
|
->transformWith(BackupTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +152,7 @@ class BackupController extends ClientApiController
|
||||||
*
|
*
|
||||||
* @throws \Throwable
|
* @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)) {
|
if (!$request->user()->can(Permission::ACTION_BACKUP_DELETE, $server)) {
|
||||||
throw new AuthorizationException();
|
throw new AuthorizationException();
|
||||||
|
@ -162,7 +164,7 @@ class BackupController extends ClientApiController
|
||||||
$this->deleteBackupService->handle($backup);
|
$this->deleteBackupService->handle($backup);
|
||||||
});
|
});
|
||||||
|
|
||||||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
return $this->returnNoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -205,7 +207,7 @@ class BackupController extends ClientApiController
|
||||||
*
|
*
|
||||||
* @throws \Throwable
|
* @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)) {
|
if (!$request->user()->can(Permission::ACTION_BACKUP_RESTORE, $server)) {
|
||||||
throw new AuthorizationException();
|
throw new AuthorizationException();
|
||||||
|
@ -237,6 +239,6 @@ class BackupController extends ClientApiController
|
||||||
$this->daemonRepository->setServer($server)->restore($backup, $url ?? null, $request->input('truncate'));
|
$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
|
class CommandController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private DaemonCommandRepository $repository;
|
||||||
* @var \Pterodactyl\Repositories\Wings\DaemonCommandRepository
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CommandController constructor.
|
* CommandController constructor.
|
||||||
|
|
|
@ -18,25 +18,10 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Databases\RotatePasswordRequest
|
||||||
|
|
||||||
class DatabaseController extends ClientApiController
|
class DatabaseController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private DeployServerDatabaseService $deployDatabaseService;
|
||||||
* @var \Pterodactyl\Services\Databases\DeployServerDatabaseService
|
private DatabaseRepository $repository;
|
||||||
*/
|
private DatabaseManagementService $managementService;
|
||||||
private $deployDatabaseService;
|
private DatabasePasswordService $passwordService;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\DatabaseRepository
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Databases\DatabaseManagementService
|
|
||||||
*/
|
|
||||||
private $managementService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Databases\DatabasePasswordService
|
|
||||||
*/
|
|
||||||
private $passwordService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DatabaseController constructor.
|
* DatabaseController constructor.
|
||||||
|
@ -57,11 +42,13 @@ class DatabaseController extends ClientApiController
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all of the databases that belong to the given server.
|
* Return all of the databases that belong to the given server.
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function index(GetDatabasesRequest $request, Server $server): array
|
public function index(GetDatabasesRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
return $this->fractal->collection($server->databases)
|
return $this->fractal->collection($server->databases)
|
||||||
->transformWith($this->getTransformer(DatabaseTransformer::class))
|
->transformWith(DatabaseTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +65,7 @@ class DatabaseController extends ClientApiController
|
||||||
|
|
||||||
return $this->fractal->item($database)
|
return $this->fractal->item($database)
|
||||||
->parseIncludes(['password'])
|
->parseIncludes(['password'])
|
||||||
->transformWith($this->getTransformer(DatabaseTransformer::class))
|
->transformWith(DatabaseTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,30 +73,28 @@ class DatabaseController extends ClientApiController
|
||||||
* Rotates the password for the given server model and returns a fresh instance to
|
* Rotates the password for the given server model and returns a fresh instance to
|
||||||
* the caller.
|
* the caller.
|
||||||
*
|
*
|
||||||
* @return array
|
|
||||||
*
|
|
||||||
* @throws \Throwable
|
* @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);
|
$this->passwordService->handle($database);
|
||||||
$database->refresh();
|
$database->refresh();
|
||||||
|
|
||||||
return $this->fractal->item($database)
|
return $this->fractal->item($database)
|
||||||
->parseIncludes(['password'])
|
->parseIncludes(['password'])
|
||||||
->transformWith($this->getTransformer(DatabaseTransformer::class))
|
->transformWith(DatabaseTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a database from the server.
|
* Removes a database from the server.
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function delete(DeleteDatabaseRequest $request, Server $server, Database $database): Response
|
public function delete(DeleteDatabaseRequest $request, Server $server, Database $database): Response
|
||||||
{
|
{
|
||||||
$this->managementService->delete($database);
|
$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 Illuminate\Http\Response;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Pterodactyl\Models\AuditLog;
|
use Pterodactyl\Models\AuditLog;
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
use Pterodactyl\Services\Nodes\NodeJWTService;
|
use Pterodactyl\Services\Nodes\NodeJWTService;
|
||||||
use Illuminate\Contracts\Routing\ResponseFactory;
|
use Illuminate\Contracts\Routing\ResponseFactory;
|
||||||
use Pterodactyl\Repositories\Wings\DaemonFileRepository;
|
use Pterodactyl\Repositories\Wings\DaemonFileRepository;
|
||||||
|
@ -26,28 +25,17 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Files\WriteFileContentRequest;
|
||||||
|
|
||||||
class FileController extends ClientApiController
|
class FileController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private DaemonFileRepository $fileRepository;
|
||||||
* @var \Pterodactyl\Repositories\Wings\DaemonFileRepository
|
private ResponseFactory $responseFactory;
|
||||||
*/
|
private NodeJWTService $jwtService;
|
||||||
private $fileRepository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Contracts\Routing\ResponseFactory
|
|
||||||
*/
|
|
||||||
private $responseFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Nodes\NodeJWTService
|
|
||||||
*/
|
|
||||||
private $jwtService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FileController constructor.
|
* FileController constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
DaemonFileRepository $fileRepository,
|
||||||
ResponseFactory $responseFactory,
|
ResponseFactory $responseFactory,
|
||||||
NodeJWTService $jwtService,
|
NodeJWTService $jwtService
|
||||||
DaemonFileRepository $fileRepository
|
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
@ -60,6 +48,7 @@ class FileController extends ClientApiController
|
||||||
* Returns a listing of files in a given directory.
|
* Returns a listing of files in a given directory.
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function directory(ListFilesRequest $request, Server $server): array
|
public function directory(ListFilesRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
|
@ -68,7 +57,7 @@ class FileController extends ClientApiController
|
||||||
->getDirectory($request->get('directory') ?? '/');
|
->getDirectory($request->get('directory') ?? '/');
|
||||||
|
|
||||||
return $this->fractal->collection($contents)
|
return $this->fractal->collection($contents)
|
||||||
->transformWith($this->getTransformer(FileObjectTransformer::class))
|
->transformWith(FileObjectTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,11 +80,9 @@ class FileController extends ClientApiController
|
||||||
* Generates a one-time token with a link that the user can use to
|
* Generates a one-time token with a link that the user can use to
|
||||||
* download a given file.
|
* download a given file.
|
||||||
*
|
*
|
||||||
* @return array
|
|
||||||
*
|
|
||||||
* @throws \Throwable
|
* @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) {
|
$token = $server->audit(AuditLog::SERVER__FILESYSTEM_DOWNLOAD, function (AuditLog $audit, Server $server) use ($request) {
|
||||||
$audit->metadata = ['file' => $request->get('file')];
|
$audit->metadata = ['file' => $request->get('file')];
|
||||||
|
@ -124,9 +111,9 @@ class FileController extends ClientApiController
|
||||||
/**
|
/**
|
||||||
* Writes the contents of the specified file to the server.
|
* 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) {
|
$server->audit(AuditLog::SERVER__FILESYSTEM_WRITE, function (AuditLog $audit, Server $server) use ($request) {
|
||||||
$audit->subaction = 'write_content';
|
$audit->subaction = 'write_content';
|
||||||
|
@ -137,7 +124,7 @@ class FileController extends ClientApiController
|
||||||
->putContent($request->get('file'), $request->getContent());
|
->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
|
* @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) {
|
$server->audit(AuditLog::SERVER__FILESYSTEM_WRITE, function (AuditLog $audit, Server $server) use ($request) {
|
||||||
$audit->subaction = 'create_folder';
|
$audit->subaction = 'create_folder';
|
||||||
|
@ -156,7 +143,7 @@ class FileController extends ClientApiController
|
||||||
->createDirectory($request->input('name'), $request->input('root', '/'));
|
->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
|
* @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) {
|
$server->audit(AuditLog::SERVER__FILESYSTEM_RENAME, function (AuditLog $audit, Server $server) use ($request) {
|
||||||
$audit->metadata = ['root' => $request->input('root'), 'files' => $request->input('files')];
|
$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'));
|
->renameFiles($request->input('root'), $request->input('files'));
|
||||||
});
|
});
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return $this->returnNoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies a file on the server.
|
* 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) {
|
$server->audit(AuditLog::SERVER__FILESYSTEM_WRITE, function (AuditLog $audit, Server $server) use ($request) {
|
||||||
$audit->subaction = 'copy_file';
|
$audit->subaction = 'copy_file';
|
||||||
|
@ -193,11 +180,11 @@ class FileController extends ClientApiController
|
||||||
->copyFile($request->input('location'));
|
->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
|
public function compress(CompressFilesRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
|
@ -215,14 +202,14 @@ class FileController extends ClientApiController
|
||||||
});
|
});
|
||||||
|
|
||||||
return $this->fractal->item($file)
|
return $this->fractal->item($file)
|
||||||
->transformWith($this->getTransformer(FileObjectTransformer::class))
|
->transformWith(FileObjectTransformer::class)
|
||||||
->toArray();
|
->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) {
|
$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.
|
// 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'));
|
->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.
|
* 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) {
|
$server->audit(AuditLog::SERVER__FILESYSTEM_DELETE, function (AuditLog $audit, Server $server) use ($request) {
|
||||||
$audit->metadata = ['root' => $request->input('root'), 'files' => $request->input('files')];
|
$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.
|
* 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
|
||||||
{
|
{
|
||||||
|
$server->audit(AuditLog::SERVER__FILESYSTEM_CHMOD, function (AuditLog $audit, Server $server) use ($request) {
|
||||||
|
$audit->metadata = ['directory' => $request->input('root'), 'files' => $request->input('files')];
|
||||||
|
|
||||||
$this->fileRepository->setServer($server)
|
$this->fileRepository->setServer($server)
|
||||||
->chmodFiles(
|
->chmodFiles(
|
||||||
$request->input('root'),
|
$request->input('root'),
|
||||||
$request->input('files')
|
$request->input('files'),
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return $this->returnNoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests that a file be downloaded from a remote location by Wings.
|
* Requests that a file be downloaded from a remote location by Wings.
|
||||||
*
|
*
|
||||||
* @param $request
|
|
||||||
*
|
|
||||||
* @throws \Throwable
|
* @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) {
|
$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
|
class FileUploadController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private NodeJWTService $jwtService;
|
||||||
* @var \Pterodactyl\Services\Nodes\NodeJWTService
|
|
||||||
*/
|
|
||||||
private $jwtService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FileUploadController constructor.
|
* FileUploadController constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(NodeJWTService $jwtService)
|
||||||
NodeJWTService $jwtService
|
{
|
||||||
) {
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->jwtService = $jwtService;
|
$this->jwtService = $jwtService;
|
||||||
|
@ -30,10 +26,8 @@ class FileUploadController extends ClientApiController
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a url where files can be uploaded to.
|
* 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([
|
return new JsonResponse([
|
||||||
'object' => 'signed_url',
|
'object' => 'signed_url',
|
||||||
|
@ -45,13 +39,11 @@ class FileUploadController extends ClientApiController
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a url where files can be uploaded to.
|
* 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
|
$token = $this->jwtService
|
||||||
->setExpiresAt(CarbonImmutable::now()->addMinutes(15))
|
->setExpiresAt(CarbonImmutable::now()->addMinutes(15)->toDateTimeImmutable())
|
||||||
->setClaims([
|
->setClaims([
|
||||||
'server_uuid' => $server->uuid,
|
'server_uuid' => $server->uuid,
|
||||||
])
|
])
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
|
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
use Pterodactyl\Models\Allocation;
|
use Pterodactyl\Models\Allocation;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||||
|
@ -19,20 +19,9 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Network\SetPrimaryAllocationReq
|
||||||
|
|
||||||
class NetworkAllocationController extends ClientApiController
|
class NetworkAllocationController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private AllocationRepository $repository;
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\AllocationRepository
|
private ServerRepository $serverRepository;
|
||||||
*/
|
private FindAssignableAllocationService $assignableAllocationService;
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
|
||||||
*/
|
|
||||||
private $serverRepository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Allocations\FindAssignableAllocationService
|
|
||||||
*/
|
|
||||||
private $assignableAllocationService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NetworkController constructor.
|
* 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.
|
* not they are currently assigned as the primary for this server.
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function index(GetNetworkRequest $request, Server $server): array
|
public function index(GetNetworkRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
return $this->fractal->collection($server->allocations)
|
return $this->fractal->collection($server->allocations)
|
||||||
->transformWith($this->getTransformer(AllocationTransformer::class))
|
->transformWith(AllocationTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +56,7 @@ class NetworkAllocationController extends ClientApiController
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function update(UpdateAllocationRequest $request, Server $server, Allocation $allocation): array
|
public function update(UpdateAllocationRequest $request, Server $server, Allocation $allocation): array
|
||||||
{
|
{
|
||||||
|
@ -73,7 +65,7 @@ class NetworkAllocationController extends ClientApiController
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $this->fractal->item($allocation)
|
return $this->fractal->item($allocation)
|
||||||
->transformWith($this->getTransformer(AllocationTransformer::class))
|
->transformWith(AllocationTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,21 +74,22 @@ class NetworkAllocationController extends ClientApiController
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function setPrimary(SetPrimaryAllocationRequest $request, Server $server, Allocation $allocation): array
|
public function setPrimary(SetPrimaryAllocationRequest $request, Server $server, Allocation $allocation): array
|
||||||
{
|
{
|
||||||
$this->serverRepository->update($server->id, ['allocation_id' => $allocation->id]);
|
$this->serverRepository->update($server->id, ['allocation_id' => $allocation->id]);
|
||||||
|
|
||||||
return $this->fractal->item($allocation)
|
return $this->fractal->item($allocation)
|
||||||
->transformWith($this->getTransformer(AllocationTransformer::class))
|
->transformWith(AllocationTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the notes for the allocation for a server.
|
* Set the notes for the allocation for a server.
|
||||||
*s.
|
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function store(NewAllocationRequest $request, Server $server): array
|
public function store(NewAllocationRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
|
@ -107,18 +100,16 @@ class NetworkAllocationController extends ClientApiController
|
||||||
$allocation = $this->assignableAllocationService->handle($server);
|
$allocation = $this->assignableAllocationService->handle($server);
|
||||||
|
|
||||||
return $this->fractal->item($allocation)
|
return $this->fractal->item($allocation)
|
||||||
->transformWith($this->getTransformer(AllocationTransformer::class))
|
->transformWith(AllocationTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete an allocation from a server.
|
* Delete an allocation from a server.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @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) {
|
if ($allocation->id === $server->allocation_id) {
|
||||||
throw new DisplayException('You cannot delete the primary allocation for this server.');
|
throw new DisplayException('You cannot delete the primary allocation for this server.');
|
||||||
|
@ -129,6 +120,6 @@ class NetworkAllocationController extends ClientApiController
|
||||||
'server_id' => null,
|
'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
|
class PowerController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private DaemonPowerRepository $repository;
|
||||||
* @var \Pterodactyl\Repositories\Wings\DaemonPowerRepository
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PowerController constructor.
|
* PowerController constructor.
|
||||||
|
|
|
@ -12,15 +12,8 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\GetServerRequest;
|
||||||
|
|
||||||
class ResourceUtilizationController extends ClientApiController
|
class ResourceUtilizationController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Repositories\Wings\DaemonServerRepository
|
|
||||||
*/
|
|
||||||
private DaemonServerRepository $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Cache\Repository
|
|
||||||
*/
|
|
||||||
private Repository $cache;
|
private Repository $cache;
|
||||||
|
private DaemonServerRepository $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ResourceUtilizationController constructor.
|
* ResourceUtilizationController constructor.
|
||||||
|
@ -39,6 +32,7 @@ class ResourceUtilizationController extends ClientApiController
|
||||||
* a flood of unnecessary API calls.
|
* a flood of unnecessary API calls.
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function __invoke(GetServerRequest $request, Server $server): array
|
public function __invoke(GetServerRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
|
@ -48,7 +42,7 @@ class ResourceUtilizationController extends ClientApiController
|
||||||
});
|
});
|
||||||
|
|
||||||
return $this->fractal->item($stats)
|
return $this->fractal->item($stats)
|
||||||
->transformWith($this->getTransformer(StatsTransformer::class))
|
->transformWith(StatsTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,13 @@ use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Pterodactyl\Models\Schedule;
|
use Pterodactyl\Models\Schedule;
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
use Pterodactyl\Helpers\Utilities;
|
use Pterodactyl\Helpers\Utilities;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
use Pterodactyl\Repositories\Eloquent\ScheduleRepository;
|
use Pterodactyl\Repositories\Eloquent\ScheduleRepository;
|
||||||
use Pterodactyl\Services\Schedules\ProcessScheduleService;
|
use Pterodactyl\Services\Schedules\ProcessScheduleService;
|
||||||
use Pterodactyl\Transformers\Api\Client\ScheduleTransformer;
|
use Pterodactyl\Transformers\Api\Client\ScheduleTransformer;
|
||||||
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
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\ViewScheduleRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\StoreScheduleRequest;
|
use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\StoreScheduleRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\DeleteScheduleRequest;
|
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
|
class ScheduleController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private ScheduleRepository $repository;
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\ScheduleRepository
|
private ProcessScheduleService $service;
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Schedules\ProcessScheduleService
|
|
||||||
*/
|
|
||||||
private $service;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ScheduleController constructor.
|
* ScheduleController constructor.
|
||||||
|
@ -48,27 +40,26 @@ class ScheduleController extends ClientApiController
|
||||||
/**
|
/**
|
||||||
* Returns all of the schedules belonging to a given server.
|
* 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 = $server->schedule;
|
||||||
$schedules->loadMissing('tasks');
|
$schedules->loadMissing('tasks');
|
||||||
|
|
||||||
return $this->fractal->collection($schedules)
|
return $this->fractal->collection($schedules)
|
||||||
->transformWith($this->getTransformer(ScheduleTransformer::class))
|
->transformWith(ScheduleTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a new schedule for a server.
|
* Store a new schedule for a server.
|
||||||
*
|
*
|
||||||
* @return array
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @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 */
|
/** @var \Pterodactyl\Models\Schedule $model */
|
||||||
$model = $this->repository->create([
|
$model = $this->repository->create([
|
||||||
|
@ -85,38 +76,33 @@ class ScheduleController extends ClientApiController
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $this->fractal->item($model)
|
return $this->fractal->item($model)
|
||||||
->transformWith($this->getTransformer(ScheduleTransformer::class))
|
->transformWith(ScheduleTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a specific schedule for the server.
|
* 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');
|
$schedule->loadMissing('tasks');
|
||||||
|
|
||||||
return $this->fractal->item($schedule)
|
return $this->fractal->item($schedule)
|
||||||
->transformWith($this->getTransformer(ScheduleTransformer::class))
|
->transformWith(ScheduleTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a given schedule with the new data provided.
|
* Updates a given schedule with the new data provided.
|
||||||
*
|
*
|
||||||
* @return array
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @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');
|
$active = (bool) $request->input('is_active');
|
||||||
|
|
||||||
|
@ -143,7 +129,7 @@ class ScheduleController extends ClientApiController
|
||||||
$this->repository->update($schedule->id, $data);
|
$this->repository->update($schedule->id, $data);
|
||||||
|
|
||||||
return $this->fractal->item($schedule->refresh())
|
return $this->fractal->item($schedule->refresh())
|
||||||
->transformWith($this->getTransformer(ScheduleTransformer::class))
|
->transformWith(ScheduleTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,27 +137,27 @@ class ScheduleController extends ClientApiController
|
||||||
* Executes a given schedule immediately rather than waiting on it's normally scheduled time
|
* Executes a given schedule immediately rather than waiting on it's normally scheduled time
|
||||||
* to pass. This does not care about the schedule state.
|
* to pass. This does not care about the schedule state.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Throwable
|
* @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);
|
$this->service->handle($schedule, true);
|
||||||
|
|
||||||
return new JsonResponse([], JsonResponse::HTTP_ACCEPTED);
|
return $this->returnAccepted();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a schedule and it's associated tasks.
|
* 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);
|
$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 Illuminate\Http\Response;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Pterodactyl\Models\Schedule;
|
use Pterodactyl\Models\Schedule;
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
use Pterodactyl\Models\Permission;
|
|
||||||
use Pterodactyl\Repositories\Eloquent\TaskRepository;
|
use Pterodactyl\Repositories\Eloquent\TaskRepository;
|
||||||
use Pterodactyl\Exceptions\Http\HttpForbiddenException;
|
use Pterodactyl\Exceptions\Http\HttpForbiddenException;
|
||||||
use Pterodactyl\Transformers\Api\Client\TaskTransformer;
|
use Pterodactyl\Transformers\Api\Client\TaskTransformer;
|
||||||
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
|
|
||||||
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
||||||
use Pterodactyl\Exceptions\Service\ServiceLimitExceededException;
|
use Pterodactyl\Exceptions\Service\ServiceLimitExceededException;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\StoreTaskRequest;
|
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
|
class ScheduleTaskController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private TaskRepository $repository;
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\TaskRepository
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ScheduleTaskController constructor.
|
* ScheduleTaskController constructor.
|
||||||
|
@ -37,13 +33,12 @@ class ScheduleTaskController extends ClientApiController
|
||||||
/**
|
/**
|
||||||
* Create a new task for a given schedule and store it in the database.
|
* Create a new task for a given schedule and store it in the database.
|
||||||
*
|
*
|
||||||
* @return array
|
* @throws \Pterodactyl\Exceptions\Http\HttpForbiddenException
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Model\HttpForbiddenException
|
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Service\ServiceLimitExceededException
|
* @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);
|
$limit = config('pterodactyl.client_features.schedules.per_schedule_task_limit', 10);
|
||||||
if ($schedule->tasks()->count() >= $limit) {
|
if ($schedule->tasks()->count() >= $limit) {
|
||||||
|
@ -68,20 +63,19 @@ class ScheduleTaskController extends ClientApiController
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $this->fractal->item($task)
|
return $this->fractal->item($task)
|
||||||
->transformWith($this->getTransformer(TaskTransformer::class))
|
->transformWith(TaskTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a given task for a server.
|
* Updates a given task for a server.
|
||||||
*
|
*
|
||||||
* @return array
|
* @throws \Pterodactyl\Exceptions\Http\HttpForbiddenException
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Model\HttpForbiddenException
|
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @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) {
|
if ($schedule->id !== $task->schedule_id || $server->id !== $schedule->server_id) {
|
||||||
throw new NotFoundHttpException();
|
throw new NotFoundHttpException();
|
||||||
|
@ -99,7 +93,7 @@ class ScheduleTaskController extends ClientApiController
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $this->fractal->item($task->refresh())
|
return $this->fractal->item($task->refresh())
|
||||||
->transformWith($this->getTransformer(TaskTransformer::class))
|
->transformWith(TaskTransformer::class)
|
||||||
->toArray();
|
->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
|
* 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.
|
* 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
|
* @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([
|
$schedule->tasks()->where('sequence_id', '>', $task->sequence_id)->update([
|
||||||
'sequence_id' => $schedule->tasks()->getConnection()->raw('(sequence_id - 1)'),
|
'sequence_id' => $schedule->tasks()->getConnection()->raw('(sequence_id - 1)'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$task->delete();
|
$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
|
class ServerController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private SubuserRepository $repository;
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\SubuserRepository
|
private GetUserPermissionsService $permissionsService;
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Servers\GetUserPermissionsService
|
|
||||||
*/
|
|
||||||
private $permissionsService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServerController constructor.
|
* ServerController constructor.
|
||||||
|
@ -35,11 +28,13 @@ class ServerController extends ClientApiController
|
||||||
/**
|
/**
|
||||||
* Transform an individual server into a response that can be consumed by a
|
* Transform an individual server into a response that can be consumed by a
|
||||||
* client using the API.
|
* client using the API.
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function index(GetServerRequest $request, Server $server): array
|
public function index(GetServerRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
return $this->fractal->item($server)
|
return $this->fractal->item($server)
|
||||||
->transformWith($this->getTransformer(ServerTransformer::class))
|
->transformWith(ServerTransformer::class)
|
||||||
->addMeta([
|
->addMeta([
|
||||||
'is_server_owner' => $request->user()->id === $server->owner_id,
|
'is_server_owner' => $request->user()->id === $server->owner_id,
|
||||||
'user_permissions' => $this->permissionsService->handle($server, $request->user()),
|
'user_permissions' => $this->permissionsService->handle($server, $request->user()),
|
||||||
|
|
|
@ -4,7 +4,6 @@ namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
|
||||||
|
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||||
use Pterodactyl\Services\Servers\ReinstallServerService;
|
use Pterodactyl\Services\Servers\ReinstallServerService;
|
||||||
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
||||||
|
@ -15,15 +14,8 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Settings\ReinstallServerRequest
|
||||||
|
|
||||||
class SettingsController extends ClientApiController
|
class SettingsController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private ServerRepository $repository;
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
private ReinstallServerService $reinstallServerService;
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Servers\ReinstallServerService
|
|
||||||
*/
|
|
||||||
private $reinstallServerService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SettingsController constructor.
|
* SettingsController constructor.
|
||||||
|
@ -41,42 +33,36 @@ class SettingsController extends ClientApiController
|
||||||
/**
|
/**
|
||||||
* Renames a server.
|
* Renames a server.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @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, [
|
$this->repository->update($server->id, [
|
||||||
'name' => $request->input('name'),
|
'name' => $request->input('name'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return $this->returnNoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reinstalls the server on the daemon.
|
* Reinstalls the server on the daemon.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function reinstall(ReinstallServerRequest $request, Server $server)
|
public function reinstall(ReinstallServerRequest $request, Server $server): Response
|
||||||
{
|
{
|
||||||
$this->reinstallServerService->handle($server);
|
$this->reinstallServerService->handle($server);
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_ACCEPTED);
|
return $this->returnAccepted();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the Docker image in use by the server.
|
* Changes the Docker image in use by the server.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Throwable
|
* @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)) {
|
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.');
|
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();
|
$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
|
class StartupController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private VariableValidatorService $service;
|
||||||
* @var \Pterodactyl\Services\Servers\VariableValidatorService
|
private ServerVariableRepository $repository;
|
||||||
*/
|
private StartupCommandService $startupCommandService;
|
||||||
private $service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\ServerVariableRepository
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Servers\StartupCommandService
|
|
||||||
*/
|
|
||||||
private $startupCommandService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StartupController constructor.
|
* StartupController constructor.
|
||||||
|
@ -44,16 +33,16 @@ class StartupController extends ClientApiController
|
||||||
/**
|
/**
|
||||||
* Returns the startup information for the server including all of the variables.
|
* 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);
|
$startup = $this->startupCommandService->handle($server, false);
|
||||||
|
|
||||||
return $this->fractal->collection(
|
return $this->fractal->collection(
|
||||||
$server->variables()->where('user_viewable', true)->get()
|
$server->variables()->where('user_viewable', true)->get()
|
||||||
)
|
)
|
||||||
->transformWith($this->getTransformer(EggVariableTransformer::class))
|
->transformWith(EggVariableTransformer::class)
|
||||||
->addMeta([
|
->addMeta([
|
||||||
'startup_command' => $startup,
|
'startup_command' => $startup,
|
||||||
'docker_images' => $server->egg->docker_images,
|
'docker_images' => $server->egg->docker_images,
|
||||||
|
@ -65,13 +54,12 @@ class StartupController extends ClientApiController
|
||||||
/**
|
/**
|
||||||
* Updates a single variable for a server.
|
* Updates a single variable for a server.
|
||||||
*
|
*
|
||||||
* @return array
|
|
||||||
*
|
|
||||||
* @throws \Illuminate\Validation\ValidationException
|
* @throws \Illuminate\Validation\ValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @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 */
|
/** @var \Pterodactyl\Models\EggVariable $variable */
|
||||||
$variable = $server->variables()->where('env_variable', $request->input('key'))->first();
|
$variable = $server->variables()->where('env_variable', $request->input('key'))->first();
|
||||||
|
@ -98,7 +86,7 @@ class StartupController extends ClientApiController
|
||||||
$startup = $this->startupCommandService->handle($server, false);
|
$startup = $this->startupCommandService->handle($server, false);
|
||||||
|
|
||||||
return $this->fractal->item($variable)
|
return $this->fractal->item($variable)
|
||||||
->transformWith($this->getTransformer(EggVariableTransformer::class))
|
->transformWith(EggVariableTransformer::class)
|
||||||
->addMeta([
|
->addMeta([
|
||||||
'startup_command' => $startup,
|
'startup_command' => $startup,
|
||||||
'raw_startup_command' => $server->startup,
|
'raw_startup_command' => $server->startup,
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
|
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Pterodactyl\Models\Subuser;
|
||||||
use Pterodactyl\Models\Permission;
|
use Pterodactyl\Models\Permission;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Pterodactyl\Repositories\Eloquent\SubuserRepository;
|
use Pterodactyl\Repositories\Eloquent\SubuserRepository;
|
||||||
|
@ -20,20 +21,9 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Subusers\UpdateSubuserRequest;
|
||||||
|
|
||||||
class SubuserController extends ClientApiController
|
class SubuserController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private SubuserRepository $repository;
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\SubuserRepository
|
private SubuserCreationService $creationService;
|
||||||
*/
|
private DaemonServerRepository $serverRepository;
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Subusers\SubuserCreationService
|
|
||||||
*/
|
|
||||||
private $creationService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Repositories\Wings\DaemonServerRepository
|
|
||||||
*/
|
|
||||||
private $serverRepository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SubuserController constructor.
|
* SubuserController constructor.
|
||||||
|
@ -53,40 +43,36 @@ class SubuserController extends ClientApiController
|
||||||
/**
|
/**
|
||||||
* Return the users associated with this server instance.
|
* 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)
|
return $this->fractal->collection($server->subusers)
|
||||||
->transformWith($this->getTransformer(SubuserTransformer::class))
|
->transformWith(SubuserTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a single subuser associated with this server instance.
|
* 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)
|
return $this->fractal->item($subuser)
|
||||||
->transformWith($this->getTransformer(SubuserTransformer::class))
|
->transformWith(SubuserTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new subuser for the given server.
|
* Create a new subuser for the given server.
|
||||||
*
|
*
|
||||||
* @return array
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Service\Subuser\ServerSubuserExistsException
|
* @throws \Pterodactyl\Exceptions\Service\Subuser\ServerSubuserExistsException
|
||||||
* @throws \Pterodactyl\Exceptions\Service\Subuser\UserIsServerOwnerException
|
* @throws \Pterodactyl\Exceptions\Service\Subuser\UserIsServerOwnerException
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function store(StoreSubuserRequest $request, Server $server)
|
public function store(StoreSubuserRequest $request, Server $server): array
|
||||||
{
|
{
|
||||||
$response = $this->creationService->handle(
|
$response = $this->creationService->handle(
|
||||||
$server,
|
$server,
|
||||||
|
@ -95,7 +81,7 @@ class SubuserController extends ClientApiController
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->fractal->item($response)
|
return $this->fractal->item($response)
|
||||||
->transformWith($this->getTransformer(SubuserTransformer::class))
|
->transformWith(SubuserTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,12 +90,10 @@ class SubuserController extends ClientApiController
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @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);
|
$permissions = $this->getDefaultPermissions($request);
|
||||||
$current = $subuser->permissions;
|
$current = $subuser->permissions;
|
||||||
|
|
||||||
|
@ -133,20 +117,15 @@ class SubuserController extends ClientApiController
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->fractal->item($subuser->refresh())
|
return $this->fractal->item($subuser->refresh())
|
||||||
->transformWith($this->getTransformer(SubuserTransformer::class))
|
->transformWith(SubuserTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a subusers from a server's assignment.
|
* 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);
|
$this->repository->delete($subuser->id);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -156,7 +135,7 @@ class SubuserController extends ClientApiController
|
||||||
Log::warning($exception, ['user_id' => $subuser->user_id, 'server_id' => $server->id]);
|
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 Carbon\CarbonImmutable;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Pterodactyl\Models\Permission;
|
|
||||||
use Pterodactyl\Services\Nodes\NodeJWTService;
|
use Pterodactyl\Services\Nodes\NodeJWTService;
|
||||||
use Pterodactyl\Exceptions\Http\HttpForbiddenException;
|
use Pterodactyl\Exceptions\Http\HttpForbiddenException;
|
||||||
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
|
|
||||||
use Pterodactyl\Services\Servers\GetUserPermissionsService;
|
use Pterodactyl\Services\Servers\GetUserPermissionsService;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Client\WebsocketTokenRequest;
|
||||||
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
||||||
|
|
||||||
class WebsocketController extends ClientApiController
|
class WebsocketController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private NodeJWTService $jwtService;
|
||||||
* @var \Pterodactyl\Services\Nodes\NodeJWTService
|
private GetUserPermissionsService $permissionsService;
|
||||||
*/
|
|
||||||
private $jwtService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Servers\GetUserPermissionsService
|
|
||||||
*/
|
|
||||||
private $permissionsService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WebsocketController constructor.
|
* 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.
|
* 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
|
* 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.
|
* 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();
|
$permissions = $this->permissionsService->handle($server, $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);
|
|
||||||
|
|
||||||
$node = $server->node;
|
$node = $server->node;
|
||||||
if (!is_null($server->transfer)) {
|
if (!is_null($server->transfer)) {
|
||||||
|
@ -68,13 +53,13 @@ class WebsocketController extends ClientApiController
|
||||||
}
|
}
|
||||||
|
|
||||||
$token = $this->jwtService
|
$token = $this->jwtService
|
||||||
->setExpiresAt(CarbonImmutable::now()->addMinutes(10))
|
->setExpiresAt(CarbonImmutable::now()->addMinutes(10)->toDateTimeImmutable())
|
||||||
->setClaims([
|
->setClaims([
|
||||||
'user_id' => $request->user()->id,
|
'user_id' => $request->user()->id,
|
||||||
'server_uuid' => $server->uuid,
|
'server_uuid' => $server->uuid,
|
||||||
'permissions' => $permissions,
|
'permissions' => $permissions,
|
||||||
])
|
])
|
||||||
->handle($node, $user->id . $server->uuid);
|
->handle($node, $request->user()->id . $server->uuid);
|
||||||
|
|
||||||
$socket = str_replace(['https://', 'http://'], ['wss://', 'ws://'], $node->getConnectionAddress());
|
$socket = str_replace(['https://', 'http://'], ['wss://', 'ws://'], $node->getConnectionAddress());
|
||||||
|
|
||||||
|
|
|
@ -14,20 +14,9 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
|
|
||||||
class TwoFactorController extends ClientApiController
|
class TwoFactorController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private ToggleTwoFactorService $toggleTwoFactorService;
|
||||||
* @var \Pterodactyl\Services\Users\TwoFactorSetupService
|
private TwoFactorSetupService $setupService;
|
||||||
*/
|
private Factory $validation;
|
||||||
private $setupService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Contracts\Validation\Factory
|
|
||||||
*/
|
|
||||||
private $validation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Users\ToggleTwoFactorService
|
|
||||||
*/
|
|
||||||
private $toggleTwoFactorService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TwoFactorController constructor.
|
* TwoFactorController constructor.
|
||||||
|
@ -39,9 +28,9 @@ class TwoFactorController extends ClientApiController
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->toggleTwoFactorService = $toggleTwoFactorService;
|
||||||
$this->setupService = $setupService;
|
$this->setupService = $setupService;
|
||||||
$this->validation = $validation;
|
$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
|
* it on their account. If two-factor is already enabled this endpoint
|
||||||
* will return a 400 error.
|
* will return a 400 error.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function index(Request $request)
|
public function index(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
if ($request->user()->use_totp) {
|
if ($request->user()->use_totp) {
|
||||||
throw new BadRequestHttpException('Two-factor authentication is already enabled on this account.');
|
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.
|
* Updates a user's account to have two-factor enabled.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
* @throws \Illuminate\Validation\ValidationException
|
* @throws \Illuminate\Validation\ValidationException
|
||||||
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
|
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
|
||||||
|
@ -77,7 +62,7 @@ class TwoFactorController extends ClientApiController
|
||||||
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
|
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
|
||||||
* @throws \Pterodactyl\Exceptions\Service\User\TwoFactorAuthenticationTokenInvalid
|
* @throws \Pterodactyl\Exceptions\Service\User\TwoFactorAuthenticationTokenInvalid
|
||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$validator = $this->validation->make($request->all(), [
|
$validator = $this->validation->make($request->all(), [
|
||||||
'code' => 'required|string',
|
'code' => 'required|string',
|
||||||
|
@ -100,10 +85,8 @@ class TwoFactorController extends ClientApiController
|
||||||
/**
|
/**
|
||||||
* Disables two-factor authentication on an account if the password provided
|
* Disables two-factor authentication on an account if the password provided
|
||||||
* is valid.
|
* 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)) {
|
if (!password_verify($request->input('password') ?? '', $request->user()->password)) {
|
||||||
throw new BadRequestHttpException('The password provided was not valid.');
|
throw new BadRequestHttpException('The password provided was not valid.');
|
||||||
|
@ -117,6 +100,6 @@ class TwoFactorController extends ClientApiController
|
||||||
'use_totp' => false,
|
'use_totp' => false,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return $this->returnNoContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
125
app/Http/Controllers/Api/Client/WebauthnController.php
Normal file
125
app/Http/Controllers/Api/Client/WebauthnController.php
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Controllers\Api\Client;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Pterodactyl\Models\WebauthnKey;
|
||||||
|
use LaravelWebauthn\Facades\Webauthn;
|
||||||
|
use Webauthn\PublicKeyCredentialCreationOptions;
|
||||||
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||||
|
use Pterodactyl\Transformers\Api\Client\WebauthnKeyTransformer;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
|
|
||||||
|
class WebauthnController extends ClientApiController
|
||||||
|
{
|
||||||
|
private const SESSION_PUBLICKEY_CREATION = 'webauthn.publicKeyCreation';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ?
|
||||||
|
*
|
||||||
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
|
*/
|
||||||
|
public function index(Request $request): array
|
||||||
|
{
|
||||||
|
return $this->fractal->collection(WebauthnKey::query()->where('user_id', '=', $request->user()->id)->get())
|
||||||
|
->transformWith(WebauthnKeyTransformer::class)
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ?
|
||||||
|
*/
|
||||||
|
public function register(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
if (!Webauthn::canRegister($request->user())) {
|
||||||
|
return new JsonResponse([
|
||||||
|
'error' => [
|
||||||
|
'message' => trans('webauthn::errors.cannot_register_new_key'),
|
||||||
|
],
|
||||||
|
], JsonResponse::HTTP_FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
$publicKey = Webauthn::getRegisterData($request->user());
|
||||||
|
|
||||||
|
$request->session()->put(self::SESSION_PUBLICKEY_CREATION, $publicKey);
|
||||||
|
$request->session()->save();
|
||||||
|
|
||||||
|
return new JsonResponse([
|
||||||
|
'public_key' => $publicKey,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ?
|
||||||
|
*
|
||||||
|
* @return array|JsonResponse
|
||||||
|
*/
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
if (!Webauthn::canRegister($request->user())) {
|
||||||
|
return new JsonResponse([
|
||||||
|
'error' => [
|
||||||
|
'message' => trans('webauthn::errors.cannot_register_new_key'),
|
||||||
|
],
|
||||||
|
], JsonResponse::HTTP_FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->input('register') === null) {
|
||||||
|
throw new BadRequestHttpException('Missing register data in request body.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->input('name') === null) {
|
||||||
|
throw new BadRequestHttpException('Missing name in request body.');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$publicKey = $request->session()->pull(self::SESSION_PUBLICKEY_CREATION);
|
||||||
|
if (!$publicKey instanceof PublicKeyCredentialCreationOptions) {
|
||||||
|
throw new ModelNotFoundException(trans('webauthn::errors.create_data_not_found'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$webauthnKey = Webauthn::doRegister(
|
||||||
|
$request->user(),
|
||||||
|
$publicKey,
|
||||||
|
$request->input('register'),
|
||||||
|
$request->input('name'),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->fractal->item($webauthnKey)
|
||||||
|
->transformWith(WebauthnKeyTransformer::class)
|
||||||
|
->toArray();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return new JsonResponse([
|
||||||
|
'error' => [
|
||||||
|
'message' => $e->getMessage(),
|
||||||
|
],
|
||||||
|
], JsonResponse::HTTP_FORBIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ?
|
||||||
|
*/
|
||||||
|
public function deleteKey(Request $request, int $webauthnKeyId): JsonResponse
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
WebauthnKey::query()
|
||||||
|
->where('user_id', $request->user()->getAuthIdentifier())
|
||||||
|
->findOrFail($webauthnKeyId)
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
return new JsonResponse([
|
||||||
|
'deleted' => true,
|
||||||
|
'id' => $webauthnKeyId,
|
||||||
|
]);
|
||||||
|
} catch (ModelNotFoundException $e) {
|
||||||
|
return new JsonResponse([
|
||||||
|
'error' => [
|
||||||
|
'message' => trans('webauthn::errors.object_not_found'),
|
||||||
|
],
|
||||||
|
], JsonResponse::HTTP_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,15 +17,8 @@ class BackupRemoteUploadController extends Controller
|
||||||
{
|
{
|
||||||
public const PART_SIZE = 5 * 1024 * 1024 * 1024;
|
public const PART_SIZE = 5 * 1024 * 1024 * 1024;
|
||||||
|
|
||||||
/**
|
private BackupRepository $repository;
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\BackupRepository
|
private BackupManager $backupManager;
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Extensions\Backups\BackupManager
|
|
||||||
*/
|
|
||||||
private $backupManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BackupRemoteUploadController constructor.
|
* BackupRemoteUploadController constructor.
|
||||||
|
@ -37,15 +30,13 @@ class BackupRemoteUploadController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the required presigned urls to upload a backup to S3 cloud storage.
|
* Returns the required pre-signed urls to upload a backup to S3 cloud storage.
|
||||||
*
|
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
|
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
|
||||||
*/
|
*/
|
||||||
public function __invoke(Request $request, string $backup)
|
public function __invoke(Request $request, string $backup): JsonResponse
|
||||||
{
|
{
|
||||||
// Get the size query parameter.
|
// Get the size query parameter.
|
||||||
$size = (int) $request->query('size');
|
$size = (int) $request->query('size');
|
||||||
|
|
|
@ -4,10 +4,10 @@ namespace Pterodactyl\Http\Controllers\Api\Remote\Backups;
|
||||||
|
|
||||||
use Carbon\CarbonImmutable;
|
use Carbon\CarbonImmutable;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use Pterodactyl\Models\Backup;
|
use Pterodactyl\Models\Backup;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Pterodactyl\Models\AuditLog;
|
use Pterodactyl\Models\AuditLog;
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
use League\Flysystem\AwsS3v3\AwsS3Adapter;
|
use League\Flysystem\AwsS3v3\AwsS3Adapter;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
|
@ -17,10 +17,7 @@ use Pterodactyl\Http\Requests\Api\Remote\ReportBackupCompleteRequest;
|
||||||
|
|
||||||
class BackupStatusController extends Controller
|
class BackupStatusController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
private BackupManager $backupManager;
|
||||||
* @var \Pterodactyl\Extensions\Backups\BackupManager
|
|
||||||
*/
|
|
||||||
private $backupManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BackupStatusController constructor.
|
* BackupStatusController constructor.
|
||||||
|
@ -33,11 +30,9 @@ class BackupStatusController extends Controller
|
||||||
/**
|
/**
|
||||||
* Handles updating the state of a backup.
|
* Handles updating the state of a backup.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function index(ReportBackupCompleteRequest $request, string $backup)
|
public function index(ReportBackupCompleteRequest $request, string $backup): Response
|
||||||
{
|
{
|
||||||
/** @var \Pterodactyl\Models\Backup $model */
|
/** @var \Pterodactyl\Models\Backup $model */
|
||||||
$model = Backup::query()->where('uuid', $backup)->firstOrFail();
|
$model = Backup::query()->where('uuid', $backup)->firstOrFail();
|
||||||
|
@ -60,7 +55,7 @@ class BackupStatusController extends Controller
|
||||||
// Change the lock state to unlocked if this was a failed backup so that it can be
|
// Change the lock state to unlocked if this was a failed backup so that it can be
|
||||||
// deleted easily. Also does not make sense to have a locked backup on the system
|
// deleted easily. Also does not make sense to have a locked backup on the system
|
||||||
// that is failed.
|
// that is failed.
|
||||||
'is_locked' => $successful ? $model->is_locked : false,
|
'is_locked' => $successful && $model->is_locked,
|
||||||
'checksum' => $successful ? ($request->input('checksum_type') . ':' . $request->input('checksum')) : null,
|
'checksum' => $successful ? ($request->input('checksum_type') . ':' . $request->input('checksum')) : null,
|
||||||
'bytes' => $successful ? $request->input('size') : 0,
|
'bytes' => $successful ? $request->input('size') : 0,
|
||||||
'completed_at' => CarbonImmutable::now(),
|
'completed_at' => CarbonImmutable::now(),
|
||||||
|
@ -74,7 +69,7 @@ class BackupStatusController extends Controller
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
return new Response('', Response::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,11 +80,9 @@ class BackupStatusController extends Controller
|
||||||
* The only thing the successful field does is update the entry value for the audit logs
|
* The only thing the successful field does is update the entry value for the audit logs
|
||||||
* table tracking for this restoration.
|
* table tracking for this restoration.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function restore(Request $request, string $backup)
|
public function restore(Request $request, string $backup): Response
|
||||||
{
|
{
|
||||||
/** @var \Pterodactyl\Models\Backup $model */
|
/** @var \Pterodactyl\Models\Backup $model */
|
||||||
$model = Backup::query()->where('uuid', $backup)->firstOrFail();
|
$model = Backup::query()->where('uuid', $backup)->firstOrFail();
|
||||||
|
@ -105,7 +98,7 @@ class BackupStatusController extends Controller
|
||||||
$server->update(['status' => null]);
|
$server->update(['status' => null]);
|
||||||
});
|
});
|
||||||
|
|
||||||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
return new Response('', Response::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -10,15 +10,8 @@ use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||||
|
|
||||||
class EggInstallController extends Controller
|
class EggInstallController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
private EnvironmentService $environment;
|
||||||
* @var \Pterodactyl\Services\Servers\EnvironmentService
|
private ServerRepositoryInterface $repository;
|
||||||
*/
|
|
||||||
private $environment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EggInstallController constructor.
|
* EggInstallController constructor.
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
namespace Pterodactyl\Http\Controllers\Api\Remote\Servers;
|
namespace Pterodactyl\Http\Controllers\Api\Remote\Servers;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Pterodactyl\Models\AuditLog;
|
use Pterodactyl\Models\AuditLog;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Database\Query\Builder;
|
use Illuminate\Database\Query\Builder;
|
||||||
use Illuminate\Database\Query\JoinClause;
|
use Illuminate\Database\Query\JoinClause;
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
|
||||||
use Pterodactyl\Services\Eggs\EggConfigurationService;
|
use Pterodactyl\Services\Eggs\EggConfigurationService;
|
||||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||||
use Pterodactyl\Http\Resources\Wings\ServerConfigurationCollection;
|
use Pterodactyl\Http\Resources\Wings\ServerConfigurationCollection;
|
||||||
|
@ -17,46 +17,30 @@ use Pterodactyl\Services\Servers\ServerConfigurationStructureService;
|
||||||
|
|
||||||
class ServerDetailsController extends Controller
|
class ServerDetailsController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
private ServerRepository $repository;
|
||||||
* @var \Pterodactyl\Services\Eggs\EggConfigurationService
|
private ServerConfigurationStructureService $configurationStructureService;
|
||||||
*/
|
private EggConfigurationService $eggConfigurationService;
|
||||||
private $eggConfigurationService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
* ServerDetailsController constructor.
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Servers\ServerConfigurationStructureService
|
|
||||||
*/
|
|
||||||
private $configurationStructureService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ServerConfigurationController constructor.
|
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ServerRepository $repository,
|
ServerRepository $repository,
|
||||||
ServerConfigurationStructureService $configurationStructureService,
|
ServerConfigurationStructureService $configurationStructureService,
|
||||||
EggConfigurationService $eggConfigurationService,
|
EggConfigurationService $eggConfigurationService
|
||||||
NodeRepository $nodeRepository
|
|
||||||
) {
|
) {
|
||||||
$this->eggConfigurationService = $eggConfigurationService;
|
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
$this->configurationStructureService = $configurationStructureService;
|
$this->configurationStructureService = $configurationStructureService;
|
||||||
|
$this->eggConfigurationService = $eggConfigurationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns details about the server that allows Wings to self-recover and ensure
|
* Returns details about the server that allows Wings to self-recover and ensure
|
||||||
* that the state of the server matches the Panel at all times.
|
* that the state of the server matches the Panel at all times.
|
||||||
*
|
*
|
||||||
* @param string $uuid
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function __invoke(Request $request, $uuid)
|
public function __invoke(Request $request, string $uuid): JsonResponse
|
||||||
{
|
{
|
||||||
$server = $this->repository->getByUuid($uuid);
|
$server = $this->repository->getByUuid($uuid);
|
||||||
|
|
||||||
|
@ -68,10 +52,8 @@ class ServerDetailsController extends Controller
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists all servers with their configurations that are assigned to the requesting node.
|
* Lists all servers with their configurations that are assigned to the requesting node.
|
||||||
*
|
|
||||||
* @return \Pterodactyl\Http\Resources\Wings\ServerConfigurationCollection
|
|
||||||
*/
|
*/
|
||||||
public function list(Request $request)
|
public function list(Request $request): ServerConfigurationCollection
|
||||||
{
|
{
|
||||||
/** @var \Pterodactyl\Models\Node $node */
|
/** @var \Pterodactyl\Models\Node $node */
|
||||||
$node = $request->attributes->get('node');
|
$node = $request->attributes->get('node');
|
||||||
|
@ -93,12 +75,9 @@ class ServerDetailsController extends Controller
|
||||||
* do not get incorrectly stuck in installing/restoring from backup states since
|
* do not get incorrectly stuck in installing/restoring from backup states since
|
||||||
* a Wings reboot would completely stop those processes.
|
* a Wings reboot would completely stop those processes.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function resetState(Request $request)
|
public function resetState(Request $request): Response
|
||||||
{
|
{
|
||||||
$node = $request->attributes->get('node');
|
$node = $request->attributes->get('node');
|
||||||
|
|
||||||
|
@ -147,6 +126,6 @@ class ServerDetailsController extends Controller
|
||||||
->whereIn('status', [Server::STATUS_INSTALLING, Server::STATUS_RESTORING_BACKUP])
|
->whereIn('status', [Server::STATUS_INSTALLING, Server::STATUS_RESTORING_BACKUP])
|
||||||
->update(['status' => null]);
|
->update(['status' => null]);
|
||||||
|
|
||||||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
return new Response('', JsonResponse::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,21 +8,14 @@ use Pterodactyl\Models\Server;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||||
use Pterodactyl\Http\Requests\Api\Remote\InstallationDataRequest;
|
|
||||||
use Pterodactyl\Events\Server\Installed as ServerInstalled;
|
use Pterodactyl\Events\Server\Installed as ServerInstalled;
|
||||||
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
|
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Remote\InstallationDataRequest;
|
||||||
|
|
||||||
class ServerInstallController extends Controller
|
class ServerInstallController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
private ServerRepository $repository;
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
private EventDispatcher $eventDispatcher;
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Contracts\Events\Dispatcher
|
|
||||||
*/
|
|
||||||
private $eventDispatcher;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServerInstallController constructor.
|
* ServerInstallController constructor.
|
||||||
|
@ -36,16 +29,14 @@ class ServerInstallController extends Controller
|
||||||
/**
|
/**
|
||||||
* Returns installation information for a server.
|
* Returns installation information for a server.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function index(Request $request, string $uuid)
|
public function index(Request $request, string $uuid): JsonResponse
|
||||||
{
|
{
|
||||||
$server = $this->repository->getByUuid($uuid);
|
$server = $this->repository->getByUuid($uuid);
|
||||||
$egg = $server->egg;
|
$egg = $server->egg;
|
||||||
|
|
||||||
return JsonResponse::create([
|
return new JsonResponse([
|
||||||
'container_image' => $egg->copy_script_container,
|
'container_image' => $egg->copy_script_container,
|
||||||
'entrypoint' => $egg->copy_script_entry,
|
'entrypoint' => $egg->copy_script_entry,
|
||||||
'script' => $egg->copy_script_install,
|
'script' => $egg->copy_script_install,
|
||||||
|
@ -55,12 +46,10 @@ class ServerInstallController extends Controller
|
||||||
/**
|
/**
|
||||||
* Updates the installation state of a server.
|
* Updates the installation state of a server.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
*/
|
*/
|
||||||
public function store(InstallationDataRequest $request, string $uuid)
|
public function store(InstallationDataRequest $request, string $uuid): Response
|
||||||
{
|
{
|
||||||
$server = $this->repository->getByUuid($uuid);
|
$server = $this->repository->getByUuid($uuid);
|
||||||
|
|
||||||
|
@ -76,6 +65,6 @@ class ServerInstallController extends Controller
|
||||||
$this->eventDispatcher->dispatch(new ServerInstalled($server));
|
$this->eventDispatcher->dispatch(new ServerInstalled($server));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return new Response('', Response::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ use Carbon\CarbonImmutable;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
use Pterodactyl\Models\Allocation;
|
use Pterodactyl\Models\Allocation;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Pterodactyl\Models\ServerTransfer;
|
use Pterodactyl\Models\ServerTransfer;
|
||||||
|
@ -21,35 +20,12 @@ use Pterodactyl\Services\Servers\ServerConfigurationStructureService;
|
||||||
|
|
||||||
class ServerTransferController extends Controller
|
class ServerTransferController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
private ConnectionInterface $connection;
|
||||||
* @var \Illuminate\Database\ConnectionInterface
|
private ServerRepository $repository;
|
||||||
*/
|
private DaemonServerRepository $daemonServerRepository;
|
||||||
private $connection;
|
private DaemonTransferRepository $daemonTransferRepository;
|
||||||
|
private ServerConfigurationStructureService $configurationStructureService;
|
||||||
/**
|
private NodeJWTService $jwtService;
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Repositories\Wings\DaemonServerRepository
|
|
||||||
*/
|
|
||||||
private $daemonServerRepository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Repositories\Wings\DaemonTransferRepository
|
|
||||||
*/
|
|
||||||
private $daemonTransferRepository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Servers\ServerConfigurationStructureService
|
|
||||||
*/
|
|
||||||
private $configurationStructureService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Nodes\NodeJWTService
|
|
||||||
*/
|
|
||||||
private $jwtService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServerTransferController constructor.
|
* ServerTransferController constructor.
|
||||||
|
@ -73,12 +49,10 @@ class ServerTransferController extends Controller
|
||||||
/**
|
/**
|
||||||
* The daemon notifies us about the archive status.
|
* The daemon notifies us about the archive status.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function archive(Request $request, string $uuid)
|
public function archive(Request $request, string $uuid): Response
|
||||||
{
|
{
|
||||||
$server = $this->repository->getByUuid($uuid);
|
$server = $this->repository->getByUuid($uuid);
|
||||||
|
|
||||||
|
@ -122,17 +96,15 @@ class ServerTransferController extends Controller
|
||||||
->notify($server, $data, $server->node, $token->toString());
|
->notify($server, $data, $server->node, $token->toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return new Response('', Response::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The daemon notifies us about a transfer failure.
|
* The daemon notifies us about a transfer failure.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function failure(string $uuid)
|
public function failure(string $uuid): Response
|
||||||
{
|
{
|
||||||
$server = $this->repository->getByUuid($uuid);
|
$server = $this->repository->getByUuid($uuid);
|
||||||
|
|
||||||
|
@ -142,11 +114,9 @@ class ServerTransferController extends Controller
|
||||||
/**
|
/**
|
||||||
* The daemon notifies us about a transfer success.
|
* The daemon notifies us about a transfer success.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function success(string $uuid)
|
public function success(string $uuid): Response
|
||||||
{
|
{
|
||||||
$server = $this->repository->getByUuid($uuid);
|
$server = $this->repository->getByUuid($uuid);
|
||||||
$transfer = $server->transfer;
|
$transfer = $server->transfer;
|
||||||
|
@ -155,7 +125,9 @@ class ServerTransferController extends Controller
|
||||||
$server = $this->connection->transaction(function () use ($server, $transfer) {
|
$server = $this->connection->transaction(function () use ($server, $transfer) {
|
||||||
$allocations = [$transfer->old_allocation];
|
$allocations = [$transfer->old_allocation];
|
||||||
if (!empty($transfer->old_additional_allocations)) {
|
if (!empty($transfer->old_additional_allocations)) {
|
||||||
array_push($allocations, $transfer->old_additional_allocations);
|
foreach ($transfer->old_additional_allocations as $allocation) {
|
||||||
|
$allocations[] = $allocation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the old allocations for the server and re-assign the server to the new
|
// Remove the old allocations for the server and re-assign the server to the new
|
||||||
|
@ -173,7 +145,7 @@ class ServerTransferController extends Controller
|
||||||
});
|
});
|
||||||
|
|
||||||
// Delete the server from the old node making sure to point it to the old node so
|
// Delete the server from the old node making sure to point it to the old node so
|
||||||
// that we do not delete it from the new node the server was transfered to.
|
// that we do not delete it from the new node the server was transferred to.
|
||||||
try {
|
try {
|
||||||
$this->daemonServerRepository
|
$this->daemonServerRepository
|
||||||
->setServer($server)
|
->setServer($server)
|
||||||
|
@ -183,30 +155,30 @@ class ServerTransferController extends Controller
|
||||||
Log::warning($exception, ['transfer_id' => $server->transfer->id]);
|
Log::warning($exception, ['transfer_id' => $server->transfer->id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return new Response('', Response::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Release all of the reserved allocations for this transfer and mark it as failed in
|
* Release all of the reserved allocations for this transfer and mark it as failed in
|
||||||
* the database.
|
* the database.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*
|
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
protected function processFailedTransfer(ServerTransfer $transfer)
|
protected function processFailedTransfer(ServerTransfer $transfer): Response
|
||||||
{
|
{
|
||||||
$this->connection->transaction(function () use (&$transfer) {
|
$this->connection->transaction(function () use (&$transfer) {
|
||||||
$transfer->forceFill(['successful' => false])->saveOrFail();
|
$transfer->forceFill(['successful' => false])->saveOrFail();
|
||||||
|
|
||||||
$allocations = [$transfer->new_allocation];
|
$allocations = [$transfer->new_allocation];
|
||||||
if (!empty($transfer->new_additional_allocations)) {
|
if (!empty($transfer->new_additional_allocations)) {
|
||||||
array_push($allocations, $transfer->new_additional_allocations);
|
foreach ($transfer->new_additional_allocations as $allocation) {
|
||||||
|
$allocations[] = $allocation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Allocation::query()->whereIn('id', $allocations)->update(['server_id' => null]);
|
Allocation::query()->whereIn('id', $allocations)->update(['server_id' => null]);
|
||||||
});
|
});
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return new Response('', Response::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,28 +19,17 @@ class SftpAuthenticationController extends Controller
|
||||||
{
|
{
|
||||||
use ThrottlesLogins;
|
use ThrottlesLogins;
|
||||||
|
|
||||||
/**
|
private UserRepository $userRepository;
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\UserRepository
|
private ServerRepository $serverRepository;
|
||||||
*/
|
private GetUserPermissionsService $permissionsService;
|
||||||
private $userRepository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
* SftpAuthenticationController constructor.
|
||||||
*/
|
|
||||||
private $serverRepository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Servers\GetUserPermissionsService
|
|
||||||
*/
|
|
||||||
private $permissionsService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SftpController constructor.
|
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
GetUserPermissionsService $permissionsService,
|
|
||||||
UserRepository $userRepository,
|
UserRepository $userRepository,
|
||||||
ServerRepository $serverRepository
|
ServerRepository $serverRepository,
|
||||||
|
GetUserPermissionsService $permissionsService
|
||||||
) {
|
) {
|
||||||
$this->userRepository = $userRepository;
|
$this->userRepository = $userRepository;
|
||||||
$this->serverRepository = $serverRepository;
|
$this->serverRepository = $serverRepository;
|
||||||
|
@ -81,8 +70,14 @@ class SftpAuthenticationController extends Controller
|
||||||
['username', '=', $connection['username']],
|
['username', '=', $connection['username']],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
if ($request->input('type') === 'publicKey') {
|
||||||
|
$verified = true;
|
||||||
|
} else {
|
||||||
|
$verified = password_verify($request->input('password'), $user->password);
|
||||||
|
}
|
||||||
|
|
||||||
$server = $this->serverRepository->getByUuid($connection['server'] ?? '');
|
$server = $this->serverRepository->getByUuid($connection['server'] ?? '');
|
||||||
if (!password_verify($request->input('password'), $user->password) || $server->node_id !== $node->id) {
|
if (!$verified || $server->node_id !== $node->id) {
|
||||||
$this->incrementLoginAttempts($request);
|
$this->incrementLoginAttempts($request);
|
||||||
|
|
||||||
throw new HttpForbiddenException('Authorization credentials were not correct, please try again.');
|
throw new HttpForbiddenException('Authorization credentials were not correct, please try again.');
|
||||||
|
@ -99,9 +94,8 @@ class SftpAuthenticationController extends Controller
|
||||||
$server->validateCurrentState();
|
$server->validateCurrentState();
|
||||||
|
|
||||||
return new JsonResponse([
|
return new JsonResponse([
|
||||||
|
'ssh_keys' => $user->sshKeys->pluck('public_key')->toArray(),
|
||||||
'server' => $server->uuid,
|
'server' => $server->uuid,
|
||||||
// Deprecated, but still needed at the moment for Wings.
|
|
||||||
'token' => '',
|
|
||||||
'permissions' => $permissions ?? ['*'],
|
'permissions' => $permissions ?? ['*'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,12 +89,11 @@ abstract class AbstractLoginController extends Controller
|
||||||
|
|
||||||
$this->auth->guard()->login($user, true);
|
$this->auth->guard()->login($user, true);
|
||||||
|
|
||||||
return JsonResponse::create([
|
return new JsonResponse([
|
||||||
'data' => [
|
|
||||||
'complete' => true,
|
'complete' => true,
|
||||||
|
'methods' => [],
|
||||||
'intended' => $this->redirectPath(),
|
'intended' => $this->redirectPath(),
|
||||||
'user' => $user->toVueObject(),
|
'user' => $user->toReactObject(),
|
||||||
],
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,62 +4,34 @@ namespace Pterodactyl\Http\Controllers\Auth;
|
||||||
|
|
||||||
use Pterodactyl\Models\User;
|
use Pterodactyl\Models\User;
|
||||||
use Illuminate\Auth\AuthManager;
|
use Illuminate\Auth\AuthManager;
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
use PragmaRX\Google2FA\Google2FA;
|
use PragmaRX\Google2FA\Google2FA;
|
||||||
use Illuminate\Contracts\Config\Repository;
|
use Illuminate\Contracts\Config\Repository;
|
||||||
use Illuminate\Contracts\Encryption\Encrypter;
|
use Illuminate\Contracts\Encryption\Encrypter;
|
||||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||||
use Pterodactyl\Http\Requests\Auth\LoginCheckpointRequest;
|
use Pterodactyl\Http\Requests\Auth\LoginCheckpointRequest;
|
||||||
use Illuminate\Contracts\Cache\Repository as CacheRepository;
|
use Illuminate\Contracts\Cache\Repository as CacheRepository;
|
||||||
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
|
|
||||||
use Pterodactyl\Repositories\Eloquent\RecoveryTokenRepository;
|
|
||||||
|
|
||||||
class LoginCheckpointController extends AbstractLoginController
|
class LoginCheckpointController extends AbstractLoginController
|
||||||
{
|
{
|
||||||
/**
|
private CacheRepository $cache;
|
||||||
* @var \Illuminate\Contracts\Cache\Repository
|
private Encrypter $encrypter;
|
||||||
*/
|
private Google2FA $google2FA;
|
||||||
private $cache;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \PragmaRX\Google2FA\Google2FA
|
|
||||||
*/
|
|
||||||
private $google2FA;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Contracts\Encryption\Encrypter
|
|
||||||
*/
|
|
||||||
private $encrypter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\RecoveryTokenRepository
|
|
||||||
*/
|
|
||||||
private $recoveryTokenRepository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LoginCheckpointController constructor.
|
* LoginCheckpointController constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
AuthManager $auth,
|
AuthManager $auth,
|
||||||
Encrypter $encrypter,
|
|
||||||
Google2FA $google2FA,
|
|
||||||
Repository $config,
|
Repository $config,
|
||||||
CacheRepository $cache,
|
CacheRepository $cache,
|
||||||
RecoveryTokenRepository $recoveryTokenRepository,
|
Encrypter $encrypter,
|
||||||
UserRepositoryInterface $repository
|
Google2FA $google2FA
|
||||||
) {
|
) {
|
||||||
parent::__construct($auth, $config);
|
parent::__construct($auth, $config);
|
||||||
|
|
||||||
$this->google2FA = $google2FA;
|
|
||||||
$this->cache = $cache;
|
$this->cache = $cache;
|
||||||
$this->repository = $repository;
|
|
||||||
$this->encrypter = $encrypter;
|
$this->encrypter = $encrypter;
|
||||||
$this->recoveryTokenRepository = $recoveryTokenRepository;
|
$this->google2FA = $google2FA;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,13 +44,14 @@ class LoginCheckpointController extends AbstractLoginController
|
||||||
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
|
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
|
||||||
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
|
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
|
||||||
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
|
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
|
||||||
* @throws \Exception
|
|
||||||
* @throws \Illuminate\Validation\ValidationException
|
* @throws \Illuminate\Validation\ValidationException
|
||||||
*/
|
*/
|
||||||
public function __invoke(LoginCheckpointRequest $request): JsonResponse
|
public function __invoke(LoginCheckpointRequest $request)
|
||||||
{
|
{
|
||||||
if ($this->hasTooManyLoginAttempts($request)) {
|
if ($this->hasTooManyLoginAttempts($request)) {
|
||||||
$this->sendLockoutResponse($request);
|
$this->sendLockoutResponse($request);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$token = $request->input('confirmation_token');
|
$token = $request->input('confirmation_token');
|
||||||
|
@ -88,11 +61,13 @@ class LoginCheckpointController extends AbstractLoginController
|
||||||
} catch (ModelNotFoundException $exception) {
|
} catch (ModelNotFoundException $exception) {
|
||||||
$this->incrementLoginAttempts($request);
|
$this->incrementLoginAttempts($request);
|
||||||
|
|
||||||
return $this->sendFailedLoginResponse(
|
$this->sendFailedLoginResponse(
|
||||||
$request,
|
$request,
|
||||||
null,
|
null,
|
||||||
'The authentication token provided has expired, please refresh the page and try again.'
|
'The authentication token provided has expired, please refresh the page and try again.'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recovery tokens go through a slightly different pathway for usage.
|
// Recovery tokens go through a slightly different pathway for usage.
|
||||||
|
@ -111,8 +86,7 @@ class LoginCheckpointController extends AbstractLoginController
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->incrementLoginAttempts($request);
|
$this->incrementLoginAttempts($request);
|
||||||
|
$this->sendFailedLoginResponse($request, $user, !empty($recoveryToken) ? 'The recovery token provided is not valid.' : null);
|
||||||
return $this->sendFailedLoginResponse($request, $user, !empty($recoveryToken) ? 'The recovery token provided is not valid.' : null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue