Compare commits
465 commits
develop
...
dane/fiddl
Author | SHA1 | Date | |
---|---|---|---|
|
cd5c2bc5fd | ||
|
e02f4b8433 | ||
|
308a7f3a90 | ||
|
ae522f1585 | ||
|
ff460805c0 | ||
|
0bab962337 | ||
|
f4119df0aa | ||
|
eb56be8021 | ||
|
134ba508e2 | ||
|
0dddcfca36 | ||
|
c16fa92904 | ||
|
0e1c3a76f4 | ||
|
941cb9eda4 | ||
|
e236f74d1d | ||
|
cc43a6ec64 | ||
|
a3cdfa83f2 | ||
|
bc59ffbf37 | ||
|
4920ca41a8 | ||
|
06cc228f26 | ||
|
cb4d4b5ce6 | ||
|
4cbdaa6699 | ||
|
14c9a0a031 | ||
|
fb1f75353d | ||
|
afd0a8f768 | ||
|
b9016aa25e | ||
|
e683c0a518 | ||
|
341ff6e178 | ||
|
a4359064ca | ||
|
fac4902ccc | ||
|
d6cd0c6230 | ||
|
d9d9b1748f | ||
|
9032699deb | ||
|
b43e8835bb | ||
|
2d2352017d | ||
|
09497c234a | ||
|
54c7207836 | ||
|
969d40d6c1 | ||
|
8971e78ab5 | ||
|
cd84663ffe | ||
|
fe4d283311 | ||
|
ca6f501c70 | ||
|
b0d6be802c | ||
|
d1c9af8f04 | ||
|
6e4e0bc0a4 | ||
|
81ff03c2a3 | ||
|
9c92d51e28 | ||
|
d8da79b7fb | ||
|
ce0bc477c2 | ||
|
f7c824743f | ||
|
5359ef8407 | ||
|
34d20b2bf0 | ||
|
fad4005168 | ||
|
44f4cbc4c3 | ||
|
728adfe388 | ||
|
cdd8eabcc0 | ||
|
871d0bdd1c | ||
|
469c0b40a3 | ||
|
70cf5c17aa | ||
|
cc2ed97b0f | ||
|
c48d573cc9 | ||
|
5e99bb8dd6 | ||
|
cf1cc97340 | ||
|
bee7c4515c | ||
|
f6ac9707fa | ||
|
7f7506e5a9 | ||
|
0e870ab256 | ||
|
2948e344d2 | ||
|
b966069946 | ||
|
cddf2ce41c | ||
|
336923ec18 | ||
|
3b5fa34d85 | ||
|
a3572006cb | ||
|
8486c914ae | ||
|
85c8f4884f | ||
|
f6998018b4 | ||
|
e3aca937b5 | ||
|
00d0f49ede | ||
|
3afd8b9f03 | ||
|
fb14603e17 | ||
|
9ab8f946ec | ||
|
d945ce76f2 | ||
|
7ec78d9400 | ||
|
6814811a19 | ||
|
817a2bf8ae | ||
|
15aed3192b | ||
|
b5b65e3d81 | ||
|
fcfca0730e | ||
|
1405c881a8 | ||
|
b070efce98 | ||
|
6df90a12d8 | ||
|
b2aa05dc07 | ||
|
1eed25dcc7 | ||
|
749dc70e71 | ||
|
7239f0e336 | ||
|
e2de673488 | ||
|
2dfc264bf8 | ||
|
5a4d1a668f | ||
|
81a6a8653f | ||
|
1053b5d605 | ||
|
eaf12aec60 | ||
|
0103a0c31e | ||
|
21d717080a | ||
|
32e8406c37 | ||
|
ef47f21943 | ||
|
b2d3aed520 | ||
|
b125830859 | ||
|
7d1cb2971f | ||
|
6abf4a302c | ||
|
66443dd5d3 | ||
|
8d0dd42475 | ||
|
e8ddadc608 | ||
|
107cf72269 | ||
|
db4fb3ac53 | ||
|
34da772db7 | ||
|
9b7cea5d04 | ||
|
98da1f13a1 | ||
|
df895f4a9f | ||
|
95f3eb54db | ||
|
a6ab61adba | ||
|
656ac62ad2 | ||
|
6df2368264 | ||
|
23a160b9e1 | ||
|
df11129291 | ||
|
24d1799322 | ||
|
5843c34240 | ||
|
4da38891c7 | ||
|
004a13a5f7 | ||
|
a92f3648b2 | ||
|
a615b7fa70 | ||
|
6362731d55 | ||
|
d0a78ec067 | ||
|
3c01dbbcc5 | ||
|
6b746440fc | ||
|
c7ab6b9e6c | ||
|
38ff35873e | ||
|
1ead83383d | ||
|
fc2f8744da | ||
|
c716be263b | ||
|
0c943248bc | ||
|
927677e490 | ||
|
222300ff17 | ||
|
8acce201d6 | ||
|
1880b83944 | ||
|
42bfaf9a19 | ||
|
e384c0d5c3 | ||
|
9f00c353b1 | ||
|
ded71c9af1 | ||
|
e4fc0f5ac3 | ||
|
d167ef1f89 | ||
|
4bf9143789 | ||
|
8f43ca66df | ||
|
69df0adbd9 | ||
|
14eb482791 | ||
|
b26556e201 | ||
|
3b72049d05 | ||
|
15b03b96fc | ||
|
874e7afce3 | ||
|
9fe1527f10 | ||
|
baf8a9fb2c | ||
|
436e686037 | ||
|
cec96062e3 | ||
|
7169b481b1 | ||
|
b19ce4df7c | ||
|
5a1cceb9d2 | ||
|
3a83a2d5ac | ||
|
815ce0e451 | ||
|
3d14974d64 | ||
|
1bc1b87422 | ||
|
9e0ec8fca8 | ||
|
fdd90b3be7 | ||
|
bbf2f33c5e | ||
|
5c81f820d8 | ||
|
cf500a1a54 | ||
|
2203a4d87e | ||
|
bc1db626e7 | ||
|
74426a97f4 | ||
|
5b33a6a434 | ||
|
74a77a0e86 | ||
|
4d1a7e6637 | ||
|
56556e9660 | ||
|
e1089e0b73 | ||
|
e8474271b3 | ||
|
00b44bf3bb | ||
|
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 |
933 changed files with 40502 additions and 41972 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
.env.ci
1
.env.ci
|
@ -5,6 +5,7 @@ APP_THEME=pterodactyl
|
||||||
APP_TIMEZONE=America/Los_Angeles
|
APP_TIMEZONE=America/Los_Angeles
|
||||||
APP_URL=http://localhost/
|
APP_URL=http://localhost/
|
||||||
|
|
||||||
|
DB_CONNECTION=testing
|
||||||
TESTING_DB_HOST=127.0.0.1
|
TESTING_DB_HOST=127.0.0.1
|
||||||
TESTING_DB_DATABASE=panel_test
|
TESTING_DB_DATABASE=panel_test
|
||||||
TESTING_DB_USERNAME=root
|
TESTING_DB_USERNAME=root
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -39,11 +39,14 @@ rules:
|
||||||
comma-dangle:
|
comma-dangle:
|
||||||
- warn
|
- warn
|
||||||
- always-multiline
|
- always-multiline
|
||||||
spaced-comment:
|
spaced-comment: 0
|
||||||
- warn
|
|
||||||
array-bracket-spacing:
|
array-bracket-spacing:
|
||||||
- warn
|
- warn
|
||||||
- always
|
- always
|
||||||
|
"@typescript-eslint/no-unused-vars":
|
||||||
|
- warn
|
||||||
|
- argsIgnorePattern: '^_'
|
||||||
|
varsIgnorePattern: '^_'
|
||||||
# Remove errors for not having newlines between operands of ternary expressions https://eslint.org/docs/rules/multiline-ternary
|
# Remove errors for not having newlines between operands of ternary expressions https://eslint.org/docs/rules/multiline-ternary
|
||||||
multiline-ternary: 0
|
multiline-ternary: 0
|
||||||
"react-hooks/rules-of-hooks":
|
"react-hooks/rules-of-hooks":
|
||||||
|
|
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 .eslintignore .eslintrc.yml .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
|
||||||
|
|
45
.github/workflows/tests.yml
vendored
45
.github/workflows/tests.yml
vendored
|
@ -12,8 +12,8 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
php: [ 7.4, 8.0 ]
|
php: [ 8.1 ]
|
||||||
database: [ 'mariadb:10.2', 'mysql:8' ]
|
database: [ 'mariadb:10.6', 'mysql:8' ]
|
||||||
services:
|
services:
|
||||||
database:
|
database:
|
||||||
image: ${{ matrix.database }}
|
image: ${{ matrix.database }}
|
||||||
|
@ -25,35 +25,40 @@ jobs:
|
||||||
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||||
name: "php-${{ matrix.php }} (${{ matrix.database }})"
|
name: "php-${{ matrix.php }} (${{ matrix.database }})"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- name: Checkout
|
||||||
- name: get cache directory
|
uses: actions/checkout@v2
|
||||||
|
- 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)"
|
||||||
- uses: actions/cache@v2
|
- name: Cache
|
||||||
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.php_cs.cache
|
~/.php_cs.cache
|
||||||
${{ steps.composer-cache.outputs.dir }}
|
${{ steps.composer-cache.outputs.dir }}
|
||||||
key: ${{ runner.os }}-cache-${{ matrix.php }}-${{ hashFiles('**.composer.lock') }}
|
key: ${{ runner.os }}-cache-${{ matrix.php }}-${{ hashFiles('composer.lock') }}
|
||||||
- uses: shivammathur/setup-php@v2
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: ${{ matrix.php }}
|
php-version: ${{ matrix.php }}
|
||||||
extensions: bcmath, cli, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip
|
extensions: bcmath, cli, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip
|
||||||
tools: composer:v2
|
tools: composer:v2
|
||||||
coverage: none
|
coverage: none
|
||||||
- run: cp .env.ci .env
|
- name: Configure .env
|
||||||
- run: composer install --prefer-dist --no-interaction --no-progress
|
run: cp .env.ci .env
|
||||||
- run: vendor/bin/php-cs-fixer fix --dry-run --diff --diff-format=udiff --config .php-cs-fixer.dist.php
|
- name: composer install
|
||||||
continue-on-error: true
|
run: composer install --prefer-dist --no-interaction --no-progress
|
||||||
- name: execute unit tests
|
- name: Run cs-fixer
|
||||||
run: vendor/bin/phpunit --bootstrap vendor/autoload.php tests/Unit
|
run: vendor/bin/php-cs-fixer fix --dry-run --diff --format=txt --config .php-cs-fixer.dist.php
|
||||||
if: ${{ always() }}
|
- name: Static Analysis
|
||||||
|
if: ${{ matrix.php }} == '8.0'
|
||||||
|
run: |
|
||||||
|
php artisan ide-helper:models -N
|
||||||
|
./vendor/bin/phpstan analyse --memory-limit=2G
|
||||||
env:
|
env:
|
||||||
DB_CONNECTION: testing
|
DB_PORT: ${{ job.services.database.ports[3306] }}
|
||||||
TESTING_DB_HOST: UNIT_NO_DB
|
- name: Execute Tests
|
||||||
- name: execute integration tests
|
run: php artisan test
|
||||||
run: vendor/bin/phpunit tests/Integration
|
|
||||||
env:
|
env:
|
||||||
TESTING_DB_PORT: ${{ job.services.database.ports[3306] }}
|
DB_PORT: ${{ job.services.database.ports[3306] }}
|
||||||
TESTING_DB_USERNAME: root
|
|
||||||
|
|
109
.gitignore
vendored
109
.gitignore
vendored
|
@ -1,40 +1,85 @@
|
||||||
|
#------------------#
|
||||||
|
# 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
|
||||||
|
_ide_helper.php
|
||||||
|
_ide_helper_models.php
|
||||||
|
.phpstorm.meta.php
|
||||||
|
|
||||||
|
#-------------------#
|
||||||
|
# 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.php
|
|
||||||
_ide_helper_models.php
|
_ide_helper_models.php
|
||||||
|
_ide_helper.php
|
||||||
.phpstorm.meta.php
|
.phpstorm.meta.php
|
||||||
.php_cs.cache
|
|
||||||
.yarn
|
|
||||||
public/assets/manifest.json
|
|
||||||
|
|
||||||
# For local development with docker
|
|
||||||
# Remove if we ever put the Dockerfile in the repo
|
|
||||||
.dockerignore
|
|
||||||
#Dockerfile
|
|
||||||
docker-compose.yml
|
|
||||||
|
|
||||||
# for image related files
|
|
||||||
misc
|
|
||||||
.phpstorm.meta.php
|
|
||||||
.php_cs.cache
|
|
||||||
|
|
||||||
coverage.xml
|
|
||||||
|
|
||||||
# Vagrant
|
|
||||||
*.log
|
|
||||||
resources/lang/locales.js
|
|
||||||
resources/assets/pterodactyl/scripts/helpers/ziggy.js
|
|
||||||
resources/assets/scripts/helpers/ziggy.js
|
|
||||||
.phpunit.result.cache
|
|
||||||
|
|
|
@ -10,6 +10,9 @@ $finder = (new Finder())
|
||||||
'node_modules',
|
'node_modules',
|
||||||
'storage',
|
'storage',
|
||||||
'bootstrap/cache',
|
'bootstrap/cache',
|
||||||
|
'.phpstorm.meta.php',
|
||||||
|
'_ide_helper.php',
|
||||||
|
'_ide_helper_models.php',
|
||||||
])
|
])
|
||||||
->notName(['_ide_helper*']);
|
->notName(['_ide_helper*']);
|
||||||
|
|
||||||
|
@ -29,7 +32,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',
|
||||||
|
|
631
.yarn/releases/yarn-3.0.2.cjs
vendored
Executable file
631
.yarn/releases/yarn-3.0.2.cjs
vendored
Executable file
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
||||||
@types/react-native
|
|
6
.yarnrc.yml
Normal file
6
.yarnrc.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
nodeLinker: node-modules
|
||||||
|
|
||||||
|
pnpIgnorePatterns:
|
||||||
|
- ./public/**/*
|
||||||
|
|
||||||
|
yarnPath: .yarn/releases/yarn-3.0.2.cjs
|
|
@ -50,6 +50,11 @@ class AppSettingsCommand extends Command
|
||||||
*/
|
*/
|
||||||
protected $config;
|
protected $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Validation\Factory
|
||||||
|
*/
|
||||||
|
protected $validator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
|
@ -114,6 +119,7 @@ class AppSettingsCommand extends Command
|
||||||
foreach ($validator->errors()->all() as $error) {
|
foreach ($validator->errors()->all() as $error) {
|
||||||
$this->output->error($error);
|
$this->output->error($error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,15 +54,15 @@ class InfoCommand extends Command
|
||||||
$this->output->title('Version Information');
|
$this->output->title('Version Information');
|
||||||
$this->table([], [
|
$this->table([], [
|
||||||
['Panel Version', $this->config->get('app.version')],
|
['Panel Version', $this->config->get('app.version')],
|
||||||
['Latest Version', $this->versionService->getPanel()],
|
['Latest Version', $this->versionService->getLatestPanel()],
|
||||||
['Up-to-Date', $this->versionService->isLatestPanel() ? 'Yes' : $this->formatText('No', 'bg=red')],
|
['Up-to-Date', $this->versionService->isLatestPanel() ? 'Yes' : $this->formatText('No', 'bg=red')],
|
||||||
['Unique Identifier', $this->config->get('pterodactyl.service.author')],
|
['Unique Identifier', $this->config->get('pterodactyl.service.author')],
|
||||||
], 'compact');
|
], 'compact');
|
||||||
|
|
||||||
$this->output->title('Application Configuration');
|
$this->output->title('Application Configuration');
|
||||||
$this->table([], [
|
$this->table([], [
|
||||||
['Environment', $this->formatText($this->config->get('app.env'), $this->config->get('app.env') === 'production' ?: 'bg=red')],
|
['Environment', $this->formatText($this->config->get('app.env'), $this->config->get('app.env') === 'production' ? '' : 'bg=red')],
|
||||||
['Debug Mode', $this->formatText($this->config->get('app.debug') ? 'Yes' : 'No', !$this->config->get('app.debug') ?: 'bg=red')],
|
['Debug Mode', $this->formatText($this->config->get('app.debug') ? 'Yes' : 'No', !$this->config->get('app.debug') ? '' : 'bg=red')],
|
||||||
['Installation URL', $this->config->get('app.url')],
|
['Installation URL', $this->config->get('app.url')],
|
||||||
['Installation Directory', base_path()],
|
['Installation Directory', base_path()],
|
||||||
['Timezone', $this->config->get('app.timezone')],
|
['Timezone', $this->config->get('app.timezone')],
|
||||||
|
@ -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');
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
<?php
|
<?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\Console\Commands\Location;
|
namespace Pterodactyl\Console\Commands\Location;
|
||||||
|
|
||||||
|
@ -26,9 +19,9 @@ class DeleteLocationCommand extends Command
|
||||||
protected $description = 'Deletes a location from the Panel.';
|
protected $description = 'Deletes a location from the Panel.';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Illuminate\Support\Collection
|
* @var \Illuminate\Support\Collection|null
|
||||||
*/
|
*/
|
||||||
protected $locations;
|
protected $locations = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
|
* @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
|
||||||
|
|
|
@ -13,14 +13,14 @@ class SeedCommand extends BaseSeedCommand
|
||||||
* Block someone from running this seed command if they have not completed
|
* Block someone from running this seed command if they have not completed
|
||||||
* the migration process.
|
* the migration process.
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle(): int
|
||||||
{
|
{
|
||||||
if (!$this->hasCompletedMigrations()) {
|
if (!$this->hasCompletedMigrations()) {
|
||||||
$this->showMigrationWarning();
|
$this->showMigrationWarning();
|
||||||
|
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::handle();
|
return parent::handle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,14 @@ class UpCommand extends BaseUpCommand
|
||||||
* Block someone from running this up command if they have not completed
|
* Block someone from running this up command if they have not completed
|
||||||
* the migration process.
|
* the migration process.
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle(): int
|
||||||
{
|
{
|
||||||
if (!$this->hasCompletedMigrations()) {
|
if (!$this->hasCompletedMigrations()) {
|
||||||
$this->showMigrationWarning();
|
$this->showMigrationWarning();
|
||||||
|
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::handle();
|
return parent::handle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ class ProcessRunnableCommand extends Command
|
||||||
/**
|
/**
|
||||||
* Handle command execution.
|
* Handle command execution.
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle(): int
|
||||||
{
|
{
|
||||||
$schedules = Schedule::query()->with('tasks')
|
$schedules = Schedule::query()->with('tasks')
|
||||||
->where('is_active', true)
|
->where('is_active', true)
|
||||||
|
@ -35,7 +35,7 @@ class ProcessRunnableCommand extends Command
|
||||||
if ($schedules->count() < 1) {
|
if ($schedules->count() < 1) {
|
||||||
$this->line('There are no scheduled tasks for servers that need to be run.');
|
$this->line('There are no scheduled tasks for servers that need to be run.');
|
||||||
|
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$bar = $this->output->createProgressBar(count($schedules));
|
$bar = $this->output->createProgressBar(count($schedules));
|
||||||
|
@ -47,6 +47,8 @@ class ProcessRunnableCommand extends Command
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->line('');
|
$this->line('');
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,7 +71,7 @@ class ProcessRunnableCommand extends Command
|
||||||
'schedule' => $schedule->name,
|
'schedule' => $schedule->name,
|
||||||
'hash' => $schedule->hashid,
|
'hash' => $schedule->hashid,
|
||||||
]));
|
]));
|
||||||
} catch (Throwable | Exception $exception) {
|
} catch (Throwable|Exception $exception) {
|
||||||
Log::error($exception, ['schedule_id' => $schedule->id]);
|
Log::error($exception, ['schedule_id' => $schedule->id]);
|
||||||
|
|
||||||
$this->error("An error was encountered while processing Schedule #{$schedule->id}: " . $exception->getMessage());
|
$this->error("An error was encountered while processing Schedule #{$schedule->id}: " . $exception->getMessage());
|
||||||
|
|
|
@ -87,11 +87,12 @@ class UpgradeCommand extends Command
|
||||||
|
|
||||||
if (!$this->confirm('Are you sure you want to run the upgrade process for your Panel?')) {
|
if (!$this->confirm('Are you sure you want to run the upgrade process for your Panel?')) {
|
||||||
$this->warn('Upgrade process terminated by user.');
|
$this->warn('Upgrade process terminated by user.');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ini_set('output_buffering', 0);
|
ini_set('output_buffering', '0');
|
||||||
$bar = $this->output->createProgressBar($skipDownload ? 9 : 10);
|
$bar = $this->output->createProgressBar($skipDownload ? 9 : 10);
|
||||||
$bar->start();
|
$bar->start();
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
<?php
|
<?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\Console\Commands\User;
|
namespace Pterodactyl\Console\Commands\User;
|
||||||
|
|
||||||
|
@ -47,11 +40,9 @@ class DeleteUserCommand extends Command
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle(): int
|
||||||
{
|
{
|
||||||
$search = $this->option('user') ?? $this->ask(trans('command/messages.user.search_users'));
|
$search = $this->option('user') ?? $this->ask(trans('command/messages.user.search_users'));
|
||||||
Assert::notEmpty($search, 'Search term should be an email address, got: %s.');
|
Assert::notEmpty($search, 'Search term should be an email address, got: %s.');
|
||||||
|
@ -68,13 +59,13 @@ class DeleteUserCommand extends Command
|
||||||
return $this->handle();
|
return $this->handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->input->isInteractive()) {
|
if ($this->input->isInteractive()) {
|
||||||
$tableValues = [];
|
$tableValues = [];
|
||||||
foreach ($results as $user) {
|
foreach ($results as $user) {
|
||||||
$tableValues[] = [$user->id, $user->email, $user->name];
|
$tableValues[] = [$user->id, $user->email, $user->name_first];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->table(['User ID', 'Email', 'Name'], $tableValues);
|
$this->table(['User ID', 'Email', 'Name'], $tableValues);
|
||||||
|
@ -85,7 +76,7 @@ class DeleteUserCommand extends Command
|
||||||
if (count($results) > 1) {
|
if (count($results) > 1) {
|
||||||
$this->error(trans('command/messages.user.multiple_found'));
|
$this->error(trans('command/messages.user.multiple_found'));
|
||||||
|
|
||||||
return false;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$deleteUser = $results->first();
|
$deleteUser = $results->first();
|
||||||
|
@ -95,5 +86,7 @@ class DeleteUserCommand extends Command
|
||||||
$this->deletionService->handle($deleteUser);
|
$this->deletionService->handle($deleteUser);
|
||||||
$this->info(trans('command/messages.user.deleted'));
|
$this->info(trans('command/messages.user.deleted'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,12 +57,12 @@ 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],
|
||||||
['Username', $user->username],
|
['Username', $user->username],
|
||||||
['Name', $user->name],
|
['Name', $user->name_first],
|
||||||
['Admin', $user->root_admin ? 'Yes' : 'No'],
|
['Admin', $user->root_admin ? 'Yes' : 'No'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -39,10 +39,8 @@ interface DatabaseRepositoryInterface extends RepositoryInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new database user on a given connection.
|
* Create a new database user on a given connection.
|
||||||
*
|
|
||||||
* @param $max_connections
|
|
||||||
*/
|
*/
|
||||||
public function createUser(string $username, string $remote, string $password, string $max_connections): bool;
|
public function createUser(string $username, string $remote, string $password, int $max_connections): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Give a specific user access to a given database.
|
* Give a specific user access to a given database.
|
||||||
|
@ -61,8 +59,6 @@ interface DatabaseRepositoryInterface extends RepositoryInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drop a given user on a specific connection.
|
* Drop a given user on a specific connection.
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*/
|
*/
|
||||||
public function dropUser(string $username, string $remote): bool;
|
public function dropUser(string $username, string $remote): bool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,6 @@ interface LocationRepositoryInterface extends RepositoryInterface
|
||||||
/**
|
/**
|
||||||
* Return all of the nodes and their respective count of servers for a location.
|
* Return all of the nodes and their respective count of servers for a location.
|
||||||
*
|
*
|
||||||
* @return mixed
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getWithNodes(int $id): Location;
|
public function getWithNodes(int $id): Location;
|
||||||
|
@ -29,8 +27,6 @@ interface LocationRepositoryInterface extends RepositoryInterface
|
||||||
/**
|
/**
|
||||||
* Return a location and the count of nodes in that location.
|
* Return a location and the count of nodes in that location.
|
||||||
*
|
*
|
||||||
* @return mixed
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getWithNodeCount(int $id): Location;
|
public function getWithNodeCount(int $id): Location;
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
<?php
|
<?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\Contracts\Repository;
|
namespace Pterodactyl\Contracts\Repository;
|
||||||
|
|
||||||
|
@ -16,27 +9,7 @@ interface NestRepositoryInterface extends RepositoryInterface
|
||||||
/**
|
/**
|
||||||
* Return a nest or all nests with their associated eggs and variables.
|
* Return a nest or all nests with their associated eggs and variables.
|
||||||
*
|
*
|
||||||
* @param int $id
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Database\Eloquent\Collection|\Pterodactyl\Models\Nest
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getWithEggs(int $id = null);
|
public function getWithEggs(int $id = null): Nest;
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a nest or all nests and the count of eggs and servers for that nest.
|
|
||||||
*
|
|
||||||
* @return \Pterodactyl\Models\Nest|\Illuminate\Database\Eloquent\Collection
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
|
||||||
public function getWithCounts(int $id = null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a nest along with its associated eggs and the servers relation on those eggs.
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
|
||||||
public function getWithEggServers(int $id): Nest;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@ class Installed extends Event
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new event instance.
|
* Create a new event instance.
|
||||||
*
|
|
||||||
* @var \Pterodactyl\Models\Server
|
|
||||||
*/
|
*/
|
||||||
public function __construct(Server $server)
|
public function __construct(Server $server)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,6 @@ use Throwable;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Container\Container;
|
use Illuminate\Container\Container;
|
||||||
use Prologue\Alerts\AlertsMessageBag;
|
|
||||||
|
|
||||||
class DisplayException extends PterodactylException
|
class DisplayException extends PterodactylException
|
||||||
{
|
{
|
||||||
|
@ -68,8 +67,6 @@ class DisplayException extends PterodactylException
|
||||||
]), method_exists($this, 'getStatusCode') ? $this->getStatusCode() : Response::HTTP_BAD_REQUEST);
|
]), method_exists($this, 'getStatusCode') ? $this->getStatusCode() : Response::HTTP_BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
Container::getInstance()->make(AlertsMessageBag::class)->danger($this->getMessage())->flash();
|
|
||||||
|
|
||||||
return redirect()->back()->withInput();
|
return redirect()->back()->withInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +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 Swift_TransportException;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Container\Container;
|
use Illuminate\Container\Container;
|
||||||
|
@ -19,6 +19,7 @@ use Illuminate\Validation\ValidationException;
|
||||||
use Illuminate\Auth\Access\AuthorizationException;
|
use Illuminate\Auth\Access\AuthorizationException;
|
||||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||||
|
use Symfony\Component\Mailer\Exception\TransportException;
|
||||||
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
|
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
|
||||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||||
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
||||||
|
@ -35,7 +36,7 @@ class Handler extends ExceptionHandler
|
||||||
/**
|
/**
|
||||||
* A list of the exception types that should not be reported.
|
* A list of the exception types that should not be reported.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array<int, class-string<Throwable>>
|
||||||
*/
|
*/
|
||||||
protected $dontReport = [
|
protected $dontReport = [
|
||||||
AuthenticationException::class,
|
AuthenticationException::class,
|
||||||
|
@ -50,7 +51,7 @@ class Handler extends ExceptionHandler
|
||||||
/**
|
/**
|
||||||
* A list of the inputs that are never flashed for validation exceptions.
|
* A list of the inputs that are never flashed for validation exceptions.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
protected $dontFlash = [
|
protected $dontFlash = [
|
||||||
'token',
|
'token',
|
||||||
|
@ -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
|
||||||
|
@ -77,7 +88,7 @@ class Handler extends ExceptionHandler
|
||||||
$ex = $this->generateCleanedExceptionStack($ex);
|
$ex = $this->generateCleanedExceptionStack($ex);
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->reportable(function (Swift_TransportException $ex) {
|
$this->reportable(function (TransportException $ex) {
|
||||||
$ex = $this->generateCleanedExceptionStack($ex);
|
$ex = $this->generateCleanedExceptionStack($ex);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,20 +9,16 @@ class RecordNotFoundException extends RepositoryException implements HttpExcepti
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Returns the status code.
|
* Returns the status code.
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function getStatusCode()
|
public function getStatusCode(): int
|
||||||
{
|
{
|
||||||
return Response::HTTP_NOT_FOUND;
|
return Response::HTTP_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns response headers.
|
* Returns response headers.
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function getHeaders()
|
public function getHeaders(): array
|
||||||
{
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
9
app/Exceptions/Service/Egg/BadYamlFormatException.php
Normal file
9
app/Exceptions/Service/Egg/BadYamlFormatException.php
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Exceptions\Service\Egg;
|
||||||
|
|
||||||
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
|
|
||||||
|
class BadYamlFormatException extends DisplayException
|
||||||
|
{
|
||||||
|
}
|
|
@ -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;
|
||||||
|
@ -21,24 +21,21 @@ class Fractal extends SpatieFractal
|
||||||
public function createData()
|
public function createData()
|
||||||
{
|
{
|
||||||
// Set the serializer by default.
|
// Set the serializer by default.
|
||||||
if (is_null($this->serializer)) {
|
if (is_null($this->serializer)) { // @phpstan-ignore-line
|
||||||
$this->serializer = new PterodactylSerializer();
|
$this->serializer = new PterodactylSerializer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automatically set the paginator on the response object if the
|
// Automatically set the paginator on the response object if the
|
||||||
// data being provided implements a paginator.
|
// data being provided implements a paginator.
|
||||||
if (is_null($this->paginator) && $this->data instanceof LengthAwarePaginator) {
|
if (is_null($this->paginator) && $this->data instanceof LengthAwarePaginator) { // @phpstan-ignore-line
|
||||||
$this->paginator = new IlluminatePaginatorAdapter($this->data);
|
$this->paginator = new IlluminatePaginatorAdapter($this->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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) { // @phpstan-ignore-line
|
||||||
&& $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, '/');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,6 +17,6 @@ final class Time
|
||||||
{
|
{
|
||||||
$offset = round(CarbonImmutable::now($timezone)->getTimezone()->getOffset(CarbonImmutable::now('UTC')) / 3600);
|
$offset = round(CarbonImmutable::now($timezone)->getTimezone()->getOffset(CarbonImmutable::now('UTC')) / 3600);
|
||||||
|
|
||||||
return sprintf('%s%s:00', $offset > 0 ? '+' : '-', str_pad(abs($offset), 2, '0', STR_PAD_LEFT));
|
return sprintf('%s%s:00', $offset > 0 ? '+' : '-', str_pad((string) abs($offset), 2, '0', STR_PAD_LEFT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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->get('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 = (int) $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();
|
||||||
|
}
|
||||||
|
}
|
119
app/Http/Controllers/Api/Application/Eggs/EggController.php
Normal file
119
app/Http/Controllers/Api/Application/Eggs/EggController.php
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Controllers\Api\Application\Eggs;
|
||||||
|
|
||||||
|
use Ramsey\Uuid\Uuid;
|
||||||
|
use Pterodactyl\Models\Egg;
|
||||||
|
use Pterodactyl\Models\Nest;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Spatie\QueryBuilder\QueryBuilder;
|
||||||
|
use Pterodactyl\Services\Eggs\Sharing\EggExporterService;
|
||||||
|
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\ExportEggRequest;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\Eggs\UpdateEggRequest;
|
||||||
|
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
|
||||||
|
class EggController extends ApplicationApiController
|
||||||
|
{
|
||||||
|
private EggExporterService $eggExporterService;
|
||||||
|
|
||||||
|
public function __construct(EggExporterService $eggExporterService)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->eggExporterService = $eggExporterService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array of all eggs on a given nest.
|
||||||
|
*/
|
||||||
|
public function index(GetEggsRequest $request, Nest $nest): array
|
||||||
|
{
|
||||||
|
$perPage = (int) $request->query('per_page', '10');
|
||||||
|
if ($perPage > 100) {
|
||||||
|
throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
|
$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.
|
||||||
|
*/
|
||||||
|
public function view(GetEggRequest $request, Egg $egg): array
|
||||||
|
{
|
||||||
|
return $this->fractal->item($egg)
|
||||||
|
->transformWith(EggTransformer::class)
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new egg.
|
||||||
|
*/
|
||||||
|
public function store(StoreEggRequest $request): JsonResponse
|
||||||
|
{
|
||||||
|
$validated = $request->validated();
|
||||||
|
$merged = array_merge($validated, [
|
||||||
|
'uuid' => Uuid::uuid4()->toString(),
|
||||||
|
// TODO: allow this to be set in the request, and default to config value if null or not present.
|
||||||
|
'author' => config('pterodactyl.service.author'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$egg = Egg::query()->create($merged);
|
||||||
|
|
||||||
|
return $this->fractal->item($egg)
|
||||||
|
->transformWith(EggTransformer::class)
|
||||||
|
->respond(Response::HTTP_CREATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an egg.
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exports an egg.
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
|
*/
|
||||||
|
public function export(ExportEggRequest $request, int $eggId): JsonResponse
|
||||||
|
{
|
||||||
|
return new JsonResponse($this->eggExporterService->handle($eggId));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Controllers\Api\Application\Eggs;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Egg;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
use Pterodactyl\Models\EggVariable;
|
||||||
|
use Illuminate\Database\ConnectionInterface;
|
||||||
|
use Pterodactyl\Services\Eggs\Variables\VariableUpdateService;
|
||||||
|
use Pterodactyl\Services\Eggs\Variables\VariableCreationService;
|
||||||
|
use Pterodactyl\Transformers\Api\Application\EggVariableTransformer;
|
||||||
|
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\Eggs\Variables\StoreEggVariableRequest;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\Eggs\Variables\UpdateEggVariablesRequest;
|
||||||
|
|
||||||
|
class EggVariableController extends ApplicationApiController
|
||||||
|
{
|
||||||
|
private ConnectionInterface $connection;
|
||||||
|
|
||||||
|
private VariableCreationService $variableCreationService;
|
||||||
|
|
||||||
|
private VariableUpdateService $variableUpdateService;
|
||||||
|
|
||||||
|
public function __construct(ConnectionInterface $connection, VariableCreationService $variableCreationService, VariableUpdateService $variableUpdateService)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->connection = $connection;
|
||||||
|
$this->variableCreationService = $variableCreationService;
|
||||||
|
$this->variableUpdateService = $variableUpdateService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new egg variable.
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\Service\Egg\Variable\BadValidationRuleException
|
||||||
|
* @throws \Pterodactyl\Exceptions\Service\Egg\Variable\ReservedVariableNameException
|
||||||
|
*/
|
||||||
|
public function store(StoreEggVariableRequest $request, Egg $egg): array
|
||||||
|
{
|
||||||
|
$variable = $this->variableCreationService->handle($egg->id, $request->validated());
|
||||||
|
|
||||||
|
return $this->fractal->item($variable)
|
||||||
|
->transformWith(EggVariableTransformer::class)
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates multiple egg variables.
|
||||||
|
*
|
||||||
|
* @throws \Throwable
|
||||||
|
*/
|
||||||
|
public function update(UpdateEggVariablesRequest $request, Egg $egg): array
|
||||||
|
{
|
||||||
|
$validated = $request->validated();
|
||||||
|
|
||||||
|
$this->connection->transaction(function () use ($egg, $validated) {
|
||||||
|
foreach ($validated as $data) {
|
||||||
|
$this->variableUpdateService->handle($egg, $data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this->fractal->collection($egg->refresh()->variables)
|
||||||
|
->transformWith(EggVariableTransformer::class)
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a single egg variable.
|
||||||
|
*/
|
||||||
|
public function delete(Request $request, Egg $egg, EggVariable $eggVariable): Response
|
||||||
|
{
|
||||||
|
EggVariable::query()
|
||||||
|
->where('id', $eggVariable->id)
|
||||||
|
->where('egg_id', $egg->id)
|
||||||
|
->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 = (int) $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,18 +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([
|
|
||||||
'resource' => route('api.application.locations.view', [
|
|
||||||
'location' => $location->id,
|
|
||||||
]),
|
|
||||||
])
|
|
||||||
->respond(201);
|
->respond(201);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,13 +94,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 +110,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 = (int) $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,138 @@
|
||||||
namespace Pterodactyl\Http\Controllers\Api\Application\Nests;
|
namespace Pterodactyl\Http\Controllers\Api\Application\Nests;
|
||||||
|
|
||||||
use Pterodactyl\Models\Nest;
|
use Pterodactyl\Models\Nest;
|
||||||
use Pterodactyl\Contracts\Repository\NestRepositoryInterface;
|
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\Services\Eggs\Sharing\EggImporterService;
|
||||||
|
use Pterodactyl\Transformers\Api\Application\EggTransformer;
|
||||||
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\Eggs\ImportEggRequest;
|
||||||
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 NestCreationService $nestCreationService;
|
||||||
* @var \Pterodactyl\Contracts\Repository\NestRepositoryInterface
|
private NestDeletionService $nestDeletionService;
|
||||||
*/
|
private NestUpdateService $nestUpdateService;
|
||||||
private $repository;
|
private EggImporterService $eggImporterService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NestController constructor.
|
* NestController constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(NestRepositoryInterface $repository)
|
public function __construct(
|
||||||
{
|
NestCreationService $nestCreationService,
|
||||||
|
NestDeletionService $nestDeletionService,
|
||||||
|
NestUpdateService $nestUpdateService,
|
||||||
|
EggImporterService $eggImporterService
|
||||||
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->repository = $repository;
|
$this->nestCreationService = $nestCreationService;
|
||||||
|
$this->nestDeletionService = $nestDeletionService;
|
||||||
|
$this->nestUpdateService = $nestUpdateService;
|
||||||
|
$this->eggImporterService = $eggImporterService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 = (int) $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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports an egg.
|
||||||
|
*/
|
||||||
|
public function import(ImportEggRequest $request, Nest $nest): array
|
||||||
|
{
|
||||||
|
$egg = $this->eggImporterService->handleContent(
|
||||||
|
$nest->id,
|
||||||
|
$request->getContent(),
|
||||||
|
$request->headers->get('Content-Type'),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->fractal->item($egg)
|
||||||
|
->transformWith(EggTransformer::class)
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing nest.
|
||||||
|
*
|
||||||
|
* @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,14 @@
|
||||||
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 Spatie\QueryBuilder\QueryBuilder;
|
||||||
|
use Spatie\QueryBuilder\AllowedFilter;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
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 +19,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 +37,32 @@ 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 = (int) $request->query('per_page', '10');
|
||||||
|
if ($perPage < 1 || $perPage > 100) {
|
||||||
|
throw new QueryValueOutOfRangeHttpException('per_page', 1, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
$allocations = QueryBuilder::for(Allocation::query()->where('node_id', '=', $node->id))
|
||||||
|
->allowedFilters([
|
||||||
|
'id', 'ip', 'port', 'alias',
|
||||||
|
AllowedFilter::callback('server_id', function (Builder $query, $value) {
|
||||||
|
if ($value === '0') {
|
||||||
|
$query->whereNull('server_id');
|
||||||
|
} else {
|
||||||
|
$query->where('server_id', '=', $value);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
->allowedSorts(['id', 'ip', 'port', 'server_id'])
|
||||||
|
->paginate($perPage);
|
||||||
|
|
||||||
return $this->fractal->collection($allocations)
|
return $this->fractal->collection($allocations)
|
||||||
->transformWith($this->getTransformer(AllocationTransformer::class))
|
->transformWith(AllocationTransformer::class)
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,11 +75,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 +87,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,13 +3,14 @@
|
||||||
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;
|
||||||
use Pterodactyl\Services\Nodes\NodeCreationService;
|
use Pterodactyl\Services\Nodes\NodeCreationService;
|
||||||
use Pterodactyl\Services\Nodes\NodeDeletionService;
|
use Pterodactyl\Services\Nodes\NodeDeletionService;
|
||||||
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,25 +20,9 @@ use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
|
||||||
class NodeController extends ApplicationApiController
|
class NodeController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private NodeCreationService $creationService;
|
||||||
* @var \Pterodactyl\Services\Nodes\NodeCreationService
|
private NodeDeletionService $deletionService;
|
||||||
*/
|
private NodeUpdateService $updateService;
|
||||||
private $creationService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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.
|
||||||
|
@ -45,12 +30,10 @@ class NodeController extends ApplicationApiController
|
||||||
public function __construct(
|
public function __construct(
|
||||||
NodeCreationService $creationService,
|
NodeCreationService $creationService,
|
||||||
NodeDeletionService $deletionService,
|
NodeDeletionService $deletionService,
|
||||||
NodeUpdateService $updateService,
|
NodeUpdateService $updateService
|
||||||
NodeRepositoryInterface $repository
|
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->repository = $repository;
|
|
||||||
$this->creationService = $creationService;
|
$this->creationService = $creationService;
|
||||||
$this->deletionService = $deletionService;
|
$this->deletionService = $deletionService;
|
||||||
$this->updateService = $updateService;
|
$this->updateService = $updateService;
|
||||||
|
@ -58,26 +41,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 = (int) $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,18 +78,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([
|
|
||||||
'resource' => route('api.application.nodes.view', [
|
|
||||||
'node' => $node->id,
|
|
||||||
]),
|
|
||||||
])
|
|
||||||
->respond(201);
|
->respond(201);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,11 +99,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 +113,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
|
||||||
|
@ -37,10 +35,10 @@ class NodeDeploymentController extends ApplicationApiController
|
||||||
$nodes = $this->viableNodesService->setLocations($data['location_ids'] ?? [])
|
$nodes = $this->viableNodesService->setLocations($data['location_ids'] ?? [])
|
||||||
->setMemory($data['memory'])
|
->setMemory($data['memory'])
|
||||||
->setDisk($data['disk'])
|
->setDisk($data['disk'])
|
||||||
->handle($request->query('per_page'), $request->query('page'));
|
->handle($request->query('per_page'), $request->query('page')); // @phpstan-ignore-line
|
||||||
|
|
||||||
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 = (int) $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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,6 @@ use Pterodactyl\Models\Database;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Pterodactyl\Services\Databases\DatabasePasswordService;
|
use Pterodactyl\Services\Databases\DatabasePasswordService;
|
||||||
use Pterodactyl\Services\Databases\DatabaseManagementService;
|
use Pterodactyl\Services\Databases\DatabaseManagementService;
|
||||||
use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
|
||||||
use Pterodactyl\Transformers\Api\Application\ServerDatabaseTransformer;
|
use Pterodactyl\Transformers\Api\Application\ServerDatabaseTransformer;
|
||||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Servers\Databases\GetServerDatabaseRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Servers\Databases\GetServerDatabaseRequest;
|
||||||
|
@ -18,54 +17,44 @@ 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 $databaseManagementService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Services\Databases\DatabasePasswordService
|
|
||||||
*/
|
|
||||||
private $databasePasswordService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DatabaseController constructor.
|
* DatabaseController constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
DatabaseManagementService $databaseManagementService,
|
DatabaseManagementService $databaseManagementService,
|
||||||
DatabasePasswordService $databasePasswordService,
|
DatabasePasswordService $databasePasswordService
|
||||||
DatabaseRepositoryInterface $repository
|
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->databaseManagementService = $databaseManagementService;
|
$this->databaseManagementService = $databaseManagementService;
|
||||||
$this->databasePasswordService = $databasePasswordService;
|
$this->databasePasswordService = $databasePasswordService;
|
||||||
$this->repository = $repository;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 +63,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,25 +82,19 @@ class DatabaseController extends ApplicationApiController
|
||||||
]));
|
]));
|
||||||
|
|
||||||
return $this->fractal->item($database)
|
return $this->fractal->item($database)
|
||||||
->transformWith($this->getTransformer(ServerDatabaseTransformer::class))
|
->transformWith(ServerDatabaseTransformer::class)
|
||||||
->addMeta([
|
|
||||||
'resource' => route('api.application.servers.databases.view', [
|
|
||||||
'server' => $server->id,
|
|
||||||
'database' => $database->id,
|
|
||||||
]),
|
|
||||||
])
|
|
||||||
->respond(Response::HTTP_CREATED);
|
->respond(Response::HTTP_CREATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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,30 +8,24 @@ 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\Services\Servers\BuildModificationService;
|
||||||
|
use Pterodactyl\Services\Servers\DetailsModificationService;
|
||||||
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;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Servers\StoreServerRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Servers\StoreServerRequest;
|
||||||
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\Servers\UpdateServerRequest;
|
||||||
|
|
||||||
class ServerController extends ApplicationApiController
|
class ServerController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private ServerCreationService $creationService;
|
||||||
* @var \Pterodactyl\Services\Servers\ServerCreationService
|
private ServerDeletionService $deletionService;
|
||||||
*/
|
|
||||||
private $creationService;
|
|
||||||
|
|
||||||
/**
|
private BuildModificationService $buildModificationService;
|
||||||
* @var \Pterodactyl\Services\Servers\ServerDeletionService
|
private DetailsModificationService $detailsModificationService;
|
||||||
*/
|
|
||||||
private $deletionService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServerController constructor.
|
* ServerController constructor.
|
||||||
|
@ -39,27 +33,37 @@ class ServerController extends ApplicationApiController
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ServerCreationService $creationService,
|
ServerCreationService $creationService,
|
||||||
ServerDeletionService $deletionService,
|
ServerDeletionService $deletionService,
|
||||||
ServerRepositoryInterface $repository
|
BuildModificationService $buildModificationService,
|
||||||
|
DetailsModificationService $detailsModificationService
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->creationService = $creationService;
|
$this->creationService = $creationService;
|
||||||
$this->deletionService = $deletionService;
|
$this->deletionService = $deletionService;
|
||||||
$this->repository = $repository;
|
|
||||||
|
$this->buildModificationService = $buildModificationService;
|
||||||
|
$this->detailsModificationService = $detailsModificationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 = (int) $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,32 +73,36 @@ 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
|
||||||
*/
|
*/
|
||||||
public function store(StoreServerRequest $request): JsonResponse
|
public function store(StoreServerRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$server = $this->creationService->handle($request->validated(), $request->getDeploymentObject());
|
$server = $this->creationService->handle($request->validated());
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
|
@ -102,4 +110,24 @@ class ServerController extends ApplicationApiController
|
||||||
|
|
||||||
return $this->returnNoContent();
|
return $this->returnNoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a server.
|
||||||
|
*
|
||||||
|
* @throws \Throwable
|
||||||
|
* @throws \Illuminate\Validation\ValidationException
|
||||||
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
|
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableAllocationException
|
||||||
|
* @throws \Pterodactyl\Exceptions\Service\Deployment\NoViableNodeException
|
||||||
|
*/
|
||||||
|
public function update(UpdateServerRequest $request, Server $server): array
|
||||||
|
{
|
||||||
|
$server = $this->buildModificationService->handle($server, $request->validated());
|
||||||
|
$server = $this->detailsModificationService->returnUpdatedModel()->handle($server, $request->validated());
|
||||||
|
|
||||||
|
return $this->fractal->item($server)
|
||||||
|
->transformWith(ServerTransformer::class)
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,9 @@ use Spatie\QueryBuilder\QueryBuilder;
|
||||||
use Pterodactyl\Services\Users\UserUpdateService;
|
use Pterodactyl\Services\Users\UserUpdateService;
|
||||||
use Pterodactyl\Services\Users\UserCreationService;
|
use Pterodactyl\Services\Users\UserCreationService;
|
||||||
use Pterodactyl\Services\Users\UserDeletionService;
|
use Pterodactyl\Services\Users\UserDeletionService;
|
||||||
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,31 +20,14 @@ use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
|
||||||
class UserController extends ApplicationApiController
|
class UserController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
/**
|
private UserCreationService $creationService;
|
||||||
* @var \Pterodactyl\Services\Users\UserCreationService
|
private UserDeletionService $deletionService;
|
||||||
*/
|
private UserUpdateService $updateService;
|
||||||
private $creationService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
UserRepositoryInterface $repository,
|
|
||||||
UserCreationService $creationService,
|
UserCreationService $creationService,
|
||||||
UserDeletionService $deletionService,
|
UserDeletionService $deletionService,
|
||||||
UserUpdateService $updateService
|
UserUpdateService $updateService
|
||||||
|
@ -52,7 +36,6 @@ class UserController extends ApplicationApiController
|
||||||
|
|
||||||
$this->creationService = $creationService;
|
$this->creationService = $creationService;
|
||||||
$this->deletionService = $deletionService;
|
$this->deletionService = $deletionService;
|
||||||
$this->repository = $repository;
|
|
||||||
$this->updateService = $updateService;
|
$this->updateService = $updateService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,27 +43,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 = (int) $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 +86,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,12 +110,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([
|
|
||||||
'resource' => route('api.application.users.view', [
|
|
||||||
'user' => $user->id,
|
|
||||||
]),
|
|
||||||
])
|
|
||||||
->respond(201);
|
->respond(201);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,10 +120,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,20 +12,17 @@ use Pterodactyl\Http\Requests\Api\Client\Account\UpdatePasswordRequest;
|
||||||
|
|
||||||
class AccountController extends ClientApiController
|
class AccountController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
private UserUpdateService $updateService;
|
||||||
* @var \Pterodactyl\Services\Users\UserUpdateService
|
|
||||||
*/
|
|
||||||
private $updateService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Illuminate\Auth\SessionGuard
|
* @var \Illuminate\Auth\AuthManager
|
||||||
*/
|
*/
|
||||||
private $sessionGuard;
|
private $sessionGuard;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountController constructor.
|
* AccountController constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(AuthManager $sessionGuard, UserUpdateService $updateService)
|
public function __construct(UserUpdateService $updateService, AuthManager $sessionGuard)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
@ -34,24 +30,24 @@ class AccountController extends ClientApiController
|
||||||
$this->sessionGuard = $sessionGuard;
|
$this->sessionGuard = $sessionGuard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets information about the currently authenticated user.
|
||||||
|
*/
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the authenticated user's email address.
|
* Update the authenticated user's email address.
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function updateEmail(UpdateEmailRequest $request): JsonResponse
|
public function updateEmail(UpdateEmailRequest $request): Response
|
||||||
{
|
{
|
||||||
$this->updateService->handle($request->user(), $request->validated());
|
$this->updateService->handle($request->user(), $request->validated());
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return $this->returnNoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +56,7 @@ class AccountController extends ClientApiController
|
||||||
*
|
*
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function updatePassword(UpdatePasswordRequest $request): JsonResponse
|
public function updatePassword(UpdatePasswordRequest $request): Response
|
||||||
{
|
{
|
||||||
$user = $this->updateService->handle($request->user(), $request->validated());
|
$user = $this->updateService->handle($request->user(), $request->validated());
|
||||||
|
|
||||||
|
@ -68,10 +64,13 @@ class AccountController extends ClientApiController
|
||||||
// cached copy of the user that does not include the updated password. Do this
|
// cached copy of the user that does not include the updated password. Do this
|
||||||
// to correctly store the new user details in the guard and allow the logout
|
// to correctly store the new user details in the guard and allow the logout
|
||||||
// other devices functionality to work.
|
// other devices functionality to work.
|
||||||
$this->sessionGuard->setUser($user);
|
if (method_exists($this->sessionGuard, 'setUser')) {
|
||||||
|
$this->sessionGuard->setUser($user);
|
||||||
|
}
|
||||||
|
|
||||||
$this->sessionGuard->logoutOtherDevices($request->input('password'));
|
// TODO: Find another way to do this, function doesn't exist due to API changes.
|
||||||
|
//$this->sessionGuard->logoutOtherDevices($request->input('password'));
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
return $this->returnNoContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,106 +2,57 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Api\Client;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,39 +7,24 @@ use Pterodactyl\Models\Permission;
|
||||||
use Spatie\QueryBuilder\QueryBuilder;
|
use Spatie\QueryBuilder\QueryBuilder;
|
||||||
use Spatie\QueryBuilder\AllowedFilter;
|
use Spatie\QueryBuilder\AllowedFilter;
|
||||||
use Pterodactyl\Models\Filters\MultiFieldServerFilter;
|
use Pterodactyl\Models\Filters\MultiFieldServerFilter;
|
||||||
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
|
||||||
use Pterodactyl\Transformers\Api\Client\ServerTransformer;
|
use Pterodactyl\Transformers\Api\Client\ServerTransformer;
|
||||||
use Pterodactyl\Http\Requests\Api\Client\GetServersRequest;
|
use Pterodactyl\Http\Requests\Api\Client\GetServersRequest;
|
||||||
|
|
||||||
class ClientController extends ClientApiController
|
class ClientController extends ClientApiController
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ClientController constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(ServerRepository $repository)
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
|
|
||||||
$this->repository = $repository;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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',
|
||||||
|
@ -68,17 +53,15 @@ class ClientController extends ClientApiController
|
||||||
$builder = $builder->whereIn('servers.id', $user->accessibleServers()->pluck('id')->all());
|
$builder = $builder->whereIn('servers.id', $user->accessibleServers()->pluck('id')->all());
|
||||||
}
|
}
|
||||||
|
|
||||||
$servers = $builder->paginate(min($request->query('per_page', 50), 100))->appends($request->query());
|
$servers = $builder->paginate(min((int) $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);
|
||||||
|
}
|
||||||
|
}
|
116
app/Http/Controllers/Api/Client/SecurityKeyController.php
Normal file
116
app/Http/Controllers/Api/Client/SecurityKeyController.php
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Controllers\Api\Client;
|
||||||
|
|
||||||
|
use Carbon\CarbonImmutable;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Pterodactyl\Models\SecurityKey;
|
||||||
|
use Illuminate\Contracts\Cache\Repository;
|
||||||
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
|
use Webauthn\PublicKeyCredentialCreationOptions;
|
||||||
|
use Pterodactyl\Transformers\Api\Client\SecurityKeyTransformer;
|
||||||
|
use Pterodactyl\Repositories\SecurityKeys\WebauthnServerRepository;
|
||||||
|
use Pterodactyl\Services\Users\SecurityKeys\StoreSecurityKeyService;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Client\Account\RegisterWebauthnTokenRequest;
|
||||||
|
use Pterodactyl\Services\Users\SecurityKeys\CreatePublicKeyCredentialsService;
|
||||||
|
|
||||||
|
class SecurityKeyController extends ClientApiController
|
||||||
|
{
|
||||||
|
protected CreatePublicKeyCredentialsService $createPublicKeyCredentials;
|
||||||
|
|
||||||
|
protected Repository $cache;
|
||||||
|
|
||||||
|
protected WebauthnServerRepository $webauthnServerRepository;
|
||||||
|
|
||||||
|
protected StoreSecurityKeyService $storeSecurityKeyService;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
Repository $cache,
|
||||||
|
WebauthnServerRepository $webauthnServerRepository,
|
||||||
|
StoreSecurityKeyService $storeSecurityKeyService,
|
||||||
|
CreatePublicKeyCredentialsService $createPublicKeyCredentials
|
||||||
|
) {
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->cache = $cache;
|
||||||
|
$this->webauthnServerRepository = $webauthnServerRepository;
|
||||||
|
$this->createPublicKeyCredentials = $createPublicKeyCredentials;
|
||||||
|
$this->storeSecurityKeyService = $storeSecurityKeyService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all of the hardware security keys (WebAuthn) that exists for a user.
|
||||||
|
*/
|
||||||
|
public function index(Request $request): array
|
||||||
|
{
|
||||||
|
return $this->fractal->collection($request->user()->securityKeys)
|
||||||
|
->transformWith(SecurityKeyTransformer::class)
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the data necessary for creating a new hardware security key for the
|
||||||
|
* user.
|
||||||
|
*/
|
||||||
|
public function create(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
$tokenId = Str::random(64);
|
||||||
|
$credentials = $this->createPublicKeyCredentials->handle($request->user());
|
||||||
|
|
||||||
|
// TODO: session
|
||||||
|
$this->cache->put(
|
||||||
|
"register-security-key:$tokenId",
|
||||||
|
serialize($credentials),
|
||||||
|
CarbonImmutable::now()->addMinutes(10)
|
||||||
|
);
|
||||||
|
|
||||||
|
return new JsonResponse([
|
||||||
|
'data' => [
|
||||||
|
'token_id' => $tokenId,
|
||||||
|
'credentials' => $credentials->jsonSerialize(),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores a new key for a user account.
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
|
* @throws \Throwable
|
||||||
|
*/
|
||||||
|
public function store(RegisterWebauthnTokenRequest $request): array
|
||||||
|
{
|
||||||
|
$credentials = unserialize(
|
||||||
|
$this->cache->pull("register-security-key:{$request->input('token_id')}", serialize(null))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!is_object($credentials) ||
|
||||||
|
!$credentials instanceof PublicKeyCredentialCreationOptions ||
|
||||||
|
$credentials->getUser()->getId() !== $request->user()->uuid
|
||||||
|
) {
|
||||||
|
throw new DisplayException('Could not register security key: invalid data present in session, please try again.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = $this->storeSecurityKeyService
|
||||||
|
->setRequest(SecurityKey::getPsrRequestFactory($request))
|
||||||
|
->setKeyName($request->input('name'))
|
||||||
|
->handle($request->user(), $request->input('registration'), $credentials);
|
||||||
|
|
||||||
|
return $this->fractal->item($key)
|
||||||
|
->transformWith(SecurityKeyTransformer::class)
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a WebAuthn key from a user's account.
|
||||||
|
*/
|
||||||
|
public function delete(Request $request, string $securityKey): JsonResponse
|
||||||
|
{
|
||||||
|
$request->user()->securityKeys()->where('uuid', $securityKey)->delete();
|
||||||
|
|
||||||
|
return new JsonResponse([], JsonResponse::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;
|
||||||
|
@ -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.
|
||||||
|
|
|
@ -5,7 +5,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 Pterodactyl\Models\Database;
|
use Pterodactyl\Models\Database;
|
||||||
use Pterodactyl\Repositories\Eloquent\DatabaseRepository;
|
|
||||||
use Pterodactyl\Services\Databases\DatabasePasswordService;
|
use Pterodactyl\Services\Databases\DatabasePasswordService;
|
||||||
use Pterodactyl\Transformers\Api\Client\DatabaseTransformer;
|
use Pterodactyl\Transformers\Api\Client\DatabaseTransformer;
|
||||||
use Pterodactyl\Services\Databases\DatabaseManagementService;
|
use Pterodactyl\Services\Databases\DatabaseManagementService;
|
||||||
|
@ -18,25 +17,9 @@ 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 DatabaseManagementService $managementService;
|
||||||
*/
|
private DatabasePasswordService $passwordService;
|
||||||
private $deployDatabaseService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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.
|
||||||
|
@ -44,24 +27,24 @@ class DatabaseController extends ClientApiController
|
||||||
public function __construct(
|
public function __construct(
|
||||||
DatabaseManagementService $managementService,
|
DatabaseManagementService $managementService,
|
||||||
DatabasePasswordService $passwordService,
|
DatabasePasswordService $passwordService,
|
||||||
DatabaseRepository $repository,
|
|
||||||
DeployServerDatabaseService $deployDatabaseService
|
DeployServerDatabaseService $deployDatabaseService
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->deployDatabaseService = $deployDatabaseService;
|
$this->deployDatabaseService = $deployDatabaseService;
|
||||||
$this->repository = $repository;
|
|
||||||
$this->managementService = $managementService;
|
$this->managementService = $managementService;
|
||||||
$this->passwordService = $passwordService;
|
$this->passwordService = $passwordService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 +61,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 +69,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,9 +6,7 @@ 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 Pterodactyl\Repositories\Wings\DaemonFileRepository;
|
use Pterodactyl\Repositories\Wings\DaemonFileRepository;
|
||||||
use Pterodactyl\Transformers\Daemon\FileObjectTransformer;
|
use Pterodactyl\Transformers\Daemon\FileObjectTransformer;
|
||||||
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
||||||
|
@ -26,33 +24,19 @@ 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 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(
|
||||||
ResponseFactory $responseFactory,
|
DaemonFileRepository $fileRepository,
|
||||||
NodeJWTService $jwtService,
|
NodeJWTService $jwtService
|
||||||
DaemonFileRepository $fileRepository
|
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->fileRepository = $fileRepository;
|
$this->fileRepository = $fileRepository;
|
||||||
$this->responseFactory = $responseFactory;
|
|
||||||
$this->jwtService = $jwtService;
|
$this->jwtService = $jwtService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +44,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 +53,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 +76,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 +107,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 +120,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 +128,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 +139,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 +147,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 +157,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 +176,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
|
||||||
{
|
{
|
||||||
|
@ -210,21 +193,21 @@ class FileController extends ClientApiController
|
||||||
return $this->fileRepository->setServer($server)
|
return $this->fileRepository->setServer($server)
|
||||||
->compressFiles(
|
->compressFiles(
|
||||||
$request->input('root'),
|
$request->input('root'),
|
||||||
$request->input('files')
|
$request->input('files'),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
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) {
|
$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.
|
||||||
set_time_limit(300);
|
set_time_limit(300);
|
||||||
|
|
||||||
|
@ -234,15 +217,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 +237,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
|
||||||
{
|
{
|
||||||
$this->fileRepository->setServer($server)
|
$server->audit(AuditLog::SERVER__FILESYSTEM_CHMOD, function (AuditLog $audit, Server $server) use ($request) {
|
||||||
->chmodFiles(
|
$audit->metadata = ['root' => $request->input('root'), 'files' => $request->input('files')];
|
||||||
$request->input('root'),
|
|
||||||
$request->input('files')
|
|
||||||
);
|
|
||||||
|
|
||||||
return new JsonResponse([], Response::HTTP_NO_CONTENT);
|
$this->fileRepository->setServer($server)
|
||||||
|
->chmodFiles(
|
||||||
|
$request->input('root'),
|
||||||
|
$request->input('files'),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this->returnNoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests that a file be downloaded from a remote location by Wings.
|
* 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 = ['root' => $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.
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue