database backups

This commit is contained in:
Saeed Vaziry
2023-08-25 21:05:18 +02:00
parent f9ac454a7c
commit ea3f011f34
55 changed files with 1111 additions and 172 deletions

View File

@ -1,14 +1,12 @@
<?php
namespace App\Actions\Backup;
namespace App\Actions\Database;
use App\Enums\BackupStatus;
use App\Enums\DatabaseStatus;
use App\Models\Backup;
use App\Models\Database;
use App\Models\Server;
use App\Models\User;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
@ -19,23 +17,18 @@ class CreateBackup
* @throws AuthorizationException
* @throws ValidationException
*/
public function create($type, Server $server, User $user, array $input): Backup
public function create($type, Server $server, array $input): Backup
{
$this->validate($type, $server, $user, $input);
if ($type == 'database') {
Gate::forUser($user)->authorize('viewAny', [Database::class, $server]);
}
$this->validate($type, $server, $input);
$backup = new Backup([
'name' => $input['name'],
'type' => $type,
'server_id' => $server->id,
'database_id' => $input['database'] ?? null,
'storage_id' => $input['storage'],
'interval' => $input['interval'],
'keep_backups' => $input['keep_backups'],
'status' => 'running',
'interval' => $input['interval'] == 'custom' ? $input['custom'] : $input['interval'],
'keep_backups' => $input['keep'],
'status' => BackupStatus::RUNNING,
]);
$backup->save();
@ -47,17 +40,14 @@ public function create($type, Server $server, User $user, array $input): Backup
/**
* @throws ValidationException
*/
private function validate($type, Server $server, User $user, array $input): void
private function validate($type, Server $server, array $input): void
{
$rules = [
'name' => 'required',
'storage' => [
'required',
Rule::exists('storage_providers', 'id')
->where('user_id', $user->id)
->where('connected', 1),
Rule::exists('storage_providers', 'id'),
],
'keep_backups' => [
'keep' => [
'required',
'numeric',
'min:1',
@ -69,9 +59,15 @@ private function validate($type, Server $server, User $user, array $input): void
'0 0 * * *',
'0 0 * * 0',
'0 0 1 * *',
'custom'
]),
],
];
if ($input['interval'] == 'custom') {
$rules['custom'] = [
'required',
];
}
if ($type === 'database') {
$rules['database'] = [
'required',
@ -80,6 +76,6 @@ private function validate($type, Server $server, User $user, array $input): void
->where('status', DatabaseStatus::READY),
];
}
Validator::make($input, $rules)->validateWithBag('createBackup');
Validator::make($input, $rules)->validate();
}
}

View File

@ -1,30 +0,0 @@
<?php
namespace App\Actions\StorageProvider;
use App\Models\StorageProvider;
use App\Models\User;
use Illuminate\Validation\ValidationException;
class AddStorageProvider
{
use ValidateProvider;
/**
* @throws ValidationException
*/
public function add(User $user, array $input): mixed
{
$this->validate($user, $input);
$storageProvider = new StorageProvider([
'user_id' => $user->id,
'provider' => $input['provider'],
'label' => $input['label'],
'connected' => false,
]);
$storageProvider->save();
return $storageProvider->provider()->connect();
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace App\Actions\StorageProvider;
use App\Models\StorageProvider;
use App\Models\User;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
class CreateStorageProvider
{
/**
* @throws ValidationException
*/
public function create(User $user, array $input): void
{
$this->validate($user, $input);
$storageProvider = new StorageProvider([
'user_id' => $user->id,
'provider' => $input['provider'],
'profile' => $input['name'],
'credentials' => [
'token' => $input['token']
]
]);
if (! $storageProvider->provider()->connect()) {
throw ValidationException::withMessages([
'token' => __("Couldn't connect to the provider")
]);
}
$storageProvider->save();;
}
private function validate(User $user, array $input): void
{
Validator::make($input, [
'provider' => [
'required',
Rule::in(config('core.storage_providers')),
],
'name' => [
'required',
Rule::unique('storage_providers', 'profile')->where('user_id', $user->id),
],
'token' => [
'required'
]
])->validate();
}
}

View File

@ -1,34 +0,0 @@
<?php
namespace App\Actions\StorageProvider;
use App\Models\StorageProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Laravel\Socialite\Facades\Socialite;
use Laravel\Socialite\Two\User;
use Throwable;
class HandleProviderCallback
{
public function callback(Request $request, string $provider): string|RedirectResponse
{
try {
$providerId = $request->session()->get('storage_provider_id');
/** @var StorageProvider $storageProvider */
$storageProvider = StorageProvider::query()->findOrFail($providerId);
/** @var User $oauthUser */
$oauthUser = Socialite::driver($provider)->user();
$storageProvider->token = $oauthUser->token;
$storageProvider->refresh_token = $oauthUser->refreshToken;
$storageProvider->token_expires_at = now()->addSeconds($oauthUser->expiresIn);
$storageProvider->connected = true;
$storageProvider->save();
/** @TODO toast success message */
} catch (Throwable) {
/** @TODO toast failed message */
}
return redirect()->route('storage-providers');
}
}

View File

@ -1,28 +0,0 @@
<?php
namespace App\Actions\StorageProvider;
use App\Models\User;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
trait ValidateProvider
{
/**
* @throws ValidationException
*/
private function validate(User $user, array $input): void
{
Validator::make($input, [
'label' => [
'required',
Rule::unique('storage_providers', 'label')->where('user_id', $user->id),
],
'provider' => [
'required',
Rule::in(config('core.storage_providers')),
],
])->validateWithBag('addStorageProvider');
}
}