mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-02 14:36:17 +00:00
added FTP support to storage providers (#58)
* added FTP support to storage providers * build and code style fix
This commit is contained in:
@ -21,13 +21,15 @@ public function create(User $user, array $input): void
|
||||
'user_id' => $user->id,
|
||||
'provider' => $input['provider'],
|
||||
'profile' => $input['name'],
|
||||
'credentials' => [
|
||||
'token' => $input['token'],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->validateProvider($input, $storageProvider->provider()->validationRules());
|
||||
|
||||
$storageProvider->credentials = $storageProvider->provider()->credentialData($input);
|
||||
|
||||
if (! $storageProvider->provider()->connect()) {
|
||||
throw ValidationException::withMessages([
|
||||
'token' => __("Couldn't connect to the provider"),
|
||||
'provider' => __("Couldn't connect to the provider"),
|
||||
]);
|
||||
}
|
||||
$storageProvider->save();
|
||||
@ -44,9 +46,11 @@ private function validate(User $user, array $input): void
|
||||
'required',
|
||||
Rule::unique('storage_providers', 'profile')->where('user_id', $user->id),
|
||||
],
|
||||
'token' => [
|
||||
'required',
|
||||
],
|
||||
])->validate();
|
||||
}
|
||||
|
||||
private function validateProvider(array $input, array $rules): void
|
||||
{
|
||||
Validator::make($input, $rules)->validate();
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,10 @@
|
||||
|
||||
interface StorageProvider
|
||||
{
|
||||
public function validationRules(): array;
|
||||
|
||||
public function credentialData(array $input): array;
|
||||
|
||||
public function connect(): bool;
|
||||
|
||||
public function upload(Server $server, string $src, string $dest): array;
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
final class StorageProvider extends Enum
|
||||
{
|
||||
const GOOGLE = 'google';
|
||||
|
||||
const DROPBOX = 'dropbox';
|
||||
|
||||
const FTP = 'ftp';
|
||||
}
|
||||
|
@ -14,6 +14,20 @@ class ConnectProvider extends Component
|
||||
|
||||
public string $token;
|
||||
|
||||
public string $host;
|
||||
|
||||
public string $port;
|
||||
|
||||
public string $path = '/';
|
||||
|
||||
public string $username;
|
||||
|
||||
public string $password;
|
||||
|
||||
public int $ssl = 1;
|
||||
|
||||
public int $passive = 0;
|
||||
|
||||
public function connect(): void
|
||||
{
|
||||
app(CreateStorageProvider::class)->create(auth()->user(), $this->all());
|
||||
|
@ -76,7 +76,7 @@ public function getPathAttribute(): string
|
||||
|
||||
public function getStoragePathAttribute(): string
|
||||
{
|
||||
return '/'.$this->backup->database->name.'/'.$this->name.'.zip';
|
||||
return '/'.$this->name.'.zip';
|
||||
}
|
||||
|
||||
public function restore(Database $database): void
|
||||
|
40
app/SSHCommands/Storage/DownloadFromFTPCommand.php
Normal file
40
app/SSHCommands/Storage/DownloadFromFTPCommand.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\SSHCommands\Storage;
|
||||
|
||||
use App\SSHCommands\Command;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class DownloadFromFTPCommand extends Command
|
||||
{
|
||||
public function __construct(
|
||||
protected string $src,
|
||||
protected string $dest,
|
||||
protected string $host,
|
||||
protected string $port,
|
||||
protected string $username,
|
||||
protected string $password,
|
||||
protected bool $ssl,
|
||||
protected bool $passive,
|
||||
) {
|
||||
}
|
||||
|
||||
public function file(): string
|
||||
{
|
||||
return File::get(resource_path('commands/storage/download-from-ftp.sh'));
|
||||
}
|
||||
|
||||
public function content(): string
|
||||
{
|
||||
return str($this->file())
|
||||
->replace('__src__', $this->src)
|
||||
->replace('__dest__', $this->dest)
|
||||
->replace('__host__', $this->host)
|
||||
->replace('__port__', $this->port)
|
||||
->replace('__username__', $this->username)
|
||||
->replace('__password__', $this->password)
|
||||
->replace('__ssl__', $this->ssl ? 's' : '')
|
||||
->replace('__passive__', $this->passive ? '--ftp-pasv' : '')
|
||||
->toString();
|
||||
}
|
||||
}
|
40
app/SSHCommands/Storage/UploadToFTPCommand.php
Normal file
40
app/SSHCommands/Storage/UploadToFTPCommand.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\SSHCommands\Storage;
|
||||
|
||||
use App\SSHCommands\Command;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class UploadToFTPCommand extends Command
|
||||
{
|
||||
public function __construct(
|
||||
protected string $src,
|
||||
protected string $dest,
|
||||
protected string $host,
|
||||
protected string $port,
|
||||
protected string $username,
|
||||
protected string $password,
|
||||
protected bool $ssl,
|
||||
protected bool $passive,
|
||||
) {
|
||||
}
|
||||
|
||||
public function file(): string
|
||||
{
|
||||
return File::get(resource_path('commands/storage/upload-to-ftp.sh'));
|
||||
}
|
||||
|
||||
public function content(): string
|
||||
{
|
||||
return str($this->file())
|
||||
->replace('__src__', $this->src)
|
||||
->replace('__dest__', $this->dest)
|
||||
->replace('__host__', $this->host)
|
||||
->replace('__port__', $this->port)
|
||||
->replace('__username__', $this->username)
|
||||
->replace('__password__', $this->password)
|
||||
->replace('__ssl__', $this->ssl ? 's' : '')
|
||||
->replace('__passive__', $this->passive ? '--ftp-pasv' : '')
|
||||
->toString();
|
||||
}
|
||||
}
|
@ -13,6 +13,20 @@ class Dropbox extends AbstractStorageProvider
|
||||
{
|
||||
protected string $apiUrl = 'https://api.dropboxapi.com/2';
|
||||
|
||||
public function validationRules(): array
|
||||
{
|
||||
return [
|
||||
'token' => 'required',
|
||||
];
|
||||
}
|
||||
|
||||
public function credentialData(array $input): array
|
||||
{
|
||||
return [
|
||||
'token' => $input['token'],
|
||||
];
|
||||
}
|
||||
|
||||
public function connect(): bool
|
||||
{
|
||||
$res = Http::withToken($this->storageProvider->credentials['token'])
|
||||
|
129
app/StorageProviders/FTP.php
Normal file
129
app/StorageProviders/FTP.php
Normal file
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
namespace App\StorageProviders;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\SSHCommands\Storage\DownloadFromFTPCommand;
|
||||
use App\SSHCommands\Storage\UploadToFTPCommand;
|
||||
use FTP\Connection;
|
||||
use Throwable;
|
||||
|
||||
class FTP extends AbstractStorageProvider
|
||||
{
|
||||
public function validationRules(): array
|
||||
{
|
||||
return [
|
||||
'host' => 'required',
|
||||
'port' => 'required|numeric',
|
||||
'path' => 'required',
|
||||
'username' => 'required',
|
||||
'password' => 'required',
|
||||
'ssl' => 'required',
|
||||
'passive' => 'required',
|
||||
];
|
||||
}
|
||||
|
||||
public function credentialData(array $input): array
|
||||
{
|
||||
return [
|
||||
'host' => $input['host'],
|
||||
'port' => $input['port'],
|
||||
'path' => $input['path'],
|
||||
'username' => $input['username'],
|
||||
'password' => $input['password'],
|
||||
'ssl' => (bool) $input['ssl'],
|
||||
'passive' => (bool) $input['passive'],
|
||||
];
|
||||
}
|
||||
|
||||
public function connect(): bool
|
||||
{
|
||||
$connection = $this->connection();
|
||||
|
||||
$isConnected = $connection && $this->login($connection);
|
||||
|
||||
if ($isConnected) {
|
||||
ftp_close($connection);
|
||||
}
|
||||
|
||||
return $isConnected;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function upload(Server $server, string $src, string $dest): array
|
||||
{
|
||||
$server->ssh()->exec(
|
||||
new UploadToFTPCommand(
|
||||
$src,
|
||||
$this->storageProvider->credentials['path'].'/'.$dest,
|
||||
$this->storageProvider->credentials['host'],
|
||||
$this->storageProvider->credentials['port'],
|
||||
$this->storageProvider->credentials['username'],
|
||||
$this->storageProvider->credentials['password'],
|
||||
$this->storageProvider->credentials['ssl'],
|
||||
$this->storageProvider->credentials['passive'],
|
||||
),
|
||||
'upload-to-ftp'
|
||||
);
|
||||
|
||||
return [
|
||||
'size' => null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function download(Server $server, string $src, string $dest): void
|
||||
{
|
||||
$server->ssh()->exec(
|
||||
new DownloadFromFTPCommand(
|
||||
$this->storageProvider->credentials['path'].'/'.$src,
|
||||
$dest,
|
||||
$this->storageProvider->credentials['host'],
|
||||
$this->storageProvider->credentials['port'],
|
||||
$this->storageProvider->credentials['username'],
|
||||
$this->storageProvider->credentials['password'],
|
||||
$this->storageProvider->credentials['ssl'],
|
||||
$this->storageProvider->credentials['passive'],
|
||||
),
|
||||
'download-from-ftp'
|
||||
);
|
||||
}
|
||||
|
||||
public function delete(array $paths): void
|
||||
{
|
||||
$connection = $this->connection();
|
||||
|
||||
if ($connection && $this->login($connection)) {
|
||||
if ($this->storageProvider->credentials['passive']) {
|
||||
ftp_pasv($connection, true);
|
||||
}
|
||||
|
||||
foreach ($paths as $path) {
|
||||
ftp_delete($connection, $this->storageProvider->credentials['path'].'/'.$path);
|
||||
}
|
||||
}
|
||||
|
||||
ftp_close($connection);
|
||||
}
|
||||
|
||||
private function connection(): bool|Connection
|
||||
{
|
||||
$credentials = $this->storageProvider->credentials;
|
||||
if ($credentials['ssl']) {
|
||||
return ftp_ssl_connect($credentials['host'], $credentials['port'], 5);
|
||||
}
|
||||
|
||||
return ftp_connect($credentials['host'], $credentials['port'], 5);
|
||||
}
|
||||
|
||||
private function login(Connection $connection): bool
|
||||
{
|
||||
$credentials = $this->storageProvider->credentials;
|
||||
|
||||
return ftp_login($connection, $credentials['username'], $credentials['password']);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user