Cleanup frontend controllers and middleware

This commit is contained in:
Dane Everitt 2017-10-27 21:42:53 -05:00
parent d73d580724
commit e0d03513e4
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
33 changed files with 400 additions and 594 deletions

View file

@ -9,23 +9,28 @@
namespace Pterodactyl\Contracts\Repository;
use Pterodactyl\Models\Schedule;
use Illuminate\Support\Collection;
interface ScheduleRepositoryInterface extends RepositoryInterface
{
/**
* Return all of the schedules for a given server.
*
* @param int $server
* @return \Illuminate\Database\Eloquent\Collection
* @return \Illuminate\Support\Collection
*/
public function getServerSchedules($server);
public function findServerSchedules(int $server): Collection;
/**
* Return a schedule model with all of the associated tasks as a relationship.
*
* @param int $schedule
* @return \Illuminate\Support\Collection
* @return \Pterodactyl\Models\Schedule
*
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function getScheduleWithTasks($schedule);
public function getScheduleWithTasks(int $schedule): Schedule;
/**
* Return all of the schedules that should be processed.

View file

@ -1,35 +1,28 @@
<?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Contracts\Repository;
use Pterodactyl\Models\Subuser;
interface SubuserRepositoryInterface extends RepositoryInterface
{
/**
* Return a subuser with the associated server relationship.
*
* @param int $id
* @param \Pterodactyl\Models\Subuser $subuser
* @param bool $refresh
* @return \Pterodactyl\Models\Subuser
*
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function getWithServer($id);
public function getWithServer(Subuser $subuser, bool $refresh = false): Subuser;
/**
* Return a subuser with the associated permissions relationship.
*
* @param int $id
* @return \Illuminate\Database\Eloquent\Collection
*
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
* @param \Pterodactyl\Models\Subuser $subuser
* @param bool $refresh
* @return \Pterodactyl\Models\Subuser
*/
public function getWithPermissions($id);
public function getWithPermissions(Subuser $subuser, bool $refresh = false): Subuser;
/**
* Return a subuser and associated permissions given a user_id and server_id.

View file

@ -1,15 +1,9 @@
<?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Http\Controllers\Server;
use Illuminate\Contracts\Session\Session;
use Illuminate\View\View;
use Illuminate\Http\Request;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Traits\Controllers\JavascriptInjection;
use Illuminate\Contracts\Config\Repository as ConfigRepository;
@ -23,35 +17,27 @@ class ConsoleController extends Controller
*/
protected $config;
/**
* @var \Illuminate\Contracts\Session\Session
*/
protected $session;
/**
* ConsoleController constructor.
*
* @param \Illuminate\Contracts\Config\Repository $config
* @param \Illuminate\Contracts\Session\Session $session
*/
public function __construct(
ConfigRepository $config,
Session $session
) {
public function __construct(ConfigRepository $config)
{
$this->config = $config;
$this->session = $session;
}
/**
* Render server index page with the console and power options.
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @param \Illuminate\Http\Request $request
* @return \Illuminate\View\View
*/
public function index()
public function index(Request $request): View
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$this->injectJavascript([
$this->setRequest($request)->injectJavascript([
'meta' => [
'saveFile' => route('server.files.save', $server->uuidShort),
'csrfToken' => csrf_token(),
@ -68,11 +54,12 @@ class ConsoleController extends Controller
/**
* Render a stand-alone console in the browser.
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @param \Illuminate\Http\Request $request
* @return \Illuminate\View\View
*/
public function console()
public function console(Request $request): View
{
$this->injectJavascript(['config' => [
$this->setRequest($request)->injectJavascript(['config' => [
'console_count' => $this->config->get('pterodactyl.console.count'),
'console_freq' => $this->config->get('pterodactyl.console.frequency'),
]]);

View file

@ -9,8 +9,9 @@
namespace Pterodactyl\Http\Controllers\Server\Files;
use Illuminate\Http\Request;
use Illuminate\Cache\Repository;
use Illuminate\Contracts\Session\Session;
use Illuminate\Http\RedirectResponse;
use Pterodactyl\Http\Controllers\Controller;
class DownloadController extends Controller
@ -20,42 +21,35 @@ class DownloadController extends Controller
*/
protected $cache;
/**
* @var \Illuminate\Contracts\Session\Session
*/
protected $session;
/**
* DownloadController constructor.
*
* @param \Illuminate\Cache\Repository $cache
* @param \Illuminate\Contracts\Session\Session $session
* @param \Illuminate\Cache\Repository $cache
*/
public function __construct(Repository $cache, Session $session)
public function __construct(Repository $cache)
{
$this->cache = $cache;
$this->session = $session;
}
/**
* Setup a unique download link for a user to download a file from.
*
* @param string $uuid
* @param string $file
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @param \Illuminate\Http\Request $request
* @param string $uuid
* @param string $file
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index($uuid, $file)
public function index(Request $request, string $uuid, string $file): RedirectResponse
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$this->authorize('download-files', $server);
$token = str_random(40);
$node = $server->getRelation('node');
$this->cache->tags(['Server:Downloads'])->put($token, ['server' => $server->uuid, 'path' => $file], 5);
return redirect(sprintf(
'%s://%s:%s/v1/server/file/download/%s', $server->node->scheme, $server->node->fqdn, $server->node->daemonListen, $token
));
return redirect(sprintf('%s://%s:%s/v1/server/file/download/%s', $node->scheme, $node->fqdn, $node->daemonListen, $token));
}
}

View file

@ -9,15 +9,14 @@
namespace Pterodactyl\Http\Controllers\Server\Files;
use Illuminate\Log\Writer;
use Illuminate\View\View;
use Illuminate\Http\Request;
use Illuminate\Contracts\Session\Session;
use GuzzleHttp\Exception\RequestException;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Traits\Controllers\JavascriptInjection;
use Pterodactyl\Http\Requests\Server\UpdateFileContentsFormRequest;
use Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface;
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
class FileActionsController extends Controller
{
@ -26,30 +25,16 @@ class FileActionsController extends Controller
/**
* @var \Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface
*/
protected $fileRepository;
/**
* @var \Illuminate\Contracts\Session\Session
*/
protected $session;
/**
* @var \Illuminate\Log\Writer
*/
protected $writer;
protected $repository;
/**
* FileActionsController constructor.
*
* @param \Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface $fileRepository
* @param \Illuminate\Contracts\Session\Session $session
* @param \Illuminate\Log\Writer $writer
* @param \Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface $repository
*/
public function __construct(FileRepositoryInterface $fileRepository, Session $session, Writer $writer)
public function __construct(FileRepositoryInterface $repository)
{
$this->fileRepository = $fileRepository;
$this->session = $session;
$this->writer = $writer;
$this->repository = $repository;
}
/**
@ -60,12 +45,12 @@ class FileActionsController extends Controller
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index(Request $request)
public function index(Request $request): View
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$this->authorize('list-files', $server);
$this->injectJavascript([
$this->setRequest($request)->injectJavascript([
'meta' => [
'directoryList' => route('server.files.directory-list', $server->uuidShort),
'csrftoken' => csrf_token(),
@ -92,10 +77,10 @@ class FileActionsController extends Controller
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function create(Request $request)
public function create(Request $request): View
{
$this->authorize('create-files', $this->session->get('server_data.model'));
$this->injectJavascript();
$this->authorize('create-files', $request->attributes->get('server'));
$this->setRequest($request)->injectJavascript();
return view('server.files.add', [
'directory' => (in_array($request->get('dir'), [null, '/', ''])) ? '' : trim($request->get('dir'), '/') . '/',
@ -114,31 +99,24 @@ class FileActionsController extends Controller
* @throws \Pterodactyl\Exceptions\DisplayException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function update(UpdateFileContentsFormRequest $request, $uuid, $file)
public function update(UpdateFileContentsFormRequest $request, string $uuid, string $file): View
{
$server = $this->session->get('server_data.model');
$this->authorize('edit-files', $server);
$server = $request->attributes->get('server');
$dirname = pathinfo($file, PATHINFO_DIRNAME);
try {
$content = $this->fileRepository->setNode($server->node_id)
->setAccessServer($server->uuid)
->setAccessToken($this->session->get('server_data.token'))
$content = $this->repository->setNode($server->node_id)->setAccessServer($server->uuid)
->setAccessToken($request->attributes->get('server_token'))
->getContent($file);
} catch (RequestException $exception) {
$response = $exception->getResponse();
$this->writer->warning($exception);
throw new DisplayException(trans('exceptions.daemon_connection_failed', [
'code' => is_null($response) ? 'E_CONN_REFUSED' : $response->getStatusCode(),
]));
throw new DaemonConnectionException($exception);
}
$this->injectJavascript(['stat' => $request->getStats()]);
$this->setRequest($request)->injectJavascript(['stat' => $request->attributes->get('file_stats')]);
return view('server.files.edit', [
'file' => $file,
'stat' => $request->getStats(),
'stat' => $request->attributes->get('file_stats'),
'contents' => $content,
'directory' => (in_array($dirname, ['.', './', '/'])) ? '/' : trim($dirname, '/') . '/',
]);

View file

@ -1,21 +1,15 @@
<?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Http\Controllers\Server\Files;
use Illuminate\Log\Writer;
use Illuminate\View\View;
use Illuminate\Http\Request;
use Illuminate\Contracts\Session\Session;
use Illuminate\Http\Response;
use GuzzleHttp\Exception\RequestException;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Contracts\Config\Repository as ConfigRepository;
use Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface;
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
class RemoteRequestController extends Controller
{
@ -27,50 +21,33 @@ class RemoteRequestController extends Controller
/**
* @var \Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface
*/
protected $fileRepository;
/**
* @var \Illuminate\Contracts\Session\Session
*/
protected $session;
/**
* @var \Illuminate\Log\Writer
*/
protected $writer;
protected $repository;
/**
* RemoteRequestController constructor.
*
* @param \Illuminate\Contracts\Config\Repository $config
* @param \Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface $fileRepository
* @param \Illuminate\Contracts\Session\Session $session
* @param \Illuminate\Log\Writer $writer
* @param \Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface $repository
*/
public function __construct(
ConfigRepository $config,
FileRepositoryInterface $fileRepository,
Session $session,
Writer $writer
) {
public function __construct(ConfigRepository $config, FileRepositoryInterface $repository)
{
$this->config = $config;
$this->fileRepository = $fileRepository;
$this->session = $session;
$this->writer = $writer;
$this->repository = $repository;
}
/**
* Return a listing of a servers file directory.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse|\Illuminate\View\View
* @return \Illuminate\View\View
*
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function directory(Request $request)
public function directory(Request $request): View
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$this->authorize('list-files', $server);
$requestDirectory = '/' . trim(urldecode($request->input('directory', '/')), '/');
@ -89,17 +66,12 @@ class RemoteRequestController extends Controller
}
try {
$listing = $this->fileRepository->setNode($server->node_id)
$listing = $this->repository->setNode($server->node_id)
->setAccessServer($server->uuid)
->setAccessToken($this->session->get('server_data.token'))
->setAccessToken($request->attributes->get('server_token'))
->getDirectory($requestDirectory);
} catch (RequestException $exception) {
$this->writer->warning($exception);
$response = $exception->getResponse();
return response()->json(['error' => trans('exceptions.daemon_connection_failed', [
'code' => is_null($response) ? 'E_CONN_REFUSED' : $response->getStatusCode(),
])], 500);
throw new DaemonConnectionException($exception);
}
return view('server.files.list', [
@ -114,31 +86,26 @@ class RemoteRequestController extends Controller
* Put the contents of a file onto the daemon.
*
* @param \Illuminate\Http\Request $request
* @param string $uuid
* @return \Illuminate\Http\JsonResponse
* @return \Illuminate\Http\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function store(Request $request, $uuid)
public function store(Request $request): Response
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$this->authorize('save-files', $server);
try {
$this->fileRepository->setNode($server->node_id)
$this->repository->setNode($server->node_id)
->setAccessServer($server->uuid)
->setAccessToken($this->session->get('server_data.token'))
->setAccessToken($request->attributes->get('server_token'))
->putContent($request->input('file'), $request->input('contents'));
return response('', 204);
} catch (RequestException $exception) {
$this->writer->warning($exception);
$response = $exception->getResponse();
return response()->json(['error' => trans('exceptions.daemon_connection_failed', [
'code' => is_null($response) ? 'E_CONN_REFUSED' : $response->getStatusCode(),
])], 500);
throw new DaemonConnectionException($exception);
}
}
}

View file

@ -4,7 +4,6 @@ namespace Pterodactyl\Http\Controllers\Server\Settings;
use Illuminate\View\View;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Http\JsonResponse;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Contracts\Extensions\HashidsInterface;

View file

@ -2,6 +2,7 @@
namespace Pterodactyl\Http\Controllers\Server\Settings;
use Illuminate\View\View;
use Illuminate\Http\Request;
use Pterodactyl\Models\User;
use Illuminate\Http\RedirectResponse;
@ -57,11 +58,11 @@ class StartupController extends Controller
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function index(Request $request)
public function index(Request $request): View
{
$server = $request->attributes->get('server');
$this->authorize('view-startup', $server);
$this->injectJavascript();
$this->setRequest($request)->injectJavascript();
$data = $this->commandViewService->handle($server->id);

View file

@ -1,24 +1,21 @@
<?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Http\Controllers\Server;
use Illuminate\View\View;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Pterodactyl\Models\Permission;
use Illuminate\Http\RedirectResponse;
use Prologue\Alerts\AlertsMessageBag;
use Illuminate\Contracts\Session\Session;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Services\Subusers\SubuserUpdateService;
use Pterodactyl\Traits\Controllers\JavascriptInjection;
use Pterodactyl\Services\Subusers\SubuserCreationService;
use Pterodactyl\Services\Subusers\SubuserDeletionService;
use Pterodactyl\Contracts\Repository\SubuserRepositoryInterface;
use Pterodactyl\Http\Requests\Server\Subuser\SubuserStoreFormRequest;
use Pterodactyl\Http\Requests\Server\Subuser\SubuserUpdateFormRequest;
class SubuserController extends Controller
{
@ -34,11 +31,6 @@ class SubuserController extends Controller
*/
protected $repository;
/**
* @var \Illuminate\Contracts\Session\Session
*/
protected $session;
/**
* @var \Pterodactyl\Services\Subusers\SubuserCreationService
*/
@ -58,7 +50,6 @@ class SubuserController extends Controller
* SubuserController constructor.
*
* @param \Prologue\Alerts\AlertsMessageBag $alert
* @param \Illuminate\Contracts\Session\Session $session
* @param \Pterodactyl\Services\Subusers\SubuserCreationService $subuserCreationService
* @param \Pterodactyl\Services\Subusers\SubuserDeletionService $subuserDeletionService
* @param \Pterodactyl\Contracts\Repository\SubuserRepositoryInterface $repository
@ -66,7 +57,6 @@ class SubuserController extends Controller
*/
public function __construct(
AlertsMessageBag $alert,
Session $session,
SubuserCreationService $subuserCreationService,
SubuserDeletionService $subuserDeletionService,
SubuserRepositoryInterface $repository,
@ -74,7 +64,6 @@ class SubuserController extends Controller
) {
$this->alert = $alert;
$this->repository = $repository;
$this->session = $session;
$this->subuserCreationService = $subuserCreationService;
$this->subuserDeletionService = $subuserDeletionService;
$this->subuserUpdateService = $subuserUpdateService;
@ -83,17 +72,16 @@ class SubuserController extends Controller
/**
* Displays the subuser overview index.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\View\View
*
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function index()
public function index(Request $request): View
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$this->authorize('list-subusers', $server);
$this->injectJavascript();
$this->setRequest($request)->injectJavascript();
return view('server.users.index', [
'subusers' => $this->repository->findWhere([['server_id', '=', $server->id]]),
@ -101,27 +89,25 @@ class SubuserController extends Controller
}
/**
* Displays the a single subuser overview.
* Displays a single subuser overview.
*
* @param string $uuid
* @param int $id
* @param \Illuminate\Http\Request $request
* @return \Illuminate\View\View
*
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function view($uuid, $id)
public function view(Request $request): View
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$this->authorize('view-subuser', $server);
$subuser = $this->repository->getWithPermissions($id);
$this->injectJavascript();
$subuser = $this->repository->getWithPermissions($request->attributes->get('subuser'));
$this->setRequest($request)->injectJavascript();
return view('server.users.view', [
'subuser' => $subuser,
'permlist' => Permission::getPermissions(),
'permissions' => $subuser->permissions->mapWithKeys(function ($item, $key) {
'permissions' => $subuser->getRelation('permissions')->mapWithKeys(function ($item) {
return [$item->permission => true];
}),
]);
@ -130,9 +116,9 @@ class SubuserController extends Controller
/**
* Handles editing a subuser.
*
* @param \Illuminate\Http\Request $request
* @param string $uuid
* @param int $id
* @param \Pterodactyl\Http\Requests\Server\Subuser\SubuserUpdateFormRequest $request
* @param string $uuid
* @param string $hash
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
@ -140,30 +126,26 @@ class SubuserController extends Controller
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function update(Request $request, $uuid, $id)
public function update(SubuserUpdateFormRequest $request, string $uuid, string $hash): RedirectResponse
{
$server = $this->session->get('server_data.model');
$this->authorize('edit-subuser', $server);
$this->subuserUpdateService->handle($id, $request->input('permissions', []));
$this->subuserUpdateService->handle($request->attributes->get('subuser'), $request->input('permissions'));
$this->alert->success(trans('server.users.user_updated'))->flash();
return redirect()->route('server.subusers.view', ['uuid' => $uuid, 'id' => $id]);
return redirect()->route('server.subusers.view', ['uuid' => $uuid, 'subuser' => $hash]);
}
/**
* Display new subuser creation page.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\View\View
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function create()
public function create(Request $request): View
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$this->authorize('create-subuser', $server);
$this->injectJavascript();
$this->setRequest($request)->injectJavascript();
return view('server.users.new', ['permissions' => Permission::getPermissions()]);
}
@ -171,24 +153,22 @@ class SubuserController extends Controller
/**
* Handles creating a new subuser.
*
* @param \Illuminate\Http\Request $request
* @param string $uuid
* @param \Pterodactyl\Http\Requests\Server\Subuser\SubuserStoreFormRequest $request
* @param string $uuid
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Exception
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Pterodactyl\Exceptions\DisplayException
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
* @throws \Pterodactyl\Exceptions\Service\Subuser\ServerSubuserExistsException
* @throws \Pterodactyl\Exceptions\Service\Subuser\UserIsServerOwnerException
*/
public function store(Request $request, $uuid)
public function store(SubuserStoreFormRequest $request, $uuid): RedirectResponse
{
$server = $this->session->get('server_data.model');
$this->authorize('create-subuser', $server);
$server = $request->attributes->get('server');
$subuser = $this->subuserCreationService->handle($server, $request->input('email'), $request->input('permissions', []));
$subuser = $this->subuserCreationService->handle($server, $request->input('email'), $request->input('permissions'));
$this->alert->success(trans('server.users.user_assigned'))->flash();
return redirect()->route('server.subusers.view', [
@ -200,20 +180,19 @@ class SubuserController extends Controller
/**
* Handles deleting a subuser.
*
* @param string $uuid
* @param int $id
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Pterodactyl\Exceptions\DisplayException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function delete($uuid, $id)
public function delete(Request $request): Response
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$this->authorize('delete-subuser', $server);
$this->subuserDeletionService->handle($id);
$this->subuserDeletionService->handle($request->attributes->get('subuser'));
return response('', 204);
}

View file

@ -1,166 +0,0 @@
<?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Http\Controllers\Server;
use Log;
use Alert;
use Illuminate\Http\Request;
use Pterodactyl\Models\Server;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Repositories\TaskRepository;
use Pterodactyl\Exceptions\DisplayValidationException;
class TaskController extends Controller
{
/**
* Display task index page.
*
* @param \Illuminate\Http\Request $request
* @param string $uuid
* @return \Illuminate\View\View
*/
public function index(Request $request, $uuid)
{
$server = Server::byUuid($uuid)->load('tasks');
$this->authorize('list-tasks', $server);
$server->js();
return view('server.schedules.index', [
'server' => $server,
'node' => $server->node,
'tasks' => $server->tasks,
'actions' => [
'command' => trans('server.schedules.actions.command'),
'power' => trans('server.schedules.actions.power'),
],
]);
}
/**
* Display new task page.
*
* @param \Illuminate\Http\Request $request
* @param string $uuid
* @return \Illuminate\View\View
*/
public function create(Request $request, $uuid)
{
$server = Server::byUuid($uuid);
$this->authorize('create-task', $server);
$server->js();
return view('server.schedules.new', [
'server' => $server,
'node' => $server->node,
]);
}
/**
* Handle creation of new task.
*
* @param \Illuminate\Http\Request $request
* @param string $uuid
* @return \Illuminate\Http\RedirectResponse
*/
public function store(Request $request, $uuid)
{
$server = Server::byUuid($uuid);
$this->authorize('create-task', $server);
$repo = new TaskRepository;
try {
$repo->create($server->id, $request->user()->id, $request->except([
'_token',
]));
return redirect()->route('server.schedules', $uuid);
} catch (DisplayValidationException $ex) {
return redirect()->route('server.schedules.new', $uuid)->withErrors(json_decode($ex->getMessage()))->withInput();
} catch (DisplayException $ex) {
Alert::danger($ex->getMessage())->flash();
} catch (\Exception $ex) {
Log::error($ex);
Alert::danger('An unknown error occured while attempting to create this task.')->flash();
}
return redirect()->route('server.schedules.new', $uuid);
}
/**
* Handle deletion of a task.
*
* @param \Illuminate\Http\Request $request
* @param string $uuid
* @param int $id
* @return \Illuminate\Http\JsonResponse
*/
public function delete(Request $request, $uuid, $id)
{
$server = Server::byUuid($uuid)->load('tasks');
$this->authorize('delete-task', $server);
$task = $server->tasks->where('id', $id)->first();
if (! $task) {
return response()->json([
'error' => 'No task by that ID was found associated with this server.',
], 404);
}
$repo = new TaskRepository;
try {
$repo->delete($id);
return response()->json([], 204);
} catch (\Exception $ex) {
Log::error($ex);
return response()->json([
'error' => 'A server error occured while attempting to delete this task.',
], 503);
}
}
/**
* Toggle the status of a task.
*
* @param \Illuminate\Http\Request $request
* @param string $uuid
* @param int $id
* @return \Illuminate\Http\JsonResponse
*/
public function toggle(Request $request, $uuid, $id)
{
$server = Server::byUuid($uuid)->load('tasks');
$this->authorize('toggle-task', $server);
$task = $server->tasks->where('id', $id)->first();
if (! $task) {
return response()->json([
'error' => 'No task by that ID was found associated with this server.',
], 404);
}
$repo = new TaskRepository;
try {
$resp = $repo->toggle($id);
return response()->json([
'status' => $resp,
]);
} catch (\Exception $ex) {
Log::error($ex);
return response()->json([
'error' => 'A server error occured while attempting to toggle this task.',
], 503);
}
}
}

View file

@ -1,17 +1,12 @@
<?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Http\Controllers\Server\Tasks;
use Illuminate\View\View;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Http\RedirectResponse;
use Prologue\Alerts\AlertsMessageBag;
use Illuminate\Contracts\Session\Session;
use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Contracts\Extensions\HashidsInterface;
use Pterodactyl\Traits\Controllers\JavascriptInjection;
@ -43,24 +38,17 @@ class TaskManagementController extends Controller
*/
protected $repository;
/**
* @var \Illuminate\Contracts\Session\Session
*/
protected $session;
/**
* TaskManagementController constructor.
*
* @param \Prologue\Alerts\AlertsMessageBag $alert
* @param \Pterodactyl\Contracts\Extensions\HashidsInterface $hashids
* @param \Illuminate\Contracts\Session\Session $session
* @param \Pterodactyl\Services\Schedules\ScheduleCreationService $creationService
* @param \Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface $repository
*/
public function __construct(
AlertsMessageBag $alert,
HashidsInterface $hashids,
Session $session,
ScheduleCreationService $creationService,
ScheduleRepositoryInterface $repository
) {
@ -68,24 +56,24 @@ class TaskManagementController extends Controller
$this->creationService = $creationService;
$this->hashids = $hashids;
$this->repository = $repository;
$this->session = $session;
}
/**
* Display the task page listing.
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @param \Illuminate\Http\Request $request
* @return \Illuminate\View\View
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index()
public function index(Request $request): View
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$this->authorize('list-schedules', $server);
$this->injectJavascript();
$this->setRequest($request)->injectJavascript();
return view('server.schedules.index', [
'schedules' => $this->repository->getServerSchedules($server->id),
'schedules' => $this->repository->findServerSchedules($server->id),
'actions' => [
'command' => trans('server.schedule.actions.command'),
'power' => trans('server.schedule.actions.power'),
@ -96,38 +84,39 @@ class TaskManagementController extends Controller
/**
* Display the task creation page.
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @param \Illuminate\Http\Request $request
* @return \Illuminate\View\View
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function create()
public function create(Request $request): View
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$this->authorize('create-schedule', $server);
$this->injectJavascript();
$this->setRequest($request)->injectJavascript();
return view('server.schedules.new');
}
/**
* Handle request to store a new schedule and tasks in the database.
*
* @param \Pterodactyl\Http\Requests\Server\ScheduleCreationFormRequest $request
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Service\Schedule\Task\TaskIntervalTooLongException
*/
public function store(ScheduleCreationFormRequest $request)
public function store(ScheduleCreationFormRequest $request): RedirectResponse
{
$server = $this->session->get('server_data.model');
$this->authorize('create-schedule', $server);
$server = $request->attributes->get('server');
$schedule = $this->creationService->handle($server, $request->normalize(), $request->getTasks());
$this->alert->success(trans('server.schedules.task_created'))->flash();
return redirect()->route('server.schedules.view', [
'server' => $server->uuidShort,
'task' => $schedule->hashid,
'schedule' => $schedule->hashid,
]);
}
@ -136,17 +125,19 @@ class TaskManagementController extends Controller
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\View\View
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function view(Request $request)
public function view(Request $request): View
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$schedule = $request->attributes->get('schedule');
$this->authorize('view-schedule', $server);
$this->injectJavascript([
'tasks' => $schedule->tasks->map(function ($schedule) {
return collect($schedule->toArray())->only('action', 'time_offset', 'payload')->all();
$this->setRequest($request)->injectJavascript([
'tasks' => $schedule->getRelation('tasks')->map(function ($task) {
/* @var \Pterodactyl\Models\Task $task */
return collect($task->toArray())->only('action', 'time_offset', 'payload')->all();
}),
]);
@ -161,18 +152,18 @@ class TaskManagementController extends Controller
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(ScheduleCreationFormRequest $request)
public function update(ScheduleCreationFormRequest $request): RedirectResponse
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$schedule = $request->attributes->get('schedule');
$this->authorize('edit-schedule', $server);
// $this->updateService->handle($task, $request->normalize(), $request->getChainedTasks());
// $this->alert->success(trans('server.schedules.task_updated'))->flash();
$this->alert->warning('Function is not implemented.')->flash();
// $this->updateService->handle($task, $request->normalize(), $request->getChainedTasks());
// $this->alert->success(trans('server.schedules.task_updated'))->flash();
return redirect()->route('server.schedules.view', [
'server' => $server->uuidShort,
'task' => $schedule->hashid,
'schedule' => $schedule->hashid,
]);
}
@ -180,13 +171,13 @@ class TaskManagementController extends Controller
* Delete a parent task from the Panel.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
* @return \Illuminate\Http\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function delete(Request $request)
public function delete(Request $request): Response
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server_data.model');
$schedule = $request->attributes->get('schedule');
$this->authorize('delete-schedule', $server);

View file

@ -5,6 +5,7 @@ namespace Pterodactyl\Http;
use Pterodactyl\Http\Middleware\DaemonAuthenticate;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Pterodactyl\Http\Middleware\AccessingValidServer;
use Pterodactyl\Http\Middleware\Server\SubuserBelongsToServer;
use Pterodactyl\Http\Middleware\Server\DatabaseBelongsToServer;
use Pterodactyl\Http\Middleware\Server\ScheduleBelongsToServer;
@ -64,7 +65,7 @@ class Kernel extends HttpKernel
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \Pterodactyl\Http\Middleware\RedirectIfAuthenticated::class,
'server' => \Pterodactyl\Http\Middleware\ServerAuthenticate::class,
'server' => AccessingValidServer::class,
'subuser.auth' => \Pterodactyl\Http\Middleware\SubuserAccessAuthenticate::class,
'admin' => \Pterodactyl\Http\Middleware\AdminAuthenticate::class,
'daemon-old' => DaemonAuthenticate::class,

View file

@ -1,11 +1,4 @@
<?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Http\Middleware;
@ -19,7 +12,7 @@ use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
class ServerAuthenticate
class AccessingValidServer
{
/**
* @var \Illuminate\Contracts\Config\Repository
@ -42,7 +35,7 @@ class ServerAuthenticate
protected $session;
/**
* ServerAuthenticate constructor.
* AccessingValidServer constructor.
*
* @param \Illuminate\Contracts\Config\Repository $config
* @param \Pterodactyl\Contracts\Repository\ServerRepositoryInterface $repository

View file

@ -1,51 +1,34 @@
<?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Http\Middleware\Server;
use Closure;
use Illuminate\Contracts\Session\Session;
use Pterodactyl\Contracts\Extensions\HashidsInterface;
use Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class ScheduleBelongsToServer
{
/**
* @var \Pterodactyl\Contracts\Extensions\HashidsInterface
*/
protected $hashids;
private $hashids;
/**
* @var \Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface
*/
protected $repository;
/**
* @var \Illuminate\Contracts\Session\Session
*/
protected $session;
private $repository;
/**
* TaskAccess constructor.
*
* @param \Pterodactyl\Contracts\Extensions\HashidsInterface $hashids
* @param \Illuminate\Contracts\Session\Session $session
* @param \Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface $repository
*/
public function __construct(
HashidsInterface $hashids,
Session $session,
ScheduleRepositoryInterface $repository
) {
public function __construct(HashidsInterface $hashids, ScheduleRepositoryInterface $repository)
{
$this->hashids = $hashids;
$this->repository = $repository;
$this->session = $session;
}
/**
@ -55,18 +38,18 @@ class ScheduleBelongsToServer
* @param \Closure $next
* @return mixed
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function handle($request, Closure $next)
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$scheduleId = $this->hashids->decodeFirst($request->route()->parameter('schedule'), 0);
$schedule = $this->repository->getScheduleWithTasks($scheduleId);
if (object_get($schedule, 'server_id') !== $server->id) {
abort(404);
throw new NotFoundHttpException;
}
$request->attributes->set('schedule', $schedule);

View file

@ -1,42 +1,35 @@
<?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Http\Middleware\Server;
use Closure;
use Illuminate\Contracts\Session\Session;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Contracts\Extensions\HashidsInterface;
use Pterodactyl\Contracts\Repository\SubuserRepositoryInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class SubuserBelongsToServer
{
/**
* @var \Pterodactyl\Contracts\Repository\SubuserRepositoryInterface
* @var \Pterodactyl\Contracts\Extensions\HashidsInterface
*/
protected $repository;
private $hashids;
/**
* @var \Illuminate\Contracts\Session\Session
* @var \Pterodactyl\Contracts\Repository\SubuserRepositoryInterface
*/
protected $session;
private $repository;
/**
* SubuserAccess constructor.
*
* @param \Illuminate\Contracts\Session\Session $session
* @param \Pterodactyl\Contracts\Extensions\HashidsInterface $hashids
* @param \Pterodactyl\Contracts\Repository\SubuserRepositoryInterface $repository
*/
public function __construct(Session $session, SubuserRepositoryInterface $repository)
public function __construct(HashidsInterface $hashids, SubuserRepositoryInterface $repository)
{
$this->hashids = $hashids;
$this->repository = $repository;
$this->session = $session;
}
/**
@ -52,10 +45,11 @@ class SubuserBelongsToServer
*/
public function handle($request, Closure $next)
{
$server = $this->session->get('server_data.model');
$server = $request->attributes->get('server');
$subuser = $this->repository->find($request->route()->parameter('subuser', 0));
if ($subuser->server_id !== $server->id) {
$hash = $request->route()->parameter('subuser', 0);
$subuser = $this->repository->find($this->hashids->decodeFirst($hash, 0));
if (! $subuser || $subuser->server_id !== $server->id) {
throw new NotFoundHttpException;
}
@ -65,6 +59,8 @@ class SubuserBelongsToServer
}
}
$request->attributes->set('subuser', $subuser);
return $next($request);
}
}

View file

@ -9,10 +9,22 @@
namespace Pterodactyl\Http\Requests\Server;
use Pterodactyl\Http\Requests\FrontendUserFormRequest;
class ScheduleCreationFormRequest extends FrontendUserFormRequest
class ScheduleCreationFormRequest extends ServerFormRequest
{
/**
* Permission to validate this request aganist.
*
* @return string
*/
protected function permission(): string
{
if ($this->method() === 'PATCH') {
return 'edit-schedule';
}
return 'create-schedule';
}
/**
* Validation rules to apply to the request.
*

View file

@ -0,0 +1,29 @@
<?php
namespace Pterodactyl\Http\Requests\Server;
use Pterodactyl\Http\Requests\FrontendUserFormRequest;
abstract class ServerFormRequest extends FrontendUserFormRequest
{
/**
* Return the user permission to validate this request aganist.
*
* @return string
*/
abstract protected function permission(): string;
/**
* Determine if a user has permission to access this resource.
*
* @return bool
*/
public function authorize()
{
if (! parent::authorize()) {
return false;
}
return $this->user()->can($this->permission(), $this->attributes->get('server'));
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace Pterodactyl\Http\Requests\Server\Subuser;
use Pterodactyl\Http\Requests\Server\ServerFormRequest;
class SubuserStoreFormRequest extends ServerFormRequest
{
/**
* Return the user permission to validate this request aganist.
*
* @return string
*/
protected function permission(): string
{
return 'create-subuser';
}
/**
* The rules to validate this request submission aganist.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required|email',
'permissions' => 'present|array',
];
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace Pterodactyl\Http\Requests\Server\Subuser;
use Pterodactyl\Http\Requests\Server\ServerFormRequest;
class SubuserUpdateFormRequest extends ServerFormRequest
{
/**
* Return the user permission to validate this request aganist.
*
* @return string
*/
protected function permission(): string
{
return 'edit-subuser';
}
/**
* The rules to validate this request submission aganist.
*
* @return array
*/
public function rules()
{
return [
'permissions' => 'present|array',
];
}
}

View file

@ -9,22 +9,24 @@
namespace Pterodactyl\Http\Requests\Server;
use Illuminate\Log\Writer;
use Illuminate\Contracts\Session\Session;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Contracts\Config\Repository;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Requests\FrontendUserFormRequest;
use Pterodactyl\Exceptions\Http\Server\FileSizeTooLargeException;
use Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface;
use Pterodactyl\Exceptions\Http\Server\FileTypeNotEditableException;
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
class UpdateFileContentsFormRequest extends FrontendUserFormRequest
class UpdateFileContentsFormRequest extends ServerFormRequest
{
/**
* @var object
* Return the permission string to validate this request aganist.
*
* @return string
*/
protected $stats;
protected function permission(): string
{
return 'edit-files';
}
/**
* Authorize a request to edit a file.
@ -38,17 +40,13 @@ class UpdateFileContentsFormRequest extends FrontendUserFormRequest
*/
public function authorize()
{
parent::authorize();
$session = app()->make(Session::class);
$server = $session->get('server_data.model');
$token = $session->get('server_data.token');
$permission = $this->user()->can('edit-files', $server);
if (! $permission) {
if (! parent::authorize()) {
return false;
}
$server = $this->attributes->get('server');
$token = $this->attributes->get('server_token');
return $this->checkFileCanBeEdited($server, $token);
}
@ -61,16 +59,8 @@ class UpdateFileContentsFormRequest extends FrontendUserFormRequest
}
/**
* Return the file stats from the Daemon.
* Checks if a given file can be edited by a user on this server.
*
* @return object
*/
public function getStats()
{
return $this->stats;
}
/**
* @param \Pterodactyl\Models\Server $server
* @param string $token
* @return bool
@ -80,33 +70,29 @@ class UpdateFileContentsFormRequest extends FrontendUserFormRequest
* @throws \Pterodactyl\Exceptions\Http\Server\FileTypeNotEditableException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
protected function checkFileCanBeEdited($server, $token)
private function checkFileCanBeEdited($server, $token)
{
$config = app()->make(Repository::class);
$repository = app()->make(FileRepositoryInterface::class);
try {
$this->stats = $repository->setNode($server->node_id)
->setAccessServer($server->uuid)
$stats = $repository->setNode($server->node_id)->setAccessServer($server->uuid)
->setAccessToken($token)
->getFileStat($this->route()->parameter('file'));
} catch (RequestException $exception) {
$response = $exception->getResponse();
app()->make(Writer::class)->warning($exception);
throw new DisplayException(trans('exceptions.daemon_connection_failed', [
'code' => is_null($response) ? 'E_CONN_REFUSED' : $response->getStatusCode(),
]));
throw new DaemonConnectionException($exception);
}
if (! $this->stats->file || ! in_array($this->stats->mime, $config->get('pterodactyl.files.editable'))) {
if (! $stats->file || ! in_array($stats->mime, $config->get('pterodactyl.files.editable'))) {
throw new FileTypeNotEditableException(trans('server.files.exceptions.invalid_mime'));
}
if ($this->stats->size > $config->get('pterodactyl.files.max_edit_size')) {
if ($stats->size > $config->get('pterodactyl.files.max_edit_size')) {
throw new FileSizeTooLargeException(trans('server.files.exceptions.max_size'));
}
$this->attributes->set('file_stats', $stats);
return true;
}
}

View file

@ -60,6 +60,16 @@ class Subuser extends Model implements CleansAttributes, ValidableContract
'server_id' => 'numeric|exists:servers,id',
];
/**
* Return a hashid encoded string to represent the ID of the subuser.
*
* @return string
*/
public function getHashidAttribute()
{
return app()->make('hashids')->encode($this->id);
}
/**
* Gets the server associated with a subuser.
*

View file

@ -10,6 +10,8 @@
namespace Pterodactyl\Repositories\Eloquent;
use Pterodactyl\Models\Schedule;
use Illuminate\Support\Collection;
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
use Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface;
class ScheduleRepository extends EloquentRepository implements ScheduleRepositoryInterface
@ -23,19 +25,33 @@ class ScheduleRepository extends EloquentRepository implements ScheduleRepositor
}
/**
* {@inheritdoc}
* Return all of the schedules for a given server.
*
* @param int $server
* @return \Illuminate\Support\Collection
*/
public function getServerSchedules($server)
public function findServerSchedules(int $server): Collection
{
return $this->getBuilder()->withCount('tasks')->where('server_id', '=', $server)->get($this->getColumns());
}
/**
* {@inheritdoc}
* Return a schedule model with all of the associated tasks as a relationship.
*
* @param int $schedule
* @return \Pterodactyl\Models\Schedule
*
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function getScheduleWithTasks($schedule)
public function getScheduleWithTasks(int $schedule): Schedule
{
return $this->getBuilder()->with('tasks')->find($schedule, $this->getColumns());
/** @var \Pterodactyl\Models\Schedule $instance */
$instance = $this->getBuilder()->with('tasks')->find($schedule, $this->getColumns());
if (! $instance) {
throw new RecordNotFoundException;
}
return $instance;
}
/**

View file

@ -25,33 +25,39 @@ class SubuserRepository extends EloquentRepository implements SubuserRepositoryI
}
/**
* {@inheritdoc}
* Return a subuser with the associated server relationship.
*
* @param \Pterodactyl\Models\Subuser $subuser
* @param bool $refresh
* @return \Pterodactyl\Models\Subuser
*/
public function getWithServer($id)
public function getWithServer(Subuser $subuser, bool $refresh = false): Subuser
{
Assert::numeric($id, 'First argument passed to getWithServer must be numeric, received %s.');
$instance = $this->getBuilder()->with('server', 'user')->find($id, $this->getColumns());
if (! $instance) {
throw new RecordNotFoundException;
if (! $subuser->relationLoaded('server') || $refresh) {
$subuser->load('server');
}
return $instance;
return $subuser;
}
/**
* {@inheritdoc}
* Return a subuser with the associated permissions relationship.
*
* @param \Pterodactyl\Models\Subuser $subuser
* @param bool $refresh
* @return \Pterodactyl\Models\Subuser
*/
public function getWithPermissions($id)
public function getWithPermissions(Subuser $subuser, bool $refresh = false): Subuser
{
Assert::numeric($id, 'First argument passed to getWithPermissions must be numeric, received %s.');
$instance = $this->getBuilder()->with('permissions', 'user')->find($id, $this->getColumns());
if (! $instance) {
throw new RecordNotFoundException;
if (! $subuser->relationLoaded('permissions') || $refresh) {
$subuser->load('permissions');
}
return $instance;
if (! $subuser->relationLoaded('user') || $refresh) {
$subuser->load('user');
}
return $subuser;
}
/**

View file

@ -51,17 +51,13 @@ class SubuserDeletionService
/**
* Delete a subuser and their associated permissions from the Panel and Daemon.
*
* @param int|\Pterodactyl\Models\Subuser $subuser
* @param \Pterodactyl\Models\Subuser $subuser
*
* @throws \Pterodactyl\Exceptions\DisplayException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function handle($subuser)
public function handle(Subuser $subuser)
{
if (! $subuser instanceof Subuser) {
$subuser = $this->repository->find($subuser);
}
$this->connection->beginTransaction();
$this->keyDeletionService->handle($subuser->server_id, $subuser->user_id);
$this->repository->delete($subuser->id);

View file

@ -9,13 +9,13 @@
namespace Pterodactyl\Services\Subusers;
use Illuminate\Log\Writer;
use Pterodactyl\Models\Subuser;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Database\ConnectionInterface;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService;
use Pterodactyl\Contracts\Repository\SubuserRepositoryInterface;
use Pterodactyl\Contracts\Repository\PermissionRepositoryInterface;
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
use Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface as DaemonServerRepositoryInterface;
class SubuserUpdateService
@ -23,12 +23,12 @@ class SubuserUpdateService
/**
* @var \Illuminate\Database\ConnectionInterface
*/
protected $connection;
private $connection;
/**
* @var \Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface
*/
protected $daemonRepository;
private $daemonRepository;
/**
* @var \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService
@ -38,22 +38,17 @@ class SubuserUpdateService
/**
* @var \Pterodactyl\Contracts\Repository\PermissionRepositoryInterface
*/
protected $permissionRepository;
private $permissionRepository;
/**
* @var \Pterodactyl\Services\Subusers\PermissionCreationService
*/
protected $permissionService;
private $permissionService;
/**
* @var \Pterodactyl\Contracts\Repository\SubuserRepositoryInterface
*/
protected $repository;
/**
* @var \Illuminate\Log\Writer
*/
protected $writer;
private $repository;
/**
* SubuserUpdateService constructor.
@ -64,7 +59,6 @@ class SubuserUpdateService
* @param \Pterodactyl\Services\Subusers\PermissionCreationService $permissionService
* @param \Pterodactyl\Contracts\Repository\PermissionRepositoryInterface $permissionRepository
* @param \Pterodactyl\Contracts\Repository\SubuserRepositoryInterface $repository
* @param \Illuminate\Log\Writer $writer
*/
public function __construct(
ConnectionInterface $connection,
@ -72,8 +66,7 @@ class SubuserUpdateService
DaemonServerRepositoryInterface $daemonRepository,
PermissionCreationService $permissionService,
PermissionRepositoryInterface $permissionRepository,
SubuserRepositoryInterface $repository,
Writer $writer
SubuserRepositoryInterface $repository
) {
$this->connection = $connection;
$this->daemonRepository = $daemonRepository;
@ -81,20 +74,19 @@ class SubuserUpdateService
$this->permissionRepository = $permissionRepository;
$this->permissionService = $permissionService;
$this->repository = $repository;
$this->writer = $writer;
}
/**
* Update permissions for a given subuser.
*
* @param int $subuser
* @param array $permissions
* @param \Pterodactyl\Models\Subuser $subuser
* @param array $permissions
*
* @throws \Pterodactyl\Exceptions\DisplayException
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function handle($subuser, array $permissions)
public function handle(Subuser $subuser, array $permissions)
{
$subuser = $this->repository->getWithServer($subuser);
@ -104,15 +96,10 @@ class SubuserUpdateService
try {
$token = $this->keyProviderService->handle($subuser->server_id, $subuser->user_id, false);
$this->daemonRepository->setNode($subuser->server->node_id)->revokeAccessKey($token);
$this->daemonRepository->setNode($subuser->getRelation('server')->node_id)->revokeAccessKey($token);
} catch (RequestException $exception) {
$this->connection->rollBack();
$this->writer->warning($exception);
$response = $exception->getResponse();
throw new DisplayException(trans('exceptions.daemon_connection_failed', [
'code' => is_null($response) ? 'E_CONN_REFUSED' : $response->getStatusCode(),
]));
throw new DaemonConnectionException($exception);
}
$this->connection->commit();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -66,7 +66,7 @@ class FileManager {
swal({
type: 'error',
title: 'File Error',
text: jqXHR.responseText || 'An error occured while attempting to process this request. Please try again.',
text: jqXHR.responseJSON.error || 'An error occured while attempting to process this request. Please try again.',
});
console.error(jqXHR);
});

View file

@ -34,7 +34,7 @@ $(document).ready(function () {
}, function () {
$.ajax({
method: 'DELETE',
url: Router.route('server.schedules.delete', {
url: Router.route('server.schedules.view', {
server: Pterodactyl.server.uuidShort,
schedule: self.data('schedule-id'),
}),

View file

@ -57,14 +57,14 @@
<td class="middle hidden-xs">{{ $subuser->user->created_at }}</td>
@can('view-subuser', $server)
<td class="text-center middle">
<a href="{{ route('server.subusers.view', ['server' => $server->uuidShort, 'id' => $subuser->id]) }}">
<a href="{{ route('server.subusers.view', ['server' => $server->uuidShort, 'subuser' => $subuser->hashid]) }}">
<button class="btn btn-xs btn-primary">@lang('server.users.configure')</button>
</a>
</td>
@endcan
@can('delete-subuser', $server)
<td class="text-center middle">
<a href="#/delete/{{ $subuser->id }}" data-action="delete" data-id="{{ $subuser->id }}">
<a href="#/delete/{{ $subuser->hashid }}" data-action="delete" data-id="{{ $subuser->hashid }}">
<button class="btn btn-xs btn-danger">@lang('strings.revoke')</button>
</a>
</td>
@ -98,9 +98,9 @@
}, function () {
$.ajax({
method: 'DELETE',
url: Router.route('server.subusers.delete', {
url: Router.route('server.subusers.view', {
server: Pterodactyl.server.uuidShort,
id: self.data('id'),
subuser: self.data('id'),
}),
headers: {
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),

View file

@ -21,7 +21,7 @@
@section('content')
@can('edit-subuser', $server)
<form action="{{ route('server.subusers.view', [ 'uuid' => $server->uuidShort, 'id' => $subuser->id ]) }}" method="POST">
<form action="{{ route('server.subusers.view', [ 'uuid' => $server->uuidShort, 'subuser' => $subuser->hashid ]) }}" method="POST">
@endcan
<div class="row">
<div class="col-sm-12">

View file

@ -70,13 +70,13 @@ Route::group(['prefix' => 'files'], function () {
Route::group(['prefix' => 'users'], function () {
Route::get('/', 'SubuserController@index')->name('server.subusers');
Route::get('/new', 'SubuserController@create')->name('server.subusers.new');
Route::get('/view/{subuser}', 'SubuserController@view')->middleware('server..subuser')->name('server.subusers.view');
Route::post('/new', 'SubuserController@store');
Route::patch('/view/{subuser}', 'SubuserController@update')->middleware('server..subuser');
Route::delete('/view/{subuser}/delete', 'SubuserController@delete')->middleware('server..subuser')->name('server.subusers.delete');
Route::group(['middleware' => 'server..subuser'], function () {
Route::get('/view/{subuser}', 'SubuserController@view')->name('server.subusers.view');
Route::patch('/view/{subuser}', 'SubuserController@update');
Route::delete('/view/{subuser}', 'SubuserController@delete');
});
});
/*
@ -90,12 +90,14 @@ Route::group(['prefix' => 'users'], function () {
Route::group(['prefix' => 'schedules'], function () {
Route::get('/', 'Tasks\TaskManagementController@index')->name('server.schedules');
Route::get('/new', 'Tasks\TaskManagementController@create')->name('server.schedules.new');
Route::get('/view/{schedule}', 'Tasks\TaskManagementController@view')->middleware('server..schedule')->name('server.schedules.view');
Route::post('/new', 'Tasks\TaskManagementController@store');
Route::patch('/view/{schedule}', 'Tasks\TaskManagementController@update')->middleware('server..schedule');
Route::patch('/view/{schedule}/toggle', 'Tasks\TaskToggleController@index')->middleware('server..schedule')->name('server.schedules.toggle');
Route::group(['middleware' => 'server..schedule'], function () {
Route::get('/view/{schedule}', 'Tasks\TaskManagementController@view')->name('server.schedules.view');
Route::delete('/view/{schedule}/delete', 'Tasks\TaskManagementController@delete')->middleware('server..schedule')->name('server.schedules.delete');
Route::patch('/view/{schedule}', 'Tasks\TaskManagementController@update');
Route::patch('/view/{schedule}/toggle', 'Tasks\TaskToggleController@index')->name('server.schedules.toggle');
Route::delete('/view/{schedule}', 'Tasks\TaskManagementController@delete');
});
});