Skip to content

Commit 4a65dff

Browse files
committed
Implement admin user management API routes
1 parent 95ba8da commit 4a65dff

File tree

3 files changed

+146
-22
lines changed

3 files changed

+146
-22
lines changed

app/Exceptions/Handler.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public function render($request, Exception $exception)
7171
$response = response()->json(
7272
[
7373
'error' => $displayError,
74+
'type' => (! config('app.debug')) ? null : class_basename($exception),
7475
'http_code' => (method_exists($exception, 'getStatusCode')) ? $exception->getStatusCode() : 500,
7576
'trace' => (! config('app.debug')) ? null : $exception->getTrace(),
7677
],

app/Http/Controllers/API/Admin/Users/UserController.php

Lines changed: 141 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,30 @@
44

55
use Spatie\Fractal\Fractal;
66
use Illuminate\Http\Request;
7+
use Pterodactyl\Models\User;
8+
use Illuminate\Http\Response;
9+
use Illuminate\Http\JsonResponse;
710
use Pterodactyl\Http\Controllers\Controller;
11+
use Pterodactyl\Services\Users\UserUpdateService;
12+
use Pterodactyl\Services\Users\UserCreationService;
13+
use Pterodactyl\Services\Users\UserDeletionService;
814
use Pterodactyl\Transformers\Admin\UserTransformer;
15+
use Pterodactyl\Http\Requests\Admin\UserFormRequest;
916
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
1017
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
11-
use Illuminate\Contracts\Config\Repository as ConfigRepository;
12-
13-
/**
14-
* @SWG\Swagger(
15-
* schemes={"https"},
16-
* basePath="/api/admin/users"
17-
* )
18-
*/
18+
1919
class UserController extends Controller
2020
{
21+
/**
22+
* @var \Pterodactyl\Services\Users\UserCreationService
23+
*/
24+
private $creationService;
25+
26+
/**
27+
* @var \Pterodactyl\Services\Users\UserDeletionService
28+
*/
29+
private $deletionService;
30+
2131
/**
2232
* @var \Spatie\Fractal\Fractal
2333
*/
@@ -27,47 +37,160 @@ class UserController extends Controller
2737
* @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
2838
*/
2939
private $repository;
40+
3041
/**
31-
* @var \Illuminate\Contracts\Config\Repository
42+
* @var \Pterodactyl\Services\Users\UserUpdateService
3243
*/
33-
private $config;
44+
private $updateService;
3445

3546
/**
3647
* UserController constructor.
3748
*
38-
* @param \Illuminate\Contracts\Config\Repository $config
3949
* @param \Spatie\Fractal\Fractal $fractal
4050
* @param \Pterodactyl\Contracts\Repository\UserRepositoryInterface $repository
51+
* @param \Pterodactyl\Services\Users\UserCreationService $creationService
52+
* @param \Pterodactyl\Services\Users\UserDeletionService $deletionService
53+
* @param \Pterodactyl\Services\Users\UserUpdateService $updateService
4154
*/
4255
public function __construct(
43-
ConfigRepository $config,
4456
Fractal $fractal,
45-
UserRepositoryInterface $repository
57+
UserRepositoryInterface $repository,
58+
UserCreationService $creationService,
59+
UserDeletionService $deletionService,
60+
UserUpdateService $updateService
4661
) {
62+
$this->creationService = $creationService;
63+
$this->deletionService = $deletionService;
4764
$this->fractal = $fractal;
4865
$this->repository = $repository;
49-
$this->config = $config;
66+
$this->updateService = $updateService;
5067
}
5168

5269
/**
53-
* Handle request to list all users on the panel.
70+
* Handle request to list all users on the panel. Returns a JSONAPI representation
71+
* of a collection of users including any defined relations passed in
72+
* the request.
5473
*
5574
* @param \Illuminate\Http\Request $request
5675
* @return array
5776
*/
58-
public function index(Request $request)
77+
public function index(Request $request): array
5978
{
60-
$users = $this->repository->all($this->config->get('pterodactyl.paginate.api.users'));
79+
$users = $this->repository->all(config('pterodactyl.paginate.api.users'));
6180

6281
$fractal = $this->fractal->collection($users)
6382
->transformWith(new UserTransformer($request))
6483
->withResourceName('user')
6584
->paginateWith(new IlluminatePaginatorAdapter($users));
6685

67-
if ($this->config->get('pterodactyl.api.include_on_list') && $request->input('include')) {
86+
if (config('pterodactyl.api.include_on_list') && $request->has('include')) {
87+
$fractal->parseIncludes(explode(',', $request->input('include')));
88+
}
89+
90+
return $fractal->toArray();
91+
}
92+
93+
/**
94+
* Handle a request to view a single user. Includes any relations that
95+
* were defined in the request.
96+
*
97+
* @param \Illuminate\Http\Request $request
98+
* @param \Pterodactyl\Models\User $user
99+
* @return array
100+
*/
101+
public function view(Request $request, User $user): array
102+
{
103+
$fractal = $this->fractal->item($user)
104+
->transformWith(new UserTransformer($request))
105+
->withResourceName('user');
106+
107+
if ($request->has('include')) {
68108
$fractal->parseIncludes(explode(',', $request->input('include')));
69109
}
70110

71111
return $fractal->toArray();
72112
}
113+
114+
/**
115+
* Update an existing user on the system and return the response. Returns the
116+
* updated user model response on success. Supports handling of token revocation
117+
* errors when switching a user from an admin to a normal user.
118+
*
119+
* Revocation errors are returned under the 'revocation_errors' key in the response
120+
* meta. If there are no errors this is an empty array.
121+
*
122+
* @param \Pterodactyl\Http\Requests\Admin\UserFormRequest $request
123+
* @param \Pterodactyl\Models\User $user
124+
* @return array
125+
*
126+
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
127+
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
128+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
129+
*/
130+
public function update(UserFormRequest $request, User $user): array
131+
{
132+
$this->updateService->setUserLevel(User::USER_LEVEL_ADMIN);
133+
$collection = $this->updateService->handle($user, $request->normalize());
134+
135+
$errors = [];
136+
if (! empty($collection->get('exceptions'))) {
137+
foreach ($collection->get('exceptions') as $node => $exception) {
138+
/** @var \GuzzleHttp\Exception\RequestException $exception */
139+
/** @var \GuzzleHttp\Psr7\Response|null $response */
140+
$response = method_exists($exception, 'getResponse') ? $exception->getResponse() : null;
141+
$message = trans('admin/server.exceptions.daemon_exception', [
142+
'code' => is_null($response) ? 'E_CONN_REFUSED' : $response->getStatusCode(),
143+
]);
144+
145+
$errors[] = ['message' => $message, 'node' => $node];
146+
}
147+
}
148+
149+
return $this->fractal->item($collection->get('user'))
150+
->transformWith(new UserTransformer($request))
151+
->withResourceName('user')
152+
->addMeta([
153+
'revocation_errors' => $errors,
154+
])
155+
->toArray();
156+
}
157+
158+
/**
159+
* Store a new user on the system. Returns the created user and a HTTP/201
160+
* header on successful creation.
161+
*
162+
* @param \Pterodactyl\Http\Requests\Admin\UserFormRequest $request
163+
* @return \Illuminate\Http\JsonResponse
164+
*
165+
* @throws \Exception
166+
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
167+
*/
168+
public function store(UserFormRequest $request): JsonResponse
169+
{
170+
$user = $this->creationService->handle($request->normalize());
171+
172+
return $this->fractal->item($user)
173+
->transformWith(new UserTransformer($request))
174+
->withResourceName('user')
175+
->addMeta([
176+
'link' => route('api.admin.user.view', ['user' => $user->id]),
177+
])
178+
->respond(201);
179+
}
180+
181+
/**
182+
* Handle a request to delete a user from the Panel. Returns a HTTP/204 response
183+
* on successful deletion.
184+
*
185+
* @param \Pterodactyl\Models\User $user
186+
* @return \Illuminate\Http\Response
187+
*
188+
* @throws \Pterodactyl\Exceptions\DisplayException
189+
*/
190+
public function delete(User $user): Response
191+
{
192+
$this->deletionService->handle($user);
193+
194+
return response('', 204);
195+
}
73196
}

routes/api-admin.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
*/
1111
Route::group(['prefix' => '/users'], function () {
1212
Route::get('/', 'Users\UserController@index')->name('api.admin.user.list');
13-
Route::get('/{id}', 'Users\UserController@view');
13+
Route::get('/{user}', 'Users\UserController@view')->name('api.admin.user.view');
1414

15-
Route::post('/', 'Users\UserController@store');
16-
Route::put('/{id}', 'Users\UserController@update');
15+
Route::post('/', 'Users\UserController@store')->name('api.admin.user.store');
16+
Route::put('/{user}', 'Users\UserController@update')->name('api.admin.user.update');
1717

18-
Route::delete('/{id}', 'Users\UserController@delete');
18+
Route::delete('/{user}', 'Users\UserController@delete')->name('api.admin.user.delete');
1919
});

0 commit comments

Comments
 (0)