Add back API (#80)
Re-implements the API after it was removed in the Laravel 5.3 upgrade.
This commit is contained in:
parent
b02df8e610
commit
7529e961de
|
@ -10,6 +10,7 @@ This file is a running track of new features and fixes to each version of the pa
|
||||||
* Adds support for IP Aliases on display pages for users. This makes it possible to use GRE tunnels and still show the user what IP they should be connecting to.
|
* Adds support for IP Aliases on display pages for users. This makes it possible to use GRE tunnels and still show the user what IP they should be connecting to.
|
||||||
* Adds support for suspending servers
|
* Adds support for suspending servers
|
||||||
* Adds support for viewing SFTP password within the panel (#74, thanks @ET-Bent)
|
* Adds support for viewing SFTP password within the panel (#74, thanks @ET-Bent)
|
||||||
|
* Improved API with support for server suspension and build modification.
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
* Fixes password auto-generation on 'Manage Server' page. (#67, thanks @ET-Bent)
|
* Fixes password auto-generation on 'Manage Server' page. (#67, thanks @ET-Bent)
|
||||||
|
@ -19,4 +20,4 @@ This file is a running track of new features and fixes to each version of the pa
|
||||||
* Fixes a few display issues relating to subusers and database management.
|
* Fixes a few display issues relating to subusers and database management.
|
||||||
|
|
||||||
### General
|
### General
|
||||||
* Update Laravel to version `5.3` and update dependencies. **[BREAKING]** This removes the remote API from the panel due to Dingo API instability. This message will be removed when it is added back.
|
* Update Laravel to version `5.3` and update dependencies.
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
namespace Pterodactyl\Http\Controllers\API;
|
||||||
|
|
||||||
|
use Dingo\Api\Routing\Helpers;
|
||||||
|
use Illuminate\Routing\Controller;
|
||||||
|
|
||||||
|
class BaseController extends Controller
|
||||||
|
{
|
||||||
|
use Helpers;
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
namespace Pterodactyl\Http\Controllers\API;
|
||||||
|
|
||||||
|
use DB;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Pterodactyl\Models\Location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Resource("Servers")
|
||||||
|
*/
|
||||||
|
class LocationController extends BaseController
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List All Locations
|
||||||
|
*
|
||||||
|
* Lists all locations currently on the system.
|
||||||
|
*
|
||||||
|
* @Get("/locations")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Response(200)
|
||||||
|
*/
|
||||||
|
public function list(Request $request)
|
||||||
|
{
|
||||||
|
$locations = Location::select('locations.*', DB::raw('GROUP_CONCAT(nodes.id) as nodes'))
|
||||||
|
->join('nodes', 'locations.id', '=', 'nodes.location')
|
||||||
|
->groupBy('locations.id')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
foreach($locations as &$location) {
|
||||||
|
$location->nodes = explode(',', $location->nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $locations;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,203 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
namespace Pterodactyl\Http\Controllers\API;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
use Pterodactyl\Models;
|
||||||
|
use Pterodactyl\Transformers\NodeTransformer;
|
||||||
|
use Pterodactyl\Transformers\AllocationTransformer;
|
||||||
|
use Pterodactyl\Repositories\NodeRepository;
|
||||||
|
|
||||||
|
use Pterodactyl\Exceptions\DisplayValidationException;
|
||||||
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
|
use Dingo\Api\Exception\ResourceException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Resource("Servers")
|
||||||
|
*/
|
||||||
|
class NodeController extends BaseController
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List All Nodes
|
||||||
|
*
|
||||||
|
* Lists all nodes currently on the system.
|
||||||
|
*
|
||||||
|
* @Get("/nodes/{?page}")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("page", type="integer", description="The page of results to view.", default=1)
|
||||||
|
* })
|
||||||
|
* @Response(200)
|
||||||
|
*/
|
||||||
|
public function list(Request $request)
|
||||||
|
{
|
||||||
|
$nodes = Models\Node::paginate(50);
|
||||||
|
return $this->response->paginator($nodes, new NodeTransformer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a New Node
|
||||||
|
*
|
||||||
|
* @Post("/nodes")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Transaction({
|
||||||
|
* @Request({
|
||||||
|
* 'name' => 'My API Node',
|
||||||
|
* 'location' => 1,
|
||||||
|
* 'public' => 1,
|
||||||
|
* 'fqdn' => 'daemon.wuzzle.woo',
|
||||||
|
* 'scheme' => 'https',
|
||||||
|
* 'memory' => 10240,
|
||||||
|
* 'memory_overallocate' => 100,
|
||||||
|
* 'disk' => 204800,
|
||||||
|
* 'disk_overallocate' => -1,
|
||||||
|
* 'daemonBase' => '/srv/daemon-data',
|
||||||
|
* 'daemonSFTP' => 2022,
|
||||||
|
* 'daemonListen' => 8080
|
||||||
|
* }, headers={"Authorization": "Bearer <jwt-token>"}),
|
||||||
|
* @Response(201),
|
||||||
|
* @Response(422, body={
|
||||||
|
* "message": "A validation error occured.",
|
||||||
|
* "errors": {},
|
||||||
|
* "status_code": 422
|
||||||
|
* }),
|
||||||
|
* @Response(503, body={
|
||||||
|
* "message": "There was an error while attempting to add this node to the system.",
|
||||||
|
* "status_code": 503
|
||||||
|
* })
|
||||||
|
* })
|
||||||
|
*/
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$node = new NodeRepository;
|
||||||
|
$new = $node->create($request->all());
|
||||||
|
return $this->response->created(route('api.nodes.view', [
|
||||||
|
'id' => $new
|
||||||
|
]));
|
||||||
|
} catch (DisplayValidationException $ex) {
|
||||||
|
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
|
||||||
|
} catch (DisplayException $ex) {
|
||||||
|
throw new ResourceException($ex->getMessage());
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new BadRequestHttpException('There was an error while attempting to add this node to the system.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List Specific Node
|
||||||
|
*
|
||||||
|
* Lists specific fields about a server or all fields pertaining to that node.
|
||||||
|
*
|
||||||
|
* @Get("/nodes/{id}/{?fields}")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("id", type="integer", required=true, description="The ID of the node to get information on."),
|
||||||
|
* @Parameter("fields", type="string", required=false, description="A comma delimidated list of fields to include.")
|
||||||
|
* })
|
||||||
|
* @Response(200)
|
||||||
|
*/
|
||||||
|
public function view(Request $request, $id, $fields = null)
|
||||||
|
{
|
||||||
|
$query = Models\Node::where('id', $id);
|
||||||
|
|
||||||
|
if (!is_null($request->input('fields'))) {
|
||||||
|
foreach(explode(',', $request->input('fields')) as $field) {
|
||||||
|
if (!empty($field)) {
|
||||||
|
$query->addSelect($field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!$query->first()) {
|
||||||
|
throw new NotFoundHttpException('No node by that ID was found.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'node' => $query->first(),
|
||||||
|
'allocations' => [
|
||||||
|
'assigned' => Models\Allocation::where('node', $id)->whereNotNull('assigned_to')->get(),
|
||||||
|
'unassigned' => Models\Allocation::where('node', $id)->whereNull('assigned_to')->get()
|
||||||
|
]
|
||||||
|
];
|
||||||
|
} catch (NotFoundHttpException $ex) {
|
||||||
|
throw $ex;
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
throw new BadRequestHttpException('There was an issue with the fields passed in the request.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all Node Allocations
|
||||||
|
*
|
||||||
|
* Returns a listing of all allocations for every node.
|
||||||
|
*
|
||||||
|
* @Get("/nodes/allocations")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Response(200)
|
||||||
|
*/
|
||||||
|
public function allocations(Request $request)
|
||||||
|
{
|
||||||
|
$allocations = Models\Allocation::paginate(100);
|
||||||
|
if ($allocations->count() < 1) {
|
||||||
|
throw new NotFoundHttpException('No allocations have been created.');
|
||||||
|
}
|
||||||
|
return $this->response->paginator($allocations, new AllocationTransformer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete Node
|
||||||
|
*
|
||||||
|
* @Delete("/nodes/{id}")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("id", type="integer", required=true, description="The ID of the node."),
|
||||||
|
* })
|
||||||
|
* @Response(204)
|
||||||
|
*/
|
||||||
|
public function delete(Request $request, $id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$node = new NodeRepository;
|
||||||
|
$node->delete($id);
|
||||||
|
return $this->response->noContent();
|
||||||
|
} catch (DisplayException $ex) {
|
||||||
|
throw new ResourceException($ex->getMessage());
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
throw new ServiceUnavailableHttpException('An error occured while attempting to delete this node.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,282 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
namespace Pterodactyl\Http\Controllers\API;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
use Log;
|
||||||
|
use Pterodactyl\Models;
|
||||||
|
use Pterodactyl\Transformers\ServerTransformer;
|
||||||
|
use Pterodactyl\Repositories\ServerRepository;
|
||||||
|
|
||||||
|
use Pterodactyl\Exceptions\DisplayValidationException;
|
||||||
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
|
use Dingo\Api\Exception\ResourceException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Resource("Servers")
|
||||||
|
*/
|
||||||
|
class ServerController extends BaseController
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List All Servers
|
||||||
|
*
|
||||||
|
* Lists all servers currently on the system.
|
||||||
|
*
|
||||||
|
* @Get("/servers/{?page}")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("page", type="integer", description="The page of results to view.", default=1)
|
||||||
|
* })
|
||||||
|
* @Response(200)
|
||||||
|
*/
|
||||||
|
public function list(Request $request)
|
||||||
|
{
|
||||||
|
$servers = Models\Server::paginate(50);
|
||||||
|
return $this->response->paginator($servers, new ServerTransformer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Server
|
||||||
|
*
|
||||||
|
* @Post("/servers")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Response(201)
|
||||||
|
*/
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$server = new ServerRepository;
|
||||||
|
$new = $server->create($request->all());
|
||||||
|
return $this->response->created(route('api.servers.view', [
|
||||||
|
'id' => $new
|
||||||
|
]));
|
||||||
|
} catch (DisplayValidationException $ex) {
|
||||||
|
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
|
||||||
|
} catch (DisplayException $ex) {
|
||||||
|
throw new ResourceException($ex->getMessage());
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
Log::error($ex);
|
||||||
|
throw new BadRequestHttpException('There was an error while attempting to add this server to the system.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List Specific Server
|
||||||
|
*
|
||||||
|
* Lists specific fields about a server or all fields pertaining to that server.
|
||||||
|
*
|
||||||
|
* @Get("/servers/{id}{?fields}")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("id", type="integer", required=true, description="The ID of the server to get information on."),
|
||||||
|
* @Parameter("fields", type="string", required=false, description="A comma delimidated list of fields to include.")
|
||||||
|
* })
|
||||||
|
* @Response(200)
|
||||||
|
*/
|
||||||
|
public function view(Request $request, $id)
|
||||||
|
{
|
||||||
|
$query = Models\Server::where('id', $id);
|
||||||
|
|
||||||
|
if (!is_null($request->input('fields'))) {
|
||||||
|
foreach(explode(',', $request->input('fields')) as $field) {
|
||||||
|
if (!empty($field)) {
|
||||||
|
$query->addSelect($field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!$query->first()) {
|
||||||
|
throw new NotFoundHttpException('No server by that ID was found.');
|
||||||
|
}
|
||||||
|
return $query->first();
|
||||||
|
} catch (NotFoundHttpException $ex) {
|
||||||
|
throw $ex;
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
throw new BadRequestHttpException('There was an issue with the fields passed in the request.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Server configuration
|
||||||
|
*
|
||||||
|
* Updates display information on panel.
|
||||||
|
*
|
||||||
|
* @Patch("/servers/{id}/config")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Transaction({
|
||||||
|
* @Request({
|
||||||
|
* "owner": "new@email.com",
|
||||||
|
* "name": "New Name",
|
||||||
|
* "reset_token": true
|
||||||
|
* }, headers={"Authorization": "Bearer <token>"}),
|
||||||
|
* @Response(200, body={"name": "New Name"}),
|
||||||
|
* @Response(422)
|
||||||
|
* })
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("id", type="integer", required=true, description="The ID of the server to modify.")
|
||||||
|
* })
|
||||||
|
*/
|
||||||
|
public function config(Request $request, $id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$server = new ServerRepository;
|
||||||
|
$server->updateDetails($id, $request->all());
|
||||||
|
return Models\Server::findOrFail($id);
|
||||||
|
} catch (DisplayValidationException $ex) {
|
||||||
|
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
|
||||||
|
} catch (DisplayException $ex) {
|
||||||
|
throw new ResourceException($ex->getMessage());
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
throw new ServiceUnavailableHttpException('Unable to update server on system due to an error.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Server Build Configuration
|
||||||
|
*
|
||||||
|
* Updates server build information on panel and on node.
|
||||||
|
*
|
||||||
|
* @Patch("/servers/{id}/build")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Transaction({
|
||||||
|
* @Request({
|
||||||
|
* "default": "192.168.0.1:25565",
|
||||||
|
* "add_additional": [
|
||||||
|
* "192.168.0.1:25566",
|
||||||
|
* "192.168.0.1:25567",
|
||||||
|
* "192.168.0.1:25568"
|
||||||
|
* ],
|
||||||
|
* "remove_additional": [],
|
||||||
|
* "memory": 1024,
|
||||||
|
* "swap": 0,
|
||||||
|
* "io": 500,
|
||||||
|
* "cpu": 0,
|
||||||
|
* "disk": 1024
|
||||||
|
* }, headers={"Authorization": "Bearer <token>"}),
|
||||||
|
* @Response(200, body={"name": "New Name"}),
|
||||||
|
* @Response(422)
|
||||||
|
* })
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("id", type="integer", required=true, description="The ID of the server to modify.")
|
||||||
|
* })
|
||||||
|
*/
|
||||||
|
public function build(Request $request, $id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
throw new BadRequestHttpException('There was an error while attempting to add this node to the system.');
|
||||||
|
|
||||||
|
$server = new ServerRepository;
|
||||||
|
$server->changeBuild($id, $request->all());
|
||||||
|
return Models\Server::findOrFail($id);
|
||||||
|
} catch (DisplayValidationException $ex) {
|
||||||
|
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
|
||||||
|
} catch (DisplayException $ex) {
|
||||||
|
throw new ResourceException($ex->getMessage());
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
throw new ServiceUnavailableHttpException('Unable to update server on system due to an error.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suspend Server
|
||||||
|
*
|
||||||
|
* @Post("/servers/{id}/suspend")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("id", type="integer", required=true, description="The ID of the server."),
|
||||||
|
* })
|
||||||
|
* @Response(204)
|
||||||
|
*/
|
||||||
|
public function suspend(Request $request, $id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$server = new ServerRepository;
|
||||||
|
$server->suspend($id);
|
||||||
|
return $this->response->noContent();
|
||||||
|
} catch (DisplayException $ex) {
|
||||||
|
throw new ResourceException($ex->getMessage());
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
throw new ServiceUnavailableHttpException('An error occured while attempting to suspend this server instance.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsuspend Server
|
||||||
|
*
|
||||||
|
* @Post("/servers/{id}/unsuspend")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("id", type="integer", required=true, description="The ID of the server."),
|
||||||
|
* })
|
||||||
|
* @Response(204)
|
||||||
|
*/
|
||||||
|
public function unsuspend(Request $request, $id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$server = new ServerRepository;
|
||||||
|
$server->unsuspend($id);
|
||||||
|
return $this->response->noContent();
|
||||||
|
} catch (DisplayException $ex) {
|
||||||
|
throw new ResourceException($ex->getMessage());
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
throw new ServiceUnavailableHttpException('An error occured while attempting to unsuspend this server instance.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete Server
|
||||||
|
*
|
||||||
|
* @Delete("/servers/{id}/{force}")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("id", type="integer", required=true, description="The ID of the server."),
|
||||||
|
* @Parameter("force", type="string", required=false, description="Use 'force' if the server should be removed regardless of daemon response."),
|
||||||
|
* })
|
||||||
|
* @Response(204)
|
||||||
|
*/
|
||||||
|
public function delete(Request $request, $id, $force = null)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$server = new ServerRepository;
|
||||||
|
$server->deleteServer($id, $force);
|
||||||
|
return $this->response->noContent();
|
||||||
|
} catch (DisplayException $ex) {
|
||||||
|
throw new ResourceException($ex->getMessage());
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
throw new ServiceUnavailableHttpException('An error occured while attempting to delete this server.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
namespace Pterodactyl\Http\Controllers\API;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
use Pterodactyl\Models;
|
||||||
|
use Pterodactyl\Transformers\ServiceTransformer;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Resource("Services")
|
||||||
|
*/
|
||||||
|
class ServiceController extends BaseController
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public function list(Request $request)
|
||||||
|
{
|
||||||
|
return Models\Service::all();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function view(Request $request, $id)
|
||||||
|
{
|
||||||
|
$service = Models\Service::find($id);
|
||||||
|
if (!$service) {
|
||||||
|
throw new NotFoundHttpException('No service by that ID was found.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$options = Models\ServiceOptions::select('id', 'name', 'description', 'tag', 'docker_image')->where('parent_service', $service->id)->get();
|
||||||
|
foreach($options as &$opt) {
|
||||||
|
$opt->variables = Models\ServiceVariables::where('option_id', $opt->id)->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'service' => $service,
|
||||||
|
'options' => $options
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,207 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
namespace Pterodactyl\Http\Controllers\API;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
use Dingo\Api\Exception\ResourceException;
|
||||||
|
|
||||||
|
use Pterodactyl\Models;
|
||||||
|
use Pterodactyl\Transformers\UserTransformer;
|
||||||
|
use Pterodactyl\Repositories\UserRepository;
|
||||||
|
|
||||||
|
use Pterodactyl\Exceptions\DisplayValidationException;
|
||||||
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Resource("Users")
|
||||||
|
*/
|
||||||
|
class UserController extends BaseController
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List All Users
|
||||||
|
*
|
||||||
|
* Lists all users currently on the system.
|
||||||
|
*
|
||||||
|
* @Get("/users/{?page}")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("page", type="integer", description="The page of results to view.", default=1)
|
||||||
|
* })
|
||||||
|
* @Response(200)
|
||||||
|
*/
|
||||||
|
public function list(Request $request)
|
||||||
|
{
|
||||||
|
$users = Models\User::paginate(50);
|
||||||
|
return $this->response->paginator($users, new UserTransformer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List Specific User
|
||||||
|
*
|
||||||
|
* Lists specific fields about a user or all fields pertaining to that user.
|
||||||
|
*
|
||||||
|
* @Get("/users/{id}/{fields}")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("id", type="integer", required=true, description="The ID of the user to get information on."),
|
||||||
|
* @Parameter("fields", type="string", required=false, description="A comma delimidated list of fields to include.")
|
||||||
|
* })
|
||||||
|
* @Response(200)
|
||||||
|
*/
|
||||||
|
public function view(Request $request, $id)
|
||||||
|
{
|
||||||
|
$query = Models\User::where('id', $id);
|
||||||
|
|
||||||
|
if (!is_null($request->input('fields'))) {
|
||||||
|
foreach(explode(',', $request->input('fields')) as $field) {
|
||||||
|
if (!empty($field)) {
|
||||||
|
$query->addSelect($field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!$query->first()) {
|
||||||
|
throw new NotFoundHttpException('No user by that ID was found.');
|
||||||
|
}
|
||||||
|
return $query->first();
|
||||||
|
} catch (NotFoundHttpException $ex) {
|
||||||
|
throw $ex;
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
throw new BadRequestHttpException('There was an issue with the fields passed in the request.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a New User
|
||||||
|
*
|
||||||
|
* @Post("/users")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Transaction({
|
||||||
|
* @Request({
|
||||||
|
* "email": "foo@example.com",
|
||||||
|
* "password": "foopassword",
|
||||||
|
* "admin": false
|
||||||
|
* }, headers={"Authorization": "Bearer <token>"}),
|
||||||
|
* @Response(201),
|
||||||
|
* @Response(422, body={
|
||||||
|
* "message": "A validation error occured.",
|
||||||
|
* "errors": {
|
||||||
|
* "email": {"The email field is required."},
|
||||||
|
* "password": {"The password field is required."},
|
||||||
|
* "admin": {"The admin field is required."}
|
||||||
|
* },
|
||||||
|
* "status_code": 422
|
||||||
|
* })
|
||||||
|
* })
|
||||||
|
*/
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$user = new UserRepository;
|
||||||
|
$create = $user->create($request->input('email'), $request->input('password'), $request->input('admin'));
|
||||||
|
return $this->response->created(route('api.users.view', [
|
||||||
|
'id' => $create
|
||||||
|
]));
|
||||||
|
} catch (DisplayValidationException $ex) {
|
||||||
|
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
|
||||||
|
} catch (DisplayException $ex) {
|
||||||
|
throw new ResourceException($ex->getMessage());
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
throw new ServiceUnavailableHttpException('Unable to create a user on the system due to an error.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update an Existing User
|
||||||
|
*
|
||||||
|
* The data sent in the request will be used to update the existing user on the system.
|
||||||
|
*
|
||||||
|
* @Patch("/users/{id}")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Transaction({
|
||||||
|
* @Request({
|
||||||
|
* "email": "new@email.com"
|
||||||
|
* }, headers={"Authorization": "Bearer <token>"}),
|
||||||
|
* @Response(200, body={"email": "new@email.com"}),
|
||||||
|
* @Response(422)
|
||||||
|
* })
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("id", type="integer", required=true, description="The ID of the user to modify.")
|
||||||
|
* })
|
||||||
|
*/
|
||||||
|
public function update(Request $request, $id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$user = new UserRepository;
|
||||||
|
$user->update($id, $request->all());
|
||||||
|
return Models\User::findOrFail($id);
|
||||||
|
} catch (DisplayValidationException $ex) {
|
||||||
|
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
|
||||||
|
} catch (DisplayException $ex) {
|
||||||
|
throw new ResourceException($ex->getMessage());
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
throw new ServiceUnavailableHttpException('Unable to update a user on the system due to an error.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a User
|
||||||
|
*
|
||||||
|
* @Delete("/users/{id}")
|
||||||
|
* @Versions({"v1"})
|
||||||
|
* @Transaction({
|
||||||
|
* @Request(headers={"Authorization": "Bearer <token>"}),
|
||||||
|
* @Response(204),
|
||||||
|
* @Response(422)
|
||||||
|
* })
|
||||||
|
* @Parameters({
|
||||||
|
* @Parameter("id", type="integer", required=true, description="The ID of the user to delete.")
|
||||||
|
* })
|
||||||
|
*/
|
||||||
|
public function delete(Request $request, $id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$user = new UserRepository;
|
||||||
|
$user->delete($id);
|
||||||
|
return $this->response->noContent();
|
||||||
|
} catch (DisplayException $ex) {
|
||||||
|
throw new ResourceException($ex->getMessage());
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
throw new ServiceUnavailableHttpException('Unable to delete this user due to an error.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -65,7 +65,13 @@ class APIController extends Controller
|
||||||
try {
|
try {
|
||||||
$api = new APIRepository;
|
$api = new APIRepository;
|
||||||
$secret = $api->new($request->except(['_token']));
|
$secret = $api->new($request->except(['_token']));
|
||||||
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();
|
// 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();
|
||||||
|
Alert::info("<script type='text/javascript'>swal({
|
||||||
|
type: 'info',
|
||||||
|
title: 'Secret Key',
|
||||||
|
html: true,
|
||||||
|
text: 'The secret for this keypair is shown below and will not be shown again.<hr /><code style=\'text-align:center;\'>" . $secret . "</code>'
|
||||||
|
});</script>")->flash();
|
||||||
return redirect()->route('admin.api');
|
return redirect()->route('admin.api');
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
return redirect()->route('admin.api.new')->withErrors(json_decode($ex->getMessage()))->withInput();
|
return redirect()->route('admin.api.new')->withErrors(json_decode($ex->getMessage()))->withInput();
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
namespace Pterodactyl\Http\Middleware;
|
||||||
|
|
||||||
|
use Crypt;
|
||||||
|
use IPTools\IP;
|
||||||
|
use IPTools\Range;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\APIKey;
|
||||||
|
use Pterodactyl\Models\APIPermission;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Dingo\Api\Routing\Route;
|
||||||
|
use Dingo\Api\Auth\Provider\Authorization;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; // 400
|
||||||
|
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; // 401
|
||||||
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; // 403
|
||||||
|
use Symfony\Component\HttpKernel\Exception\HttpException; //500
|
||||||
|
|
||||||
|
class APISecretToken extends Authorization
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $algo = 'sha256';
|
||||||
|
|
||||||
|
protected $permissionAllowed = false;
|
||||||
|
|
||||||
|
protected $url = '';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAuthorizationMethod()
|
||||||
|
{
|
||||||
|
return 'Authorization';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authenticate(Request $request, Route $route)
|
||||||
|
{
|
||||||
|
if (!$request->bearerToken() || empty($request->bearerToken())) {
|
||||||
|
throw new UnauthorizedHttpException('The authentication header was missing or malformed');
|
||||||
|
}
|
||||||
|
|
||||||
|
list($public, $hashed) = explode('.', $request->bearerToken());
|
||||||
|
|
||||||
|
$key = APIKey::where('public', $public)->first();
|
||||||
|
if (!$key) {
|
||||||
|
throw new AccessDeniedHttpException('Invalid API Key.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for Resource Permissions
|
||||||
|
if (!empty($request->route()->getName())) {
|
||||||
|
if(!is_null($key->allowed_ips)) {
|
||||||
|
$inRange = false;
|
||||||
|
foreach(json_decode($key->allowed_ips) as $ip) {
|
||||||
|
if (Range::parse($ip)->contains(new IP($request->ip()))) {
|
||||||
|
$inRange = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$inRange) {
|
||||||
|
throw new AccessDeniedHttpException('This IP address <' . $request->ip() . '> does not have permission to use this API key.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(APIPermission::where('key_id', $key->id)->get() as &$row) {
|
||||||
|
if ($row->permission === '*' || $row->permission === $request->route()->getName()) {
|
||||||
|
$this->permissionAllowed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->permissionAllowed) {
|
||||||
|
throw new AccessDeniedHttpException('You do not have permission to access this resource.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$decrypted = Crypt::decrypt($key->secret);
|
||||||
|
} catch (\Illuminate\Contracts\Encryption\DecryptException $ex) {
|
||||||
|
throw new HttpException('There was an error while attempting to check your secret key.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->url = urldecode($request->fullUrl());
|
||||||
|
if($this->_generateHMAC($request->getContent(), $decrypted) !== base64_decode($hashed)) {
|
||||||
|
throw new BadRequestHttpException('The hashed body was not valid. Potential modification of contents in route.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function _generateHMAC($body, $key)
|
||||||
|
{
|
||||||
|
$data = $this->url . $body;
|
||||||
|
return hash_hmac($this->algo, $data, $key, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
namespace Pterodactyl\Http\Routes;
|
||||||
|
|
||||||
|
use Pterodactyl\Models;
|
||||||
|
use Illuminate\Routing\Router;
|
||||||
|
|
||||||
|
class APIRoutes
|
||||||
|
{
|
||||||
|
|
||||||
|
public function map(Router $router) {
|
||||||
|
|
||||||
|
$api = app('Dingo\Api\Routing\Router');
|
||||||
|
$api->version('v1', ['middleware' => 'api.auth'], function ($api) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User Routes
|
||||||
|
*/
|
||||||
|
$api->get('users', [
|
||||||
|
'as' => 'api.users.list',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\UserController@list'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->post('users', [
|
||||||
|
'as' => 'api.users.create',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\UserController@create'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->get('users/{id}', [
|
||||||
|
'as' => 'api.users.view',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\UserController@view'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->patch('users/{id}', [
|
||||||
|
'as' => 'api.users.update',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\UserController@update'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->delete('users/{id}', [
|
||||||
|
'as' => 'api.users.delete',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\UserController@delete'
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server Routes
|
||||||
|
*/
|
||||||
|
$api->get('servers', [
|
||||||
|
'as' => 'api.servers.list',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@list'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->post('servers', [
|
||||||
|
'as' => 'api.servers.create',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@create'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->get('servers/{id}', [
|
||||||
|
'as' => 'api.servers.view',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@view'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->patch('servers/{id}/config', [
|
||||||
|
'as' => 'api.servers.config',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@config'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->patch('servers/{id}/build', [
|
||||||
|
'as' => 'api.servers.build',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@build'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->post('servers/{id}/suspend', [
|
||||||
|
'as' => 'api.servers.suspend',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@suspend'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->post('servers/{id}/unsuspend', [
|
||||||
|
'as' => 'api.servers.unsuspend',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@unsuspend'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->delete('servers/{id}/{force?}', [
|
||||||
|
'as' => 'api.servers.delete',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\ServerController@delete'
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Node Routes
|
||||||
|
*/
|
||||||
|
$api->get('nodes', [
|
||||||
|
'as' => 'api.nodes.list',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@list'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->post('nodes', [
|
||||||
|
'as' => 'api.nodes.create',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@create'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->get('nodes/allocations', [
|
||||||
|
'as' => 'api.nodes.allocations',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@allocations'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->get('nodes/{id}', [
|
||||||
|
'as' => 'api.nodes.view',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@view'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->delete('nodes/{id}', [
|
||||||
|
'as' => 'api.nodes.delete',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\NodeController@delete'
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location Routes
|
||||||
|
*/
|
||||||
|
$api->get('locations', [
|
||||||
|
'as' => 'api.locations.list',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\LocationController@list'
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service Routes
|
||||||
|
*/
|
||||||
|
$api->get('services', [
|
||||||
|
'as' => 'api.services.list',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\ServiceController@list'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$api->get('services/{id}', [
|
||||||
|
'as' => 'api.services.view',
|
||||||
|
'uses' => 'Pterodactyl\Http\Controllers\API\ServiceController@view'
|
||||||
|
]);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -43,7 +43,10 @@ class Server extends Model
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $hidden = ['daemonSecret'];
|
protected $hidden = [
|
||||||
|
'daemonSecret',
|
||||||
|
'sftp_password'
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fields that are not mass assignable.
|
* Fields that are not mass assignable.
|
||||||
|
|
|
@ -36,44 +36,10 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
*/
|
*/
|
||||||
public function map()
|
public function map()
|
||||||
{
|
{
|
||||||
$this->mapWebRoutes();
|
Route::group(['namespace' => $this->namespace], function ($router) {
|
||||||
$this->mapApiRoutes();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Define the "web" routes for the application.
|
|
||||||
*
|
|
||||||
* These routes all receive session state, CSRF protection, etc.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function mapWebRoutes()
|
|
||||||
{
|
|
||||||
Route::group([
|
|
||||||
// 'middleware' => 'web',
|
|
||||||
'namespace' => $this->namespace,
|
|
||||||
], function ($router) {
|
|
||||||
foreach (glob(app_path('Http//Routes') . '/*.php') as $file) {
|
foreach (glob(app_path('Http//Routes') . '/*.php') as $file) {
|
||||||
$this->app->make('Pterodactyl\\Http\\Routes\\' . basename($file, '.php'))->map($router);
|
$this->app->make('Pterodactyl\\Http\\Routes\\' . basename($file, '.php'))->map($router);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Define the "api" routes for the application.
|
|
||||||
*
|
|
||||||
* These routes are typically stateless.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function mapApiRoutes()
|
|
||||||
{
|
|
||||||
Route::group([
|
|
||||||
'middleware' => 'api',
|
|
||||||
'namespace' => $this->namespace,
|
|
||||||
'prefix' => 'api',
|
|
||||||
], function ($router) {
|
|
||||||
foreach (glob(app_path('Http//Routes//Api') . '/*.php') as $file) {
|
|
||||||
$this->app->make('Pterodactyl\\Http\\Routes\\Api\\' . basename($file, '.php'))->map($router);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,31 +43,35 @@ class APIRepository
|
||||||
'*',
|
'*',
|
||||||
|
|
||||||
// User Management Routes
|
// User Management Routes
|
||||||
'api.users',
|
'api.users.list',
|
||||||
|
'api.users.create',
|
||||||
'api.users.view',
|
'api.users.view',
|
||||||
'api.users.post',
|
'api.users.update',
|
||||||
'api.users.delete',
|
'api.users.delete',
|
||||||
'api.users.patch',
|
|
||||||
|
|
||||||
// Server Manaement Routes
|
// Server Manaement Routes
|
||||||
'api.servers',
|
'api.servers.list',
|
||||||
|
'api.servers.create',
|
||||||
'api.servers.view',
|
'api.servers.view',
|
||||||
'api.servers.post',
|
'api.servers.config',
|
||||||
|
'api.servers.build',
|
||||||
'api.servers.suspend',
|
'api.servers.suspend',
|
||||||
'api.servers.unsuspend',
|
'api.servers.unsuspend',
|
||||||
'api.servers.delete',
|
'api.servers.delete',
|
||||||
|
|
||||||
// Node Management Routes
|
// Node Management Routes
|
||||||
'api.nodes',
|
'api.nodes.list',
|
||||||
'api.nodes.view',
|
'api.nodes.create',
|
||||||
'api.nodes.post',
|
'api.nodes.list',
|
||||||
'api.nodes.view_allocations',
|
'api.nodes.allocations',
|
||||||
'api.nodes.delete',
|
'api.nodes.delete',
|
||||||
|
|
||||||
// Assorted Routes
|
// Service Routes
|
||||||
'api.services',
|
'api.services.list',
|
||||||
'api.services.view',
|
'api.services.view',
|
||||||
'api.locations',
|
|
||||||
|
// Location Routes
|
||||||
|
'api.locations.list',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -96,8 +96,9 @@ class ServerRepository
|
||||||
'io' => 'required|numeric|min:10|max:1000',
|
'io' => 'required|numeric|min:10|max:1000',
|
||||||
'cpu' => 'required|numeric|min:0',
|
'cpu' => 'required|numeric|min:0',
|
||||||
'disk' => 'required|numeric|min:0',
|
'disk' => 'required|numeric|min:0',
|
||||||
'ip' => 'required|ip',
|
'allocation' => 'numeric|exists:allocations,id|required_without:ip,port',
|
||||||
'port' => 'required|numeric|min:1|max:65535',
|
'ip' => 'required_without:allocation|ip',
|
||||||
|
'port' => 'required_without:allocation|numeric|min:1|max:65535',
|
||||||
'service' => 'required|numeric|min:1|exists:services,id',
|
'service' => 'required|numeric|min:1|exists:services,id',
|
||||||
'option' => 'required|numeric|min:1|exists:service_options,id',
|
'option' => 'required|numeric|min:1|exists:service_options,id',
|
||||||
'startup' => 'required',
|
'startup' => 'required',
|
||||||
|
@ -113,14 +114,20 @@ class ServerRepository
|
||||||
// Get the User ID; user exists since we passed the 'exists:users,email' part of the validation
|
// Get the User ID; user exists since we passed the 'exists:users,email' part of the validation
|
||||||
$user = Models\User::select('id')->where('email', $data['owner'])->first();
|
$user = Models\User::select('id')->where('email', $data['owner'])->first();
|
||||||
|
|
||||||
|
// Get Node Information
|
||||||
|
$node = Models\Node::getByID($data['node']);
|
||||||
|
|
||||||
// Verify IP & Port are a.) free and b.) assigned to the node.
|
// Verify IP & Port are a.) free and b.) assigned to the node.
|
||||||
// We know the node exists because of 'exists:nodes,id' in the validation
|
// We know the node exists because of 'exists:nodes,id' in the validation
|
||||||
$node = Models\Node::getByID($data['node']);
|
if (!isset($data['allocation'])) {
|
||||||
$allocation = Models\Allocation::where('ip', $data['ip'])->where('port', $data['port'])->where('node', $data['node'])->whereNull('assigned_to')->first();
|
$allocation = Models\Allocation::where('ip', $data['ip'])->where('port', $data['port'])->where('node', $data['node'])->whereNull('assigned_to')->first();
|
||||||
|
} else {
|
||||||
|
$allocation = Models\Allocation::where('id' , $data['allocation'])->where('node', $data['node'])->whereNull('assigned_to')->first();
|
||||||
|
}
|
||||||
|
|
||||||
// Something failed in the query, either that combo doesn't exist, or it is in use.
|
// Something failed in the query, either that combo doesn't exist, or it is in use.
|
||||||
if (!$allocation) {
|
if (!$allocation) {
|
||||||
throw new DisplayException('The selected IP/Port combination (' . $data['ip'] . ':' . $data['port'] . ') is either already in use, or unavaliable for this node.');
|
throw new DisplayException('The selected IP/Port combination or Allocation ID is either already in use, or unavaliable for this node.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate those Service Option Variables
|
// Validate those Service Option Variables
|
||||||
|
@ -282,7 +289,7 @@ class ServerRepository
|
||||||
return $server->id;
|
return $server->id;
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw new DisplayException('An error occured while attempting to create the server.', $ex);
|
throw new DisplayException('There was an error while attempting to connect to the daemon to add this server.', $ex);
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
Log:error($ex);
|
Log:error($ex);
|
||||||
|
@ -735,6 +742,12 @@ class ServerRepository
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
// Already suspended, no need to make more requests.
|
||||||
|
if ($server->suspended === 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
$server->suspended = 1;
|
$server->suspended = 1;
|
||||||
$server->save();
|
$server->save();
|
||||||
|
|
||||||
|
@ -749,7 +762,7 @@ class ServerRepository
|
||||||
return DB::commit();
|
return DB::commit();
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw new DisplayException('An error occured while attempting to suspend this server.', $ex);
|
throw new DisplayException('An error occured while attempting to contact the remote daemon to suspend this server.', $ex);
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw $ex;
|
throw $ex;
|
||||||
|
@ -769,6 +782,12 @@ class ServerRepository
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
// Already unsuspended, no need to make more requests.
|
||||||
|
if ($server->suspended === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
$server->suspended = 0;
|
$server->suspended = 0;
|
||||||
$server->save();
|
$server->save();
|
||||||
|
|
||||||
|
@ -783,7 +802,7 @@ class ServerRepository
|
||||||
return DB::commit();
|
return DB::commit();
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw new DisplayException('An error occured while attempting to un-suspend this server.', $ex);
|
throw new DisplayException('An error occured while attempting to contact the remote daemon to un-suspend this server.', $ex);
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw $ex;
|
throw $ex;
|
||||||
|
|
|
@ -49,8 +49,8 @@ class UserRepository
|
||||||
/**
|
/**
|
||||||
* Creates a user on the panel. Returns the created user's ID.
|
* Creates a user on the panel. Returns the created user's ID.
|
||||||
*
|
*
|
||||||
* @param string $email
|
* @param string $email
|
||||||
* @param string|null $password An unhashed version of the user's password.
|
* @param string|null $password An unhashed version of the user's password.
|
||||||
* @return bool|integer
|
* @return bool|integer
|
||||||
*/
|
*/
|
||||||
public function create($email, $password = null, $admin = false)
|
public function create($email, $password = null, $admin = false)
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
namespace Pterodactyl\Transformers;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Allocation;
|
||||||
|
use League\Fractal\TransformerAbstract;
|
||||||
|
|
||||||
|
class AllocationTransformer extends TransformerAbstract
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn this item object into a generic array
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function transform(Allocation $allocation)
|
||||||
|
{
|
||||||
|
return array_except($allocation, ['created_at', 'updated_at']);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
namespace Pterodactyl\Transformers;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Node;
|
||||||
|
use League\Fractal\TransformerAbstract;
|
||||||
|
|
||||||
|
class NodeTransformer extends TransformerAbstract
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn this item object into a generic array
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function transform(Node $node)
|
||||||
|
{
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
namespace Pterodactyl\Transformers;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Server;
|
||||||
|
use League\Fractal\TransformerAbstract;
|
||||||
|
|
||||||
|
class ServerTransformer extends TransformerAbstract
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn this item object into a generic array
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function transform(Server $server)
|
||||||
|
{
|
||||||
|
return $server;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
namespace Pterodactyl\Transformers;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\User;
|
||||||
|
use League\Fractal\TransformerAbstract;
|
||||||
|
|
||||||
|
class UserTransformer extends TransformerAbstract
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn this item object into a generic array
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function transform(User $user)
|
||||||
|
{
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,220 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Standards Tree
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Versioning an API with Dingo revolves around content negotiation and
|
||||||
|
| custom MIME types. A custom type will belong to one of three
|
||||||
|
| standards trees, the Vendor tree (vnd), the Personal tree
|
||||||
|
| (prs), and the Unregistered tree (x).
|
||||||
|
|
|
||||||
|
| By default the Unregistered tree (x) is used, however, should you wish
|
||||||
|
| to you can register your type with the IANA. For more details:
|
||||||
|
| https://tools.ietf.org/html/rfc6838
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'standardsTree' => env('API_STANDARDS_TREE', 'x'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| API Subtype
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Your subtype will follow the standards tree you use when used in the
|
||||||
|
| "Accept" header to negotiate the content type and version.
|
||||||
|
|
|
||||||
|
| For example: Accept: application/x.SUBTYPE.v1+json
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'subtype' => env('API_SUBTYPE', ''),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default API Version
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This is the default version when strict mode is disabled and your API
|
||||||
|
| is accessed via a web browser. It's also used as the default version
|
||||||
|
| when generating your APIs documentation.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'version' => env('API_VERSION', 'v1'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default API Prefix
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| A default prefix to use for your API routes so you don't have to
|
||||||
|
| specify it for each group.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'prefix' => env('API_PREFIX', 'api'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default API Domain
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| A default domain to use for your API routes so you don't have to
|
||||||
|
| specify it for each group.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'domain' => env('API_DOMAIN', null),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Name
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| When documenting your API using the API Blueprint syntax you can
|
||||||
|
| configure a default name to avoid having to manually specify
|
||||||
|
| one when using the command.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'name' => env('API_NAME', null),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Conditional Requests
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Globally enable conditional requests so that an ETag header is added to
|
||||||
|
| any successful response. Subsequent requests will perform a check and
|
||||||
|
| will return a 304 Not Modified. This can also be enabled or disabled
|
||||||
|
| on certain groups or routes.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'conditionalRequest' => env('API_CONDITIONAL_REQUEST', true),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Strict Mode
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Enabling strict mode will require clients to send a valid Accept header
|
||||||
|
| with every request. This also voids the default API version, meaning
|
||||||
|
| your API will not be browsable via a web browser.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'strict' => env('API_STRICT', false),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Debug Mode
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Enabling debug mode will result in error responses caused by thrown
|
||||||
|
| exceptions to have a "debug" key that will be populated with
|
||||||
|
| more detailed information on the exception.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'debug' => env('API_DEBUG', false),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Generic Error Format
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| When some HTTP exceptions are not caught and dealt with the API will
|
||||||
|
| generate a generic error response in the format provided. Any
|
||||||
|
| keys that aren't replaced with corresponding values will be
|
||||||
|
| removed from the final response.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'errorFormat' => [
|
||||||
|
'message' => ':message',
|
||||||
|
'errors' => ':errors',
|
||||||
|
'code' => ':code',
|
||||||
|
'status_code' => ':status_code',
|
||||||
|
'debug' => ':debug',
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| API Middleware
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Middleware that will be applied globally to all API requests.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'middleware' => [
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Authentication Providers
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The authentication providers that should be used when attempting to
|
||||||
|
| authenticate an incoming API request.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'auth' => [
|
||||||
|
'custom' => 'Pterodactyl\Http\Middleware\APISecretToken',
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Throttling / Rate Limiting
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Consumers of your API can be limited to the amount of requests they can
|
||||||
|
| make. You can create your own throttles or simply change the default
|
||||||
|
| throttles.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'throttling' => [
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Response Transformer
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Responses can be transformed so that they are easier to format. By
|
||||||
|
| default a Fractal transformer will be used to transform any
|
||||||
|
| responses prior to formatting. You can easily replace
|
||||||
|
| this with your own transformer.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'transformer' => env('API_TRANSFORMER', Dingo\Api\Transformer\Adapter\Fractal::class),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Response Formats
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Responses can be returned in multiple formats by registering different
|
||||||
|
| response formatters. You can also customize an existing response
|
||||||
|
| formatter.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'defaultFormat' => env('API_DEFAULT_FORMAT', 'json'),
|
||||||
|
|
||||||
|
'formats' => [
|
||||||
|
'json' => Dingo\Api\Http\Response\Format\Json::class,
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
|
@ -114,6 +114,8 @@ return [
|
||||||
|
|
||||||
'providers' => [
|
'providers' => [
|
||||||
|
|
||||||
|
Dingo\Api\Provider\LaravelServiceProvider::class,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Laravel Framework Service Providers...
|
* Laravel Framework Service Providers...
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
<code style="line-height:2;">{{ $perm->permission }}</code><br />
|
<code style="line-height:2;">{{ $perm->permission }}</code><br />
|
||||||
@endforeach
|
@endforeach
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">{{ $key->created_at }}</td>
|
<td class="text-center">{{ (new Carbon($key->created_at))->toDayDateTimeString() }}</td>
|
||||||
<td class="text-center"><a href="#delete" class="text-danger" data-action="delete" data-attr="{{ $key->public }}"><i class="fa fa-trash"></i></a></td>
|
<td class="text-center"><a href="#delete" class="text-danger" data-action="delete" data-attr="{{ $key->public }}"><i class="fa fa-trash"></i></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
|
@ -47,31 +47,31 @@
|
||||||
<h4>User Management</h4><hr />
|
<h4>User Management</h4><hr />
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.users"> <strong>GET /users</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.users.list"> <strong><span class="label label-default">GET</span> /users</strong>
|
||||||
<p class="text-muted"><small>Allows listing of all users currently on the system.</small><p>
|
<p class="text-muted"><small>Allows listing of all users currently on the system.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.users.post"> <strong>POST /users</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.users.create"> <strong><span class="label label-default">POST</span> /users</strong>
|
||||||
<p class="text-muted"><small>Allows creating a new user on the system.</small><p>
|
<p class="text-muted"><small>Allows creating a new user on the system.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.users.view"> <strong>GET /users/{id}</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.users.view"> <strong><span class="label label-default">GET</span> /users/{id}</strong>
|
||||||
<p class="text-muted"><small>Allows viewing details about a specific user including active services.</small><p>
|
<p class="text-muted"><small>Allows viewing details about a specific user including active services.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.users.patch"> <strong>PATCH /users/{id}</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.users.update"> <strong><span class="label label-default">PATCH</span> /users/{id}</strong>
|
||||||
<p class="text-muted"><small>Allows modifying user details (email, password, TOTP information).</small><p>
|
<p class="text-muted"><small>Allows modifying user details (email, password, TOTP information).</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.users.delete"> <strong>DELETE /users/{id}</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.users.delete"> <strong><span class="label label-danger">DELETE</span> /users/{id}</strong>
|
||||||
<p class="text-muted"><small>Allows deleting a user.</small><p>
|
<p class="text-muted"><small>Allows deleting a user.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -80,37 +80,49 @@
|
||||||
<h4>Server Management</h4><hr />
|
<h4>Server Management</h4><hr />
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers"> <strong>GET /servers</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers.list"> <strong><span class="label label-default">GET</span> /servers</strong>
|
||||||
<p class="text-muted"><small>Allows listing of all servers currently on the system.</small><p>
|
<p class="text-muted"><small>Allows listing of all servers currently on the system.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers.post"> <strong>POST /servers</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers.create"> <strong><span class="label label-default">POST</span> /servers</strong>
|
||||||
<p class="text-muted"><small>Allows creating a new server on the system.</small><p>
|
<p class="text-muted"><small>Allows creating a new server on the system.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers.view"> <strong>GET /servers/{id}</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers.view"> <strong><span class="label label-default">GET</span> /servers/{id}</strong>
|
||||||
<p class="text-muted"><small>Allows viewing details about a specific server.</small><p>
|
<p class="text-muted"><small>Allows viewing details about a specific server.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers.suspend"> <strong>POST /servers/{id}/suspend</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers.config"> <strong><span class="label label-default">PATCH</span> /servers/{id}/config</strong>
|
||||||
|
<p class="text-muted"><small>Allows modifying server config (name, owner, and access token).</small><p>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox highlight">
|
||||||
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers.build"> <strong><span class="label label-default">PATCH</span> /servers/{id}/build</strong>
|
||||||
|
<p class="text-muted"><small>Allows modifying a server's build parameters such as memory, CPU, and disk space along with assigned and default IPs.</small><p>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox highlight">
|
||||||
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers.suspend"> <strong><span class="label label-default">POST</span> /servers/{id}/suspend</strong>
|
||||||
<p class="text-muted"><small>Allows suspending a server instance.</small><p>
|
<p class="text-muted"><small>Allows suspending a server instance.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers.unsuspend"> <strong>POST /servers/{id}/unsuspend</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers.unsuspend"> <strong><span class="label label-default">POST</span> /servers/{id}/unsuspend</strong>
|
||||||
<p class="text-muted"><small>Allows unsuspending a server instance.</small><p>
|
<p class="text-muted"><small>Allows unsuspending a server instance.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers.delete"> <strong>DELETE /servers/{id}</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.servers.delete"> <strong><span class="label label-danger">DELETE</span> /servers/{id}</strong>
|
||||||
<p class="text-muted"><small>Allows deleting a server.</small><p>
|
<p class="text-muted"><small>Allows deleting a server.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -121,31 +133,31 @@
|
||||||
<h4>Node Management</h4><hr />
|
<h4>Node Management</h4><hr />
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.nodes"> <strong>GET /nodes</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.nodes.list"> <strong><span class="label label-default">GET</span> /nodes</strong>
|
||||||
<p class="text-muted"><small>Allows listing of all nodes currently on the system.</small><p>
|
<p class="text-muted"><small>Allows listing of all nodes currently on the system.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.nodes.post"> <strong>POST /nodes</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.nodes.create"> <strong><span class="label label-default">POST</span> /nodes</strong>
|
||||||
<p class="text-muted"><small>Allows creating a new node on the system.</small><p>
|
<p class="text-muted"><small>Allows creating a new node on the system.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.nodes.view"> <strong>GET /nodes/{id}</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.nodes.view"> <strong><span class="label label-default">GET</span> /nodes/{id}</strong>
|
||||||
<p class="text-muted"><small>Allows viewing details about a specific node including active services.</small><p>
|
<p class="text-muted"><small>Allows viewing details about a specific node including active services.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.nodes.view_allocations"> <strong>GET /nodes/{id}/allocations</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.nodes.allocations"> <strong><span class="label label-default">GET</span> /nodes/allocations</strong>
|
||||||
<p class="text-muted"><small>Allows viewing details about a specific node including active services.</small><p>
|
<p class="text-muted"><small>Allows viewing all allocations on the panel for all nodes.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.nodes.delete"> <strong>DELETE /nodes/{id}</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.nodes.delete"> <strong><span class="label label-danger">DELETE</span> /nodes/{id}</strong>
|
||||||
<p class="text-muted"><small>Allows deleting a node.</small><p>
|
<p class="text-muted"><small>Allows deleting a node.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -154,20 +166,20 @@
|
||||||
<h4>Service Management</h4><hr />
|
<h4>Service Management</h4><hr />
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.services"> <strong>GET /services</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.services.list"> <strong><span class="label label-default">GET</span> /services</strong>
|
||||||
<p class="text-muted"><small>Allows listing of all services configured on the system.</small><p>
|
<p class="text-muted"><small>Allows listing of all services configured on the system.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.services.view"> <strong>GET /services/{id}</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.services.view"> <strong><span class="label label-default">GET</span> /services/{id}</strong>
|
||||||
<p class="text-muted"><small>Allows listing details about each service on the system including service options and variables.</small><p>
|
<p class="text-muted"><small>Allows listing details about each service on the system including service options and variables.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<h4>Location Management</h4><hr />
|
<h4>Location Management</h4><hr />
|
||||||
<div class="checkbox highlight">
|
<div class="checkbox highlight">
|
||||||
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
<label class="checkbox-custom highlight" data-initialize="checkbox">
|
||||||
<input class="sr-only" name="permissions[]" type="checkbox" value="api.locations"> <strong>GET /locations</strong>
|
<input class="sr-only" name="permissions[]" type="checkbox" value="api.locations.list"> <strong><span class="label label-default">GET</span> /locations</strong>
|
||||||
<p class="text-muted"><small>Allows listing all locations and thier associated nodes.</small><p>
|
<p class="text-muted"><small>Allows listing all locations and thier associated nodes.</small><p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue