forked from pterodactyl/panel
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSubuserRequest.php
More file actions
131 lines (115 loc) · 4.47 KB
/
SubuserRequest.php
File metadata and controls
131 lines (115 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<?php
namespace Pterodactyl\Http\Requests\Api\Client\Servers\Subusers;
use Illuminate\Http\Request;
use Pterodactyl\Models\Server;
use Pterodactyl\Exceptions\Http\HttpForbiddenException;
use Pterodactyl\Repositories\Eloquent\SubuserRepository;
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
abstract class SubuserRequest extends ClientApiRequest
{
/**
* @var \Pterodactyl\Models\Subuser|null
*/
protected $model;
/**
* Authorize the request and ensure that a user is not trying to modify themselves.
*
* @return bool
*/
public function authorize(): bool
{
if (! parent::authorize()) {
return false;
}
// If there is a subuser present in the URL, validate that it is not the same as the
// current request user. You're not allowed to modify yourself.
if ($this->route()->hasParameter('subuser')) {
if ($this->endpointSubuser()->user_id === $this->user()->id) {
return false;
}
}
// If this is a POST request, validate that the user can even assign the permissions they
// have selected to assign.
if ($this->method() === Request::METHOD_POST && $this->has('permissions')) {
$this->validatePermissionsCanBeAssigned(
$this->input('permissions') ?? []
);
}
return true;
}
/**
* Validates that the permissions we are trying to assign can actually be assigned
* by the user making the request.
*
* @param array $permissions
*/
protected function validatePermissionsCanBeAssigned(array $permissions)
{
$user = $this->user();
/** @var \Pterodactyl\Models\Server $server */
$server = $this->route()->parameter('server');
// If we are a root admin or the server owner, no need to perform these checks.
if ($user->root_admin || $user->id === $server->owner_id) {
return;
}
// Otherwise, get the current subuser's permission set, and ensure that the
// permissions they are trying to assign are not _more_ than the ones they
// already have.
if (count(array_diff($permissions, $this->currentUserPermissions())) > 0) {
throw new HttpForbiddenException(
'Cannot assign permissions to a subuser that your account does not actively possess.'
);
}
}
/**
* Returns the currently authenticated user's permissions.
*
* @return array
*/
public function currentUserPermissions(): array
{
/** @var \Pterodactyl\Repositories\Eloquent\SubuserRepository $repository */
$repository = $this->container->make(SubuserRepository::class);
/* @var \Pterodactyl\Models\Subuser $model */
try {
$model = $repository->findFirstWhere([
['server_id', $this->route()->parameter('server')->id],
['user_id' => $this->user()->id],
]);
} catch (RecordNotFoundException $exception) {
return [];
}
return $model->permissions;
}
/**
* Return the subuser model for the given request which can then be validated. If
* required request parameters are missing a 404 error will be returned, otherwise
* a model exception will be returned if the model is not found.
*
* This returns the subuser based on the endpoint being hit, not the actual subuser
* for the account making the request.
*
* @return \Pterodactyl\Models\Subuser
*
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
public function endpointSubuser()
{
/** @var \Pterodactyl\Repositories\Eloquent\SubuserRepository $repository */
$repository = $this->container->make(SubuserRepository::class);
$parameters = $this->route()->parameters();
if (
! isset($parameters['server'], $parameters['server'])
|| ! is_string($parameters['subuser'])
|| ! $parameters['server'] instanceof Server
) {
throw new NotFoundHttpException;
}
return $this->model ?: $this->model = $repository->getUserForServer(
$parameters['server']->id, $parameters['subuser']
);
}
}