feat(auth): implement authorization checks for database management
This commit is contained in:
@@ -5,6 +5,7 @@ namespace App\Livewire\Project\Database;
|
|||||||
use App\Models\InstanceSettings;
|
use App\Models\InstanceSettings;
|
||||||
use App\Models\ScheduledDatabaseBackup;
|
use App\Models\ScheduledDatabaseBackup;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Livewire\Attributes\Locked;
|
use Livewire\Attributes\Locked;
|
||||||
@@ -14,6 +15,8 @@ use Spatie\Url\Url;
|
|||||||
|
|
||||||
class BackupEdit extends Component
|
class BackupEdit extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
public ScheduledDatabaseBackup $backup;
|
public ScheduledDatabaseBackup $backup;
|
||||||
|
|
||||||
#[Locked]
|
#[Locked]
|
||||||
@@ -129,6 +132,8 @@ class BackupEdit extends Component
|
|||||||
|
|
||||||
public function delete($password)
|
public function delete($password)
|
||||||
{
|
{
|
||||||
|
$this->authorize('manageBackups', $this->backup->database);
|
||||||
|
|
||||||
if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) {
|
if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) {
|
||||||
if (! Hash::check($password, Auth::user()->password)) {
|
if (! Hash::check($password, Auth::user()->password)) {
|
||||||
$this->addError('password', 'The provided password is incorrect.');
|
$this->addError('password', 'The provided password is incorrect.');
|
||||||
@@ -186,6 +191,8 @@ class BackupEdit extends Component
|
|||||||
public function instantSave()
|
public function instantSave()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('manageBackups', $this->backup->database);
|
||||||
|
|
||||||
$this->syncData(true);
|
$this->syncData(true);
|
||||||
$this->dispatch('success', 'Backup updated successfully.');
|
$this->dispatch('success', 'Backup updated successfully.');
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
@@ -214,6 +221,8 @@ class BackupEdit extends Component
|
|||||||
public function submit()
|
public function submit()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('manageBackups', $this->backup->database);
|
||||||
|
|
||||||
$this->syncData(true);
|
$this->syncData(true);
|
||||||
$this->dispatch('success', 'Backup updated successfully.');
|
$this->dispatch('success', 'Backup updated successfully.');
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
|
@@ -3,14 +3,19 @@
|
|||||||
namespace App\Livewire\Project\Database;
|
namespace App\Livewire\Project\Database;
|
||||||
|
|
||||||
use App\Jobs\DatabaseBackupJob;
|
use App\Jobs\DatabaseBackupJob;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class BackupNow extends Component
|
class BackupNow extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
public $backup;
|
public $backup;
|
||||||
|
|
||||||
public function backupNow()
|
public function backupNow()
|
||||||
{
|
{
|
||||||
|
$this->authorize('manageBackups', $this->backup->database);
|
||||||
|
|
||||||
DatabaseBackupJob::dispatch($this->backup);
|
DatabaseBackupJob::dispatch($this->backup);
|
||||||
$this->dispatch('success', 'Backup queued. It will be available in a few minutes.');
|
$this->dispatch('success', 'Backup queued. It will be available in a few minutes.');
|
||||||
}
|
}
|
||||||
|
@@ -8,11 +8,14 @@ use App\Models\Server;
|
|||||||
use App\Models\StandaloneClickhouse;
|
use App\Models\StandaloneClickhouse;
|
||||||
use App\Support\ValidationPatterns;
|
use App\Support\ValidationPatterns;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class General extends Component
|
class General extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
public Server $server;
|
public Server $server;
|
||||||
|
|
||||||
public StandaloneClickhouse $database;
|
public StandaloneClickhouse $database;
|
||||||
@@ -131,6 +134,8 @@ class General extends Component
|
|||||||
public function instantSaveAdvanced()
|
public function instantSaveAdvanced()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (! $this->server->isLogDrainEnabled()) {
|
if (! $this->server->isLogDrainEnabled()) {
|
||||||
$this->isLogDrainEnabled = false;
|
$this->isLogDrainEnabled = false;
|
||||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||||
@@ -149,6 +154,8 @@ class General extends Component
|
|||||||
public function instantSave()
|
public function instantSave()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if ($this->isPublic && ! $this->publicPort) {
|
if ($this->isPublic && ! $this->publicPort) {
|
||||||
$this->dispatch('error', 'Public port is required.');
|
$this->dispatch('error', 'Public port is required.');
|
||||||
$this->isPublic = false;
|
$this->isPublic = false;
|
||||||
@@ -186,6 +193,8 @@ class General extends Component
|
|||||||
public function submit()
|
public function submit()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (str($this->publicPort)->isEmpty()) {
|
if (str($this->publicPort)->isEmpty()) {
|
||||||
$this->publicPort = null;
|
$this->publicPort = null;
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ class Configuration extends Component
|
|||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
$this->currentRoute = request()->route()->getName();
|
$this->currentRoute = request()->route()->getName();
|
||||||
|
|
||||||
$project = currentTeam()
|
$project = currentTeam()
|
||||||
@@ -48,6 +49,16 @@ class Configuration extends Component
|
|||||||
$this->database->isConfigurationChanged(true);
|
$this->database->isConfigurationChanged(true);
|
||||||
$this->dispatch('configurationChanged');
|
$this->dispatch('configurationChanged');
|
||||||
}
|
}
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
if ($e instanceof \Illuminate\Auth\Access\AuthorizationException) {
|
||||||
|
return redirect()->route('dashboard');
|
||||||
|
}
|
||||||
|
if ($e instanceof \Illuminate\Support\ItemNotFoundException) {
|
||||||
|
return redirect()->route('dashboard');
|
||||||
|
}
|
||||||
|
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Livewire\Project\Database;
|
namespace App\Livewire\Project\Database;
|
||||||
|
|
||||||
use App\Models\ScheduledDatabaseBackup;
|
use App\Models\ScheduledDatabaseBackup;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Livewire\Attributes\Locked;
|
use Livewire\Attributes\Locked;
|
||||||
use Livewire\Attributes\Validate;
|
use Livewire\Attributes\Validate;
|
||||||
@@ -10,6 +11,8 @@ use Livewire\Component;
|
|||||||
|
|
||||||
class CreateScheduledBackup extends Component
|
class CreateScheduledBackup extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
#[Validate(['required', 'string'])]
|
#[Validate(['required', 'string'])]
|
||||||
public $frequency;
|
public $frequency;
|
||||||
|
|
||||||
@@ -41,6 +44,8 @@ class CreateScheduledBackup extends Component
|
|||||||
public function submit()
|
public function submit()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('manageBackups', $this->database);
|
||||||
|
|
||||||
$this->validate();
|
$this->validate();
|
||||||
|
|
||||||
$isValid = validate_cron_expression($this->frequency);
|
$isValid = validate_cron_expression($this->frequency);
|
||||||
|
@@ -11,11 +11,14 @@ use App\Models\StandaloneDragonfly;
|
|||||||
use App\Support\ValidationPatterns;
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class General extends Component
|
class General extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
public Server $server;
|
public Server $server;
|
||||||
|
|
||||||
public StandaloneDragonfly $database;
|
public StandaloneDragonfly $database;
|
||||||
@@ -142,6 +145,8 @@ class General extends Component
|
|||||||
public function instantSaveAdvanced()
|
public function instantSaveAdvanced()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (! $this->server->isLogDrainEnabled()) {
|
if (! $this->server->isLogDrainEnabled()) {
|
||||||
$this->isLogDrainEnabled = false;
|
$this->isLogDrainEnabled = false;
|
||||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||||
@@ -160,6 +165,8 @@ class General extends Component
|
|||||||
public function instantSave()
|
public function instantSave()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if ($this->isPublic && ! $this->publicPort) {
|
if ($this->isPublic && ! $this->publicPort) {
|
||||||
$this->dispatch('error', 'Public port is required.');
|
$this->dispatch('error', 'Public port is required.');
|
||||||
$this->isPublic = false;
|
$this->isPublic = false;
|
||||||
@@ -197,6 +204,8 @@ class General extends Component
|
|||||||
public function submit()
|
public function submit()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (str($this->publicPort)->isEmpty()) {
|
if (str($this->publicPort)->isEmpty()) {
|
||||||
$this->publicPort = null;
|
$this->publicPort = null;
|
||||||
}
|
}
|
||||||
@@ -216,6 +225,8 @@ class General extends Component
|
|||||||
public function instantSaveSSL()
|
public function instantSaveSSL()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$this->syncData(true);
|
$this->syncData(true);
|
||||||
$this->dispatch('success', 'SSL configuration updated.');
|
$this->dispatch('success', 'SSL configuration updated.');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
@@ -226,6 +237,8 @@ class General extends Component
|
|||||||
public function regenerateSslCertificate()
|
public function regenerateSslCertificate()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$existingCert = $this->database->sslCertificates()->first();
|
$existingCert = $this->database->sslCertificates()->first();
|
||||||
|
|
||||||
if (! $existingCert) {
|
if (! $existingCert) {
|
||||||
|
@@ -7,10 +7,13 @@ use App\Actions\Database\StartDatabase;
|
|||||||
use App\Actions\Database\StopDatabase;
|
use App\Actions\Database\StopDatabase;
|
||||||
use App\Actions\Docker\GetContainersStatus;
|
use App\Actions\Docker\GetContainersStatus;
|
||||||
use App\Events\ServiceStatusChanged;
|
use App\Events\ServiceStatusChanged;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Heading extends Component
|
class Heading extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
public $database;
|
public $database;
|
||||||
|
|
||||||
public array $parameters;
|
public array $parameters;
|
||||||
@@ -67,6 +70,8 @@ class Heading extends Component
|
|||||||
public function stop()
|
public function stop()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('manage', $this->database);
|
||||||
|
|
||||||
$this->dispatch('info', 'Gracefully stopping database.');
|
$this->dispatch('info', 'Gracefully stopping database.');
|
||||||
StopDatabase::dispatch($this->database, false, $this->docker_cleanup);
|
StopDatabase::dispatch($this->database, false, $this->docker_cleanup);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
@@ -76,12 +81,16 @@ class Heading extends Component
|
|||||||
|
|
||||||
public function restart()
|
public function restart()
|
||||||
{
|
{
|
||||||
|
$this->authorize('manage', $this->database);
|
||||||
|
|
||||||
$activity = RestartDatabase::run($this->database);
|
$activity = RestartDatabase::run($this->database);
|
||||||
$this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class);
|
$this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function start()
|
public function start()
|
||||||
{
|
{
|
||||||
|
$this->authorize('manage', $this->database);
|
||||||
|
|
||||||
$activity = StartDatabase::run($this->database);
|
$activity = StartDatabase::run($this->database);
|
||||||
$this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class);
|
$this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class);
|
||||||
}
|
}
|
||||||
|
@@ -3,12 +3,15 @@
|
|||||||
namespace App\Livewire\Project\Database;
|
namespace App\Livewire\Project\Database;
|
||||||
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Import extends Component
|
class Import extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
public bool $unsupported = false;
|
public bool $unsupported = false;
|
||||||
|
|
||||||
public $resource;
|
public $resource;
|
||||||
@@ -165,6 +168,8 @@ EOD;
|
|||||||
|
|
||||||
public function runImport()
|
public function runImport()
|
||||||
{
|
{
|
||||||
|
$this->authorize('update', $this->resource);
|
||||||
|
|
||||||
if ($this->filename === '') {
|
if ($this->filename === '') {
|
||||||
$this->dispatch('error', 'Please select a file to import.');
|
$this->dispatch('error', 'Please select a file to import.');
|
||||||
|
|
||||||
|
@@ -11,11 +11,14 @@ use App\Models\StandaloneKeydb;
|
|||||||
use App\Support\ValidationPatterns;
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class General extends Component
|
class General extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
public Server $server;
|
public Server $server;
|
||||||
|
|
||||||
public StandaloneKeydb $database;
|
public StandaloneKeydb $database;
|
||||||
@@ -150,6 +153,8 @@ class General extends Component
|
|||||||
public function instantSaveAdvanced()
|
public function instantSaveAdvanced()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (! $this->server->isLogDrainEnabled()) {
|
if (! $this->server->isLogDrainEnabled()) {
|
||||||
$this->isLogDrainEnabled = false;
|
$this->isLogDrainEnabled = false;
|
||||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||||
@@ -168,6 +173,8 @@ class General extends Component
|
|||||||
public function instantSave()
|
public function instantSave()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if ($this->isPublic && ! $this->publicPort) {
|
if ($this->isPublic && ! $this->publicPort) {
|
||||||
$this->dispatch('error', 'Public port is required.');
|
$this->dispatch('error', 'Public port is required.');
|
||||||
$this->isPublic = false;
|
$this->isPublic = false;
|
||||||
@@ -205,6 +212,8 @@ class General extends Component
|
|||||||
public function submit()
|
public function submit()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('manageEnvironment', $this->database);
|
||||||
|
|
||||||
if (str($this->publicPort)->isEmpty()) {
|
if (str($this->publicPort)->isEmpty()) {
|
||||||
$this->publicPort = null;
|
$this->publicPort = null;
|
||||||
}
|
}
|
||||||
@@ -224,6 +233,8 @@ class General extends Component
|
|||||||
public function instantSaveSSL()
|
public function instantSaveSSL()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$this->syncData(true);
|
$this->syncData(true);
|
||||||
$this->dispatch('success', 'SSL configuration updated.');
|
$this->dispatch('success', 'SSL configuration updated.');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
@@ -234,6 +245,8 @@ class General extends Component
|
|||||||
public function regenerateSslCertificate()
|
public function regenerateSslCertificate()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$existingCert = $this->database->sslCertificates()->first();
|
$existingCert = $this->database->sslCertificates()->first();
|
||||||
|
|
||||||
if (! $existingCert) {
|
if (! $existingCert) {
|
||||||
|
@@ -11,11 +11,14 @@ use App\Models\StandaloneMariadb;
|
|||||||
use App\Support\ValidationPatterns;
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class General extends Component
|
class General extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
protected $listeners = ['refresh'];
|
protected $listeners = ['refresh'];
|
||||||
|
|
||||||
public Server $server;
|
public Server $server;
|
||||||
@@ -108,6 +111,8 @@ class General extends Component
|
|||||||
public function instantSaveAdvanced()
|
public function instantSaveAdvanced()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (! $this->server->isLogDrainEnabled()) {
|
if (! $this->server->isLogDrainEnabled()) {
|
||||||
$this->database->is_log_drain_enabled = false;
|
$this->database->is_log_drain_enabled = false;
|
||||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||||
@@ -125,6 +130,8 @@ class General extends Component
|
|||||||
public function submit()
|
public function submit()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (str($this->database->public_port)->isEmpty()) {
|
if (str($this->database->public_port)->isEmpty()) {
|
||||||
$this->database->public_port = null;
|
$this->database->public_port = null;
|
||||||
}
|
}
|
||||||
@@ -145,6 +152,8 @@ class General extends Component
|
|||||||
public function instantSave()
|
public function instantSave()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if ($this->database->is_public && ! $this->database->public_port) {
|
if ($this->database->is_public && ! $this->database->public_port) {
|
||||||
$this->dispatch('error', 'Public port is required.');
|
$this->dispatch('error', 'Public port is required.');
|
||||||
$this->database->is_public = false;
|
$this->database->is_public = false;
|
||||||
@@ -176,6 +185,8 @@ class General extends Component
|
|||||||
public function instantSaveSSL()
|
public function instantSaveSSL()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$this->database->save();
|
$this->database->save();
|
||||||
$this->dispatch('success', 'SSL configuration updated.');
|
$this->dispatch('success', 'SSL configuration updated.');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
@@ -186,6 +197,8 @@ class General extends Component
|
|||||||
public function regenerateSslCertificate()
|
public function regenerateSslCertificate()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$existingCert = $this->database->sslCertificates()->first();
|
$existingCert = $this->database->sslCertificates()->first();
|
||||||
|
|
||||||
if (! $existingCert) {
|
if (! $existingCert) {
|
||||||
|
@@ -11,11 +11,14 @@ use App\Models\StandaloneMongodb;
|
|||||||
use App\Support\ValidationPatterns;
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class General extends Component
|
class General extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
protected $listeners = ['refresh'];
|
protected $listeners = ['refresh'];
|
||||||
|
|
||||||
public Server $server;
|
public Server $server;
|
||||||
@@ -108,6 +111,8 @@ class General extends Component
|
|||||||
public function instantSaveAdvanced()
|
public function instantSaveAdvanced()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (! $this->server->isLogDrainEnabled()) {
|
if (! $this->server->isLogDrainEnabled()) {
|
||||||
$this->database->is_log_drain_enabled = false;
|
$this->database->is_log_drain_enabled = false;
|
||||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||||
@@ -125,6 +130,8 @@ class General extends Component
|
|||||||
public function submit()
|
public function submit()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (str($this->database->public_port)->isEmpty()) {
|
if (str($this->database->public_port)->isEmpty()) {
|
||||||
$this->database->public_port = null;
|
$this->database->public_port = null;
|
||||||
}
|
}
|
||||||
@@ -148,6 +155,8 @@ class General extends Component
|
|||||||
public function instantSave()
|
public function instantSave()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if ($this->database->is_public && ! $this->database->public_port) {
|
if ($this->database->is_public && ! $this->database->public_port) {
|
||||||
$this->dispatch('error', 'Public port is required.');
|
$this->dispatch('error', 'Public port is required.');
|
||||||
$this->database->is_public = false;
|
$this->database->is_public = false;
|
||||||
@@ -184,6 +193,8 @@ class General extends Component
|
|||||||
public function instantSaveSSL()
|
public function instantSaveSSL()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$this->database->save();
|
$this->database->save();
|
||||||
$this->dispatch('success', 'SSL configuration updated.');
|
$this->dispatch('success', 'SSL configuration updated.');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
@@ -194,6 +205,8 @@ class General extends Component
|
|||||||
public function regenerateSslCertificate()
|
public function regenerateSslCertificate()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$existingCert = $this->database->sslCertificates()->first();
|
$existingCert = $this->database->sslCertificates()->first();
|
||||||
|
|
||||||
if (! $existingCert) {
|
if (! $existingCert) {
|
||||||
|
@@ -11,11 +11,14 @@ use App\Models\StandaloneMysql;
|
|||||||
use App\Support\ValidationPatterns;
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class General extends Component
|
class General extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
protected $listeners = ['refresh'];
|
protected $listeners = ['refresh'];
|
||||||
|
|
||||||
public StandaloneMysql $database;
|
public StandaloneMysql $database;
|
||||||
@@ -111,6 +114,8 @@ class General extends Component
|
|||||||
public function instantSaveAdvanced()
|
public function instantSaveAdvanced()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (! $this->server->isLogDrainEnabled()) {
|
if (! $this->server->isLogDrainEnabled()) {
|
||||||
$this->database->is_log_drain_enabled = false;
|
$this->database->is_log_drain_enabled = false;
|
||||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||||
@@ -128,6 +133,8 @@ class General extends Component
|
|||||||
public function submit()
|
public function submit()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (str($this->database->public_port)->isEmpty()) {
|
if (str($this->database->public_port)->isEmpty()) {
|
||||||
$this->database->public_port = null;
|
$this->database->public_port = null;
|
||||||
}
|
}
|
||||||
@@ -148,6 +155,8 @@ class General extends Component
|
|||||||
public function instantSave()
|
public function instantSave()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if ($this->database->is_public && ! $this->database->public_port) {
|
if ($this->database->is_public && ! $this->database->public_port) {
|
||||||
$this->dispatch('error', 'Public port is required.');
|
$this->dispatch('error', 'Public port is required.');
|
||||||
$this->database->is_public = false;
|
$this->database->is_public = false;
|
||||||
@@ -184,6 +193,8 @@ class General extends Component
|
|||||||
public function instantSaveSSL()
|
public function instantSaveSSL()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$this->database->save();
|
$this->database->save();
|
||||||
$this->dispatch('success', 'SSL configuration updated.');
|
$this->dispatch('success', 'SSL configuration updated.');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
@@ -194,6 +205,8 @@ class General extends Component
|
|||||||
public function regenerateSslCertificate()
|
public function regenerateSslCertificate()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$existingCert = $this->database->sslCertificates()->first();
|
$existingCert = $this->database->sslCertificates()->first();
|
||||||
|
|
||||||
if (! $existingCert) {
|
if (! $existingCert) {
|
||||||
|
@@ -11,11 +11,14 @@ use App\Models\StandalonePostgresql;
|
|||||||
use App\Support\ValidationPatterns;
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class General extends Component
|
class General extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
public StandalonePostgresql $database;
|
public StandalonePostgresql $database;
|
||||||
|
|
||||||
public Server $server;
|
public Server $server;
|
||||||
@@ -118,6 +121,8 @@ class General extends Component
|
|||||||
public function instantSaveAdvanced()
|
public function instantSaveAdvanced()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (! $this->server->isLogDrainEnabled()) {
|
if (! $this->server->isLogDrainEnabled()) {
|
||||||
$this->database->is_log_drain_enabled = false;
|
$this->database->is_log_drain_enabled = false;
|
||||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||||
@@ -140,6 +145,8 @@ class General extends Component
|
|||||||
public function instantSaveSSL()
|
public function instantSaveSSL()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$this->database->save();
|
$this->database->save();
|
||||||
$this->dispatch('success', 'SSL configuration updated.');
|
$this->dispatch('success', 'SSL configuration updated.');
|
||||||
$this->db_url = $this->database->internal_db_url;
|
$this->db_url = $this->database->internal_db_url;
|
||||||
@@ -152,6 +159,8 @@ class General extends Component
|
|||||||
public function regenerateSslCertificate()
|
public function regenerateSslCertificate()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$existingCert = $this->database->sslCertificates()->first();
|
$existingCert = $this->database->sslCertificates()->first();
|
||||||
|
|
||||||
if (! $existingCert) {
|
if (! $existingCert) {
|
||||||
@@ -184,6 +193,8 @@ class General extends Component
|
|||||||
public function instantSave()
|
public function instantSave()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if ($this->database->is_public && ! $this->database->public_port) {
|
if ($this->database->is_public && ! $this->database->public_port) {
|
||||||
$this->dispatch('error', 'Public port is required.');
|
$this->dispatch('error', 'Public port is required.');
|
||||||
$this->database->is_public = false;
|
$this->database->is_public = false;
|
||||||
@@ -214,6 +225,8 @@ class General extends Component
|
|||||||
|
|
||||||
public function save_init_script($script)
|
public function save_init_script($script)
|
||||||
{
|
{
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$initScripts = collect($this->database->init_scripts ?? []);
|
$initScripts = collect($this->database->init_scripts ?? []);
|
||||||
|
|
||||||
$existingScript = $initScripts->firstWhere('filename', $script['filename']);
|
$existingScript = $initScripts->firstWhere('filename', $script['filename']);
|
||||||
@@ -264,6 +277,8 @@ class General extends Component
|
|||||||
|
|
||||||
public function delete_init_script($script)
|
public function delete_init_script($script)
|
||||||
{
|
{
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$collection = collect($this->database->init_scripts);
|
$collection = collect($this->database->init_scripts);
|
||||||
$found = $collection->firstWhere('filename', $script['filename']);
|
$found = $collection->firstWhere('filename', $script['filename']);
|
||||||
if ($found) {
|
if ($found) {
|
||||||
@@ -298,6 +313,8 @@ class General extends Component
|
|||||||
|
|
||||||
public function save_new_init_script()
|
public function save_new_init_script()
|
||||||
{
|
{
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$this->validate([
|
$this->validate([
|
||||||
'new_filename' => 'required|string',
|
'new_filename' => 'required|string',
|
||||||
'new_content' => 'required|string',
|
'new_content' => 'required|string',
|
||||||
@@ -327,6 +344,8 @@ class General extends Component
|
|||||||
public function submit()
|
public function submit()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (str($this->database->public_port)->isEmpty()) {
|
if (str($this->database->public_port)->isEmpty()) {
|
||||||
$this->database->public_port = null;
|
$this->database->public_port = null;
|
||||||
}
|
}
|
||||||
|
@@ -11,11 +11,14 @@ use App\Models\StandaloneRedis;
|
|||||||
use App\Support\ValidationPatterns;
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class General extends Component
|
class General extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
public Server $server;
|
public Server $server;
|
||||||
|
|
||||||
public StandaloneRedis $database;
|
public StandaloneRedis $database;
|
||||||
@@ -105,6 +108,8 @@ class General extends Component
|
|||||||
public function instantSaveAdvanced()
|
public function instantSaveAdvanced()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if (! $this->server->isLogDrainEnabled()) {
|
if (! $this->server->isLogDrainEnabled()) {
|
||||||
$this->database->is_log_drain_enabled = false;
|
$this->database->is_log_drain_enabled = false;
|
||||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||||
@@ -122,6 +127,8 @@ class General extends Component
|
|||||||
public function submit()
|
public function submit()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('manageEnvironment', $this->database);
|
||||||
|
|
||||||
$this->validate();
|
$this->validate();
|
||||||
|
|
||||||
if (version_compare($this->redis_version, '6.0', '>=')) {
|
if (version_compare($this->redis_version, '6.0', '>=')) {
|
||||||
@@ -147,6 +154,8 @@ class General extends Component
|
|||||||
public function instantSave()
|
public function instantSave()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
if ($this->database->is_public && ! $this->database->public_port) {
|
if ($this->database->is_public && ! $this->database->public_port) {
|
||||||
$this->dispatch('error', 'Public port is required.');
|
$this->dispatch('error', 'Public port is required.');
|
||||||
$this->database->is_public = false;
|
$this->database->is_public = false;
|
||||||
@@ -178,6 +187,8 @@ class General extends Component
|
|||||||
public function instantSaveSSL()
|
public function instantSaveSSL()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$this->database->save();
|
$this->database->save();
|
||||||
$this->dispatch('success', 'SSL configuration updated.');
|
$this->dispatch('success', 'SSL configuration updated.');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
@@ -188,6 +199,8 @@ class General extends Component
|
|||||||
public function regenerateSslCertificate()
|
public function regenerateSslCertificate()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$existingCert = $this->database->sslCertificates()->first();
|
$existingCert = $this->database->sslCertificates()->first();
|
||||||
|
|
||||||
if (! $existingCert) {
|
if (! $existingCert) {
|
||||||
|
@@ -3,10 +3,13 @@
|
|||||||
namespace App\Livewire\Project\Database;
|
namespace App\Livewire\Project\Database;
|
||||||
|
|
||||||
use App\Models\ScheduledDatabaseBackup;
|
use App\Models\ScheduledDatabaseBackup;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class ScheduledBackups extends Component
|
class ScheduledBackups extends Component
|
||||||
{
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
|
||||||
public $database;
|
public $database;
|
||||||
|
|
||||||
public $parameters;
|
public $parameters;
|
||||||
@@ -53,6 +56,8 @@ class ScheduledBackups extends Component
|
|||||||
|
|
||||||
public function setCustomType()
|
public function setCustomType()
|
||||||
{
|
{
|
||||||
|
$this->authorize('update', $this->database);
|
||||||
|
|
||||||
$this->database->custom_type = $this->custom_type;
|
$this->database->custom_type = $this->custom_type;
|
||||||
$this->database->save();
|
$this->database->save();
|
||||||
$this->dispatch('success', 'Database type set.');
|
$this->dispatch('success', 'Database type set.');
|
||||||
@@ -61,7 +66,10 @@ class ScheduledBackups extends Component
|
|||||||
|
|
||||||
public function delete($scheduled_backup_id): void
|
public function delete($scheduled_backup_id): void
|
||||||
{
|
{
|
||||||
$this->database->scheduledBackups->find($scheduled_backup_id)->delete();
|
$backup = $this->database->scheduledBackups->find($scheduled_backup_id);
|
||||||
|
$this->authorize('manageBackups', $this->database);
|
||||||
|
|
||||||
|
$backup->delete();
|
||||||
$this->dispatch('success', 'Scheduled backup deleted.');
|
$this->dispatch('success', 'Scheduled backup deleted.');
|
||||||
$this->refreshScheduledBackups();
|
$this->refreshScheduledBackups();
|
||||||
}
|
}
|
||||||
|
@@ -45,12 +45,16 @@ class All extends Component
|
|||||||
|
|
||||||
public function instantSave()
|
public function instantSave()
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
$this->authorize('manageEnvironment', $this->resource);
|
$this->authorize('manageEnvironment', $this->resource);
|
||||||
|
|
||||||
$this->resource->settings->is_env_sorting_enabled = $this->is_env_sorting_enabled;
|
$this->resource->settings->is_env_sorting_enabled = $this->is_env_sorting_enabled;
|
||||||
$this->resource->settings->save();
|
$this->resource->settings->save();
|
||||||
$this->sortEnvironmentVariables();
|
$this->sortEnvironmentVariables();
|
||||||
$this->dispatch('success', 'Environment variable settings updated.');
|
$this->dispatch('success', 'Environment variable settings updated.');
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sortEnvironmentVariables()
|
public function sortEnvironmentVariables()
|
||||||
@@ -98,9 +102,8 @@ class All extends Component
|
|||||||
|
|
||||||
public function submit($data = null)
|
public function submit($data = null)
|
||||||
{
|
{
|
||||||
$this->authorize('manageEnvironment', $this->resource);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
$this->authorize('manageEnvironment', $this->resource);
|
||||||
if ($data === null) {
|
if ($data === null) {
|
||||||
$this->handleBulkSubmit();
|
$this->handleBulkSubmit();
|
||||||
} else {
|
} else {
|
||||||
|
93
app/Policies/DatabasePolicy.php
Normal file
93
app/Policies/DatabasePolicy.php
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Policies;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Auth\Access\Response;
|
||||||
|
|
||||||
|
class DatabasePolicy
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view any models.
|
||||||
|
*/
|
||||||
|
public function viewAny(User $user): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view the model.
|
||||||
|
*/
|
||||||
|
public function view(User $user, $database): bool
|
||||||
|
{
|
||||||
|
return $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can create models.
|
||||||
|
*/
|
||||||
|
public function create(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->isAdmin();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can update the model.
|
||||||
|
*/
|
||||||
|
public function update(User $user, $database): Response
|
||||||
|
{
|
||||||
|
if ($user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null) {
|
||||||
|
return Response::allow();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response::deny('As a member, you cannot update this database.<br/><br/>You need at least admin or owner permissions.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can delete the model.
|
||||||
|
*/
|
||||||
|
public function delete(User $user, $database): bool
|
||||||
|
{
|
||||||
|
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can restore the model.
|
||||||
|
*/
|
||||||
|
public function restore(User $user, $database): bool
|
||||||
|
{
|
||||||
|
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can permanently delete the model.
|
||||||
|
*/
|
||||||
|
public function forceDelete(User $user, $database): bool
|
||||||
|
{
|
||||||
|
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can start/stop the database.
|
||||||
|
*/
|
||||||
|
public function manage(User $user, $database): bool
|
||||||
|
{
|
||||||
|
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can manage database backups.
|
||||||
|
*/
|
||||||
|
public function manageBackups(User $user, $database): bool
|
||||||
|
{
|
||||||
|
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can manage environment variables.
|
||||||
|
*/
|
||||||
|
public function manageEnvironment(User $user, $database): bool
|
||||||
|
{
|
||||||
|
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user