* @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, int $targetUserId): JsonResponse { $this->authorizeServerAdmin($request, $server); $effective = $this->resolver->resolveAll( $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.'); } }