Update logic that handles creation of folders for a server

This commit is contained in:
Dane Everitt 2019-05-01 21:45:39 -07:00
parent ec87330a81
commit 95d19bf09e
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
13 changed files with 116 additions and 9 deletions

View file

@ -47,4 +47,13 @@ interface FileRepositoryInterface extends BaseRepositoryInterface
* @throws \GuzzleHttp\Exception\TransferException * @throws \GuzzleHttp\Exception\TransferException
*/ */
public function getDirectory(string $path): array; public function getDirectory(string $path): array;
/**
* Creates a new directory for the server in the given $path.
*
* @param string $name
* @param string $path
* @return \Psr\Http\Message\ResponseInterface
*/
public function createDirectory(string $name, string $path): ResponseInterface;
} }

View file

@ -4,12 +4,14 @@ namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
use Carbon\Carbon; use Carbon\Carbon;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
use Illuminate\Http\Response;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Contracts\Cache\Repository as CacheRepository; use Illuminate\Contracts\Cache\Repository as CacheRepository;
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController; use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
use Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface; use Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface;
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\ListFilesRequest; use Pterodactyl\Http\Requests\Api\Client\Servers\Files\ListFilesRequest;
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\CreateFolderRequest;
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\DownloadFileRequest; use Pterodactyl\Http\Requests\Api\Client\Servers\Files\DownloadFileRequest;
class FileController extends ClientApiController class FileController extends ClientApiController
@ -53,6 +55,21 @@ class FileController extends ClientApiController
]); ]);
} }
/**
* Creates a new folder on the server.
*
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\Files\CreateFolderRequest $request
* @return \Illuminate\Http\Response
*/
public function createFolder(CreateFolderRequest $request): Response
{
$this->fileRepository
->setServer($request->getModel(Server::class))
->createDirectory($request->input('name'), $request->input('directory', '/'));
return Response::create('s');
}
/** /**
* Configure a reference to a file to download in the cache so that when the * Configure a reference to a file to download in the cache so that when the
* user hits the Daemon and it verifies with the Panel they'll actually be able * user hits the Daemon and it verifies with the Panel they'll actually be able

View file

@ -39,7 +39,7 @@ class AuthenticateServerAccess
$server = $request->route()->parameter('server'); $server = $request->route()->parameter('server');
if (! $server instanceof Server) { if (! $server instanceof Server) {
throw new NotFoundHttpException; throw new NotFoundHttpException(trans('exceptions.api.resource_not_found'));
} }
if ($server->suspended) { if ($server->suspended) {

View file

@ -26,8 +26,13 @@ class SubstituteClientApiBindings extends ApiSubstituteBindings
// column rather than the default 'id'. // column rather than the default 'id'.
$this->router->bind('server', function ($value) use ($request) { $this->router->bind('server', function ($value) use ($request) {
try { try {
$column = 'uuidShort';
if (preg_match('/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i', $value)) {
$column = 'uuid';
}
return Container::getInstance()->make(ServerRepositoryInterface::class)->findFirstWhere([ return Container::getInstance()->make(ServerRepositoryInterface::class)->findFirstWhere([
['uuidShort', '=', $value], [$column, '=', $value],
]); ]);
} catch (RecordNotFoundException $ex) { } catch (RecordNotFoundException $ex) {
$request->attributes->set('is_missing_model', true); $request->attributes->set('is_missing_model', true);

View file

@ -0,0 +1,30 @@
<?php
namespace Pterodactyl\Http\Requests\Api\Client\Servers\Files;
use Pterodactyl\Models\Server;
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
class CreateFolderRequest extends ClientApiRequest
{
/**
* Checks that the authenticated user is allowed to create files on the server.
*
* @return bool
*/
public function authorize(): bool
{
return $this->user()->can('create-files', $this->getModel(Server::class));
}
/**
* @return array
*/
public function rules(): array
{
return [
'root' => 'sometimes|nullable|string',
'name' => 'required|string',
];
}
}

View file

