151 lines
5.0 KiB
PHP
151 lines
5.0 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @author Ball Studios <https://git.balls.studio>
|
|
* @license MIT
|
|
*/
|
|
|
|
namespace Pterodactyl\Addons\AdvancedAdmin\Http\Controllers\Client;
|
|
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Routing\Controller;
|
|
use Pterodactyl\Addons\AdvancedAdmin\Http\Resources\RoleResource;
|
|
use Pterodactyl\Addons\AdvancedAdmin\Http\Resources\EffectivePermissionResource;
|
|
use Pterodactyl\Addons\AdvancedAdmin\Models\ServerRoleAssignment;
|
|
use Pterodactyl\Addons\AdvancedAdmin\Services\Roles\PermissionResolver;
|
|
use Pterodactyl\Addons\AdvancedAdmin\Services\Roles\RoleService;
|
|
use Pterodactyl\Models\Server;
|
|
|
|
class ServerRoleController extends Controller
|
|
{
|
|
public function __construct(
|
|
private readonly RoleService $roleService,
|
|
private readonly PermissionResolver $resolver,
|
|
) {}
|
|
|
|
/** GET /api/client/servers/{server}/addons/roles/users */
|
|
public function listUsers(Request $request, Server $server): JsonResponse
|
|
{
|
|
$this->authorizeServerAdmin($request, $server);
|
|
|
|
$assignments = ServerRoleAssignment::query()
|
|
->where('server_id', $server->id)
|
|
->with(['user', 'role.permissions'])
|
|
->get()
|
|
->groupBy('user_id')
|
|
->map(function ($items) {
|
|
$user = $items->first()->user;
|
|
$roles = $items->pluck('role');
|
|
return ['user' => $user, 'roles' => $roles];
|
|
})
|
|
->values();
|
|
|
|
return response()->json(['data' => $assignments]);
|
|
}
|
|
|
|
/** POST /api/client/servers/{server}/addons/roles/assign */
|
|
public function assign(Request $request, Server $server): JsonResponse
|
|
{
|
|
$this->authorizeServerAdmin($request, $server);
|
|
|
|
$data = $request->validate([
|
|
'user_id' => 'required|integer|exists:users,id',
|
|
'role_id' => 'required|integer|exists:addon_roles,id',
|
|
]);
|
|
|
|
$assignment = $this->roleService->assignToUser(
|
|
$server->id,
|
|
$data['user_id'],
|
|
$data['role_id'],
|
|
$request->user()->id,
|
|
);
|
|
|
|
return response()->json(['data' => $assignment], 201);
|
|
}
|
|
|
|
/** DELETE /api/client/servers/{server}/addons/roles/assign */
|
|
public function unassign(Request $request, Server $server): JsonResponse
|
|
{
|
|
$this->authorizeServerAdmin($request, $server);
|
|
|
|
$data = $request->validate([
|
|
'user_id' => 'required|integer|exists:users,id',
|
|
'role_id' => 'required|integer|exists:addon_roles,id',
|
|
]);
|
|
|
|
$this->roleService->unassignFromUser(
|
|
$server->id,
|
|
$data['user_id'],
|
|
$data['role_id'],
|
|
$request->user()->id,
|
|
);
|
|
|
|
return response()->json(['deleted' => true]);
|
|
}
|
|
|
|
/** GET /api/client/servers/{server}/addons/permissions/effective/{userId} */
|
|
public function effectivePermissions(Request $request, Server $server, string $targetUserId): JsonResponse
|
|
{
|
|
// Allow callers to pass "me" to resolve to their own user ID
|
|
if ($targetUserId === 'me') {
|
|
$targetUserId = (string) $request->user()?->id;
|
|
}
|
|
|
|
// Non-admins can only query their own permissions
|
|
$user = $request->user();
|
|
$isAdmin = $user && ($user->root_admin || $server->owner_id === $user->id);
|
|
if (!$isAdmin && (string) $user?->id !== $targetUserId) {
|
|
abort(403, 'You may only query your own permissions.');
|
|
}
|
|
|
|
$effective = $this->resolver->resolveAll(
|
|
(int) $targetUserId,
|
|
$server->id,
|
|
RoleService::KNOWN_PERMISSIONS
|
|
);
|
|
|
|
return response()->json(['data' => $effective]);
|
|
}
|
|
|
|
/** PUT /api/client/servers/{server}/addons/permissions/override */
|
|
public function setOverride(Request $request, Server $server): JsonResponse
|
|
{
|
|
$this->authorizeServerAdmin($request, $server);
|
|
|
|
$data = $request->validate([
|
|
'user_id' => 'required|integer|exists:users,id',
|
|
'permission' => 'required|string|max:100',
|
|
'value' => 'required|in:allow,deny,unset',
|
|
]);
|
|
|
|
$override = $this->roleService->setOverride(
|
|
$server->id,
|
|
$data['user_id'],
|
|
$data['permission'],
|
|
$data['value'],
|
|
$request->user()->id,
|
|
);
|
|
|
|
return response()->json(['data' => $override]);
|
|
}
|
|
|
|
private function authorizeServerAdmin(Request $request, Server $server): void
|
|
{
|
|
$user = $request->user();
|
|
abort_unless($user, 401);
|
|
|
|
$isOwner = $server->owner_id === $user->id;
|
|
$isAdmin = $user->root_admin;
|
|
|
|
// Subusers with user.update can also manage roles on their server
|
|
$isSubuserAdmin = false;
|
|
if (!$isOwner && !$isAdmin) {
|
|
$subuser = $server->subusers()->where('user_id', $user->id)->first();
|
|
$isSubuserAdmin = $subuser && in_array('user.update', $subuser->permissions ?? [], true);
|
|
}
|
|
|
|
abort_unless($isOwner || $isAdmin || $isSubuserAdmin, 403, 'Insufficient privileges.');
|
|
}
|
|
}
|