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

@ -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;
}
}