@ -17,4 +17,14 @@ class ListFilesRequest extends ClientApiRequest
{ {
return $this->user()->can('list-files', $this->getModel(Server::class)); return $this->user()->can('list-files', $this->getModel(Server::class));
} }
/**
* @return array
*/
public function rules(): array
{
return [
'directory' => 'sometimes|nullable|string',
];
}
} }

View file

@ -3,6 +3,7 @@
namespace Pterodactyl\Repositories\Daemon; namespace Pterodactyl\Repositories\Daemon;
use stdClass; use stdClass;
use RuntimeException;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface; use Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface;
@ -86,4 +87,18 @@ class FileRepository extends BaseRepository implements FileRepositoryInterface
return json_decode($response->getBody()); return json_decode($response->getBody());
} }
/**
* Creates a new directory for the server in the given $path.
*
* @param string $name
* @param string $path
* @return \Psr\Http\Message\ResponseInterface
*
* @throws \RuntimeException
*/
public function createDirectory(string $name, string $path): ResponseInterface
{
throw new RuntimeException('Not implemented.');
}
} }

View file

@ -66,4 +66,22 @@ class FileRepository extends BaseWingsRepository implements FileRepositoryInterf
return json_decode($response->getBody(), true); return json_decode($response->getBody(), true);
} }
/**
* Creates a new directory for the server in the given $path.
*
* @param string $name
* @param string $path
* @return \Psr\Http\Message\ResponseInterface
*/
public function createDirectory(string $name, string $path): ResponseInterface
{
return $this->getHttpClient()->post(
sprintf('/api/servers/%s/files/create-directory', $this->getServer()->uuid),
[
'name' => $name,
'directory' => $path,
]
);
}
} }

View file

@ -1,4 +1,4 @@
import axios, {AxiosInstance, AxiosRequestConfig} from 'axios'; import axios, {AxiosInstance} from 'axios';
import {ServerApplicationCredentials} from "@/store/types"; import {ServerApplicationCredentials} from "@/store/types";
// This token is set in the bootstrap.js file at the beginning of the request // This token is set in the bootstrap.js file at the beginning of the request

View file

@ -1,12 +1,13 @@
import {ServerApplicationCredentials} from "@/store/types"; import http from "@/api/http";
import {withCredentials} from "@/api/http";
/** /**
* Connects to the remote daemon and creates a new folder on the server. * Connects to the remote daemon and creates a new folder on the server.
*/ */
export function createFolder(server: string, credentials: ServerApplicationCredentials, path: string): Promise<void> { export function createFolder(server: string, directory: string, name: string): Promise<void> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
withCredentials(server, credentials).post('/v1/server/file/folder', { path }) http.post(`/api/client/servers/${server}/files/create-folder`, {
directory, name,
})
.then(() => resolve()) .then(() => resolve())
.catch(reject); .catch(reject);
}); });

View file

@ -83,7 +83,7 @@
} }
this.isLoading = true; this.isLoading = true;
createFolder(this.server.uuid, this.credentials, `${this.fm.currentDirectory}/${this.folderName.replace(/^\//, '')}`) createFolder(this.server.uuid, this.fm.currentDirectory, this.folderName.replace(/^\//, ''))
.then(() => { .then(() => {
this.$emit('created', this.folderName.replace(/^\//, '')); this.$emit('created', this.folderName.replace(/^\//, ''));
this.onModalClose(); this.onModalClose();

File diff suppressed because one or more lines are too long

View file

@ -44,6 +44,8 @@ Route::group(['prefix' => '/servers/{server}', 'middleware' => [AuthenticateServ
Route::group(['prefix' => '/files'], function () { Route::group(['prefix' => '/files'], function () {
Route::get('/list', 'Servers\FileController@listDirectory')->name('api.client.servers.files.list'); Route::get('/list', 'Servers\FileController@listDirectory')->name('api.client.servers.files.list');
Route::post('/create-folder', 'Servers\FileController@createFolder')->name('api.client.servers.files.create-folder');
Route::post('/download/{file}', 'Servers\FileController@download') Route::post('/download/{file}', 'Servers\FileController@download')
->where('file', '.*') ->where('file', '.*')
->name('api.client.servers.files.download'); ->name('api.client.servers.files.download');