feat(acl): Change views/backend code to able to use proper ACL's later on. Currently it is not enabled.
This commit is contained in:
@@ -72,5 +72,7 @@ class Kernel extends HttpKernel
|
||||
'api.ability' => \App\Http\Middleware\ApiAbility::class,
|
||||
'api.sensitive' => \App\Http\Middleware\ApiSensitiveData::class,
|
||||
'can.create.resources' => \App\Http\Middleware\CanCreateResources::class,
|
||||
'can.update.resource' => \App\Http\Middleware\CanUpdateResource::class,
|
||||
'can.access.terminal' => \App\Http\Middleware\CanAccessTerminal::class,
|
||||
];
|
||||
}
|
||||
|
||||
31
app/Http/Middleware/CanAccessTerminal.php
Normal file
31
app/Http/Middleware/CanAccessTerminal.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class CanAccessTerminal
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
return $next($request);
|
||||
|
||||
// if (! auth()->check()) {
|
||||
// abort(401, 'Authentication required');
|
||||
// }
|
||||
|
||||
// // Only admins/owners can access terminal functionality
|
||||
// if (! auth()->user()->can('canAccessTerminal')) {
|
||||
// abort(403, 'Access to terminal functionality is restricted to team administrators');
|
||||
// }
|
||||
|
||||
// return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,11 @@ class CanCreateResources
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
if (! Gate::allows('createAnyResource')) {
|
||||
abort(403, 'You do not have permission to create resources.');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
// if (! Gate::allows('createAnyResource')) {
|
||||
// abort(403, 'You do not have permission to create resources.');
|
||||
// }
|
||||
|
||||
// return $next($request);
|
||||
}
|
||||
}
|
||||
|
||||
75
app/Http/Middleware/CanUpdateResource.php
Normal file
75
app/Http/Middleware/CanUpdateResource.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\Environment;
|
||||
use App\Models\Project;
|
||||
use App\Models\Service;
|
||||
use App\Models\ServiceApplication;
|
||||
use App\Models\ServiceDatabase;
|
||||
use App\Models\StandaloneClickhouse;
|
||||
use App\Models\StandaloneDragonfly;
|
||||
use App\Models\StandaloneKeydb;
|
||||
use App\Models\StandaloneMariadb;
|
||||
use App\Models\StandaloneMongodb;
|
||||
use App\Models\StandaloneMysql;
|
||||
use App\Models\StandalonePostgresql;
|
||||
use App\Models\StandaloneRedis;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class CanUpdateResource
|
||||
{
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
return $next($request);
|
||||
|
||||
// Get resource from route parameters
|
||||
// $resource = null;
|
||||
// if ($request->route('application_uuid')) {
|
||||
// $resource = Application::where('uuid', $request->route('application_uuid'))->first();
|
||||
// } elseif ($request->route('service_uuid')) {
|
||||
// $resource = Service::where('uuid', $request->route('service_uuid'))->first();
|
||||
// } elseif ($request->route('stack_service_uuid')) {
|
||||
// // Handle ServiceApplication or ServiceDatabase
|
||||
// $stack_service_uuid = $request->route('stack_service_uuid');
|
||||
// $resource = ServiceApplication::where('uuid', $stack_service_uuid)->first() ??
|
||||
// ServiceDatabase::where('uuid', $stack_service_uuid)->first();
|
||||
// } elseif ($request->route('database_uuid')) {
|
||||
// // Try different database types
|
||||
// $database_uuid = $request->route('database_uuid');
|
||||
// $resource = StandalonePostgresql::where('uuid', $database_uuid)->first() ??
|
||||
// StandaloneMysql::where('uuid', $database_uuid)->first() ??
|
||||
// StandaloneMariadb::where('uuid', $database_uuid)->first() ??
|
||||
// StandaloneRedis::where('uuid', $database_uuid)->first() ??
|
||||
// StandaloneKeydb::where('uuid', $database_uuid)->first() ??
|
||||
// StandaloneDragonfly::where('uuid', $database_uuid)->first() ??
|
||||
// StandaloneClickhouse::where('uuid', $database_uuid)->first() ??
|
||||
// StandaloneMongodb::where('uuid', $database_uuid)->first();
|
||||
// } elseif ($request->route('server_uuid')) {
|
||||
// // For server routes, check if user can manage servers
|
||||
// if (! auth()->user()->isAdmin()) {
|
||||
// abort(403, 'You do not have permission to access this resource.');
|
||||
// }
|
||||
|
||||
// return $next($request);
|
||||
// } elseif ($request->route('environment_uuid')) {
|
||||
// $resource = Environment::where('uuid', $request->route('environment_uuid'))->first();
|
||||
// } elseif ($request->route('project_uuid')) {
|
||||
// $resource = Project::ownedByCurrentTeam()->where('uuid', $request->route('project_uuid'))->first();
|
||||
// }
|
||||
|
||||
// if (! $resource) {
|
||||
// abort(404, 'Resource not found.');
|
||||
// }
|
||||
|
||||
// if (! Gate::allows('update', $resource)) {
|
||||
// abort(403, 'You do not have permission to update this resource.');
|
||||
// }
|
||||
|
||||
// return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,15 @@ namespace App\Livewire\Destination;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\SwarmDocker;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
class Show extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
#[Locked]
|
||||
public $destination;
|
||||
|
||||
@@ -63,6 +66,8 @@ class Show extends Component
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->destination);
|
||||
|
||||
$this->syncData(true);
|
||||
$this->dispatch('success', 'Destination saved.');
|
||||
} catch (\Throwable $e) {
|
||||
@@ -73,6 +78,8 @@ class Show extends Component
|
||||
public function delete()
|
||||
{
|
||||
try {
|
||||
$this->authorize('delete', $this->destination);
|
||||
|
||||
if ($this->destination->getMorphClass() === \App\Models\StandaloneDocker::class) {
|
||||
if ($this->destination->attachedTo()) {
|
||||
return $this->dispatch('error', 'You must delete all resources before deleting this destination.');
|
||||
|
||||
@@ -5,11 +5,14 @@ namespace App\Livewire\Notifications;
|
||||
use App\Models\DiscordNotificationSettings;
|
||||
use App\Models\Team;
|
||||
use App\Notifications\Test;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
class Discord extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public Team $team;
|
||||
|
||||
public DiscordNotificationSettings $settings;
|
||||
@@ -67,6 +70,7 @@ class Discord extends Component
|
||||
try {
|
||||
$this->team = auth()->user()->currentTeam();
|
||||
$this->settings = $this->team->discordNotificationSettings;
|
||||
$this->authorize('view', $this->settings);
|
||||
$this->syncData();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
@@ -77,6 +81,7 @@ class Discord extends Component
|
||||
{
|
||||
if ($toModel) {
|
||||
$this->validate();
|
||||
$this->authorize('update', $this->settings);
|
||||
$this->settings->discord_enabled = $this->discordEnabled;
|
||||
$this->settings->discord_webhook_url = $this->discordWebhookUrl;
|
||||
|
||||
@@ -182,6 +187,7 @@ class Discord extends Component
|
||||
public function sendTestNotification()
|
||||
{
|
||||
try {
|
||||
$this->authorize('sendTest', $this->settings);
|
||||
$this->team->notify(new Test(channel: 'discord'));
|
||||
$this->dispatch('success', 'Test notification sent.');
|
||||
} catch (\Throwable $e) {
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Livewire\Notifications;
|
||||
use App\Models\EmailNotificationSettings;
|
||||
use App\Models\Team;
|
||||
use App\Notifications\Test;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Attributes\Validate;
|
||||
@@ -12,6 +13,8 @@ use Livewire\Component;
|
||||
|
||||
class Email extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
protected $listeners = ['refresh' => '$refresh'];
|
||||
|
||||
#[Locked]
|
||||
@@ -110,6 +113,7 @@ class Email extends Component
|
||||
$this->team = auth()->user()->currentTeam();
|
||||
$this->emails = auth()->user()->email;
|
||||
$this->settings = $this->team->emailNotificationSettings;
|
||||
$this->authorize('view', $this->settings);
|
||||
$this->syncData();
|
||||
$this->testEmailAddress = auth()->user()->email;
|
||||
} catch (\Throwable $e) {
|
||||
@@ -121,6 +125,7 @@ class Email extends Component
|
||||
{
|
||||
if ($toModel) {
|
||||
$this->validate();
|
||||
$this->authorize('update', $this->settings);
|
||||
$this->settings->smtp_enabled = $this->smtpEnabled;
|
||||
$this->settings->smtp_from_address = $this->smtpFromAddress;
|
||||
$this->settings->smtp_from_name = $this->smtpFromName;
|
||||
@@ -311,6 +316,7 @@ class Email extends Component
|
||||
public function sendTestEmail()
|
||||
{
|
||||
try {
|
||||
$this->authorize('sendTest', $this->settings);
|
||||
$this->validate([
|
||||
'testEmailAddress' => 'required|email',
|
||||
], [
|
||||
@@ -338,6 +344,7 @@ class Email extends Component
|
||||
|
||||
public function copyFromInstanceSettings()
|
||||
{
|
||||
$this->authorize('update', $this->settings);
|
||||
$settings = instanceSettings();
|
||||
$this->smtpFromAddress = $settings->smtp_from_address;
|
||||
$this->smtpFromName = $settings->smtp_from_name;
|
||||
|
||||
@@ -5,12 +5,15 @@ namespace App\Livewire\Notifications;
|
||||
use App\Models\PushoverNotificationSettings;
|
||||
use App\Models\Team;
|
||||
use App\Notifications\Test;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
class Pushover extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
protected $listeners = ['refresh' => '$refresh'];
|
||||
|
||||
#[Locked]
|
||||
@@ -72,6 +75,7 @@ class Pushover extends Component
|
||||
try {
|
||||
$this->team = auth()->user()->currentTeam();
|
||||
$this->settings = $this->team->pushoverNotificationSettings;
|
||||
$this->authorize('view', $this->settings);
|
||||
$this->syncData();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
@@ -82,6 +86,7 @@ class Pushover extends Component
|
||||
{
|
||||
if ($toModel) {
|
||||
$this->validate();
|
||||
$this->authorize('update', $this->settings);
|
||||
$this->settings->pushover_enabled = $this->pushoverEnabled;
|
||||
$this->settings->pushover_user_key = $this->pushoverUserKey;
|
||||
$this->settings->pushover_api_token = $this->pushoverApiToken;
|
||||
@@ -175,6 +180,7 @@ class Pushover extends Component
|
||||
public function sendTestNotification()
|
||||
{
|
||||
try {
|
||||
$this->authorize('sendTest', $this->settings);
|
||||
$this->team->notify(new Test(channel: 'pushover'));
|
||||
$this->dispatch('success', 'Test notification sent.');
|
||||
} catch (\Throwable $e) {
|
||||
|
||||
@@ -5,12 +5,15 @@ namespace App\Livewire\Notifications;
|
||||
use App\Models\SlackNotificationSettings;
|
||||
use App\Models\Team;
|
||||
use App\Notifications\Test;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
class Slack extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
protected $listeners = ['refresh' => '$refresh'];
|
||||
|
||||
#[Locked]
|
||||
@@ -69,6 +72,7 @@ class Slack extends Component
|
||||
try {
|
||||
$this->team = auth()->user()->currentTeam();
|
||||
$this->settings = $this->team->slackNotificationSettings;
|
||||
$this->authorize('view', $this->settings);
|
||||
$this->syncData();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
@@ -79,6 +83,7 @@ class Slack extends Component
|
||||
{
|
||||
if ($toModel) {
|
||||
$this->validate();
|
||||
$this->authorize('update', $this->settings);
|
||||
$this->settings->slack_enabled = $this->slackEnabled;
|
||||
$this->settings->slack_webhook_url = $this->slackWebhookUrl;
|
||||
|
||||
@@ -168,6 +173,7 @@ class Slack extends Component
|
||||
public function sendTestNotification()
|
||||
{
|
||||
try {
|
||||
$this->authorize('sendTest', $this->settings);
|
||||
$this->team->notify(new Test(channel: 'slack'));
|
||||
$this->dispatch('success', 'Test notification sent.');
|
||||
} catch (\Throwable $e) {
|
||||
|
||||
@@ -5,12 +5,15 @@ namespace App\Livewire\Notifications;
|
||||
use App\Models\Team;
|
||||
use App\Models\TelegramNotificationSettings;
|
||||
use App\Notifications\Test;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
class Telegram extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
protected $listeners = ['refresh' => '$refresh'];
|
||||
|
||||
#[Locked]
|
||||
@@ -111,6 +114,7 @@ class Telegram extends Component
|
||||
try {
|
||||
$this->team = auth()->user()->currentTeam();
|
||||
$this->settings = $this->team->telegramNotificationSettings;
|
||||
$this->authorize('view', $this->settings);
|
||||
$this->syncData();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
@@ -121,6 +125,7 @@ class Telegram extends Component
|
||||
{
|
||||
if ($toModel) {
|
||||
$this->validate();
|
||||
$this->authorize('update', $this->settings);
|
||||
$this->settings->telegram_enabled = $this->telegramEnabled;
|
||||
$this->settings->telegram_token = $this->telegramToken;
|
||||
$this->settings->telegram_chat_id = $this->telegramChatId;
|
||||
@@ -241,6 +246,7 @@ class Telegram extends Component
|
||||
public function sendTestNotification()
|
||||
{
|
||||
try {
|
||||
$this->authorize('sendTest', $this->settings);
|
||||
$this->team->notify(new Test(channel: 'telegram'));
|
||||
$this->dispatch('success', 'Test notification sent.');
|
||||
} catch (\Throwable $e) {
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
namespace App\Livewire\Project\Application\Preview;
|
||||
|
||||
use App\Models\Application;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
use Spatie\Url\Url;
|
||||
|
||||
class Form extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public Application $application;
|
||||
|
||||
#[Validate('required')]
|
||||
@@ -27,6 +30,7 @@ class Form extends Component
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->application);
|
||||
$this->resetErrorBag();
|
||||
$this->validate();
|
||||
$this->application->preview_url_template = str_replace(' ', '', $this->previewUrlTemplate);
|
||||
@@ -41,6 +45,7 @@ class Form extends Component
|
||||
public function resetToDefault()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->application);
|
||||
$this->application->preview_url_template = '{{pr_id}}.{{domain}}';
|
||||
$this->previewUrlTemplate = $this->application->preview_url_template;
|
||||
$this->application->save();
|
||||
|
||||
@@ -38,6 +38,7 @@ class Previews extends Component
|
||||
public function load_prs()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->application);
|
||||
['rate_limit_remaining' => $rate_limit_remaining, 'data' => $data] = githubApi(source: $this->application->source, endpoint: "/repos/{$this->application->git_repository}/pulls");
|
||||
$this->rate_limit_remaining = $rate_limit_remaining;
|
||||
$this->pull_requests = $data->sortBy('number')->values();
|
||||
|
||||
@@ -176,6 +176,7 @@ EOD;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$this->importRunning = true;
|
||||
$this->importCommands = [];
|
||||
if (filled($this->customLocation)) {
|
||||
$backupFileName = '/tmp/restore_'.$this->resource->uuid;
|
||||
|
||||
@@ -20,6 +20,7 @@ class Index extends Component
|
||||
$this->private_keys = PrivateKey::ownedByCurrentTeam()->get();
|
||||
$this->projects = Project::ownedByCurrentTeam()->get()->map(function ($project) {
|
||||
$project->settingsRoute = route('project.edit', ['project_uuid' => $project->uuid]);
|
||||
$project->canUpdate = auth()->user()->can('update', $project);
|
||||
|
||||
return $project;
|
||||
});
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
namespace App\Livewire\Project\Service;
|
||||
|
||||
use App\Models\Service;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Livewire\Component;
|
||||
|
||||
class Configuration extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public $currentRoute;
|
||||
|
||||
public $project;
|
||||
@@ -40,24 +43,30 @@ class Configuration extends Component
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = get_route_parameters();
|
||||
$this->currentRoute = request()->route()->getName();
|
||||
$this->query = request()->query();
|
||||
$project = currentTeam()
|
||||
->projects()
|
||||
->select('id', 'uuid', 'team_id')
|
||||
->where('uuid', request()->route('project_uuid'))
|
||||
->firstOrFail();
|
||||
$environment = $project->environments()
|
||||
->select('id', 'uuid', 'name', 'project_id')
|
||||
->where('uuid', request()->route('environment_uuid'))
|
||||
->firstOrFail();
|
||||
$this->service = $environment->services()->whereUuid(request()->route('service_uuid'))->firstOrFail();
|
||||
try {
|
||||
$this->parameters = get_route_parameters();
|
||||
$this->currentRoute = request()->route()->getName();
|
||||
$this->query = request()->query();
|
||||
$project = currentTeam()
|
||||
->projects()
|
||||
->select('id', 'uuid', 'team_id')
|
||||
->where('uuid', request()->route('project_uuid'))
|
||||
->firstOrFail();
|
||||
$environment = $project->environments()
|
||||
->select('id', 'uuid', 'name', 'project_id')
|
||||
->where('uuid', request()->route('environment_uuid'))
|
||||
->firstOrFail();
|
||||
$this->service = $environment->services()->whereUuid(request()->route('service_uuid'))->firstOrFail();
|
||||
|
||||
$this->project = $project;
|
||||
$this->environment = $environment;
|
||||
$this->applications = $this->service->applications->sort();
|
||||
$this->databases = $this->service->databases->sort();
|
||||
$this->authorize('view', $this->service);
|
||||
|
||||
$this->project = $project;
|
||||
$this->environment = $environment;
|
||||
$this->applications = $this->service->applications->sort();
|
||||
$this->databases = $this->service->databases->sort();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function refreshServices()
|
||||
@@ -70,6 +79,7 @@ class Configuration extends Component
|
||||
public function restartApplication($id)
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->service);
|
||||
$application = $this->service->applications->find($id);
|
||||
if ($application) {
|
||||
$application->restart();
|
||||
@@ -83,6 +93,7 @@ class Configuration extends Component
|
||||
public function restartDatabase($id)
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->service);
|
||||
$database = $this->service->databases->find($id);
|
||||
if ($database) {
|
||||
$database->restart();
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Actions\Database\StartDatabaseProxy;
|
||||
use App\Actions\Database\StopDatabaseProxy;
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\ServiceDatabase;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
@@ -13,6 +14,8 @@ use Livewire\Component;
|
||||
|
||||
class Database extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public ServiceDatabase $database;
|
||||
|
||||
public ?string $db_url_public = null;
|
||||
@@ -40,24 +43,31 @@ class Database extends Component
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = get_route_parameters();
|
||||
if ($this->database->is_public) {
|
||||
$this->db_url_public = $this->database->getServiceDatabaseUrl();
|
||||
try {
|
||||
$this->parameters = get_route_parameters();
|
||||
$this->authorize('view', $this->database);
|
||||
if ($this->database->is_public) {
|
||||
$this->db_url_public = $this->database->getServiceDatabaseUrl();
|
||||
}
|
||||
$this->refreshFileStorages();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
$this->refreshFileStorages();
|
||||
}
|
||||
|
||||
public function delete($password)
|
||||
{
|
||||
if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) {
|
||||
if (! Hash::check($password, Auth::user()->password)) {
|
||||
$this->addError('password', 'The provided password is incorrect.');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->authorize('delete', $this->database);
|
||||
|
||||
if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) {
|
||||
if (! Hash::check($password, Auth::user()->password)) {
|
||||
$this->addError('password', 'The provided password is incorrect.');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->database->delete();
|
||||
$this->dispatch('success', 'Database deleted.');
|
||||
|
||||
@@ -69,24 +79,35 @@ class Database extends Component
|
||||
|
||||
public function instantSaveExclude()
|
||||
{
|
||||
$this->submit();
|
||||
try {
|
||||
$this->authorize('update', $this->database);
|
||||
$this->submit();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function instantSaveLogDrain()
|
||||
{
|
||||
if (! $this->database->service->destination->server->isLogDrainEnabled()) {
|
||||
$this->database->is_log_drain_enabled = false;
|
||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||
try {
|
||||
$this->authorize('update', $this->database);
|
||||
if (! $this->database->service->destination->server->isLogDrainEnabled()) {
|
||||
$this->database->is_log_drain_enabled = false;
|
||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
$this->submit();
|
||||
$this->dispatch('success', 'You need to restart the service for the changes to take effect.');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
$this->submit();
|
||||
$this->dispatch('success', 'You need to restart the service for the changes to take effect.');
|
||||
}
|
||||
|
||||
public function convertToApplication()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->database);
|
||||
$service = $this->database->service;
|
||||
$serviceDatabase = $this->database;
|
||||
|
||||
@@ -122,28 +143,33 @@ class Database extends Component
|
||||
|
||||
public function instantSave()
|
||||
{
|
||||
if ($this->database->is_public && ! $this->database->public_port) {
|
||||
$this->dispatch('error', 'Public port is required.');
|
||||
$this->database->is_public = false;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($this->database->is_public) {
|
||||
if (! str($this->database->status)->startsWith('running')) {
|
||||
$this->dispatch('error', 'Database must be started to be publicly accessible.');
|
||||
try {
|
||||
$this->authorize('update', $this->database);
|
||||
if ($this->database->is_public && ! $this->database->public_port) {
|
||||
$this->dispatch('error', 'Public port is required.');
|
||||
$this->database->is_public = false;
|
||||
|
||||
return;
|
||||
}
|
||||
StartDatabaseProxy::run($this->database);
|
||||
$this->db_url_public = $this->database->getServiceDatabaseUrl();
|
||||
$this->dispatch('success', 'Database is now publicly accessible.');
|
||||
} else {
|
||||
StopDatabaseProxy::run($this->database);
|
||||
$this->db_url_public = null;
|
||||
$this->dispatch('success', 'Database is no longer publicly accessible.');
|
||||
if ($this->database->is_public) {
|
||||
if (! str($this->database->status)->startsWith('running')) {
|
||||
$this->dispatch('error', 'Database must be started to be publicly accessible.');
|
||||
$this->database->is_public = false;
|
||||
|
||||
return;
|
||||
}
|
||||
StartDatabaseProxy::run($this->database);
|
||||
$this->db_url_public = $this->database->getServiceDatabaseUrl();
|
||||
$this->dispatch('success', 'Database is now publicly accessible.');
|
||||
} else {
|
||||
StopDatabaseProxy::run($this->database);
|
||||
$this->db_url_public = null;
|
||||
$this->dispatch('success', 'Database is no longer publicly accessible.');
|
||||
}
|
||||
$this->submit();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
$this->submit();
|
||||
}
|
||||
|
||||
public function refreshFileStorages()
|
||||
@@ -154,11 +180,13 @@ class Database extends Component
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->database);
|
||||
$this->validate();
|
||||
$this->database->save();
|
||||
updateCompose($this->database);
|
||||
$this->dispatch('success', 'Database saved.');
|
||||
} catch (\Throwable) {
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
} finally {
|
||||
$this->dispatch('generateDockerCompose');
|
||||
}
|
||||
|
||||
@@ -15,12 +15,15 @@ use App\Models\StandaloneMongodb;
|
||||
use App\Models\StandaloneMysql;
|
||||
use App\Models\StandalonePostgresql;
|
||||
use App\Models\StandaloneRedis;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Livewire\Component;
|
||||
|
||||
class FileStorage extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public LocalFileVolume $fileStorage;
|
||||
|
||||
public ServiceApplication|StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse|ServiceDatabase|Application $resource;
|
||||
@@ -54,6 +57,8 @@ class FileStorage extends Component
|
||||
public function convertToDirectory()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
|
||||
$this->fileStorage->deleteStorageOnServer();
|
||||
$this->fileStorage->is_directory = true;
|
||||
$this->fileStorage->content = null;
|
||||
@@ -70,6 +75,8 @@ class FileStorage extends Component
|
||||
public function loadStorageOnServer()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
|
||||
$this->fileStorage->loadStorageOnServer();
|
||||
$this->dispatch('success', 'File storage loaded from server.');
|
||||
} catch (\Throwable $e) {
|
||||
@@ -82,6 +89,8 @@ class FileStorage extends Component
|
||||
public function convertToFile()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
|
||||
$this->fileStorage->deleteStorageOnServer();
|
||||
$this->fileStorage->is_directory = false;
|
||||
$this->fileStorage->content = null;
|
||||
@@ -99,6 +108,8 @@ class FileStorage extends Component
|
||||
|
||||
public function delete($password)
|
||||
{
|
||||
$this->authorize('update', $this->resource);
|
||||
|
||||
if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) {
|
||||
if (! Hash::check($password, Auth::user()->password)) {
|
||||
$this->addError('password', 'The provided password is incorrect.');
|
||||
@@ -127,6 +138,8 @@ class FileStorage extends Component
|
||||
|
||||
public function submit()
|
||||
{
|
||||
$this->authorize('update', $this->resource);
|
||||
|
||||
$original = $this->fileStorage->getOriginal();
|
||||
try {
|
||||
$this->validate();
|
||||
|
||||
@@ -5,11 +5,14 @@ namespace App\Livewire\Project\Service;
|
||||
use App\Models\Service;
|
||||
use App\Models\ServiceApplication;
|
||||
use App\Models\ServiceDatabase;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Collection;
|
||||
use Livewire\Component;
|
||||
|
||||
class Index extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public ?Service $service = null;
|
||||
|
||||
public ?ServiceApplication $serviceApplication = null;
|
||||
@@ -36,6 +39,7 @@ class Index extends Component
|
||||
if (! $this->service) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
$this->authorize('view', $this->service);
|
||||
$service = $this->service->applications()->whereUuid($this->parameters['stack_service_uuid'])->first();
|
||||
if ($service) {
|
||||
$this->serviceApplication = $service;
|
||||
@@ -52,7 +56,12 @@ class Index extends Component
|
||||
|
||||
public function generateDockerCompose()
|
||||
{
|
||||
$this->service->parse();
|
||||
try {
|
||||
$this->authorize('update', $this->service);
|
||||
$this->service->parse();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Livewire\Project\Service;
|
||||
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\ServiceApplication;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
@@ -12,6 +13,8 @@ use Spatie\Url\Url;
|
||||
|
||||
class ServiceApplicationView extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public ServiceApplication $application;
|
||||
|
||||
public $parameters;
|
||||
@@ -34,32 +37,44 @@ class ServiceApplicationView extends Component
|
||||
|
||||
public function instantSave()
|
||||
{
|
||||
$this->submit();
|
||||
try {
|
||||
$this->authorize('update', $this->application);
|
||||
$this->submit();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function instantSaveAdvanced()
|
||||
{
|
||||
if (! $this->application->service->destination->server->isLogDrainEnabled()) {
|
||||
$this->application->is_log_drain_enabled = false;
|
||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||
try {
|
||||
$this->authorize('update', $this->application);
|
||||
if (! $this->application->service->destination->server->isLogDrainEnabled()) {
|
||||
$this->application->is_log_drain_enabled = false;
|
||||
$this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.');
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
$this->application->save();
|
||||
$this->dispatch('success', 'You need to restart the service for the changes to take effect.');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
$this->application->save();
|
||||
$this->dispatch('success', 'You need to restart the service for the changes to take effect.');
|
||||
}
|
||||
|
||||
public function delete($password)
|
||||
{
|
||||
if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) {
|
||||
if (! Hash::check($password, Auth::user()->password)) {
|
||||
$this->addError('password', 'The provided password is incorrect.');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->authorize('delete', $this->application);
|
||||
|
||||
if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) {
|
||||
if (! Hash::check($password, Auth::user()->password)) {
|
||||
$this->addError('password', 'The provided password is incorrect.');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->application->delete();
|
||||
$this->dispatch('success', 'Application deleted.');
|
||||
|
||||
@@ -71,12 +86,18 @@ class ServiceApplicationView extends Component
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = get_route_parameters();
|
||||
try {
|
||||
$this->parameters = get_route_parameters();
|
||||
$this->authorize('view', $this->application);
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function convertToDatabase()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->application);
|
||||
$service = $this->application->service;
|
||||
$serviceApplication = $this->application;
|
||||
|
||||
@@ -111,6 +132,7 @@ class ServiceApplicationView extends Component
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->application);
|
||||
$this->application->fqdn = str($this->application->fqdn)->replaceEnd(',', '')->trim();
|
||||
$this->application->fqdn = str($this->application->fqdn)->replaceStart(',', '')->trim();
|
||||
$this->application->fqdn = str($this->application->fqdn)->trim()->explode(',')->map(function ($domain) {
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
namespace App\Livewire\Project\Service;
|
||||
|
||||
use App\Models\LocalPersistentVolume;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class Storage extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public $resource;
|
||||
|
||||
public $fileStorage;
|
||||
@@ -42,6 +45,8 @@ class Storage extends Component
|
||||
public function addNewVolume($data)
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
|
||||
LocalPersistentVolume::create([
|
||||
'name' => $data['name'],
|
||||
'mount_path' => $data['mount_path'],
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
|
||||
namespace App\Livewire\Project\Shared\EnvironmentVariable;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class Add extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public $parameters;
|
||||
|
||||
public bool $shared = false;
|
||||
|
||||
@@ -5,11 +5,12 @@ namespace App\Livewire\Project\Shared\EnvironmentVariable;
|
||||
use App\Models\EnvironmentVariable as ModelsEnvironmentVariable;
|
||||
use App\Models\SharedEnvironmentVariable;
|
||||
use App\Traits\EnvironmentVariableProtection;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class Show extends Component
|
||||
{
|
||||
use EnvironmentVariableProtection;
|
||||
use AuthorizesRequests, EnvironmentVariableProtection;
|
||||
|
||||
public $parameters;
|
||||
|
||||
@@ -75,6 +76,11 @@ class Show extends Component
|
||||
}
|
||||
}
|
||||
|
||||
public function getResourceProperty()
|
||||
{
|
||||
return $this->env->resourceable ?? $this->env;
|
||||
}
|
||||
|
||||
public function refresh()
|
||||
{
|
||||
$this->syncData();
|
||||
@@ -140,6 +146,8 @@ class Show extends Component
|
||||
|
||||
public function lock()
|
||||
{
|
||||
$this->authorize('update', $this->env);
|
||||
|
||||
$this->env->is_shown_once = true;
|
||||
if ($this->isSharedVariable) {
|
||||
unset($this->env->is_required);
|
||||
@@ -158,6 +166,8 @@ class Show extends Component
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->env);
|
||||
|
||||
if (! $this->isSharedVariable && $this->is_required && str($this->value)->isEmpty()) {
|
||||
$oldValue = $this->env->getOriginal('value');
|
||||
$this->value = $oldValue;
|
||||
@@ -179,9 +189,11 @@ class Show extends Component
|
||||
public function delete()
|
||||
{
|
||||
try {
|
||||
$this->authorize('delete', $this->env);
|
||||
|
||||
// Check if the variable is used in Docker Compose
|
||||
if ($this->type === 'service' || $this->type === 'application' && $this->env->resource()?->docker_compose) {
|
||||
[$isUsed, $reason] = $this->isEnvironmentVariableUsedInDockerCompose($this->env->key, $this->env->resource()?->docker_compose);
|
||||
if ($this->type === 'service' || $this->type === 'application' && $this->env->resourceable?->docker_compose) {
|
||||
[$isUsed, $reason] = $this->isEnvironmentVariableUsedInDockerCompose($this->env->key, $this->env->resourceable?->docker_compose);
|
||||
|
||||
if ($isUsed) {
|
||||
$this->dispatch('error', "Cannot delete environment variable '{$this->env->key}' <br><br>Please remove it from the Docker Compose file first.");
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
|
||||
namespace App\Livewire\Project\Shared;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class HealthChecks extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public $resource;
|
||||
|
||||
protected $rules = [
|
||||
@@ -27,6 +30,7 @@ class HealthChecks extends Component
|
||||
|
||||
public function instantSave()
|
||||
{
|
||||
$this->authorize('update', $this->resource);
|
||||
$this->resource->save();
|
||||
$this->dispatch('success', 'Health check updated.');
|
||||
}
|
||||
@@ -34,6 +38,7 @@ class HealthChecks extends Component
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
$this->validate();
|
||||
$this->resource->save();
|
||||
$this->dispatch('success', 'Health check updated.');
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
|
||||
namespace App\Livewire\Project\Shared;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class ResourceLimits extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public $resource;
|
||||
|
||||
protected $rules = [
|
||||
@@ -31,6 +34,7 @@ class ResourceLimits extends Component
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
if (! $this->resource->limits_memory) {
|
||||
$this->resource->limits_memory = '0';
|
||||
}
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
namespace App\Livewire\Project\Shared\ScheduledTask;
|
||||
|
||||
use App\Models\ScheduledTask;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Collection;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Component;
|
||||
|
||||
class Add extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public $parameters;
|
||||
|
||||
#[Locked]
|
||||
@@ -20,6 +23,9 @@ class Add extends Component
|
||||
#[Locked]
|
||||
public Collection $containerNames;
|
||||
|
||||
#[Locked]
|
||||
public $resource;
|
||||
|
||||
public string $name;
|
||||
|
||||
public string $command;
|
||||
@@ -45,6 +51,22 @@ class Add extends Component
|
||||
public function mount()
|
||||
{
|
||||
$this->parameters = get_route_parameters();
|
||||
|
||||
// Get the resource based on type and id
|
||||
switch ($this->type) {
|
||||
case 'application':
|
||||
$this->resource = \App\Models\Application::findOrFail($this->id);
|
||||
break;
|
||||
case 'service':
|
||||
$this->resource = \App\Models\Service::findOrFail($this->id);
|
||||
break;
|
||||
case 'standalone-postgresql':
|
||||
$this->resource = \App\Models\StandalonePostgresql::findOrFail($this->id);
|
||||
break;
|
||||
default:
|
||||
throw new \Exception('Invalid resource type');
|
||||
}
|
||||
|
||||
if ($this->containerNames->count() > 0) {
|
||||
$this->container = $this->containerNames->first();
|
||||
}
|
||||
@@ -53,6 +75,7 @@ class Add extends Component
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
$this->validate();
|
||||
$isValid = validate_cron_expression($this->frequency);
|
||||
if (! $isValid) {
|
||||
|
||||
@@ -6,12 +6,15 @@ use App\Jobs\ScheduledTaskJob;
|
||||
use App\Models\Application;
|
||||
use App\Models\ScheduledTask;
|
||||
use App\Models\Service;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
class Show extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public Application|Service $resource;
|
||||
|
||||
public ScheduledTask $task;
|
||||
@@ -109,6 +112,7 @@ class Show extends Component
|
||||
public function instantSave()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
$this->syncData(true);
|
||||
$this->dispatch('success', 'Scheduled task updated.');
|
||||
$this->refreshTasks();
|
||||
@@ -120,6 +124,7 @@ class Show extends Component
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
$this->syncData(true);
|
||||
$this->dispatch('success', 'Scheduled task updated.');
|
||||
} catch (\Exception $e) {
|
||||
@@ -139,6 +144,7 @@ class Show extends Component
|
||||
public function delete()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
$this->task->delete();
|
||||
|
||||
if ($this->type === 'application') {
|
||||
@@ -154,6 +160,7 @@ class Show extends Component
|
||||
public function executeNow()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
ScheduledTaskJob::dispatch($this->task);
|
||||
$this->dispatch('success', 'Scheduled task executed.');
|
||||
} catch (\Exception $e) {
|
||||
|
||||
@@ -4,10 +4,13 @@ namespace App\Livewire\Project\Shared\Storages;
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\LocalFileVolume;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class Add extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public $resource;
|
||||
|
||||
public $uuid;
|
||||
@@ -77,6 +80,8 @@ class Add extends Component
|
||||
public function submitFileStorage()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
|
||||
$this->validate([
|
||||
'file_storage_path' => 'string',
|
||||
'file_storage_content' => 'nullable|string',
|
||||
@@ -112,6 +117,8 @@ class Add extends Component
|
||||
public function submitFileStorageDirectory()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
|
||||
$this->validate([
|
||||
'file_storage_directory_source' => 'string',
|
||||
'file_storage_directory_destination' => 'string',
|
||||
@@ -140,6 +147,8 @@ class Add extends Component
|
||||
public function submitPersistentVolume()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
|
||||
$this->validate([
|
||||
'name' => 'required|string',
|
||||
'mount_path' => 'required|string',
|
||||
|
||||
@@ -4,14 +4,19 @@ namespace App\Livewire\Project\Shared\Storages;
|
||||
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\LocalPersistentVolume;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Livewire\Component;
|
||||
|
||||
class Show extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public LocalPersistentVolume $storage;
|
||||
|
||||
public $resource;
|
||||
|
||||
public bool $isReadOnly = false;
|
||||
|
||||
public bool $isFirst = true;
|
||||
@@ -34,6 +39,8 @@ class Show extends Component
|
||||
|
||||
public function submit()
|
||||
{
|
||||
$this->authorize('update', $this->resource);
|
||||
|
||||
$this->validate();
|
||||
$this->storage->save();
|
||||
$this->dispatch('success', 'Storage updated successfully');
|
||||
@@ -41,6 +48,8 @@ class Show extends Component
|
||||
|
||||
public function delete($password)
|
||||
{
|
||||
$this->authorize('update', $this->resource);
|
||||
|
||||
if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) {
|
||||
if (! Hash::check($password, Auth::user()->password)) {
|
||||
$this->addError('password', 'The provided password is incorrect.');
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
namespace App\Livewire\Project\Shared;
|
||||
|
||||
use App\Models\Tag;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
// Refactored ✅
|
||||
class Tags extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public $resource = null;
|
||||
|
||||
#[Validate('required|string|min:2')]
|
||||
@@ -34,6 +37,7 @@ class Tags extends Component
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
$this->validate();
|
||||
$tags = str($this->newTags)->trim()->explode(' ');
|
||||
foreach ($tags as $tag) {
|
||||
@@ -66,6 +70,7 @@ class Tags extends Component
|
||||
public function addTag(string $id, string $name)
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
$name = strip_tags($name);
|
||||
if ($this->resource->tags()->where('id', $id)->exists()) {
|
||||
$this->dispatch('error', 'Duplicate tags.', "Tag <span class='dark:text-warning'>$name</span> already added.");
|
||||
@@ -83,6 +88,7 @@ class Tags extends Component
|
||||
public function deleteTag(string $id)
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
$this->resource->tags()->detach($id);
|
||||
$found_more_tags = Tag::ownedByCurrentTeam()->find($id);
|
||||
if ($found_more_tags && $found_more_tags->applications()->count() == 0 && $found_more_tags->services()->count() == 0) {
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
|
||||
namespace App\Livewire\Project\Shared;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
// Refactored ✅
|
||||
class Webhooks extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public $resource;
|
||||
|
||||
public ?string $deploywebhook;
|
||||
|
||||
@@ -3,10 +3,14 @@
|
||||
namespace App\Livewire\Security;
|
||||
|
||||
use App\Models\InstanceSettings;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Laravel\Sanctum\PersonalAccessToken;
|
||||
use Livewire\Component;
|
||||
|
||||
class ApiTokens extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public ?string $description = null;
|
||||
|
||||
public $tokens = [];
|
||||
@@ -15,6 +19,10 @@ class ApiTokens extends Component
|
||||
|
||||
public $isApiEnabled;
|
||||
|
||||
public bool $canUseRootPermissions = false;
|
||||
|
||||
public bool $canUseWritePermissions = false;
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.security.api-tokens');
|
||||
@@ -23,6 +31,8 @@ class ApiTokens extends Component
|
||||
public function mount()
|
||||
{
|
||||
$this->isApiEnabled = InstanceSettings::get()->is_api_enabled;
|
||||
$this->canUseRootPermissions = auth()->user()->can('useRootPermissions', PersonalAccessToken::class);
|
||||
$this->canUseWritePermissions = auth()->user()->can('useWritePermissions', PersonalAccessToken::class);
|
||||
$this->getTokens();
|
||||
}
|
||||
|
||||
@@ -33,6 +43,23 @@ class ApiTokens extends Component
|
||||
|
||||
public function updatedPermissions($permissionToUpdate)
|
||||
{
|
||||
// Check if user is trying to use restricted permissions
|
||||
if ($permissionToUpdate == 'root' && ! $this->canUseRootPermissions) {
|
||||
$this->dispatch('error', 'You do not have permission to use root permissions.');
|
||||
// Remove root from permissions if it was somehow added
|
||||
$this->permissions = array_diff($this->permissions, ['root']);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (in_array($permissionToUpdate, ['write', 'write:sensitive']) && ! $this->canUseWritePermissions) {
|
||||
$this->dispatch('error', 'You do not have permission to use write permissions.');
|
||||
// Remove write permissions if they were somehow added
|
||||
$this->permissions = array_diff($this->permissions, ['write', 'write:sensitive']);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($permissionToUpdate == 'root') {
|
||||
$this->permissions = ['root'];
|
||||
} elseif ($permissionToUpdate == 'read:sensitive' && ! in_array('read', $this->permissions)) {
|
||||
@@ -50,6 +77,17 @@ class ApiTokens extends Component
|
||||
public function addNewToken()
|
||||
{
|
||||
try {
|
||||
$this->authorize('create', PersonalAccessToken::class);
|
||||
|
||||
// Validate permissions based on user role
|
||||
if (in_array('root', $this->permissions) && ! $this->canUseRootPermissions) {
|
||||
throw new \Exception('You do not have permission to create tokens with root permissions.');
|
||||
}
|
||||
|
||||
if (array_intersect(['write', 'write:sensitive'], $this->permissions) && ! $this->canUseWritePermissions) {
|
||||
throw new \Exception('You do not have permission to create tokens with write permissions.');
|
||||
}
|
||||
|
||||
$this->validate([
|
||||
'description' => 'required|min:3|max:255',
|
||||
]);
|
||||
@@ -65,6 +103,7 @@ class ApiTokens extends Component
|
||||
{
|
||||
try {
|
||||
$token = auth()->user()->tokens()->where('id', $id)->firstOrFail();
|
||||
$this->authorize('delete', $token);
|
||||
$token->delete();
|
||||
$this->getTokens();
|
||||
} catch (\Exception $e) {
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
namespace App\Livewire\Security\PrivateKey;
|
||||
|
||||
use App\Models\PrivateKey;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class Index extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public function render()
|
||||
{
|
||||
$privateKeys = PrivateKey::ownedByCurrentTeam(['name', 'uuid', 'is_git_related', 'description'])->get();
|
||||
@@ -18,6 +21,7 @@ class Index extends Component
|
||||
|
||||
public function cleanupUnusedKeys()
|
||||
{
|
||||
$this->authorize('create', PrivateKey::class);
|
||||
PrivateKey::cleanupUnusedKeys();
|
||||
$this->dispatch('success', 'Unused keys have been cleaned up.');
|
||||
}
|
||||
|
||||
@@ -3,12 +3,17 @@
|
||||
namespace App\Livewire\Server\Proxy;
|
||||
|
||||
use App\Models\Server;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class DynamicConfigurationNavbar extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public $server_id;
|
||||
|
||||
public Server $server;
|
||||
|
||||
public $fileName = '';
|
||||
|
||||
public $value = '';
|
||||
@@ -17,18 +22,18 @@ class DynamicConfigurationNavbar extends Component
|
||||
|
||||
public function delete(string $fileName)
|
||||
{
|
||||
$server = Server::ownedByCurrentTeam()->whereId($this->server_id)->first();
|
||||
$proxy_path = $server->proxyPath();
|
||||
$proxy_type = $server->proxyType();
|
||||
$this->authorize('update', $this->server);
|
||||
$proxy_path = $this->server->proxyPath();
|
||||
$proxy_type = $this->server->proxyType();
|
||||
$file = str_replace('|', '.', $fileName);
|
||||
if ($proxy_type === 'CADDY' && $file === 'Caddyfile') {
|
||||
$this->dispatch('error', 'Cannot delete Caddyfile.');
|
||||
|
||||
return;
|
||||
}
|
||||
instant_remote_process(["rm -f {$proxy_path}/dynamic/{$file}"], $server);
|
||||
instant_remote_process(["rm -f {$proxy_path}/dynamic/{$file}"], $this->server);
|
||||
if ($proxy_type === 'CADDY') {
|
||||
$server->reloadCaddy();
|
||||
$this->server->reloadCaddy();
|
||||
}
|
||||
$this->dispatch('success', 'File deleted.');
|
||||
$this->dispatch('loadDynamicConfigurations');
|
||||
|
||||
@@ -4,10 +4,13 @@ namespace App\Livewire\SharedVariables\Environment;
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\Project;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class Show extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public Project $project;
|
||||
|
||||
public Application $application;
|
||||
@@ -21,6 +24,8 @@ class Show extends Component
|
||||
public function saveKey($data)
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->environment);
|
||||
|
||||
$found = $this->environment->environment_variables()->where('key', $data['key'])->first();
|
||||
if ($found) {
|
||||
throw new \Exception('Variable already exists.');
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
namespace App\Livewire\SharedVariables\Project;
|
||||
|
||||
use App\Models\Project;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class Show extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public Project $project;
|
||||
|
||||
protected $listeners = ['refreshEnvs' => '$refresh', 'saveKey' => 'saveKey', 'environmentVariableDeleted' => '$refresh'];
|
||||
@@ -14,6 +17,8 @@ class Show extends Component
|
||||
public function saveKey($data)
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->project);
|
||||
|
||||
$found = $this->project->environment_variables()->where('key', $data['key'])->first();
|
||||
if ($found) {
|
||||
throw new \Exception('Variable already exists.');
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
namespace App\Livewire\SharedVariables\Team;
|
||||
|
||||
use App\Models\Team;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class Index extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public Team $team;
|
||||
|
||||
protected $listeners = ['refreshEnvs' => '$refresh', 'saveKey' => 'saveKey', 'environmentVariableDeleted' => '$refresh'];
|
||||
@@ -14,6 +17,8 @@ class Index extends Component
|
||||
public function saveKey($data)
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->team);
|
||||
|
||||
$found = $this->team->environment_variables()->where('key', $data['key'])->first();
|
||||
if ($found) {
|
||||
throw new \Exception('Variable already exists.');
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Livewire\Source\Github;
|
||||
use App\Jobs\GithubAppPermissionJob;
|
||||
use App\Models\GithubApp;
|
||||
use App\Models\PrivateKey;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Lcobucci\JWT\Configuration;
|
||||
use Lcobucci\JWT\Signer\Key\InMemory;
|
||||
@@ -13,7 +14,9 @@ use Livewire\Component;
|
||||
|
||||
class Change extends Component
|
||||
{
|
||||
public string $webhook_endpoint;
|
||||
use AuthorizesRequests;
|
||||
|
||||
public string $webhook_endpoint = '';
|
||||
|
||||
public ?string $ipv4 = null;
|
||||
|
||||
@@ -69,6 +72,8 @@ class Change extends Component
|
||||
public function checkPermissions()
|
||||
{
|
||||
try {
|
||||
$this->authorize('view', $this->github_app);
|
||||
|
||||
GithubAppPermissionJob::dispatchSync($this->github_app);
|
||||
$this->github_app->refresh()->makeVisible('client_secret')->makeVisible('webhook_secret');
|
||||
$this->dispatch('success', 'Github App permissions updated.');
|
||||
@@ -155,7 +160,7 @@ class Change extends Component
|
||||
if (isCloud() && ! isDev()) {
|
||||
$this->webhook_endpoint = config('app.url');
|
||||
} else {
|
||||
$this->webhook_endpoint = $this->ipv4;
|
||||
$this->webhook_endpoint = $this->ipv4 ?? '';
|
||||
$this->is_system_wide = $this->github_app->is_system_wide;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
@@ -195,6 +200,8 @@ class Change extends Component
|
||||
public function updateGithubAppName()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->github_app);
|
||||
|
||||
$privateKey = PrivateKey::ownedByCurrentTeam()->find($this->github_app->private_key_id);
|
||||
|
||||
if (! $privateKey) {
|
||||
@@ -237,6 +244,8 @@ class Change extends Component
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->github_app);
|
||||
|
||||
$this->github_app->makeVisible('client_secret')->makeVisible('webhook_secret');
|
||||
$this->validate([
|
||||
'github_app.name' => 'required|string',
|
||||
@@ -262,6 +271,8 @@ class Change extends Component
|
||||
|
||||
public function createGithubAppManually()
|
||||
{
|
||||
$this->authorize('update', $this->github_app);
|
||||
|
||||
$this->github_app->makeVisible('client_secret')->makeVisible('webhook_secret');
|
||||
$this->github_app->app_id = '1234567890';
|
||||
$this->github_app->installation_id = '1234567890';
|
||||
@@ -272,6 +283,8 @@ class Change extends Component
|
||||
public function instantSave()
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->github_app);
|
||||
|
||||
$this->github_app->makeVisible('client_secret')->makeVisible('webhook_secret');
|
||||
$this->github_app->save();
|
||||
$this->dispatch('success', 'Github App updated.');
|
||||
@@ -283,6 +296,8 @@ class Change extends Component
|
||||
public function delete()
|
||||
{
|
||||
try {
|
||||
$this->authorize('delete', $this->github_app);
|
||||
|
||||
if ($this->github_app->applications->isNotEmpty()) {
|
||||
$this->dispatch('error', 'This source is being used by an application. Please delete all applications first.');
|
||||
$this->github_app->makeVisible('client_secret')->makeVisible('webhook_secret');
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
namespace App\Livewire\Source\Github;
|
||||
|
||||
use App\Models\GithubApp;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class Create extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public string $name;
|
||||
|
||||
public ?string $organization = null;
|
||||
@@ -29,6 +32,8 @@ class Create extends Component
|
||||
public function createGitHubApp()
|
||||
{
|
||||
try {
|
||||
$this->authorize('createAnyResource');
|
||||
|
||||
$this->validate([
|
||||
'name' => 'required|string',
|
||||
'organization' => 'nullable|string',
|
||||
|
||||
@@ -4,11 +4,14 @@ namespace App\Livewire\Storage;
|
||||
|
||||
use App\Models\S3Storage;
|
||||
use App\Support\ValidationPatterns;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Uri;
|
||||
use Livewire\Component;
|
||||
|
||||
class Create extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public string $name;
|
||||
|
||||
public string $description;
|
||||
@@ -94,6 +97,8 @@ class Create extends Component
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
$this->authorize('create', S3Storage::class);
|
||||
|
||||
$this->validate();
|
||||
$this->storage = new S3Storage;
|
||||
$this->storage->name = $this->name;
|
||||
|
||||
@@ -4,10 +4,13 @@ namespace App\Livewire\Storage;
|
||||
|
||||
use App\Models\S3Storage;
|
||||
use App\Support\ValidationPatterns;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class Form extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public S3Storage $storage;
|
||||
|
||||
protected function rules(): array
|
||||
@@ -60,6 +63,8 @@ class Form extends Component
|
||||
public function testConnection()
|
||||
{
|
||||
try {
|
||||
$this->authorize('validateConnection', $this->storage);
|
||||
|
||||
$this->storage->testConnection(shouldSave: true);
|
||||
|
||||
return $this->dispatch('success', 'Connection is working.', 'Tested with "ListObjectsV2" action.');
|
||||
@@ -83,8 +88,10 @@ class Form extends Component
|
||||
|
||||
public function submit()
|
||||
{
|
||||
$this->validate();
|
||||
try {
|
||||
$this->authorize('update', $this->storage);
|
||||
|
||||
$this->validate();
|
||||
$this->testConnection();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
|
||||
@@ -5,12 +5,15 @@ namespace App\Livewire\Team;
|
||||
use App\Models\Team;
|
||||
use App\Models\TeamInvitation;
|
||||
use App\Support\ValidationPatterns;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Livewire\Component;
|
||||
|
||||
class Index extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public $invitations = [];
|
||||
|
||||
public Team $team;
|
||||
@@ -58,6 +61,7 @@ class Index extends Component
|
||||
{
|
||||
$this->validate();
|
||||
try {
|
||||
$this->authorize('update', $this->team);
|
||||
$this->team->save();
|
||||
refreshSession();
|
||||
$this->dispatch('success', 'Team updated.');
|
||||
@@ -69,6 +73,7 @@ class Index extends Component
|
||||
public function delete()
|
||||
{
|
||||
$currentTeam = currentTeam();
|
||||
$this->authorize('delete', $currentTeam);
|
||||
$currentTeam->delete();
|
||||
|
||||
$currentTeam->members->each(function ($user) use ($currentTeam) {
|
||||
|
||||
@@ -4,10 +4,13 @@ namespace App\Livewire\Team;
|
||||
|
||||
use App\Models\TeamInvitation;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class Invitations extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public $invitations;
|
||||
|
||||
protected $listeners = ['refreshInvitations'];
|
||||
@@ -15,6 +18,8 @@ class Invitations extends Component
|
||||
public function deleteInvitation(int $invitation_id)
|
||||
{
|
||||
try {
|
||||
$this->authorize('manageInvitations', currentTeam());
|
||||
|
||||
$invitation = TeamInvitation::ownedByCurrentTeam()->findOrFail($invitation_id);
|
||||
$user = User::whereEmail($invitation->email)->first();
|
||||
if (filled($user)) {
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Livewire\Team;
|
||||
|
||||
use App\Models\TeamInvitation;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
@@ -13,6 +14,8 @@ use Visus\Cuid2\Cuid2;
|
||||
|
||||
class InviteLink extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public string $email;
|
||||
|
||||
public string $role = 'member';
|
||||
@@ -40,6 +43,7 @@ class InviteLink extends Component
|
||||
private function generateInviteLink(bool $sendEmail = false)
|
||||
{
|
||||
try {
|
||||
$this->authorize('manageInvitations', currentTeam());
|
||||
$this->validate();
|
||||
if (auth()->user()->role() === 'admin' && $this->role === 'owner') {
|
||||
throw new \Exception('Admins cannot invite owners.');
|
||||
|
||||
@@ -4,16 +4,21 @@ namespace App\Livewire\Team;
|
||||
|
||||
use App\Enums\Role;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Livewire\Component;
|
||||
|
||||
class Member extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public User $member;
|
||||
|
||||
public function makeAdmin()
|
||||
{
|
||||
try {
|
||||
$this->authorize('manageMembers', currentTeam());
|
||||
|
||||
if (Role::from(auth()->user()->role())->lt(Role::ADMIN)
|
||||
|| Role::from($this->getMemberRole())->gt(auth()->user()->role())) {
|
||||
throw new \Exception('You are not authorized to perform this action.');
|
||||
@@ -28,6 +33,8 @@ class Member extends Component
|
||||
public function makeOwner()
|
||||
{
|
||||
try {
|
||||
$this->authorize('manageMembers', currentTeam());
|
||||
|
||||
if (Role::from(auth()->user()->role())->lt(Role::OWNER)
|
||||
|| Role::from($this->getMemberRole())->gt(auth()->user()->role())) {
|
||||
throw new \Exception('You are not authorized to perform this action.');
|
||||
@@ -42,6 +49,8 @@ class Member extends Component
|
||||
public function makeReadonly()
|
||||
{
|
||||
try {
|
||||
$this->authorize('manageMembers', currentTeam());
|
||||
|
||||
if (Role::from(auth()->user()->role())->lt(Role::ADMIN)
|
||||
|| Role::from($this->getMemberRole())->gt(auth()->user()->role())) {
|
||||
throw new \Exception('You are not authorized to perform this action.');
|
||||
@@ -56,6 +65,8 @@ class Member extends Component
|
||||
public function remove()
|
||||
{
|
||||
try {
|
||||
$this->authorize('manageMembers', currentTeam());
|
||||
|
||||
if (Role::from(auth()->user()->role())->lt(Role::ADMIN)
|
||||
|| Role::from($this->getMemberRole())->gt(auth()->user()->role())) {
|
||||
throw new \Exception('You are not authorized to perform this action.');
|
||||
|
||||
@@ -3,15 +3,19 @@
|
||||
namespace App\Livewire\Team\Member;
|
||||
|
||||
use App\Models\TeamInvitation;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
class Index extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
public $invitations = [];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
if (auth()->user()->isAdminFromSession()) {
|
||||
// Only load invitations for users who can manage them
|
||||
if (auth()->user()->can('manageInvitations', currentTeam())) {
|
||||
$this->invitations = TeamInvitation::whereTeamId(currentTeam()->id)->get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ class Index extends Component
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->authorize('useTerminal', Server::class);
|
||||
$this->servers = Server::isReachable()->get()->filter(function ($server) {
|
||||
return $server->isTerminalEnabled();
|
||||
});
|
||||
|
||||
@@ -12,4 +12,19 @@ class SharedEnvironmentVariable extends Model
|
||||
'key' => 'string',
|
||||
'value' => 'encrypted',
|
||||
];
|
||||
|
||||
public function team()
|
||||
{
|
||||
return $this->belongsTo(Team::class);
|
||||
}
|
||||
|
||||
public function project()
|
||||
{
|
||||
return $this->belongsTo(Project::class);
|
||||
}
|
||||
|
||||
public function environment()
|
||||
{
|
||||
return $this->belongsTo(Environment::class);
|
||||
}
|
||||
}
|
||||
|
||||
109
app/Policies/ApiTokenPolicy.php
Normal file
109
app/Policies/ApiTokenPolicy.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use Laravel\Sanctum\PersonalAccessToken;
|
||||
|
||||
class ApiTokenPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any API tokens.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
// Users can view their own API tokens
|
||||
return true;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the API token.
|
||||
*/
|
||||
public function view(User $user, PersonalAccessToken $token): bool
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
// Users can only view their own tokens
|
||||
return $user->id === $token->tokenable_id && $token->tokenable_type === User::class;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create API tokens.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
// All authenticated users can create their own API tokens
|
||||
return true;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the API token.
|
||||
*/
|
||||
public function update(User $user, PersonalAccessToken $token): bool
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
// Users can only update their own tokens
|
||||
return $user->id === $token->tokenable_id && $token->tokenable_type === User::class;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the API token.
|
||||
*/
|
||||
public function delete(User $user, PersonalAccessToken $token): bool
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
// Users can only delete their own tokens
|
||||
return $user->id === $token->tokenable_id && $token->tokenable_type === User::class;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can manage their own API tokens.
|
||||
*/
|
||||
public function manage(User $user): bool
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
// All authenticated users can manage their own API tokens
|
||||
return true;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can use root permissions for API tokens.
|
||||
*/
|
||||
public function useRootPermissions(User $user): bool
|
||||
{
|
||||
// Only admins and owners can use root permissions
|
||||
return $user->isAdmin() || $user->isOwner();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can use write permissions for API tokens.
|
||||
*/
|
||||
public function useWritePermissions(User $user): bool
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
// Only admins and owners can use write permissions
|
||||
return $user->isAdmin() || $user->isOwner();
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,10 @@ class ApplicationPolicy
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
return true;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,6 +25,10 @@ class ApplicationPolicy
|
||||
*/
|
||||
public function view(User $user, Application $application): bool
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
return true;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,11 +37,15 @@ class ApplicationPolicy
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,11 +53,15 @@ class ApplicationPolicy
|
||||
*/
|
||||
public function update(User $user, Application $application): Response
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
if ($user->isAdmin()) {
|
||||
return Response::allow();
|
||||
}
|
||||
|
||||
return Response::deny('As a member, you cannot update this application.<br/><br/>You need at least admin or owner permissions.');
|
||||
*/
|
||||
return Response::allow();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,11 +69,15 @@ class ApplicationPolicy
|
||||
*/
|
||||
public function delete(User $user, Application $application): bool
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,6 +85,10 @@ class ApplicationPolicy
|
||||
*/
|
||||
public function restore(User $user, Application $application): bool
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
return true;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -73,7 +97,11 @@ class ApplicationPolicy
|
||||
*/
|
||||
public function forceDelete(User $user, Application $application): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $application->team()->first()->id) !== null;
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
return $user->isAdmin() && $user->teams->contains('id', $application->team()->first()->id);
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,7 +109,11 @@ class ApplicationPolicy
|
||||
*/
|
||||
public function deploy(User $user, Application $application): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $application->team()->first()->id) !== null;
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
return $user->teams->contains('id', $application->team()->first()->id);
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +121,11 @@ class ApplicationPolicy
|
||||
*/
|
||||
public function manageDeployments(User $user, Application $application): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $application->team()->first()->id) !== null;
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
return $user->isAdmin() && $user->teams->contains('id', $application->team()->first()->id);
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,7 +133,11 @@ class ApplicationPolicy
|
||||
*/
|
||||
public function manageEnvironment(User $user, Application $application): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $application->team()->first()->id) !== null;
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
return $user->isAdmin() && $user->teams->contains('id', $application->team()->first()->id);
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,6 +145,10 @@ class ApplicationPolicy
|
||||
*/
|
||||
public function cleanupDeploymentQueue(User $user): bool
|
||||
{
|
||||
// Authorization temporarily disabled
|
||||
/*
|
||||
return $user->isAdmin();
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@ class ApplicationPreviewPolicy
|
||||
*/
|
||||
public function view(User $user, ApplicationPreview $applicationPreview): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $applicationPreview->application->team()->first()->id) !== null;
|
||||
// return $user->teams->contains('id', $applicationPreview->application->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,7 +30,8 @@ class ApplicationPreviewPolicy
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->isAdmin();
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,11 +39,12 @@ class ApplicationPreviewPolicy
|
||||
*/
|
||||
public function update(User $user, ApplicationPreview $applicationPreview): Response
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return Response::allow();
|
||||
}
|
||||
// if ($user->isAdmin()) {
|
||||
// return Response::allow();
|
||||
// }
|
||||
|
||||
return Response::deny('As a member, you cannot update this preview.<br/><br/>You need at least admin or owner permissions.');
|
||||
// return Response::deny('As a member, you cannot update this preview.<br/><br/>You need at least admin or owner permissions.');
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +52,8 @@ class ApplicationPreviewPolicy
|
||||
*/
|
||||
public function delete(User $user, ApplicationPreview $applicationPreview): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $applicationPreview->application->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $applicationPreview->application->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,7 +61,8 @@ class ApplicationPreviewPolicy
|
||||
*/
|
||||
public function restore(User $user, ApplicationPreview $applicationPreview): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $applicationPreview->application->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $applicationPreview->application->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +70,8 @@ class ApplicationPreviewPolicy
|
||||
*/
|
||||
public function forceDelete(User $user, ApplicationPreview $applicationPreview): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $applicationPreview->application->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $applicationPreview->application->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +79,8 @@ class ApplicationPreviewPolicy
|
||||
*/
|
||||
public function deploy(User $user, ApplicationPreview $applicationPreview): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $applicationPreview->application->team()->first()->id) !== null;
|
||||
// return $user->teams->contains('id', $applicationPreview->application->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,6 +88,7 @@ class ApplicationPreviewPolicy
|
||||
*/
|
||||
public function manageDeployments(User $user, ApplicationPreview $applicationPreview): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $applicationPreview->application->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $applicationPreview->application->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ class ApplicationSettingPolicy
|
||||
*/
|
||||
public function view(User $user, ApplicationSetting $applicationSetting): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $applicationSetting->application->team()->first()->id) !== null;
|
||||
// return $user->teams->contains('id', $applicationSetting->application->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,8 @@ class ApplicationSettingPolicy
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->isAdmin();
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +38,8 @@ class ApplicationSettingPolicy
|
||||
*/
|
||||
public function update(User $user, ApplicationSetting $applicationSetting): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $applicationSetting->application->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $applicationSetting->application->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +47,8 @@ class ApplicationSettingPolicy
|
||||
*/
|
||||
public function delete(User $user, ApplicationSetting $applicationSetting): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $applicationSetting->application->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $applicationSetting->application->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +56,8 @@ class ApplicationSettingPolicy
|
||||
*/
|
||||
public function restore(User $user, ApplicationSetting $applicationSetting): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $applicationSetting->application->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $applicationSetting->application->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,6 +65,7 @@ class ApplicationSettingPolicy
|
||||
*/
|
||||
public function forceDelete(User $user, ApplicationSetting $applicationSetting): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $applicationSetting->application->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $applicationSetting->application->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ class DatabasePolicy
|
||||
*/
|
||||
public function view(User $user, $database): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||
// return $user->teams->contains('id', $database->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,8 @@ class DatabasePolicy
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->isAdmin();
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,11 +38,12 @@ class DatabasePolicy
|
||||
*/
|
||||
public function update(User $user, $database): Response
|
||||
{
|
||||
if ($user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null) {
|
||||
return Response::allow();
|
||||
}
|
||||
// if ($user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id)) {
|
||||
// return Response::allow();
|
||||
// }
|
||||
|
||||
return Response::deny('As a member, you cannot update this database.<br/><br/>You need at least admin or owner permissions.');
|
||||
// return Response::deny('As a member, you cannot update this database.<br/><br/>You need at least admin or owner permissions.');
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,7 +51,8 @@ class DatabasePolicy
|
||||
*/
|
||||
public function delete(User $user, $database): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,7 +60,8 @@ class DatabasePolicy
|
||||
*/
|
||||
public function restore(User $user, $database): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,7 +69,8 @@ class DatabasePolicy
|
||||
*/
|
||||
public function forceDelete(User $user, $database): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,7 +78,8 @@ class DatabasePolicy
|
||||
*/
|
||||
public function manage(User $user, $database): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +87,8 @@ class DatabasePolicy
|
||||
*/
|
||||
public function manageBackups(User $user, $database): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,6 +96,7 @@ class DatabasePolicy
|
||||
*/
|
||||
public function manageEnvironment(User $user, $database): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $database->team()->first()->id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ class EnvironmentPolicy
|
||||
*/
|
||||
public function view(User $user, Environment $environment): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $environment->project->team_id) !== null;
|
||||
// return $user->teams->contains('id', $environment->project->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,8 @@ class EnvironmentPolicy
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->isAdmin();
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +38,8 @@ class EnvironmentPolicy
|
||||
*/
|
||||
public function update(User $user, Environment $environment): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $environment->project->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $environment->project->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +47,8 @@ class EnvironmentPolicy
|
||||
*/
|
||||
public function delete(User $user, Environment $environment): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $environment->project->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $environment->project->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +56,8 @@ class EnvironmentPolicy
|
||||
*/
|
||||
public function restore(User $user, Environment $environment): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $environment->project->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $environment->project->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,6 +65,7 @@ class EnvironmentPolicy
|
||||
*/
|
||||
public function forceDelete(User $user, Environment $environment): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $environment->project->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $environment->project->team_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
79
app/Policies/GithubAppPolicy.php
Normal file
79
app/Policies/GithubAppPolicy.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\GithubApp;
|
||||
use App\Models\User;
|
||||
|
||||
class GithubAppPolicy
|
||||
{
|
||||
/**
|
||||
* 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, GithubApp $githubApp): bool
|
||||
{
|
||||
// return $user->teams->contains('id', $githubApp->team_id) || $githubApp->is_system_wide;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, GithubApp $githubApp): bool
|
||||
{
|
||||
if ($githubApp->is_system_wide) {
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $githubApp->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, GithubApp $githubApp): bool
|
||||
{
|
||||
if ($githubApp->is_system_wide) {
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $githubApp->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, GithubApp $githubApp): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, GithubApp $githubApp): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
56
app/Policies/NotificationPolicy.php
Normal file
56
app/Policies/NotificationPolicy.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class NotificationPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view the notification settings.
|
||||
*/
|
||||
public function view(User $user, Model $notificationSettings): bool
|
||||
{
|
||||
// Check if the notification settings belong to the user's current team
|
||||
if (! $notificationSettings->team) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return $user->teams()->where('teams.id', $notificationSettings->team->id)->exists();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the notification settings.
|
||||
*/
|
||||
public function update(User $user, Model $notificationSettings): bool
|
||||
{
|
||||
// Check if the notification settings belong to the user's current team
|
||||
if (! $notificationSettings->team) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only owners and admins can update notification settings
|
||||
// return $user->isAdmin() || $user->isOwner();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can manage (create, update, delete) notification settings.
|
||||
*/
|
||||
public function manage(User $user, Model $notificationSettings): bool
|
||||
{
|
||||
// return $this->update($user, $notificationSettings);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can send test notifications.
|
||||
*/
|
||||
public function sendTest(User $user, Model $notificationSettings): bool
|
||||
{
|
||||
// return $this->update($user, $notificationSettings);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,8 @@ class PrivateKeyPolicy
|
||||
*/
|
||||
public function view(User $user, PrivateKey $privateKey): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $privateKey->team_id) !== null;
|
||||
// return $user->teams->contains('id', $privateKey->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,8 @@ class PrivateKeyPolicy
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->isAdmin();
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +38,8 @@ class PrivateKeyPolicy
|
||||
*/
|
||||
public function update(User $user, PrivateKey $privateKey): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $privateKey->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $privateKey->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +47,8 @@ class PrivateKeyPolicy
|
||||
*/
|
||||
public function delete(User $user, PrivateKey $privateKey): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $privateKey->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $privateKey->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,8 @@ class ProjectPolicy
|
||||
*/
|
||||
public function view(User $user, Project $project): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $project->team_id) !== null;
|
||||
// return $user->teams->contains('id', $project->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,8 @@ class ProjectPolicy
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->isAdmin();
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +38,8 @@ class ProjectPolicy
|
||||
*/
|
||||
public function update(User $user, Project $project): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $project->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $project->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +47,8 @@ class ProjectPolicy
|
||||
*/
|
||||
public function delete(User $user, Project $project): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $project->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $project->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +56,8 @@ class ProjectPolicy
|
||||
*/
|
||||
public function restore(User $user, Project $project): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $project->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $project->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,6 +65,7 @@ class ProjectPolicy
|
||||
*/
|
||||
public function forceDelete(User $user, Project $project): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $project->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $project->team_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ class ResourceCreatePolicy
|
||||
StandaloneClickhouse::class,
|
||||
Service::class,
|
||||
Application::class,
|
||||
GithubApp::class,
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -37,7 +38,8 @@ class ResourceCreatePolicy
|
||||
*/
|
||||
public function createAny(User $user): bool
|
||||
{
|
||||
return $user->isAdmin();
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +51,8 @@ class ResourceCreatePolicy
|
||||
return false;
|
||||
}
|
||||
|
||||
return $user->isAdmin();
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\S3Storage;
|
||||
use App\Models\Server;
|
||||
use App\Models\User;
|
||||
|
||||
class S3StoragePolicy
|
||||
@@ -21,7 +20,7 @@ class S3StoragePolicy
|
||||
*/
|
||||
public function view(User $user, S3Storage $storage): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $storage->team_id)->exists();
|
||||
return $user->teams->contains('id', $storage->team_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,9 +34,10 @@ class S3StoragePolicy
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Server $server): bool
|
||||
public function update(User $user, S3Storage $storage): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $server->team_id)->exists() && $user->isAdmin();
|
||||
// return $user->teams->contains('id', $storage->team_id) && $user->isAdmin();
|
||||
return $user->teams->contains('id', $storage->team_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,7 +45,8 @@ class S3StoragePolicy
|
||||
*/
|
||||
public function delete(User $user, S3Storage $storage): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $storage->team_id)->exists() && $user->isAdmin();
|
||||
// return $user->teams->contains('id', $storage->team_id) && $user->isAdmin();
|
||||
return $user->teams->contains('id', $storage->team_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,4 +64,12 @@ class S3StoragePolicy
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can validate the connection of the model.
|
||||
*/
|
||||
public function validateConnection(User $user, S3Storage $storage): bool
|
||||
{
|
||||
return $user->teams->contains('id', $storage->team_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class ServerPolicy
|
||||
*/
|
||||
public function view(User $user, Server $server): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $server->team_id) !== null;
|
||||
return $user->teams->contains('id', $server->team_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +36,7 @@ class ServerPolicy
|
||||
*/
|
||||
public function update(User $user, Server $server): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $server->team_id) !== null;
|
||||
return $user->isAdmin() && $user->teams->contains('id', $server->team_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +44,7 @@ class ServerPolicy
|
||||
*/
|
||||
public function delete(User $user, Server $server): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $server->team_id) !== null;
|
||||
return $user->isAdmin() && $user->teams->contains('id', $server->team_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,7 +68,7 @@ class ServerPolicy
|
||||
*/
|
||||
public function manageProxy(User $user, Server $server): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $server->team_id) !== null;
|
||||
return $user->isAdmin() && $user->teams->contains('id', $server->team_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,7 +76,7 @@ class ServerPolicy
|
||||
*/
|
||||
public function manageSentinel(User $user, Server $server): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $server->team_id) !== null;
|
||||
return $user->isAdmin() && $user->teams->contains('id', $server->team_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +84,7 @@ class ServerPolicy
|
||||
*/
|
||||
public function manageCaCertificate(User $user, Server $server): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $server->team_id) !== null;
|
||||
return $user->isAdmin() && $user->teams->contains('id', $server->team_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,7 +92,7 @@ class ServerPolicy
|
||||
*/
|
||||
public function viewTerminal(User $user, Server $server): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $server->team_id) !== null;
|
||||
return $user->isAdmin() && $user->teams->contains('id', $server->team_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,6 +100,6 @@ class ServerPolicy
|
||||
*/
|
||||
public function viewSecurity(User $user, Server $server): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $server->team_id) !== null;
|
||||
return $user->isAdmin() && $user->teams->contains('id', $server->team_id);
|
||||
}
|
||||
}
|
||||
|
||||
63
app/Policies/ServiceApplicationPolicy.php
Normal file
63
app/Policies/ServiceApplicationPolicy.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\ServiceApplication;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class ServiceApplicationPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, ServiceApplication $serviceApplication): bool
|
||||
{
|
||||
return Gate::allows('view', $serviceApplication->service);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, ServiceApplication $serviceApplication): bool
|
||||
{
|
||||
// return Gate::allows('update', $serviceApplication->service);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, ServiceApplication $serviceApplication): bool
|
||||
{
|
||||
// return Gate::allows('delete', $serviceApplication->service);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, ServiceApplication $serviceApplication): bool
|
||||
{
|
||||
// return Gate::allows('update', $serviceApplication->service);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, ServiceApplication $serviceApplication): bool
|
||||
{
|
||||
// return Gate::allows('delete', $serviceApplication->service);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
63
app/Policies/ServiceDatabasePolicy.php
Normal file
63
app/Policies/ServiceDatabasePolicy.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\ServiceDatabase;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class ServiceDatabasePolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, ServiceDatabase $serviceDatabase): bool
|
||||
{
|
||||
return Gate::allows('view', $serviceDatabase->service);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, ServiceDatabase $serviceDatabase): bool
|
||||
{
|
||||
// return Gate::allows('update', $serviceDatabase->service);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, ServiceDatabase $serviceDatabase): bool
|
||||
{
|
||||
// return Gate::allows('delete', $serviceDatabase->service);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, ServiceDatabase $serviceDatabase): bool
|
||||
{
|
||||
// return Gate::allows('update', $serviceDatabase->service);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, ServiceDatabase $serviceDatabase): bool
|
||||
{
|
||||
// return Gate::allows('delete', $serviceDatabase->service);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,8 @@ class ServicePolicy
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->isAdmin();
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +37,13 @@ class ServicePolicy
|
||||
*/
|
||||
public function update(User $user, Service $service): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $service->team()->first()->id) !== null;
|
||||
$team = $service->team();
|
||||
if (! $team) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $team->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,11 +51,12 @@ class ServicePolicy
|
||||
*/
|
||||
public function delete(User $user, Service $service): bool
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
// if ($user->isAdmin()) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
return false;
|
||||
// return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,6 +64,7 @@ class ServicePolicy
|
||||
*/
|
||||
public function restore(User $user, Service $service): bool
|
||||
{
|
||||
// return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -64,16 +73,23 @@ class ServicePolicy
|
||||
*/
|
||||
public function forceDelete(User $user, Service $service): bool
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
// if ($user->isAdmin()) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
return false;
|
||||
// return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function stop(User $user, Service $service): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $service->team()->first()->id) !== null;
|
||||
$team = $service->team();
|
||||
if (! $team) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return $user->teams->contains('id', $team->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,7 +97,13 @@ class ServicePolicy
|
||||
*/
|
||||
public function manageEnvironment(User $user, Service $service): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $service->team()->first()->id) !== null;
|
||||
$team = $service->team();
|
||||
if (! $team) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $team->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,6 +111,18 @@ class ServicePolicy
|
||||
*/
|
||||
public function deploy(User $user, Service $service): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $service->team()->first()->id) !== null;
|
||||
$team = $service->team();
|
||||
if (! $team) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return $user->teams->contains('id', $team->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function accessTerminal(User $user, Service $service): bool
|
||||
{
|
||||
// return $user->isAdmin() || $user->teams->contains('id', $service->team()->id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
79
app/Policies/SharedEnvironmentVariablePolicy.php
Normal file
79
app/Policies/SharedEnvironmentVariablePolicy.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\SharedEnvironmentVariable;
|
||||
use App\Models\User;
|
||||
|
||||
class SharedEnvironmentVariablePolicy
|
||||
{
|
||||
/**
|
||||
* 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, SharedEnvironmentVariable $sharedEnvironmentVariable): bool
|
||||
{
|
||||
return $user->teams->contains('id', $sharedEnvironmentVariable->team_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, SharedEnvironmentVariable $sharedEnvironmentVariable): bool
|
||||
{
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $sharedEnvironmentVariable->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, SharedEnvironmentVariable $sharedEnvironmentVariable): bool
|
||||
{
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $sharedEnvironmentVariable->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, SharedEnvironmentVariable $sharedEnvironmentVariable): bool
|
||||
{
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $sharedEnvironmentVariable->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, SharedEnvironmentVariable $sharedEnvironmentVariable): bool
|
||||
{
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $sharedEnvironmentVariable->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can manage environment variables.
|
||||
*/
|
||||
public function manageEnvironment(User $user, SharedEnvironmentVariable $sharedEnvironmentVariable): bool
|
||||
{
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $sharedEnvironmentVariable->team_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ class StandaloneDockerPolicy
|
||||
*/
|
||||
public function view(User $user, StandaloneDocker $standaloneDocker): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $standaloneDocker->server->team_id) !== null;
|
||||
return $user->teams->contains('id', $standaloneDocker->server->team_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,7 +28,8 @@ class StandaloneDockerPolicy
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->isAdmin();
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +37,8 @@ class StandaloneDockerPolicy
|
||||
*/
|
||||
public function update(User $user, StandaloneDocker $standaloneDocker): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $standaloneDocker->server->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $standaloneDocker->server->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +46,8 @@ class StandaloneDockerPolicy
|
||||
*/
|
||||
public function delete(User $user, StandaloneDocker $standaloneDocker): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $standaloneDocker->server->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $standaloneDocker->server->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +55,8 @@ class StandaloneDockerPolicy
|
||||
*/
|
||||
public function restore(User $user, StandaloneDocker $standaloneDocker): bool
|
||||
{
|
||||
return false;
|
||||
// return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,6 +64,7 @@ class StandaloneDockerPolicy
|
||||
*/
|
||||
public function forceDelete(User $user, StandaloneDocker $standaloneDocker): bool
|
||||
{
|
||||
return false;
|
||||
// return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class SwarmDockerPolicy
|
||||
*/
|
||||
public function view(User $user, SwarmDocker $swarmDocker): bool
|
||||
{
|
||||
return $user->teams()->get()->firstWhere('id', $swarmDocker->server->team_id) !== null;
|
||||
return $user->teams->contains('id', $swarmDocker->server->team_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,7 +28,8 @@ class SwarmDockerPolicy
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->isAdmin();
|
||||
// return $user->isAdmin();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +37,8 @@ class SwarmDockerPolicy
|
||||
*/
|
||||
public function update(User $user, SwarmDocker $swarmDocker): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $swarmDocker->server->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $swarmDocker->server->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +46,8 @@ class SwarmDockerPolicy
|
||||
*/
|
||||
public function delete(User $user, SwarmDocker $swarmDocker): bool
|
||||
{
|
||||
return $user->isAdmin() && $user->teams()->get()->firstWhere('id', $swarmDocker->server->team_id) !== null;
|
||||
// return $user->isAdmin() && $user->teams->contains('id', $swarmDocker->server->team_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +55,8 @@ class SwarmDockerPolicy
|
||||
*/
|
||||
public function restore(User $user, SwarmDocker $swarmDocker): bool
|
||||
{
|
||||
return false;
|
||||
// return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,6 +64,7 @@ class SwarmDockerPolicy
|
||||
*/
|
||||
public function forceDelete(User $user, SwarmDocker $swarmDocker): bool
|
||||
{
|
||||
return false;
|
||||
// return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
104
app/Policies/TeamPolicy.php
Normal file
104
app/Policies/TeamPolicy.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
|
||||
class TeamPolicy
|
||||
{
|
||||
/**
|
||||
* 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, Team $team): bool
|
||||
{
|
||||
return $user->teams->contains('id', $team->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
// All authenticated users can create teams
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Team $team): bool
|
||||
{
|
||||
// Only admins and owners can update team settings
|
||||
if (! $user->teams->contains('id', $team->id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return $user->isAdmin() || $user->isOwner();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Team $team): bool
|
||||
{
|
||||
// Only admins and owners can delete teams
|
||||
if (! $user->teams->contains('id', $team->id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return $user->isAdmin() || $user->isOwner();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can manage team members.
|
||||
*/
|
||||
public function manageMembers(User $user, Team $team): bool
|
||||
{
|
||||
// Only admins and owners can manage team members
|
||||
if (! $user->teams->contains('id', $team->id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return $user->isAdmin() || $user->isOwner();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view admin panel.
|
||||
*/
|
||||
public function viewAdmin(User $user, Team $team): bool
|
||||
{
|
||||
// Only admins and owners can view admin panel
|
||||
if (! $user->teams->contains('id', $team->id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return $user->isAdmin() || $user->isOwner();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can manage invitations.
|
||||
*/
|
||||
public function manageInvitations(User $user, Team $team): bool
|
||||
{
|
||||
// Only admins and owners can manage invitations
|
||||
if (! $user->teams->contains('id', $team->id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return $user->isAdmin() || $user->isOwner();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,11 @@ class AuthServiceProvider extends ServiceProvider
|
||||
\App\Models\ApplicationPreview::class => \App\Policies\ApplicationPreviewPolicy::class,
|
||||
\App\Models\ApplicationSetting::class => \App\Policies\ApplicationSettingPolicy::class,
|
||||
\App\Models\Service::class => \App\Policies\ServicePolicy::class,
|
||||
\App\Models\ServiceApplication::class => \App\Policies\ServiceApplicationPolicy::class,
|
||||
\App\Models\ServiceDatabase::class => \App\Policies\ServiceDatabasePolicy::class,
|
||||
\App\Models\Project::class => \App\Policies\ProjectPolicy::class,
|
||||
\App\Models\Environment::class => \App\Policies\EnvironmentPolicy::class,
|
||||
\App\Models\SharedEnvironmentVariable::class => \App\Policies\SharedEnvironmentVariablePolicy::class,
|
||||
// Database policies - all use the shared DatabasePolicy
|
||||
\App\Models\StandalonePostgresql::class => \App\Policies\DatabasePolicy::class,
|
||||
\App\Models\StandaloneMysql::class => \App\Policies\DatabasePolicy::class,
|
||||
@@ -35,6 +38,22 @@ class AuthServiceProvider extends ServiceProvider
|
||||
\App\Models\StandaloneDragonfly::class => \App\Policies\DatabasePolicy::class,
|
||||
\App\Models\StandaloneClickhouse::class => \App\Policies\DatabasePolicy::class,
|
||||
|
||||
// Notification policies - all use the shared NotificationPolicy
|
||||
\App\Models\EmailNotificationSettings::class => \App\Policies\NotificationPolicy::class,
|
||||
\App\Models\DiscordNotificationSettings::class => \App\Policies\NotificationPolicy::class,
|
||||
\App\Models\TelegramNotificationSettings::class => \App\Policies\NotificationPolicy::class,
|
||||
\App\Models\SlackNotificationSettings::class => \App\Policies\NotificationPolicy::class,
|
||||
\App\Models\PushoverNotificationSettings::class => \App\Policies\NotificationPolicy::class,
|
||||
|
||||
// API Token policy
|
||||
\Laravel\Sanctum\PersonalAccessToken::class => \App\Policies\ApiTokenPolicy::class,
|
||||
|
||||
// Team policy
|
||||
\App\Models\Team::class => \App\Policies\TeamPolicy::class,
|
||||
|
||||
// Git source policies
|
||||
\App\Models\GithubApp::class => \App\Policies\GithubAppPolicy::class,
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -44,5 +63,11 @@ class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
// Register gates for resource creation policy
|
||||
Gate::define('createAnyResource', [ResourceCreatePolicy::class, 'createAny']);
|
||||
|
||||
// Register gate for terminal access
|
||||
Gate::define('canAccessTerminal', function ($user) {
|
||||
// return $user->isAdmin() || $user->isOwner();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\View\Components\Forms;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class Button extends Component
|
||||
@@ -17,7 +18,19 @@ class Button extends Component
|
||||
public ?string $modalId = null,
|
||||
public string $defaultClass = 'button',
|
||||
public bool $showLoadingIndicator = true,
|
||||
public ?string $canGate = null,
|
||||
public mixed $canResource = null,
|
||||
public bool $autoDisable = true,
|
||||
) {
|
||||
// Handle authorization-based disabling
|
||||
if ($this->canGate && $this->canResource && $this->autoDisable) {
|
||||
$hasPermission = Gate::allows($this->canGate, $this->canResource);
|
||||
|
||||
if (! $hasPermission) {
|
||||
$this->disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->noStyle) {
|
||||
$this->defaultClass = '';
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\View\Components\Forms;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class Checkbox extends Component
|
||||
@@ -22,7 +23,20 @@ class Checkbox extends Component
|
||||
public string|bool $instantSave = false,
|
||||
public bool $disabled = false,
|
||||
public string $defaultClass = 'dark:border-neutral-700 text-coolgray-400 focus:ring-warning dark:bg-coolgray-100 rounded-sm cursor-pointer dark:disabled:bg-base dark:disabled:cursor-not-allowed',
|
||||
public ?string $canGate = null,
|
||||
public mixed $canResource = null,
|
||||
public bool $autoDisable = true,
|
||||
) {
|
||||
// Handle authorization-based disabling
|
||||
if ($this->canGate && $this->canResource && $this->autoDisable) {
|
||||
$hasPermission = Gate::allows($this->canGate, $this->canResource);
|
||||
|
||||
if (! $hasPermission) {
|
||||
$this->disabled = true;
|
||||
$this->instantSave = false; // Disable instant save for unauthorized users
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->disabled) {
|
||||
$this->defaultClass .= ' opacity-40';
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\View\Components\Forms;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\View\Component;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
@@ -26,7 +27,19 @@ class Input extends Component
|
||||
public ?int $minlength = null,
|
||||
public ?int $maxlength = null,
|
||||
public bool $autofocus = false,
|
||||
) {}
|
||||
public ?string $canGate = null,
|
||||
public mixed $canResource = null,
|
||||
public bool $autoDisable = true,
|
||||
) {
|
||||
// Handle authorization-based disabling
|
||||
if ($this->canGate && $this->canResource && $this->autoDisable) {
|
||||
$hasPermission = Gate::allows($this->canGate, $this->canResource);
|
||||
|
||||
if (! $hasPermission) {
|
||||
$this->disabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function render(): View|Closure|string
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\View\Components\Forms;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\View\Component;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
@@ -19,9 +20,19 @@ class Select extends Component
|
||||
public ?string $helper = null,
|
||||
public bool $required = false,
|
||||
public bool $disabled = false,
|
||||
public string $defaultClass = 'select w-full'
|
||||
public string $defaultClass = 'select w-full',
|
||||
public ?string $canGate = null,
|
||||
public mixed $canResource = null,
|
||||
public bool $autoDisable = true,
|
||||
) {
|
||||
//
|
||||
// Handle authorization-based disabling
|
||||
if ($this->canGate && $this->canResource && $this->autoDisable) {
|
||||
$hasPermission = Gate::allows($this->canGate, $this->canResource);
|
||||
|
||||
if (! $hasPermission) {
|
||||
$this->disabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\View\Components\Forms;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\View\Component;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
@@ -33,8 +34,18 @@ class Textarea extends Component
|
||||
public string $defaultClassInput = 'input',
|
||||
public ?int $minlength = null,
|
||||
public ?int $maxlength = null,
|
||||
public ?string $canGate = null,
|
||||
public mixed $canResource = null,
|
||||
public bool $autoDisable = true,
|
||||
) {
|
||||
//
|
||||
// Handle authorization-based disabling
|
||||
if ($this->canGate && $this->canResource && $this->autoDisable) {
|
||||
$hasPermission = Gate::allows($this->canGate, $this->canResource);
|
||||
|
||||
if (! $hasPermission) {
|
||||
$this->disabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user