Skip to content

Commit 8660fcd

Browse files
authored
Merge pull request pterodactyl#149 from Pterodactyl/feature/better-api
Implement better API system
2 parents b3f078a + f24347d commit 8660fcd

26 files changed

+1020
-598
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ This project follows [Semantic Versioning](http://semver.org) guidelines.
99
* Return node configuration from remote API by using `/api/nodes/{id}/config` endpoint. Only accepts SSL connections.
1010
* Support for filtering servers within Admin CP to narrow down results by name, email, allocation, or defined fields.
1111
* Setup scripts (user, mail, env) now support argument flags for use in containers and other non-terminal environments.
12+
* New API endpoints for individual users to control their servers with at `/api/me/*`.
1213

1314
### Changed
1415
* Creating a user, server, or node now returns `HTTP/1.1 200` and a JSON element with the user/server/node's ID.
1516
* Environment setting script is much more user friendly and does not require an excessive amount of clicking and typing.
1617
* File upload method switched from BinaryJS to Socket.io implementation to fix bugs as well as be a little speedier and allow upload throttling.
18+
* `Server::getbyUUID()` now accepts either the `uuidShort` or full-length `uuid` for server identification.
1719

1820
## v0.5.0-pre.2 (Bodacious Boreopterus)
1921

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
/**
3+
* Pterodactyl - Panel
4+
* Copyright (c) 2015 - 2016 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+
namespace Pterodactyl\Http\Controllers\API\User;
25+
26+
use Auth;
27+
use Dingo;
28+
use Pterodactyl\Models;
29+
use Illuminate\Http\Request;
30+
31+
use Pterodactyl\Http\Controllers\API\BaseController;
32+
33+
class InfoController extends BaseController
34+
{
35+
public function me(Request $request)
36+
{
37+
$servers = Models\Server::getUserServers();
38+
$response = [];
39+
40+
foreach($servers as &$server) {
41+
$response = array_merge($response, [[
42+
'id' => $server->uuidShort,
43+
'uuid' => $server->uuid,
44+
'name' => $server->name,
45+
'node' => $server->nodeName,
46+
'ip' => [
47+
'set' => $server->ip,
48+
'alias' => $server->ip_alias
49+
],
50+
'port' => $server->port,
51+
'service' => $server->a_serviceName,
52+
'option' => $server->a_serviceOptionName
53+
]]);
54+
}
55+
56+
return $response;
57+
}
58+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
/**
3+
* Pterodactyl - Panel
4+
* Copyright (c) 2015 - 2016 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+
namespace Pterodactyl\Http\Controllers\API\User;
25+
26+
use Auth;
27+
use Log;
28+
use Pterodactyl\Models;
29+
use Illuminate\Http\Request;
30+
31+
use Pterodactyl\Http\Controllers\API\BaseController;
32+
33+
class ServerController extends BaseController
34+
{
35+
36+
public function info(Request $request, $uuid)
37+
{
38+
$server = Models\Server::getByUUID($uuid);
39+
$node = Models\Node::findOrFail($server->node);
40+
$client = Models\Node::guzzleRequest($node->id);
41+
42+
try {
43+
$response = $client->request('GET', '/server', [
44+
'headers' => [
45+
'X-Access-Token' => $server->daemonSecret,
46+
'X-Access-Server' => $server->uuid
47+
]
48+
]);
49+
50+
$json = json_decode($response->getBody());
51+
$daemon = [
52+
'status' => $json->status,
53+
'stats' => $json->proc,
54+
'query' => $json->query
55+
];
56+
} catch (\Exception $ex) {
57+
$daemon = [
58+
'error' => 'An error was encountered while trying to connect to the daemon to collece information. It might be offline.'
59+
];
60+
Log::error($ex);
61+
}
62+
63+
$allocations = Models\Allocation::select('id', 'ip', 'port', 'ip_alias as alias')->where('assigned_to', $server->id)->get();
64+
foreach($allocations as &$allocation) {
65+
$allocation->default = ($allocation->id === $server->allocation);
66+
unset($allocation->id);
67+
}
68+
return [
69+
'uuidShort' => $server->uuidShort,
70+
'uuid' => $server->uuid,
71+
'name' => $server->name,
72+
'node' => $node->name,
73+
'limits' => [
74+
'memory' => $server->memory,
75+
'swap' => $server->swap,
76+
'disk' => $server->disk,
77+
'io' => $server->io,
78+
'cpu' => $server->cpu,
79+
'oom_disabled' => (bool) $server->oom_disabled
80+
],
81+
'allocations' => $allocations,
82+
'sftp' => [
83+
'username' => (Auth::user()->can('view-sftp', $server)) ? $server->username : null
84+
],
85+
'daemon' => [
86+
'token' => ($request->secure()) ? $server->daemonSecret : false,
87+
'response' => $daemon
88+
]
89+
];
90+
}
91+
92+
public function power(Request $request, $uuid)
93+
{
94+
$server = Models\Server::getByUUID($uuid);
95+
$node = Models\Node::getByID($server->node);
96+
$client = Models\Node::guzzleRequest($server->node);
97+
98+
Auth::user()->can('power-' . $request->input('action'), $server);
99+
100+
$res = $client->request('PUT', '/server/power', [
101+
'headers' => [
102+
'X-Access-Server' => $server->uuid,
103+
'X-Access-Token' => $server->daemonSecret
104+
],
105+
'exceptions' => false,
106+
'json' => [
107+
'action' => $request->input('action')
108+
]
109+
]);
110+
111+
if ($res->getStatusCode() !== 204) {
112+
return $this->response->error(json_decode($res->getBody())->error, $res->getStatusCode());
113+
}
114+
115+
return $this->response->noContent();
116+
}
117+
}

app/Http/Controllers/Admin/APIController.php renamed to app/Http/Controllers/Base/APIController.php

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/**
33
* Pterodactyl - Panel
44
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
5+
* Some Modifications (c) 2015 Dylan Seidt <dylan.seidt@gmail.com>
56
*
67
* Permission is hereby granted, free of charge, to any person obtaining a copy
78
* of this software and associated documentation files (the "Software"), to deal
@@ -21,80 +22,67 @@
2122
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2223
* SOFTWARE.
2324
*/
24-
namespace Pterodactyl\Http\Controllers\Admin;
25+
namespace Pterodactyl\Http\Controllers\Base;
2526

2627
use Alert;
2728
use Log;
2829

2930
use Pterodactyl\Models;
30-
use Pterodactyl\Repositories\APIRepository;
31-
use Pterodactyl\Http\Controllers\Controller;
3231

32+
use Pterodactyl\Repositories\APIRepository;
3333
use Pterodactyl\Exceptions\DisplayValidationException;
3434
use Pterodactyl\Exceptions\DisplayException;
35+
use Pterodactyl\Http\Controllers\Controller;
3536

3637
use Illuminate\Http\Request;
3738

3839
class APIController extends Controller
3940
{
40-
41-
public function __construct()
41+
public function index(Request $request)
4242
{
43-
//
44-
}
45-
46-
public function getIndex(Request $request)
47-
{
48-
$keys = Models\APIKey::all();
43+
$keys = Models\APIKey::where('user', $request->user()->id)->get();
4944
foreach($keys as &$key) {
5045
$key->permissions = Models\APIPermission::where('key_id', $key->id)->get();
5146
}
5247

53-
return view('admin.api.index', [
48+
return view('base.api.index', [
5449
'keys' => $keys
5550
]);
5651
}
5752

58-
public function getNew(Request $request)
53+
public function new(Request $request)
5954
{
60-
return view('admin.api.new');
55+
return view('base.api.new');
6156
}
6257

63-
public function postNew(Request $request)
58+
public function save(Request $request)
6459
{
6560
try {
66-
$api = new APIRepository;
67-
$secret = $api->new($request->except(['_token']));
68-
// Alert::info('An API Keypair has successfully been generated. The API secret for this public key is shown below and will not be shown again.<br /><br />Secret: <code>' . $secret . '</code>')->flash();
69-
Alert::info("<script type='text/javascript'>swal({
70-
type: 'info',
71-
title: 'Secret Key',
72-
html: true,
73-
text: 'The secret for this keypair is shown below and will not be shown again.<hr /><code style=\'text-align:center;\'>" . $secret . "</code>'
74-
});</script>")->flash();
75-
return redirect()->route('admin.api');
61+
$repo = new APIRepository($request->user());
62+
$secret = $repo->new($request->except(['_token']));
63+
Alert::success('An API Keypair has successfully been generated. The API secret for this public key is shown below and will not be shown again.<br /><br /><code>' . $secret . '</code>')->flash();
64+
return redirect()->route('account.api');
7665
} catch (DisplayValidationException $ex) {
77-
return redirect()->route('admin.api.new')->withErrors(json_decode($ex->getMessage()))->withInput();
66+
return redirect()->route('account.api.new')->withErrors(json_decode($ex->getMessage()))->withInput();
7867
} catch (DisplayException $ex) {
7968
Alert::danger($ex->getMessage())->flash();
8069
} catch (\Exception $ex) {
8170
Log::error($ex);
8271
Alert::danger('An unhandled exception occured while attempting to add this API key.')->flash();
8372
}
84-
return redirect()->route('admin.api.new')->withInput();
73+
return redirect()->route('account.api.new')->withInput();
8574
}
8675

87-
public function deleteRevokeKey(Request $request, $key)
76+
public function revoke(Request $request, $key)
8877
{
8978
try {
90-
$api = new APIRepository;
91-
$api->revoke($key);
79+
$repo = new APIRepository($request->user());
80+
$repo->revoke($key);
9281
return response('', 204);
9382
} catch (\Exception $ex) {
9483
return response()->json([
9584
'error' => 'An error occured while attempting to remove this key.'
9685
], 503);
9786
}
9887
}
99-
10088
}

0 commit comments

Comments
 (0)