Skip to content

Commit a6f46d3

Browse files
committed
Implement basic code for creating/updating a subuser
1 parent 51c5cf4 commit a6f46d3

File tree

17 files changed

+349
-324
lines changed

17 files changed

+349
-324
lines changed

app/Http/Controllers/Api/Client/Servers/SubuserController.php

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22

33
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
44

5+
use Illuminate\Http\Request;
56
use Pterodactyl\Models\Server;
7+
use Illuminate\Http\JsonResponse;
68
use Pterodactyl\Repositories\Eloquent\SubuserRepository;
9+
use Pterodactyl\Services\Subusers\SubuserCreationService;
710
use Pterodactyl\Transformers\Api\Client\SubuserTransformer;
811
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
912
use Pterodactyl\Http\Requests\Api\Client\Servers\Subusers\GetSubuserRequest;
13+
use Pterodactyl\Http\Requests\Api\Client\Servers\Subusers\StoreSubuserRequest;
14+
use Pterodactyl\Http\Requests\Api\Client\Servers\Subusers\DeleteSubuserRequest;
15+
use Pterodactyl\Http\Requests\Api\Client\Servers\Subusers\UpdateSubuserRequest;
1016

1117
class SubuserController extends ClientApiController
1218
{
@@ -15,16 +21,25 @@ class SubuserController extends ClientApiController
1521
*/
1622
private $repository;
1723

24+
/**
25+
* @var \Pterodactyl\Services\Subusers\SubuserCreationService
26+
*/
27+
private $creationService;
28+
1829
/**
1930
* SubuserController constructor.
2031
*
2132
* @param \Pterodactyl\Repositories\Eloquent\SubuserRepository $repository
33+
* @param \Pterodactyl\Services\Subusers\SubuserCreationService $creationService
2234
*/
23-
public function __construct(SubuserRepository $repository)
24-
{
35+
public function __construct(
36+
SubuserRepository $repository,
37+
SubuserCreationService $creationService
38+
) {
2539
parent::__construct();
2640

2741
$this->repository = $repository;
42+
$this->creationService = $creationService;
2843
}
2944

3045
/**
@@ -36,10 +51,76 @@ public function __construct(SubuserRepository $repository)
3651
*/
3752
public function index(GetSubuserRequest $request, Server $server)
3853
{
39-
$server->subusers->load('user');
40-
4154
return $this->fractal->collection($server->subusers)
4255
->transformWith($this->getTransformer(SubuserTransformer::class))
4356
->toArray();
4457
}
58+
59+
/**
60+
* Create a new subuser for the given server.
61+
*
62+
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\Subusers\StoreSubuserRequest $request
63+
* @param \Pterodactyl\Models\Server $server
64+
* @return array
65+
*
66+
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
67+
* @throws \Pterodactyl\Exceptions\Service\Subuser\ServerSubuserExistsException
68+
* @throws \Pterodactyl\Exceptions\Service\Subuser\UserIsServerOwnerException
69+
* @throws \Throwable
70+
*/
71+
public function store(StoreSubuserRequest $request, Server $server)
72+
{
73+
$response = $this->creationService->handle(
74+
$server, $request->input('email'), $this->getDefaultPermissions($request)
75+
);
76+
77+
return $this->fractal->item($response)
78+
->transformWith($this->getTransformer(SubuserTransformer::class))
79+
->toArray();
80+
}
81+
82+
/**
83+
* Update a given subuser in the system for the server.
84+
*
85+
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\Subusers\UpdateSubuserRequest $request
86+
*
87+
* @return array
88+
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
89+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
90+
*/
91+
public function update(UpdateSubuserRequest $request)
92+
{
93+
$subuser = $request->subuser();
94+
$this->repository->update($subuser->id, [
95+
'permissions' => $this->getDefaultPermissions($request),
96+
]);
97+
98+
return $this->fractal->item($subuser->refresh())
99+
->transformWith($this->getTransformer(SubuserTransformer::class))
100+
->toArray();
101+
}
102+
103+
/**
104+
* Removes a subusers from a server's assignment.
105+
*
106+
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\Subusers\DeleteSubuserRequest $request
107+
* @return \Illuminate\Http\JsonResponse
108+
*/
109+
public function delete(DeleteSubuserRequest $request)
110+
{
111+
$this->repository->delete($request->subuser()->id);
112+
113+
return JsonResponse::create([], JsonResponse::HTTP_NO_CONTENT);
114+
}
115+
116+
/**
117+
* Returns the default permissions for all subusers to ensure none are ever removed wrongly.
118+
*
119+
* @param \Illuminate\Http\Request $request
120+
* @return array
121+
*/
122+
protected function getDefaultPermissions(Request $request): array
123+
{
124+
return array_merge($request->input('permissions') ?? [], ['websocket.*']);
125+
}
45126
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Requests\Api\Client\Servers\Subusers;
4+
5+
use Pterodactyl\Models\Server;
6+
use Pterodactyl\Repositories\Eloquent\SubuserRepository;
7+
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
8+
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
9+
10+
abstract class AbstractSubuserRequest extends ClientApiRequest
11+
{
12+
/**
13+
* @var \Pterodactyl\Models\Subuser|null
14+
*/
15+
protected $model;
16+
17+
/**
18+
* Authorize the request and ensure that a user is not trying to modify themselves.
19+
*
20+
* @return bool
21+
*/
22+
public function authorize(): bool
23+
{
24+
if (! parent::authorize()) {
25+
return false;
26+
}
27+
28+
if ($this->subuser()->user_id === $this->user()->id) {
29+
return false;
30+
}
31+
32+
return true;
33+
}
34+
35+
/**
36+
* Return the subuser model for the given request which can then be validated. If
37+
* required request parameters are missing a 404 error will be returned, otherwise
38+
* a model exception will be returned if the model is not found.
39+
*
40+
* @return \Pterodactyl\Models\Subuser
41+
*
42+
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
43+
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
44+
*/
45+
public function subuser()
46+
{
47+
/** @var \Pterodactyl\Repositories\Eloquent\SubuserRepository $repository */
48+
$repository = $this->container->make(SubuserRepository::class);
49+
50+
$parameters = $this->route()->parameters();
51+
if (
52+
! isset($parameters['server'], $parameters['server'])
53+
|| ! is_string($parameters['subuser'])
54+
|| ! $parameters['server'] instanceof Server
55+
) {
56+
throw new NotFoundHttpException;
57+
}
58+
59+
return $this->model ?: $this->model = $repository->getUserForServer(
60+
$this->route()->parameter('subuser'), $this->route()->parameter('server')->id
61+
);
62+
}
63+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Requests\Api\Client\Servers\Subusers;
4+
5+
use Pterodactyl\Models\Permission;
6+
7+
class DeleteSubuserRequest extends AbstractSubuserRequest
8+
{
9+
/**
10+
* @return string
11+
*/
12+
public function permission()
13+
{
14+
return Permission::ACTION_USER_DELETE;
15+
}
16+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Requests\Api\Client\Servers\Subusers;
4+
5+
use Pterodactyl\Models\Permission;
6+
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
7+
8+
class StoreSubuserRequest extends ClientApiRequest
9+
{
10+
/**
11+
* @return string
12+
*/
13+
public function permission()
14+
{
15+
return Permission::ACTION_USER_CREATE;
16+
}
17+
18+
/**
19+
* @return array
20+
*/
21+
public function rules(): array
22+
{
23+
return [
24+
'email' => 'required|email',
25+
'permissions' => 'required|array',
26+
'permissions.*' => 'string',
27+
];
28+
}
29+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Requests\Api\Client\Servers\Subusers;
4+
5+
use Pterodactyl\Models\Permission;
6+
7+
class UpdateSubuserRequest extends AbstractSubuserRequest
8+
{
9+
/**
10+
* @return string
11+
*/
12+
public function permission()
13+
{
14+
return Permission::ACTION_USER_UPDATE;
15+
}
16+
17+
/**
18+
* @return array
19+
*/
20+
public function rules(): array
21+
{
22+
return [
23+
'permissions' => 'required|array',
24+
'permissions.*' => 'string',
25+
];
26+
}
27+
}

app/Models/Validable.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public function validate()
140140
}
141141

142142
return $this->getValidator()->setData(
143-
$this->getAttributes()
143+
$this->toArray()
144144
)->passes();
145145
}
146146
}

app/Repositories/Eloquent/SubuserRepository.php

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace Pterodactyl\Repositories\Eloquent;
44

55
use Pterodactyl\Models\Subuser;
6-
use Illuminate\Support\Collection;
76
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
87
use Pterodactyl\Contracts\Repository\SubuserRepositoryInterface;
98

@@ -20,19 +19,27 @@ public function model()
2019
}
2120

2221
/**
23-
* Returns the subusers for the given server instance with the associated user
24-
* and permission relationships pre-loaded.
22+
* Returns a subuser model for the given user and server combination. If no record
23+
* exists an exception will be thrown.
2524
*
2625
* @param int $server
27-
* @return \Illuminate\Support\Collection
26+
* @param string $uuid
27+
* @return \Pterodactyl\Models\Subuser
28+
*
29+
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
2830
*/
29-
public function getSubusersForServer(int $server): Collection
31+
public function getUserForServer(int $server, string $uuid): Subuser
3032
{
31-
return $this->getBuilder()
32-
->with('user', 'permissions')
33-
->where('server_id', $server)
34-
->get()
35-
->toBase();
33+
/** @var \Pterodactyl\Models\Subuser $model */
34+
$model = $this->getBuilder()
35+
->with('server', 'user')
36+
->select('subusers.*')
37+
->join('users', 'users.id', '=', 'subusers.user_id')
38+
->where('subusers.server_id', $server)
39+
->where('users.uuid', $uuid)
40+
->firstOrFail();
41+
42+
return $model;
3643
}
3744

3845
/**

app/Services/Subusers/PermissionCreationService.php

Lines changed: 0 additions & 63 deletions
This file was deleted.

0 commit comments

Comments
 (0)