Implement admin user management API routes

This commit is contained in:
Dane Everitt 2017-12-16 11:31:18 -06:00
parent 95ba8da99e
commit 4a65dff940
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
3 changed files with 145 additions and 21 deletions

View file

@ -71,6 +71,7 @@ class Handler extends ExceptionHandler
$response = response()->json( $response = response()->json(
[ [
'error' => $displayError, 'error' => $displayError,
'type' => (! config('app.debug')) ? null : class_basename($exception),
'http_code' => (method_exists($exception, 'getStatusCode')) ? $exception->getStatusCode() : 500, 'http_code' => (method_exists($exception, 'getStatusCode')) ? $exception->getStatusCode() : 500,
'trace' => (! config('app.debug')) ? null : $exception->getTrace(), 'trace' => (! config('app.debug')) ? null : $exception->getTrace(),
], ],

View file

@ -4,20 +4,30 @@ namespace Pterodactyl\Http\Controllers\API\Admin\Users;
use Spatie\Fractal\Fractal; use Spatie\Fractal\Fractal;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Pterodactyl\Models\User;
use Illuminate\Http\Response;
use Illuminate\Http\JsonResponse;
use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Services\Users\UserUpdateService;
use Pterodactyl\Services\Users\UserCreationService;
use Pterodactyl\Services\Users\UserDeletionService;
use Pterodactyl\Transformers\Admin\UserTransformer; use Pterodactyl\Transformers\Admin\UserTransformer;
use Pterodactyl\Http\Requests\Admin\UserFormRequest;
use League\Fractal\Pagination\IlluminatePaginatorAdapter; use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use Pterodactyl\Contracts\Repository\UserRepositoryInterface; use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
use Illuminate\Contracts\Config\Repository as ConfigRepository;
/**
* @SWG\Swagger(
* schemes={"https"},
* basePath="/api/admin/users"
* )
*/
class UserController extends Controller class UserController extends Controller
{ {
/**
* @var \Pterodactyl\Services\Users\UserCreationService
*/
private $creationService;
/**
* @var \Pterodactyl\Services\Users\UserDeletionService
*/
private $deletionService;
/** /**
* @var \Spatie\Fractal\Fractal * @var \Spatie\Fractal\Fractal
*/ */
@ -27,47 +37,160 @@ class UserController extends Controller
* @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface * @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
*/ */
private $repository; private $repository;
/** /**
* @var \Illuminate\Contracts\Config\Repository * @var \Pterodactyl\Services\Users\UserUpdateService
*/ */
private $config; private $updateService;
/** /**
* UserController constructor. * UserController constructor.
* *
* @param \Illuminate\Contracts\Config\Repository $config
* @param \Spatie\Fractal\Fractal $fractal * @param \Spatie\Fractal\Fractal $fractal
* @param \Pterodactyl\Contracts\Repository\UserRepositoryInterface $repository * @param \Pterodactyl\Contracts\Repository\UserRepositoryInterface $repository
* @param \Pterodactyl\Services\Users\UserCreationService $creationService
* @param \Pterodactyl\Services\Users\UserDeletionService $deletionService
* @param \Pterodactyl\Services\Users\UserUpdateService $updateService
*/ */
public function __construct( public function __construct(
ConfigRepository $config,
Fractal $fractal, Fractal $fractal,
UserRepositoryInterface $repository UserRepositoryInterface $repository,
UserCreationService $creationService,
UserDeletionService $deletionService,
UserUpdateService $updateService
) { ) {
$this->creationService = $creationService;
$this->deletionService = $deletionService;
$this->fractal = $fractal; $this->fractal = $fractal;
$this->repository = $repository; $this->repository = $repository;
$this->config = $config; $this->updateService = $updateService;
} }
/** /**
* Handle request to list all users on the panel. * Handle request to list all users on the panel. Returns a JSONAPI representation
* of a collection of users including any defined relations passed in
* the request.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* @return array * @return array
*/ */
public function index(Request $request) public function index(Request $request): array
{ {
$users = $this->repository->all($this->config->get('pterodactyl.paginate.api.users')); $users = $this->repository->all(config('pterodactyl.paginate.api.users'));
$fractal = $this->fractal->collection($users) $fractal = $this->fractal->collection($users)
->transformWith(new UserTransformer($request)) ->transformWith(new UserTransformer($request))
->withResourceName('user') ->withResourceName('user')
->paginateWith(new IlluminatePaginatorAdapter($users)); ->paginateWith(new IlluminatePaginatorAdapter($users));
if ($this->config->get('pterodactyl.api.include_on_list') && $request->input('include')) { if (config('pterodactyl.api.include_on_list') && $request->has('include')) {
$fractal->parseIncludes(explode(',', $request->input('include'))); $fractal->parseIncludes(explode(',', $request->input('include')));
} }
return $fractal->toArray(); return $fractal->toArray();
} }
/**
* Handle a request to view a single user. Includes any relations that
* were defined in the request.
*
* @param \Illuminate\Http\Request $request
* @param \Pterodactyl\Models\User $user
* @return array
*/
public function view(Request $request, User $user): array
{
$fractal = $this->fractal->item($user)
->transformWith(new UserTransformer($request))
->withResourceName('user');
if ($request->has('include')) {
$fractal->parseIncludes(explode(',', $request->input('include')));
}
return $fractal->toArray();
}
/**
* Update an existing user on the system and return the response. Returns the
* updated user model response on success. Supports handling of token revocation
* errors when switching a user from an admin to a normal user.
*
* Revocation errors are returned under the 'revocation_errors' key in the response
* meta. If there are no errors this is an empty array.
*
* @param \Pterodactyl\Http\Requests\Admin\UserFormRequest $request
* @param \Pterodactyl\Models\User $user
* @return array
*
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function update(UserFormRequest $request, User $user): array
{
$this->updateService->setUserLevel(User::USER_LEVEL_ADMIN);
$collection = $this->updateService->handle($user, $request->normalize());
$errors = [];
if (! empty($collection->get('exceptions'))) {
foreach ($collection->get('exceptions') as $node => $exception) {
/** @var \GuzzleHttp\Exception\RequestException $exception */
/** @var \GuzzleHttp\Psr7\Response|null $response */
$response = method_exists($exception, 'getResponse') ? $exception->getResponse() : null;
$message = trans('admin/server.exceptions.daemon_exception', [
'code' => is_null($response) ? 'E_CONN_REFUSED' : $response->getStatusCode(),
]);
$errors[] = ['message' => $message, 'node' => $node];
}
}
return $this->fractal->item($collection->get('user'))
->transformWith(new UserTransformer($request))
->withResourceName('user')
->addMeta([
'revocation_errors' => $errors,
])
->toArray();
}
/**
* Store a new user on the system. Returns the created user and a HTTP/201
* header on successful creation.
*
* @param \Pterodactyl\Http\Requests\Admin\UserFormRequest $request
* @return \Illuminate\Http\JsonResponse
*
* @throws \Exception
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
*/
public function store(UserFormRequest $request): JsonResponse
{
$user = $this->creationService->handle($request->normalize());
return $this->fractal->item($user)
->transformWith(new UserTransformer($request))
->withResourceName('user')
->addMeta([
'link' => route('api.admin.user.view', ['user' => $user->id]),
])
->respond(201);
}
/**
* Handle a request to delete a user from the Panel. Returns a HTTP/204 response
* on successful deletion.
*
* @param \Pterodactyl\Models\User $user
* @return \Illuminate\Http\Response
*
* @throws \Pterodactyl\Exceptions\DisplayException
*/
public function delete(User $user): Response
{
$this->deletionService->handle($user);
return response('', 204);
}
} }

View file

@ -10,10 +10,10 @@
*/ */
Route::group(['prefix' => '/users'], function () { Route::group(['prefix' => '/users'], function () {
Route::get('/', 'Users\UserController@index')->name('api.admin.user.list'); Route::get('/', 'Users\UserController@index')->name('api.admin.user.list');
Route::get('/{id}', 'Users\UserController@view'); Route::get('/{user}', 'Users\UserController@view')->name('api.admin.user.view');
Route::post('/', 'Users\UserController@store'); Route::post('/', 'Users\UserController@store')->name('api.admin.user.store');
Route::put('/{id}', 'Users\UserController@update'); Route::put('/{user}', 'Users\UserController@update')->name('api.admin.user.update');
Route::delete('/{id}', 'Users\UserController@delete'); Route::delete('/{user}', 'Users\UserController@delete')->name('api.admin.user.delete');
}); });