Skip to content

Commit db168e3

Browse files
authored
Merge pull request pterodactyl#371 from Pterodactyl/feature/fractal-api
Implement new API and Route Updates
2 parents 10ee777 + 93d7999 commit db168e3

File tree

73 files changed

+3915
-2672
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+3915
-2672
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ This project follows [Semantic Versioning](http://semver.org) guidelines.
2020
* Attempting to reset a password for an account that does not exist no longer returns an error, rather it displays a success message. Failed resets trigger a `Pterodactyl\Events\Auth\FailedPasswordReset` event that can be caught if needed to perform other actions.
2121
* Servers are no longer queued for deletion due to the general hassle and extra logic required.
2222
* Updated all panel components to run on Laravel v5.4 rather than 5.3 which is EOL.
23+
* Routes are now handled in the `routes/` folder, and use a significantly cleaner syntax. Controller names and methods have been updated as well to be clearer as well as avoid conflicts with PHP reserved keywords.
24+
* API has been completely overhauled to use new permissions system. **Any old API keys will immediately become invalid and fail to operate properly anymore. You will need to generate new keys.**
2325

2426
## v0.6.0-pre.7 (Courageous Carniadactylus)
2527
### Fixed

app/Exceptions/Handler.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Log;
66
use Exception;
7-
use DisplayException;
87
use Illuminate\Auth\AuthenticationException;
98
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
109

@@ -46,10 +45,20 @@ public function report(Exception $exception)
4645
*/
4746
public function render($request, Exception $exception)
4847
{
49-
if ($request->expectsJson()) {
48+
if ($request->expectsJson() || $request->isJson() || $request->is(...config('pterodactyl.json_routes'))) {
49+
$exception = $this->prepareException($exception);
50+
51+
if (config('app.debug')) {
52+
$report = [
53+
'code' => (! $this->isHttpException($exception)) ?: $exception->getStatusCode(),
54+
'message' => class_basename($exception) . ' in ' . $exception->getFile() . ' on line ' . $exception->getLine(),
55+
];
56+
}
57+
5058
$response = response()->json([
51-
'error' => ($exception instanceof DisplayException) ? $exception->getMessage() : 'An unhandled error occured while attempting to process this request.',
52-
], ($this->isHttpException($exception)) ? $exception->getStatusCode() : 500);
59+
'error' => (config('app.debug')) ? $exception->getMessage() : 'An unhandled exception was encountered with this request.',
60+
'exception' => ! isset($report) ?: $report,
61+
], ($this->isHttpException($exception)) ? $exception->getStatusCode() : 500, [], JSON_UNESCAPED_SLASHES);
5362

5463
parent::report($exception);
5564
}

app/Http/Controllers/API/LocationController.php renamed to app/Http/Controllers/API/Admin/LocationController.php

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,30 @@
2222
* SOFTWARE.
2323
*/
2424

25-
namespace Pterodactyl\Http\Controllers\API;
25+
namespace Pterodactyl\Http\Controllers\API\Admin;
2626

27+
use Fractal;
2728
use Illuminate\Http\Request;
2829
use Pterodactyl\Models\Location;
30+
use Pterodactyl\Http\Controllers\Controller;
31+
use Pterodactyl\Transformers\Admin\LocationTransformer;
2932

30-
class LocationController extends BaseController
33+
class LocationController extends Controller
3134
{
3235
/**
33-
* Lists all locations currently on the system.
36+
* Controller to handle returning all locations on the system.
3437
*
35-
* @param Request $request
38+
* @param \Illuminate\Http\Request $request
3639
* @return array
3740
*/
3841
public function index(Request $request)
3942
{
40-
return Location::with('nodes')->get()->map(function ($item) {
41-
$item->nodes->transform(function ($item) {
42-
return collect($item)->only(['id', 'name', 'fqdn', 'scheme', 'daemonListen', 'daemonSFTP']);
43-
});
43+
$this->authorize('location-list', $request->apiKey());
4444

45-
return $item;
46-
})->toArray();
45+
return Fractal::create()
46+
->collection(Location::all())
47+
->transformWith(new LocationTransformer($request))
48+
->withResourceName('location')
49+
->toArray();
4750
}
4851
}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<?php
2+
/**
3+
* Pterodactyl - Panel
4+
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
namespace Pterodactyl\Http\Controllers\API\Admin;
26+
27+
use Fractal;
28+
use Illuminate\Http\Request;
29+
use Pterodactyl\Models\Node;
30+
use Pterodactyl\Exceptions\DisplayException;
31+
use Pterodactyl\Http\Controllers\Controller;
32+
use Pterodactyl\Repositories\NodeRepository;
33+
use Pterodactyl\Transformers\Admin\NodeTransformer;
34+
use Pterodactyl\Exceptions\DisplayValidationException;
35+
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
36+
37+
class NodeController extends Controller
38+
{
39+
/**
40+
* Controller to handle returning all nodes on the system.
41+
*
42+
* @param \Illuminate\Http\Request $request
43+
* @return array
44+
*/
45+
public function index(Request $request)
46+
{
47+
$this->authorize('node-list', $request->apiKey());
48+
49+
$nodes = Node::paginate(config('pterodactyl.paginate.api.nodes'));
50+
$fractal = Fractal::create()->collection($nodes)
51+
->transformWith(new NodeTransformer($request))
52+
->withResourceName('user')
53+
->paginateWith(new IlluminatePaginatorAdapter($nodes));
54+
55+
if (config('pterodactyl.api.include_on_list') && $request->input('include')) {
56+
$fractal->parseIncludes(explode(',', $request->input('include')));
57+
}
58+
59+
return $fractal->toArray();
60+
}
61+
62+
/**
63+
* Display information about a single node on the system.
64+
*
65+
* @param \Illuminate\Http\Request $request
66+
* @param int $id
67+
* @return array
68+
*/
69+
public function view(Request $request, $id)
70+
{
71+
$this->authorize('node-view', $request->apiKey());
72+
73+
$fractal = Fractal::create()->item(Node::findOrFail($id));
74+
if ($request->input('include')) {
75+
$fractal->parseIncludes(explode(',', $request->input('include')));
76+
}
77+
78+
return $fractal->transformWith(new NodeTransformer($request))
79+
->withResourceName('node')
80+
->toArray();
81+
}
82+
83+
/**
84+
* Display information about a single node on the system.
85+
*
86+
* @param \Illuminate\Http\Request $request
87+
* @param int $id
88+
* @return \Illuminate\Http\JsonResponse
89+
*/
90+
public function viewConfig(Request $request, $id)
91+
{
92+
$this->authorize('node-view-config', $request->apiKey());
93+
94+
$node = Node::findOrFail($id);
95+
96+
return response()->json(json_decode($node->getConfigurationAsJson()));
97+
}
98+
99+
/**
100+
* Create a new node on the system.
101+
*
102+
* @param \Illuminate\Http\Request $request
103+
* @return \Illuminate\Http\JsonResponse|array
104+
*/
105+
public function store(Request $request)
106+
{
107+
$this->authorize('node-create', $request->apiKey());
108+
109+
$repo = new NodeRepository;
110+
try {
111+
$node = $repo->create(array_merge(
112+
$request->only([
113+
'public', 'disk_overallocate', 'memory_overallocate',
114+
]),
115+
$request->intersect([
116+
'name', 'location_id', 'fqdn',
117+
'scheme', 'memory', 'disk',
118+
'daemonBase', 'daemonSFTP', 'daemonListen',
119+
])
120+
));
121+
122+
$fractal = Fractal::create()->item($node)->transformWith(new NodeTransformer($request));
123+
if ($request->input('include')) {
124+
$fractal->parseIncludes(explode(',', $request->input('include')));
125+
}
126+
127+
return $fractal->withResourceName('node')->toArray();
128+
} catch (DisplayValidationException $ex) {
129+
return response()->json([
130+
'error' => json_decode($ex->getMessage()),
131+
], 400);
132+
} catch (DisplayException $ex) {
133+
return response()->json([
134+
'error' => $ex->getMessage(),
135+
], 400);
136+
} catch (\Exception $ex) {
137+
Log::error($ex);
138+
139+
return response()->json([
140+
'error' => 'An unhandled exception occured while attemping to create this node. Please try again.',
141+
], 500);
142+
}
143+
}
144+
145+
/**
146+
* Delete a node from the system.
147+
*
148+
* @param \Illuminate\Http\Request $request
149+
* @param int $id
150+
* @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
151+
*/
152+
public function delete(Request $request, $id)
153+
{
154+
$this->authorize('node-delete', $request->apiKey());
155+
156+
$repo = new NodeRepository;
157+
try {
158+
$repo->delete($id);
159+
160+
return response('', 204);
161+
} catch (DisplayException $ex) {
162+
return response()->json([
163+
'error' => $ex->getMessage(),
164+
], 400);
165+
} catch (\Exception $ex) {
166+
Log::error($ex);
167+
168+
return response()->json([
169+
'error' => 'An unhandled exception occured while attemping to delete this node. Please try again.',
170+
], 500);
171+
}
172+
}
173+
}

0 commit comments

Comments
 (0)