Better throttling of backup generation

This commit is contained in:
Dane Everitt 2020-04-09 22:35:38 -07:00
parent 63d8cd4f3f
commit 06707fd33a
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
4 changed files with 43 additions and 3 deletions

View file

@ -46,6 +46,7 @@ return PhpCsFixer\Config::create()
'psr0' => ['dir' => 'app'], 'psr0' => ['dir' => 'app'],
'psr4' => true, 'psr4' => true,
'random_api_migration' => true, 'random_api_migration' => true,
'single_line_throw' => false,
'standardize_not_equals' => true, 'standardize_not_equals' => true,
'ternary_to_null_coalescing' => true, 'ternary_to_null_coalescing' => true,
'yoda_style' => [ 'yoda_style' => [

View file

@ -2,13 +2,16 @@
namespace Pterodactyl\Http\Controllers\Api\Client\Servers; namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
use Carbon\Carbon;
use Pterodactyl\Models\Backup; use Pterodactyl\Models\Backup;
use Pterodactyl\Models\Server; use Pterodactyl\Models\Server;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Pterodactyl\Services\Backups\DeleteBackupService; use Pterodactyl\Services\Backups\DeleteBackupService;
use Pterodactyl\Repositories\Eloquent\BackupRepository;
use Pterodactyl\Services\Backups\InitiateBackupService; use Pterodactyl\Services\Backups\InitiateBackupService;
use Pterodactyl\Transformers\Api\Client\BackupTransformer; use Pterodactyl\Transformers\Api\Client\BackupTransformer;
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController; use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\GetBackupsRequest; use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\GetBackupsRequest;
use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\StoreBackupRequest; use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\StoreBackupRequest;
use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\DeleteBackupRequest; use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\DeleteBackupRequest;
@ -25,18 +28,28 @@ class BackupController extends ClientApiController
*/ */
private $deleteBackupService; private $deleteBackupService;
/**
* @var \Pterodactyl\Repositories\Eloquent\BackupRepository
*/
private $repository;
/** /**
* BackupController constructor. * BackupController constructor.
* *
* @param \Pterodactyl\Repositories\Eloquent\BackupRepository $repository
* @param \Pterodactyl\Services\Backups\DeleteBackupService $deleteBackupService * @param \Pterodactyl\Services\Backups\DeleteBackupService $deleteBackupService
* @param \Pterodactyl\Services\Backups\InitiateBackupService $initiateBackupService * @param \Pterodactyl\Services\Backups\InitiateBackupService $initiateBackupService
*/ */
public function __construct(DeleteBackupService $deleteBackupService, InitiateBackupService $initiateBackupService) public function __construct(
{ BackupRepository $repository,
DeleteBackupService $deleteBackupService,
InitiateBackupService $initiateBackupService
) {
parent::__construct(); parent::__construct();
$this->initiateBackupService = $initiateBackupService; $this->initiateBackupService = $initiateBackupService;
$this->deleteBackupService = $deleteBackupService; $this->deleteBackupService = $deleteBackupService;
$this->repository = $repository;
} }
/** /**
@ -65,6 +78,14 @@ class BackupController extends ClientApiController
*/ */
public function store(StoreBackupRequest $request, Server $server) public function store(StoreBackupRequest $request, Server $server)
{ {
$previous = $this->repository->getBackupsGeneratedDuringTimespan($server->id, 10);
if ($previous->count() >= 2) {
throw new TooManyRequestsHttpException(
Carbon::now()->diffInSeconds($previous->last()->created_at->addMinutes(10)),
'Only two backups may be generated within a 10 minute span of time.'
);
}
$backup = $this->initiateBackupService $backup = $this->initiateBackupService
->setIgnoredFiles($request->input('ignored')) ->setIgnoredFiles($request->input('ignored'))
->handle($server, $request->input('name')); ->handle($server, $request->input('name'));

View file

@ -2,6 +2,7 @@
namespace Pterodactyl\Repositories\Eloquent; namespace Pterodactyl\Repositories\Eloquent;
use Carbon\Carbon;
use Pterodactyl\Models\Backup; use Pterodactyl\Models\Backup;
class BackupRepository extends EloquentRepository class BackupRepository extends EloquentRepository
@ -13,4 +14,21 @@ class BackupRepository extends EloquentRepository
{ {
return Backup::class; return Backup::class;
} }
/**
* Determines if too many backups have been generated by the server.
*
* @param int $server
* @param int $minutes
* @return \Pterodactyl\Models\Backup[]|\Illuminate\Support\Collection
*/
public function getBackupsGeneratedDuringTimespan(int $server, int $minutes = 10)
{
return $this->getBuilder()
->withTrashed()
->where('server_id', $server)
->where('created_at', '>=', Carbon::now()->subMinutes($minutes)->toDateTimeString())
->get()
->toBase();
}
} }

View file

@ -89,7 +89,7 @@ Route::group(['prefix' => '/servers/{server}', 'middleware' => [AuthenticateServ
Route::group(['prefix' => '/backups'], function () { Route::group(['prefix' => '/backups'], function () {
Route::get('/', 'Servers\BackupController@index'); Route::get('/', 'Servers\BackupController@index');
Route::post('/', 'Servers\BackupController@store')->middleware('throttle:2,10'); Route::post('/', 'Servers\BackupController@store');
Route::get('/{backup}', 'Servers\BackupController@view'); Route::get('/{backup}', 'Servers\BackupController@view');
Route::get('/{backup}/download', 'Servers\DownloadBackupController'); Route::get('/{backup}/download', 'Servers\DownloadBackupController');
Route::delete('/{backup}', 'Servers\BackupController@delete'); Route::delete('/{backup}', 'Servers\BackupController@delete');