Finish first round of User/Node API additions
Will still need some tweaking and improvements to allow everything to be used.
This commit is contained in:
parent
d21f70c04b
commit
15289b76a7
10 changed files with 220 additions and 68 deletions
|
@ -11,6 +11,7 @@ namespace Pterodactyl\Exceptions;
|
||||||
|
|
||||||
use Log;
|
use Log;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use Prologue\Alerts\AlertsMessageBag;
|
use Prologue\Alerts\AlertsMessageBag;
|
||||||
|
|
||||||
class DisplayException extends PterodactylException
|
class DisplayException extends PterodactylException
|
||||||
|
@ -65,7 +66,7 @@ class DisplayException extends PterodactylException
|
||||||
if ($request->expectsJson()) {
|
if ($request->expectsJson()) {
|
||||||
return response()->json(Handler::convertToArray($this, [
|
return response()->json(Handler::convertToArray($this, [
|
||||||
'detail' => $this->getMessage(),
|
'detail' => $this->getMessage(),
|
||||||
]), method_exists($this, 'getStatusCode') ? $this->getStatusCode() : 500);
|
]), method_exists($this, 'getStatusCode') ? $this->getStatusCode() : Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
app()->make(AlertsMessageBag::class)->danger($this->getMessage())->flash();
|
app()->make(AlertsMessageBag::class)->danger($this->getMessage())->flash();
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Pterodactyl - Panel
|
|
||||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
|
||||||
*
|
|
||||||
* This software is licensed under the terms of the MIT license.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Pterodactyl\Exceptions\Service;
|
namespace Pterodactyl\Exceptions\Service;
|
||||||
|
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
|
|
||||||
class HasActiveServersException extends DisplayException
|
class HasActiveServersException extends DisplayException
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getStatusCode()
|
||||||
|
{
|
||||||
|
return Response::HTTP_BAD_REQUEST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Pterodactyl - Panel
|
|
||||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
|
||||||
*
|
|
||||||
* This software is licensed under the terms of the MIT license.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Pterodactyl\Exceptions\Service\Location;
|
namespace Pterodactyl\Exceptions\Service\Location;
|
||||||
|
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
|
|
||||||
class HasActiveNodesException extends DisplayException
|
class HasActiveNodesException extends DisplayException
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getStatusCode()
|
||||||
|
{
|
||||||
|
return Response::HTTP_BAD_REQUEST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,29 @@ namespace Pterodactyl\Http\Controllers\API\Admin\Nodes;
|
||||||
use Spatie\Fractal\Fractal;
|
use Spatie\Fractal\Fractal;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Pterodactyl\Models\Node;
|
use Pterodactyl\Models\Node;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
|
use Pterodactyl\Services\Nodes\NodeUpdateService;
|
||||||
|
use Pterodactyl\Services\Nodes\NodeCreationService;
|
||||||
|
use Pterodactyl\Services\Nodes\NodeDeletionService;
|
||||||
use Pterodactyl\Transformers\Api\Admin\NodeTransformer;
|
use Pterodactyl\Transformers\Api\Admin\NodeTransformer;
|
||||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
|
use Pterodactyl\Http\Requests\Admin\Node\NodeFormRequest;
|
||||||
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
|
||||||
|
|
||||||
class NodeController extends Controller
|
class NodeController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Nodes\NodeCreationService
|
||||||
|
*/
|
||||||
|
private $creationService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Nodes\NodeDeletionService
|
||||||
|
*/
|
||||||
|
private $deletionService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Spatie\Fractal\Fractal
|
* @var \Spatie\Fractal\Fractal
|
||||||
*/
|
*/
|
||||||
|
@ -22,16 +38,32 @@ class NodeController extends Controller
|
||||||
*/
|
*/
|
||||||
private $repository;
|
private $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Nodes\NodeUpdateService
|
||||||
|
*/
|
||||||
|
private $updateService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NodeController constructor.
|
* NodeController constructor.
|
||||||
*
|
*
|
||||||
* @param \Spatie\Fractal\Fractal $fractal
|
* @param \Spatie\Fractal\Fractal $fractal
|
||||||
|
* @param \Pterodactyl\Services\Nodes\NodeCreationService $creationService
|
||||||
|
* @param \Pterodactyl\Services\Nodes\NodeDeletionService $deletionService
|
||||||
|
* @param \Pterodactyl\Services\Nodes\NodeUpdateService $updateService
|
||||||
* @param \Pterodactyl\Contracts\Repository\NodeRepositoryInterface $repository
|
* @param \Pterodactyl\Contracts\Repository\NodeRepositoryInterface $repository
|
||||||
*/
|
*/
|
||||||
public function __construct(Fractal $fractal, NodeRepositoryInterface $repository)
|
public function __construct(
|
||||||
{
|
Fractal $fractal,
|
||||||
|
NodeCreationService $creationService,
|
||||||
|
NodeDeletionService $deletionService,
|
||||||
|
NodeUpdateService $updateService,
|
||||||
|
NodeRepositoryInterface $repository
|
||||||
|
) {
|
||||||
$this->fractal = $fractal;
|
$this->fractal = $fractal;
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
|
$this->creationService = $creationService;
|
||||||
|
$this->deletionService = $deletionService;
|
||||||
|
$this->updateService = $updateService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,4 +99,63 @@ class NodeController extends Controller
|
||||||
|
|
||||||
return $fractal->toArray();
|
return $fractal->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new node on the Panel. Returns the created node and a HTTP/201
|
||||||
|
* status response on success.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Http\Requests\Admin\Node\NodeFormRequest $request
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
|
*/
|
||||||
|
public function store(NodeFormRequest $request): JsonResponse
|
||||||
|
{
|
||||||
|
$node = $this->creationService->handle($request->normalize());
|
||||||
|
|
||||||
|
return $this->fractal->item($node)
|
||||||
|
->transformWith(new NodeTransformer($request))
|
||||||
|
->withResourceName('node')
|
||||||
|
->addMeta([
|
||||||
|
'link' => route('api.admin.node.view', ['node' => $node->id]),
|
||||||
|
])
|
||||||
|
->respond(201);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update an existing node on the Panel.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Http\Requests\Admin\Node\NodeFormRequest $request
|
||||||
|
* @param \Pterodactyl\Models\Node $node
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
|
*/
|
||||||
|
public function update(NodeFormRequest $request, Node $node): array
|
||||||
|
{
|
||||||
|
$node = $this->updateService->returnUpdatedModel()->handle($node, $request->normalize());
|
||||||
|
|
||||||
|
return $this->fractal->item($node)
|
||||||
|
->transformWith(new NodeTransformer($request))
|
||||||
|
->withResourceName('node')
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a given node from the Panel as long as there are no servers
|
||||||
|
* currently attached to it.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\Node $node
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\Service\HasActiveServersException
|
||||||
|
*/
|
||||||
|
public function delete(Node $node): Response
|
||||||
|
{
|
||||||
|
$this->deletionService->handle($node);
|
||||||
|
|
||||||
|
return response('', 201);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,13 +146,17 @@ class UserController extends Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->fractal->item($collection->get('user'))
|
$response = $this->fractal->item($collection->get('model'))
|
||||||
->transformWith(new UserTransformer($request))
|
->transformWith(new UserTransformer($request))
|
||||||
->withResourceName('user')
|
->withResourceName('user');
|
||||||
->addMeta([
|
|
||||||
|
if (count($errors) > 0) {
|
||||||
|
$response->addMeta([
|
||||||
'revocation_errors' => $errors,
|
'revocation_errors' => $errors,
|
||||||
])
|
]);
|
||||||
->toArray();
|
}
|
||||||
|
|
||||||
|
return $response->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,11 +4,13 @@ namespace Pterodactyl\Models;
|
||||||
|
|
||||||
use Sofa\Eloquence\Eloquence;
|
use Sofa\Eloquence\Eloquence;
|
||||||
use Sofa\Eloquence\Validable;
|
use Sofa\Eloquence\Validable;
|
||||||
|
use Illuminate\Validation\Rules\In;
|
||||||
use Illuminate\Auth\Authenticatable;
|
use Illuminate\Auth\Authenticatable;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Sofa\Eloquence\Contracts\CleansAttributes;
|
use Sofa\Eloquence\Contracts\CleansAttributes;
|
||||||
use Illuminate\Auth\Passwords\CanResetPassword;
|
use Illuminate\Auth\Passwords\CanResetPassword;
|
||||||
|
use Pterodactyl\Traits\Helpers\AvailableLanguages;
|
||||||
use Illuminate\Foundation\Auth\Access\Authorizable;
|
use Illuminate\Foundation\Auth\Access\Authorizable;
|
||||||
use Sofa\Eloquence\Contracts\Validable as ValidableContract;
|
use Sofa\Eloquence\Contracts\Validable as ValidableContract;
|
||||||
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
|
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
|
||||||
|
@ -23,7 +25,9 @@ class User extends Model implements
|
||||||
CleansAttributes,
|
CleansAttributes,
|
||||||
ValidableContract
|
ValidableContract
|
||||||
{
|
{
|
||||||
use Authenticatable, Authorizable, CanResetPassword, Eloquence, Notifiable, Validable;
|
use Authenticatable, Authorizable, AvailableLanguages, CanResetPassword, Eloquence, Notifiable, Validable {
|
||||||
|
gatherRules as eloquenceGatherRules;
|
||||||
|
}
|
||||||
|
|
||||||
const USER_LEVEL_USER = 0;
|
const USER_LEVEL_USER = 0;
|
||||||
const USER_LEVEL_ADMIN = 1;
|
const USER_LEVEL_ADMIN = 1;
|
||||||
|
@ -138,11 +142,23 @@ class User extends Model implements
|
||||||
'name_last' => 'string|between:1,255',
|
'name_last' => 'string|between:1,255',
|
||||||
'password' => 'nullable|string',
|
'password' => 'nullable|string',
|
||||||
'root_admin' => 'boolean',
|
'root_admin' => 'boolean',
|
||||||
'language' => 'string|between:2,5',
|
'language' => 'string',
|
||||||
'use_totp' => 'boolean',
|
'use_totp' => 'boolean',
|
||||||
'totp_secret' => 'nullable|string',
|
'totp_secret' => 'nullable|string',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement language verification by overriding Eloquence's gather
|
||||||
|
* rules function.
|
||||||
|
*/
|
||||||
|
protected static function gatherRules()
|
||||||
|
{
|
||||||
|
$rules = self::eloquenceGatherRules();
|
||||||
|
$rules['language'][] = new In(array_keys((new self)->getAvailableLanguages()));
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send the password reset notification.
|
* Send the password reset notification.
|
||||||
*
|
*
|
||||||
|
|
|
@ -9,82 +9,71 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Services\Nodes;
|
namespace Pterodactyl\Services\Nodes;
|
||||||
|
|
||||||
use Illuminate\Log\Writer;
|
|
||||||
use Pterodactyl\Models\Node;
|
use Pterodactyl\Models\Node;
|
||||||
use GuzzleHttp\Exception\RequestException;
|
use GuzzleHttp\Exception\RequestException;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Traits\Services\ReturnsUpdatedModels;
|
||||||
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
|
||||||
|
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
|
||||||
use Pterodactyl\Contracts\Repository\Daemon\ConfigurationRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\Daemon\ConfigurationRepositoryInterface;
|
||||||
|
|
||||||
class NodeUpdateService
|
class NodeUpdateService
|
||||||
{
|
{
|
||||||
|
use ReturnsUpdatedModels;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\Daemon\ConfigurationRepositoryInterface
|
* @var \Pterodactyl\Contracts\Repository\Daemon\ConfigurationRepositoryInterface
|
||||||
*/
|
*/
|
||||||
protected $configRepository;
|
private $configRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\NodeRepositoryInterface
|
* @var \Pterodactyl\Contracts\Repository\NodeRepositoryInterface
|
||||||
*/
|
*/
|
||||||
protected $repository;
|
private $repository;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Illuminate\Log\Writer
|
|
||||||
*/
|
|
||||||
protected $writer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateService constructor.
|
* UpdateService constructor.
|
||||||
*
|
*
|
||||||
* @param \Pterodactyl\Contracts\Repository\Daemon\ConfigurationRepositoryInterface $configurationRepository
|
* @param \Pterodactyl\Contracts\Repository\Daemon\ConfigurationRepositoryInterface $configurationRepository
|
||||||
* @param \Pterodactyl\Contracts\Repository\NodeRepositoryInterface $repository
|
* @param \Pterodactyl\Contracts\Repository\NodeRepositoryInterface $repository
|
||||||
* @param \Illuminate\Log\Writer $writer
|
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ConfigurationRepositoryInterface $configurationRepository,
|
ConfigurationRepositoryInterface $configurationRepository,
|
||||||
NodeRepositoryInterface $repository,
|
NodeRepositoryInterface $repository
|
||||||
Writer $writer
|
|
||||||
) {
|
) {
|
||||||
$this->configRepository = $configurationRepository;
|
$this->configRepository = $configurationRepository;
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
$this->writer = $writer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the configuration values for a given node on the machine.
|
* Update the configuration values for a given node on the machine.
|
||||||
*
|
*
|
||||||
* @param int|\Pterodactyl\Models\Node $node
|
* @param \Pterodactyl\Models\Node $node
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @return mixed
|
* @return \Pterodactyl\Models\Node|mixed
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function handle($node, array $data)
|
public function handle(Node $node, array $data)
|
||||||
{
|
{
|
||||||
if (! $node instanceof Node) {
|
|
||||||
$node = $this->repository->find($node);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! is_null(array_get($data, 'reset_secret'))) {
|
if (! is_null(array_get($data, 'reset_secret'))) {
|
||||||
$data['daemonSecret'] = str_random(NodeCreationService::DAEMON_SECRET_LENGTH);
|
$data['daemonSecret'] = str_random(Node::DAEMON_SECRET_LENGTH);
|
||||||
unset($data['reset_secret']);
|
unset($data['reset_secret']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$updateResponse = $this->repository->withoutFresh()->update($node->id, $data);
|
if ($this->getUpdatedModel()) {
|
||||||
|
$response = $this->repository->update($node->id, $data);
|
||||||
|
} else {
|
||||||
|
$response = $this->repository->withoutFresh()->update($node->id, $data);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->configRepository->setNode($node->id)->update();
|
$this->configRepository->setNode($node->id)->update();
|
||||||
} catch (RequestException $exception) {
|
} catch (RequestException $exception) {
|
||||||
$response = $exception->getResponse();
|
throw new DaemonConnectionException($exception);
|
||||||
$this->writer->warning($exception);
|
|
||||||
|
|
||||||
throw new DisplayException(trans('exceptions.node.daemon_off_config_updated', [
|
|
||||||
'code' => is_null($response) ? 'E_CONN_REFUSED' : $response->getStatusCode(),
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $updateResponse;
|
return $response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
35
app/Traits/Services/ReturnsUpdatedModels.php
Normal file
35
app/Traits/Services/ReturnsUpdatedModels.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Traits\Services;
|
||||||
|
|
||||||
|
trait ReturnsUpdatedModels
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $updatedModel = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function getUpdatedModel()
|
||||||
|
{
|
||||||
|
return $this->updatedModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If called a fresh model will be returned from the database. This is used
|
||||||
|
* for API calls, but is unnecessary for UI based updates where the page is
|
||||||
|
* being reloaded and a fresh model will be pulled anyways.
|
||||||
|
*
|
||||||
|
* @param bool $toggle
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function returnUpdatedModel(bool $toggle = true)
|
||||||
|
{
|
||||||
|
$this->updatedModel = $toggle;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,12 +13,25 @@ Route::group(['prefix' => '/users'], function () {
|
||||||
Route::get('/{user}', 'Users\UserController@view')->name('api.admin.user.view');
|
Route::get('/{user}', 'Users\UserController@view')->name('api.admin.user.view');
|
||||||
|
|
||||||
Route::post('/', 'Users\UserController@store')->name('api.admin.user.store');
|
Route::post('/', 'Users\UserController@store')->name('api.admin.user.store');
|
||||||
Route::put('/{user}', 'Users\UserController@update')->name('api.admin.user.update');
|
Route::patch('/{user}', 'Users\UserController@update')->name('api.admin.user.update');
|
||||||
|
|
||||||
Route::delete('/{user}', 'Users\UserController@delete')->name('api.admin.user.delete');
|
Route::delete('/{user}', 'Users\UserController@delete')->name('api.admin.user.delete');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Node Controller Routes
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Endpoint: /api/admin/nodes
|
||||||
|
|
|
||||||
|
*/
|
||||||
Route::group(['prefix' => '/nodes'], function () {
|
Route::group(['prefix' => '/nodes'], function () {
|
||||||
Route::get('/', 'Nodes\NodeController@index')->name('api.admin.node.list');
|
Route::get('/', 'Nodes\NodeController@index')->name('api.admin.node.list');
|
||||||
Route::get('/{node}', 'Nodes\NodeController@view')->name('api.admin.node.view');
|
Route::get('/{node}', 'Nodes\NodeController@view')->name('api.admin.node.view');
|
||||||
|
|
||||||
|
Route::post('/', 'Nodes\NodeController@store')->name('api.admin.node.store');
|
||||||
|
Route::patch('/{node}', 'Nodes\NodeController@update')->name('api.admin.node.update');
|
||||||
|
|
||||||
|
Route::delete('/{node}', 'Nodes\NodeController@delete')->name('api.admin.node.delete');
|
||||||
});
|
});
|
||||||
|
|
|
@ -84,16 +84,17 @@ class NodeUpdateServiceTest extends TestCase
|
||||||
$this->getFunctionMock('\\Pterodactyl\\Services\\Nodes', 'str_random')
|
$this->getFunctionMock('\\Pterodactyl\\Services\\Nodes', 'str_random')
|
||||||
->expects($this->once())->willReturn('random_string');
|
->expects($this->once())->willReturn('random_string');
|
||||||
|
|
||||||
$this->repository->shouldReceive('withoutFresh')->withNoArgs()->once()->andReturnSelf()
|
$this->repository->->shouldReceive('update')->with($this->node->id, [
|
||||||
->shouldReceive('update')->with($this->node->id, [
|
|
||||||
'name' => 'NewName',
|
'name' => 'NewName',
|
||||||
'daemonSecret' => 'random_string',
|
'daemonSecret' => 'random_string',
|
||||||
])->andReturn(true);
|
])->andReturn($this->node);
|
||||||
|
|
||||||
$this->configRepository->shouldReceive('setNode')->with($this->node->id)->once()->andReturnSelf()
|
$this->configRepository->shouldReceive('setNode')->with($this->node->id)->once()->andReturnSelf()
|
||||||
->shouldReceive('update')->withNoArgs()->once()->andReturnNull();
|
->shouldReceive('update')->withNoArgs()->once()->andReturnNull();
|
||||||
|
|
||||||
$this->assertTrue($this->service->handle($this->node, ['name' => 'NewName', 'reset_secret' => true]));
|
$response = $this->service->handle($this->node, ['name' => 'NewName', 'reset_secret' => true]);
|
||||||
|
$this->assertInstanceOf(Node::class, $response);
|
||||||
|
$this->assertSame($this->node, $response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,15 +102,16 @@ class NodeUpdateServiceTest extends TestCase
|
||||||
*/
|
*/
|
||||||
public function testNodeIsUpdatedAndDaemonSecretIsNotChanged()
|
public function testNodeIsUpdatedAndDaemonSecretIsNotChanged()
|
||||||
{
|
{
|
||||||
$this->repository->shouldReceive('withoutFresh')->withNoArgs()->once()->andReturnSelf()
|
$this->repository->shouldReceive('update')->with($this->node->id, [
|
||||||
->shouldReceive('update')->with($this->node->id, [
|
|
||||||
'name' => 'NewName',
|
'name' => 'NewName',
|
||||||
])->andReturn(true);
|
])->andReturn($this->node);
|
||||||
|
|
||||||
$this->configRepository->shouldReceive('setNode')->with($this->node->id)->once()->andReturnSelf()
|
$this->configRepository->shouldReceive('setNode')->with($this->node->id)->once()->andReturnSelf()
|
||||||
->shouldReceive('update')->withNoArgs()->once()->andReturnNull();
|
->shouldReceive('update')->withNoArgs()->once()->andReturnNull();
|
||||||
|
|
||||||
$this->assertTrue($this->service->handle($this->node, ['name' => 'NewName']));
|
$response = $this->service->handle($this->node, ['name' => 'NewName']);
|
||||||
|
$this->assertInstanceOf(Node::class, $response);
|
||||||
|
$this->assertSame($this->node, $response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,8 +119,7 @@ class NodeUpdateServiceTest extends TestCase
|
||||||
*/
|
*/
|
||||||
public function testExceptionCausedByDaemonIsHandled()
|
public function testExceptionCausedByDaemonIsHandled()
|
||||||
{
|
{
|
||||||
$this->repository->shouldReceive('withoutFresh')->withNoArgs()->once()->andReturnSelf()
|
$this->repository->->shouldReceive('update')->with($this->node->id, [
|
||||||
->shouldReceive('update')->with($this->node->id, [
|
|
||||||
'name' => 'NewName',
|
'name' => 'NewName',
|
||||||
])->andReturn(true);
|
])->andReturn(true);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue