mirror of
https://github.com/pelican-dev/panel.git
synced 2026-07-15 19:53:59 +03:00
Monthly Shift: July 2026 (#2433)
Co-authored-by: Shift <shift@laravelshift.com>
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Checks;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Composer\InstalledVersions;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Spatie\Health\Checks\Checks\ScheduleCheck as BaseCheck;
|
||||
use Spatie\Health\Checks\Result;
|
||||
|
||||
|
||||
@@ -37,9 +37,7 @@ class CheckEggUpdatesCommand extends Command
|
||||
|
||||
$extension = strtolower(pathinfo(parse_url($egg->update_url, PHP_URL_PATH), PATHINFO_EXTENSION));
|
||||
|
||||
if (empty($extension)) {
|
||||
throw new Exception('Unsupported file format.');
|
||||
}
|
||||
throw_if(empty($extension), new Exception('Unsupported file format.'));
|
||||
|
||||
$isYaml = in_array($extension, ['yaml', 'yml']);
|
||||
|
||||
@@ -49,9 +47,7 @@ class CheckEggUpdatesCommand extends Command
|
||||
|
||||
$remote = Http::timeout(5)->connectTimeout(1)->get($egg->update_url);
|
||||
|
||||
if ($remote->failed()) {
|
||||
throw new Exception("HTTP request returned status code {$remote->status()}");
|
||||
}
|
||||
throw_if($remote->failed(), new Exception("HTTP request returned status code {$remote->status()}"));
|
||||
|
||||
$remote = $remote->body();
|
||||
$remote = $isYaml ? Yaml::parse($remote) : json_decode($remote, true);
|
||||
|
||||
@@ -7,8 +7,8 @@ use App\Exceptions\Service\InvalidFileUploadException;
|
||||
use App\Models\Egg;
|
||||
use App\Services\Eggs\Sharing\EggExporterService;
|
||||
use App\Services\Eggs\Sharing\EggImporterService;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
class NormalizeEggCommand extends Command
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace App\Console\Commands\Maintenance;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Contracts\Filesystem\Factory as FilesystemFactory;
|
||||
use Illuminate\Contracts\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Carbon;
|
||||
use SplFileInfo;
|
||||
|
||||
class CleanServiceBackupFilesCommand extends Command
|
||||
|
||||
@@ -16,9 +16,7 @@ class PruneOrphanedBackupsCommand extends Command
|
||||
public function handle(): void
|
||||
{
|
||||
$since = $this->option('prune-age') ?? config('backups.prune_age', 360);
|
||||
if (!$since || !is_digit($since)) {
|
||||
throw new InvalidArgumentException('The "--prune-age" argument must be a value greater than 0.');
|
||||
}
|
||||
throw_if(!$since || !is_digit($since), new InvalidArgumentException('The "--prune-age" argument must be a value greater than 0.'));
|
||||
|
||||
$query = Backup::query()
|
||||
->whereNull('completed_at')
|
||||
|
||||
@@ -75,9 +75,7 @@ class TurnstileSchema extends BaseSchema implements CaptchaSchemaInterface
|
||||
{
|
||||
$captchaResponse ??= request()->get('cf-turnstile-response');
|
||||
|
||||
if (!$secret = env('CAPTCHA_TURNSTILE_SECRET_KEY')) {
|
||||
throw new Exception('Turnstile secret key is not defined.');
|
||||
}
|
||||
throw_unless($secret = env('CAPTCHA_TURNSTILE_SECRET_KEY'), new Exception('Turnstile secret key is not defined.'));
|
||||
|
||||
$response = Http::asJson()
|
||||
->timeout(15)
|
||||
@@ -101,9 +99,7 @@ class TurnstileSchema extends BaseSchema implements CaptchaSchemaInterface
|
||||
};
|
||||
}
|
||||
|
||||
if (!$this->verifyDomain($response['hostname'] ?? '')) {
|
||||
throw new Exception('Domain verification failed.');
|
||||
}
|
||||
throw_unless($this->verifyDomain($response['hostname'] ?? ''), new Exception('Domain verification failed.'));
|
||||
}
|
||||
|
||||
private function verifyDomain(string $hostname): bool
|
||||
|
||||
@@ -4,10 +4,10 @@ namespace App\Filament\Admin\Pages;
|
||||
|
||||
use App\Enums\TablerIcon;
|
||||
use BackedEnum;
|
||||
use Carbon\Carbon;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Pages\Page;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Spatie\Health\Commands\RunHealthChecksCommand;
|
||||
use Spatie\Health\Enums\Status;
|
||||
|
||||
@@ -265,9 +265,7 @@ class PluginResource extends Resource
|
||||
|
||||
$pluginName = str($file->getClientOriginalName())->basename()->before('.zip')->toString();
|
||||
|
||||
if (Plugin::where('id', $pluginName)->exists()) {
|
||||
throw new Exception(trans('admin/plugin.notifications.import_exists'));
|
||||
}
|
||||
throw_if(Plugin::where('id', $pluginName)->exists(), new Exception(trans('admin/plugin.notifications.import_exists')));
|
||||
|
||||
$pluginService->downloadPluginFromFile($file);
|
||||
|
||||
@@ -304,9 +302,7 @@ class PluginResource extends Resource
|
||||
try {
|
||||
$pluginName = str($data['url'])->before('.zip')->explode('/')->last();
|
||||
|
||||
if (Plugin::where('id', $pluginName)->exists()) {
|
||||
throw new Exception(trans('admin/plugin.notifications.import_exists'));
|
||||
}
|
||||
throw_if(Plugin::where('id', $pluginName)->exists(), new Exception(trans('admin/plugin.notifications.import_exists')));
|
||||
|
||||
$pluginService->downloadPluginFromUrl($data['url']);
|
||||
|
||||
|
||||
@@ -481,7 +481,7 @@ class UserResource extends Resource
|
||||
->deletable(false)
|
||||
->addable(false)
|
||||
->relationship(null, function (Builder $query) {
|
||||
$query->orderBy('timestamp', 'desc');
|
||||
$query->orderByDesc('timestamp');
|
||||
})
|
||||
->schema([
|
||||
TextEntry::make('log')
|
||||
|
||||
@@ -104,15 +104,11 @@ class UploadIcon extends Action
|
||||
|
||||
$content = Http::timeout(5)->connectTimeout(1)->withoutRedirecting()->get($data['icon_url'])->body();
|
||||
|
||||
if (empty($content)) {
|
||||
throw new Exception(trans('admin/egg.import.invalid_url'));
|
||||
}
|
||||
throw_if(empty($content), new Exception(trans('admin/egg.import.invalid_url')));
|
||||
|
||||
$extension = strtolower(pathinfo(parse_url($data['icon_url'], PHP_URL_PATH), PATHINFO_EXTENSION));
|
||||
|
||||
if (empty($extension)) {
|
||||
throw new Exception(trans('admin/egg.import.invalid_url'));
|
||||
}
|
||||
throw_if(empty($extension), new Exception(trans('admin/egg.import.invalid_url')));
|
||||
|
||||
$record->writeIcon($extension, $content);
|
||||
|
||||
@@ -136,20 +132,14 @@ class UploadIcon extends Action
|
||||
|
||||
protected function validateIconUrl(string $url): void
|
||||
{
|
||||
if (!in_array(parse_url($url, PHP_URL_SCHEME), ['http', 'https'], true)) {
|
||||
throw new Exception(trans('admin/egg.import.invalid_url'));
|
||||
}
|
||||
throw_unless(in_array(parse_url($url, PHP_URL_SCHEME), ['http', 'https'], true), new Exception(trans('admin/egg.import.invalid_url')));
|
||||
|
||||
if (!filter_var($url, FILTER_VALIDATE_URL)) {
|
||||
throw new Exception(trans('admin/egg.import.invalid_url'));
|
||||
}
|
||||
throw_unless(filter_var($url, FILTER_VALIDATE_URL), new Exception(trans('admin/egg.import.invalid_url')));
|
||||
|
||||
$host = parse_url($url, PHP_URL_HOST);
|
||||
$ip = gethostbyname($host);
|
||||
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) {
|
||||
throw new Exception(trans('admin/egg.import.no_local_ip'));
|
||||
}
|
||||
throw_if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false, new Exception(trans('admin/egg.import.no_local_ip')));
|
||||
}
|
||||
|
||||
/** @param string[] $iconFormats */
|
||||
|
||||
@@ -36,9 +36,7 @@ class MonacoEditor extends Field
|
||||
{
|
||||
$theme = $this->evaluate($this->theme);
|
||||
|
||||
if (!isset(config('monaco-editor.themes')[$theme])) {
|
||||
throw new Exception("Theme {$theme} not found in config file.");
|
||||
}
|
||||
throw_unless(isset(config('monaco-editor.themes')[$theme]), new Exception("Theme {$theme} not found in config file."));
|
||||
|
||||
return json_encode([
|
||||
'base' => config("monaco-editor.themes.{$theme}.base"),
|
||||
|
||||
@@ -448,7 +448,7 @@ class EditProfile extends BaseEditProfile
|
||||
->deletable(false)
|
||||
->addable(false)
|
||||
->relationship(null, function (Builder $query) {
|
||||
$query->orderBy('timestamp', 'desc')->limit(50);
|
||||
$query->orderByDesc('timestamp')->limit(50);
|
||||
})
|
||||
->schema([
|
||||
TextEntry::make('log')
|
||||
|
||||
@@ -632,9 +632,7 @@ class ListFiles extends ListRecords
|
||||
/** @var Server $server */
|
||||
$server = Filament::getTenant();
|
||||
|
||||
if (!user()?->can(SubuserPermission::FileCreate, $server)) {
|
||||
abort(403, 'You do not have permission to create folders.');
|
||||
}
|
||||
abort_unless(user()?->can(SubuserPermission::FileCreate, $server), 403, 'You do not have permission to create folders.');
|
||||
|
||||
try {
|
||||
$this->getDaemonFileRepository()->createDirectory($folderPath, $this->path);
|
||||
|
||||
@@ -21,7 +21,6 @@ use App\Traits\Filament\CanCustomizeRelations;
|
||||
use App\Traits\Filament\CanModifyForm;
|
||||
use App\Traits\Filament\CanModifyTable;
|
||||
use BackedEnum;
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Actions\DeleteAction;
|
||||
@@ -45,6 +44,7 @@ use Filament\Support\Exceptions\Halt;
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use Throwable;
|
||||
|
||||
|
||||
@@ -47,9 +47,7 @@ class ServerConsole extends Widget
|
||||
|
||||
protected function getToken(): string
|
||||
{
|
||||
if (!$this->user || !$this->server || $this->user->cannot(SubuserPermission::WebsocketConnect, $this->server)) {
|
||||
throw new HttpForbiddenException('You do not have permission to connect to this server\'s websocket.');
|
||||
}
|
||||
throw_if(!$this->user || !$this->server || $this->user->cannot(SubuserPermission::WebsocketConnect, $this->server), new HttpForbiddenException('You do not have permission to connect to this server\'s websocket.'));
|
||||
|
||||
$permissions = $this->getUserPermissionsService->handle($this->server, $this->user);
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ namespace App\Filament\Server\Widgets;
|
||||
|
||||
use App\Enums\CustomizationKey;
|
||||
use App\Models\Server;
|
||||
use Carbon\Carbon;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Support\RawJs;
|
||||
use Filament\Widgets\ChartWidget;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class ServerCpuChart extends ChartWidget
|
||||
{
|
||||
|
||||
@@ -4,10 +4,10 @@ namespace App\Filament\Server\Widgets;
|
||||
|
||||
use App\Enums\CustomizationKey;
|
||||
use App\Models\Server;
|
||||
use Carbon\Carbon;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Support\RawJs;
|
||||
use Filament\Widgets\ChartWidget;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class ServerMemoryChart extends ChartWidget
|
||||
{
|
||||
|
||||
@@ -4,10 +4,10 @@ namespace App\Filament\Server\Widgets;
|
||||
|
||||
use App\Enums\CustomizationKey;
|
||||
use App\Models\Server;
|
||||
use Carbon\Carbon;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Support\RawJs;
|
||||
use Filament\Widgets\ChartWidget;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class ServerNetworkChart extends ChartWidget
|
||||
{
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Cron\CronExpression;
|
||||
use Exception;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\ViewErrorBag;
|
||||
|
||||
|
||||
@@ -115,9 +115,7 @@ class MountController extends ApplicationApiController
|
||||
*/
|
||||
public function delete(DeleteMountRequest $request, Mount $mount): JsonResponse
|
||||
{
|
||||
if ($mount->servers()->count() > 0) {
|
||||
throw new HasActiveServersException(trans('exceptions.mount.servers_attached'));
|
||||
}
|
||||
throw_if($mount->servers()->count() > 0, new HasActiveServersException(trans('exceptions.mount.servers_attached')));
|
||||
|
||||
$mount->delete();
|
||||
|
||||
|
||||
@@ -68,9 +68,7 @@ class PluginController extends ApplicationApiController
|
||||
*/
|
||||
public function importFile(WritePluginRequest $request): Response
|
||||
{
|
||||
if (!$request->hasFile('plugin')) {
|
||||
throw new PanelException("No 'plugin' file in request");
|
||||
}
|
||||
throw_unless($request->hasFile('plugin'), new PanelException("No 'plugin' file in request"));
|
||||
|
||||
$this->pluginService->downloadPluginFromFile($request->file('plugin'));
|
||||
|
||||
@@ -102,9 +100,7 @@ class PluginController extends ApplicationApiController
|
||||
*/
|
||||
public function install(WritePluginRequest $request, Plugin $plugin): array
|
||||
{
|
||||
if ($plugin->status !== PluginStatus::NotInstalled) {
|
||||
throw new PanelException('Plugin is already installed');
|
||||
}
|
||||
throw_if($plugin->status !== PluginStatus::NotInstalled, new PanelException('Plugin is already installed'));
|
||||
|
||||
$this->pluginService->installPlugin($plugin);
|
||||
|
||||
@@ -124,9 +120,7 @@ class PluginController extends ApplicationApiController
|
||||
*/
|
||||
public function update(WritePluginRequest $request, Plugin $plugin): array
|
||||
{
|
||||
if (!$plugin->isUpdateAvailable()) {
|
||||
throw new PanelException("Plugin doesn't need updating");
|
||||
}
|
||||
throw_unless($plugin->isUpdateAvailable(), new PanelException("Plugin doesn't need updating"));
|
||||
|
||||
$this->pluginService->updatePlugin($plugin);
|
||||
|
||||
@@ -146,9 +140,7 @@ class PluginController extends ApplicationApiController
|
||||
*/
|
||||
public function uninstall(UninstallPluginRequest $request, Plugin $plugin): array
|
||||
{
|
||||
if ($plugin->status === PluginStatus::NotInstalled) {
|
||||
throw new PanelException('Plugin is not installed');
|
||||
}
|
||||
throw_if($plugin->status === PluginStatus::NotInstalled, new PanelException('Plugin is not installed'));
|
||||
|
||||
$this->pluginService->uninstallPlugin($plugin, $request->boolean('delete'));
|
||||
|
||||
@@ -168,9 +160,7 @@ class PluginController extends ApplicationApiController
|
||||
*/
|
||||
public function enable(WritePluginRequest $request, Plugin $plugin): array
|
||||
{
|
||||
if (!$plugin->canEnable()) {
|
||||
throw new PanelException("Plugin can't be enabled");
|
||||
}
|
||||
throw_unless($plugin->canEnable(), new PanelException("Plugin can't be enabled"));
|
||||
|
||||
$this->pluginService->enablePlugin($plugin);
|
||||
|
||||
@@ -190,9 +180,7 @@ class PluginController extends ApplicationApiController
|
||||
*/
|
||||
public function disable(WritePluginRequest $request, Plugin $plugin): array
|
||||
{
|
||||
if (!$plugin->canDisable()) {
|
||||
throw new PanelException("Plugin can't be disabled");
|
||||
}
|
||||
throw_unless($plugin->canDisable(), new PanelException("Plugin can't be disabled"));
|
||||
|
||||
$this->pluginService->disablePlugin($plugin);
|
||||
|
||||
|
||||
@@ -84,9 +84,7 @@ class RoleController extends ApplicationApiController
|
||||
*/
|
||||
public function update(UpdateRoleRequest $request, Role $role): array
|
||||
{
|
||||
if ($role->isRootAdmin()) {
|
||||
throw new PanelException('Can\'t update root admin role!');
|
||||
}
|
||||
throw_if($role->isRootAdmin(), new PanelException('Can\'t update root admin role!'));
|
||||
|
||||
$role->update($request->validated());
|
||||
|
||||
@@ -104,9 +102,7 @@ class RoleController extends ApplicationApiController
|
||||
*/
|
||||
public function delete(DeleteRoleRequest $request, Role $role): Response
|
||||
{
|
||||
if ($role->isRootAdmin()) {
|
||||
throw new PanelException('Can\'t delete root admin role!');
|
||||
}
|
||||
throw_if($role->isRootAdmin(), new PanelException('Can\'t delete root admin role!'));
|
||||
|
||||
$role->delete();
|
||||
|
||||
|
||||
@@ -75,9 +75,7 @@ class AccountController extends ClientApiController
|
||||
// Only allow a user to change their email three times in the span
|
||||
// of 24 hours. This prevents malicious users from trying to find
|
||||
// existing accounts in the system by constantly changing their email.
|
||||
if (RateLimiter::tooManyAttempts($key = "user:update-email:{$user->uuid}", 3)) {
|
||||
throw new TooManyRequestsHttpException(message: 'Your email address has been changed too many times today. Please try again later.');
|
||||
}
|
||||
throw_if(RateLimiter::tooManyAttempts($key = "user:update-email:{$user->uuid}", 3), new TooManyRequestsHttpException(message: 'Your email address has been changed too many times today. Please try again later.'));
|
||||
|
||||
$original = $user->email;
|
||||
|
||||
|
||||
@@ -37,9 +37,7 @@ class ApiKeyController extends ClientApiController
|
||||
*/
|
||||
public function store(StoreApiKeyRequest $request): array
|
||||
{
|
||||
if ($request->user()->apiKeys->count() >= config('panel.api.key_limit')) {
|
||||
throw new DisplayException('You have reached the account limit for number of API keys.');
|
||||
}
|
||||
throw_if($request->user()->apiKeys->count() >= config('panel.api.key_limit'), new DisplayException('You have reached the account limit for number of API keys.'));
|
||||
|
||||
$token = $request->user()->createToken(
|
||||
$request->input('description'),
|
||||
|
||||
@@ -50,9 +50,7 @@ class BackupController extends ClientApiController
|
||||
*/
|
||||
public function index(Request $request, Server $server): array
|
||||
{
|
||||
if (!$request->user()->can(SubuserPermission::BackupRead, $server)) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
throw_unless($request->user()->can(SubuserPermission::BackupRead, $server), new AuthorizationException());
|
||||
|
||||
$limit = min($request->query('per_page') ?? 20, 50);
|
||||
|
||||
@@ -118,9 +116,7 @@ class BackupController extends ClientApiController
|
||||
*/
|
||||
public function toggleLock(Request $request, Server $server, Backup $backup): array
|
||||
{
|
||||
if (!$request->user()->can(SubuserPermission::BackupDelete, $server)) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
throw_unless($request->user()->can(SubuserPermission::BackupDelete, $server), new AuthorizationException());
|
||||
|
||||
$action = $backup->is_locked ? 'server:backup.unlock' : 'server:backup.lock';
|
||||
|
||||
@@ -144,9 +140,7 @@ class BackupController extends ClientApiController
|
||||
*/
|
||||
public function view(Request $request, Server $server, Backup $backup): array
|
||||
{
|
||||
if (!$request->user()->can(SubuserPermission::BackupRead, $server)) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
throw_unless($request->user()->can(SubuserPermission::BackupRead, $server), new AuthorizationException());
|
||||
|
||||
return $this->fractal->item($backup)
|
||||
->transformWith($this->getTransformer(BackupTransformer::class))
|
||||
@@ -163,9 +157,7 @@ class BackupController extends ClientApiController
|
||||
*/
|
||||
public function delete(Request $request, Server $server, Backup $backup): JsonResponse
|
||||
{
|
||||
if (!$request->user()->can(SubuserPermission::BackupDelete, $server)) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
throw_unless($request->user()->can(SubuserPermission::BackupDelete, $server), new AuthorizationException());
|
||||
|
||||
$this->deleteBackupService->handle($backup);
|
||||
|
||||
@@ -189,9 +181,7 @@ class BackupController extends ClientApiController
|
||||
*/
|
||||
public function download(Request $request, Server $server, Backup $backup): JsonResponse
|
||||
{
|
||||
if (!$request->user()->can(SubuserPermission::BackupDownload, $server)) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
throw_unless($request->user()->can(SubuserPermission::BackupDownload, $server), new AuthorizationException());
|
||||
|
||||
$schema = $this->backupService->get($backup->backupHost->schema);
|
||||
if (!$schema) {
|
||||
@@ -254,13 +244,9 @@ class BackupController extends ClientApiController
|
||||
{
|
||||
// Cannot restore a backup unless a server is fully installed and not currently
|
||||
// processing a different backup restoration request.
|
||||
if (!is_null($server->status)) {
|
||||
throw new BadRequestHttpException('This server is not currently in a state that allows for a backup to be restored.');
|
||||
}
|
||||
throw_unless(is_null($server->status), new BadRequestHttpException('This server is not currently in a state that allows for a backup to be restored.'));
|
||||
|
||||
if (!$backup->is_successful && is_null($backup->completed_at)) {
|
||||
throw new BadRequestHttpException('This backup cannot be restored at this time: not completed or failed.');
|
||||
}
|
||||
throw_if(!$backup->is_successful && is_null($backup->completed_at), new BadRequestHttpException('This backup cannot be restored at this time: not completed or failed.'));
|
||||
|
||||
$log = Activity::event('server:backup.restore')
|
||||
->subject($backup)
|
||||
|
||||
@@ -31,9 +31,7 @@ class CommandController extends ClientApiController
|
||||
$previous = $exception->getPrevious();
|
||||
|
||||
if ($previous instanceof BadResponseException) {
|
||||
if ($previous->getResponse()->getStatusCode() === Response::HTTP_BAD_GATEWAY) {
|
||||
throw new HttpException(Response::HTTP_BAD_GATEWAY, 'Server must be online in order to send commands.', $exception);
|
||||
}
|
||||
throw_if($previous->getResponse()->getStatusCode() === Response::HTTP_BAD_GATEWAY, new HttpException(Response::HTTP_BAD_GATEWAY, 'Server must be online in order to send commands.', $exception));
|
||||
}
|
||||
|
||||
throw $exception;
|
||||
|
||||
@@ -110,9 +110,7 @@ class NetworkAllocationController extends ClientApiController
|
||||
$allocation = Activity::event('server:allocation.create')->transaction(function ($log) use ($server) {
|
||||
$server->allocations()->lockForUpdate();
|
||||
|
||||
if ($server->allocations->count() >= $server->allocation_limit) {
|
||||
throw new DisplayException('Cannot assign additional allocations to this server: limit has been reached.');
|
||||
}
|
||||
throw_if($server->allocations->count() >= $server->allocation_limit, new DisplayException('Cannot assign additional allocations to this server: limit has been reached.'));
|
||||
|
||||
$allocation = $this->assignableAllocationService->handle($server);
|
||||
|
||||
@@ -137,9 +135,7 @@ class NetworkAllocationController extends ClientApiController
|
||||
{
|
||||
// Don't allow the deletion of allocations if the server does not have an
|
||||
// allocation limit set.
|
||||
if (empty($server->allocation_limit)) {
|
||||
throw new DisplayException('You cannot delete allocations for this server: no allocation limit is set.');
|
||||
}
|
||||
throw_if(empty($server->allocation_limit), new DisplayException('You cannot delete allocations for this server: no allocation limit is set.'));
|
||||
|
||||
Allocation::query()->where('id', $allocation->id)->update([
|
||||
'notes' => null,
|
||||
|
||||
@@ -7,10 +7,10 @@ use App\Http\Requests\Api\Client\Servers\GetServerRequest;
|
||||
use App\Models\Server;
|
||||
use App\Repositories\Daemon\DaemonServerRepository;
|
||||
use App\Transformers\Api\Client\StatsTransformer;
|
||||
use Carbon\Carbon;
|
||||
use Dedoc\Scramble\Attributes\Group;
|
||||
use Illuminate\Cache\Repository;
|
||||
use Illuminate\Http\Client\ConnectionException;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
#[Group('Server', weight: 3)]
|
||||
class ResourceUtilizationController extends ClientApiController
|
||||
|
||||
@@ -16,12 +16,12 @@ use App\Models\Schedule;
|
||||
use App\Models\Server;
|
||||
use App\Services\Schedules\ProcessScheduleService;
|
||||
use App\Transformers\Api\Client\ScheduleTransformer;
|
||||
use Carbon\Carbon;
|
||||
use Dedoc\Scramble\Attributes\Group;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Throwable;
|
||||
|
||||
@@ -97,9 +97,7 @@ class ScheduleController extends ClientApiController
|
||||
*/
|
||||
public function view(ViewScheduleRequest $request, Server $server, Schedule $schedule): array
|
||||
{
|
||||
if ($schedule->server_id !== $server->id) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
throw_if($schedule->server_id !== $server->id, new NotFoundHttpException());
|
||||
|
||||
$schedule->loadMissing('tasks');
|
||||
|
||||
|
||||
@@ -46,13 +46,9 @@ class ScheduleTaskController extends ClientApiController
|
||||
public function store(StoreTaskRequest $request, Server $server, Schedule $schedule): array
|
||||
{
|
||||
$limit = config('panel.client_features.schedules.per_schedule_task_limit', 10);
|
||||
if ($schedule->tasks()->count() >= $limit) {
|
||||
throw new ServiceLimitExceededException("Schedules may not have more than $limit tasks associated with them. Creating this task would put this schedule over the limit.");
|
||||
}
|
||||
throw_if($schedule->tasks()->count() >= $limit, new ServiceLimitExceededException("Schedules may not have more than $limit tasks associated with them. Creating this task would put this schedule over the limit."));
|
||||
|
||||
if ($server->backup_limit === 0 && $request->action === 'backup') {
|
||||
throw new HttpForbiddenException("A backup task cannot be created when the server's backup limit is set to 0.");
|
||||
}
|
||||
throw_if($server->backup_limit === 0 && $request->action === 'backup', new HttpForbiddenException("A backup task cannot be created when the server's backup limit is set to 0."));
|
||||
|
||||
/** @var Task|null $lastTask */
|
||||
$lastTask = $schedule->tasks()->orderByDesc('sequence_id')->first();
|
||||
@@ -109,13 +105,9 @@ class ScheduleTaskController extends ClientApiController
|
||||
*/
|
||||
public function update(StoreTaskRequest $request, Server $server, Schedule $schedule, Task $task): array
|
||||
{
|
||||
if ($schedule->id !== $task->schedule_id || $server->id !== $schedule->server_id) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
throw_if($schedule->id !== $task->schedule_id || $server->id !== $schedule->server_id, new NotFoundHttpException());
|
||||
|
||||
if ($server->backup_limit === 0 && $request->action === 'backup') {
|
||||
throw new HttpForbiddenException("A backup task cannot be created when the server's backup limit is set to 0.");
|
||||
}
|
||||
throw_if($server->backup_limit === 0 && $request->action === 'backup', new HttpForbiddenException("A backup task cannot be created when the server's backup limit is set to 0."));
|
||||
|
||||
$this->connection->transaction(function () use ($request, $schedule, $task) {
|
||||
$sequenceId = $request->integer('sequence_id', $task->sequence_id);
|
||||
@@ -166,13 +158,9 @@ class ScheduleTaskController extends ClientApiController
|
||||
*/
|
||||
public function delete(ClientApiRequest $request, Server $server, Schedule $schedule, Task $task): JsonResponse
|
||||
{
|
||||
if ($task->schedule_id !== $schedule->id || $schedule->server_id !== $server->id) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
throw_if($task->schedule_id !== $schedule->id || $schedule->server_id !== $server->id, new NotFoundHttpException());
|
||||
|
||||
if (!$request->user()->can(SubuserPermission::ScheduleDelete, $server)) {
|
||||
throw new HttpForbiddenException('You do not have permission to perform this action.');
|
||||
}
|
||||
throw_unless($request->user()->can(SubuserPermission::ScheduleDelete, $server), new HttpForbiddenException('You do not have permission to perform this action.'));
|
||||
|
||||
$schedule->tasks()
|
||||
->where('sequence_id', '>', $task->sequence_id)
|
||||
|
||||
@@ -96,9 +96,7 @@ class SettingsController extends ClientApiController
|
||||
*/
|
||||
public function dockerImage(SetDockerImageRequest $request, Server $server): JsonResponse
|
||||
{
|
||||
if (!in_array($server->image, $server->egg->docker_images)) {
|
||||
throw new BadRequestHttpException('This server\'s Docker image has been manually set by an administrator and cannot be updated.');
|
||||
}
|
||||
throw_unless(in_array($server->image, $server->egg->docker_images), new BadRequestHttpException('This server\'s Docker image has been manually set by an administrator and cannot be updated.'));
|
||||
|
||||
$original = $server->image;
|
||||
$server->forceFill(['image' => $request->input('docker_image')])->saveOrFail();
|
||||
|
||||
@@ -64,11 +64,9 @@ class StartupController extends ClientApiController
|
||||
{
|
||||
$variable = $server->variables()->where('env_variable', $request->input('key'))->first();
|
||||
|
||||
if (!$variable || !$variable->user_viewable) {
|
||||
throw new BadRequestHttpException('The environment variable you are trying to edit does not exist.');
|
||||
} elseif (!$variable->user_editable) {
|
||||
throw new BadRequestHttpException('The environment variable you are trying to edit is read-only.');
|
||||
}
|
||||
throw_if(!$variable || !$variable->user_viewable, new BadRequestHttpException('The environment variable you are trying to edit does not exist.'));
|
||||
|
||||
throw_unless($variable->user_editable, new BadRequestHttpException('The environment variable you are trying to edit is read-only.'));
|
||||
|
||||
$original = $variable->server_value;
|
||||
|
||||
|
||||
@@ -38,18 +38,14 @@ class WebsocketController extends ClientApiController
|
||||
public function __invoke(ClientApiRequest $request, Server $server): JsonResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
if ($user->cannot(SubuserPermission::WebsocketConnect, $server)) {
|
||||
throw new HttpForbiddenException('You do not have permission to connect to this server\'s websocket.');
|
||||
}
|
||||
throw_if($user->cannot(SubuserPermission::WebsocketConnect, $server), new HttpForbiddenException('You do not have permission to connect to this server\'s websocket.'));
|
||||
|
||||
$permissions = $this->permissionsService->handle($server, $user);
|
||||
|
||||
$node = $server->node;
|
||||
if (!is_null($server->transfer)) {
|
||||
// Check if the user has permissions to receive transfer logs.
|
||||
if (!in_array('admin.websocket.transfer', $permissions)) {
|
||||
throw new HttpForbiddenException('You do not have permission to view server transfer logs.');
|
||||
}
|
||||
throw_unless(in_array('admin.websocket.transfer', $permissions), new HttpForbiddenException('You do not have permission to view server transfer logs.'));
|
||||
|
||||
// Redirect the websocket request to the new node if the server has been archived.
|
||||
if ($server->transfer->archived) {
|
||||
|
||||
@@ -9,9 +9,9 @@ use App\Models\ActivityLog;
|
||||
use App\Models\Node;
|
||||
use App\Models\Server;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use DateTimeInterface;
|
||||
use Exception;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
|
||||
@@ -37,9 +37,7 @@ class BackupRemoteUploadController extends Controller
|
||||
$node = $request->attributes->get('node');
|
||||
|
||||
$size = (int) $request->query('size');
|
||||
if (empty($size)) {
|
||||
throw new BadRequestHttpException('A non-empty "size" query parameter must be provided.');
|
||||
}
|
||||
throw_if(empty($size), new BadRequestHttpException('A non-empty "size" query parameter must be provided.'));
|
||||
|
||||
$backup = Backup::where('uuid', $backup)->firstOrFail();
|
||||
|
||||
|
||||
@@ -45,13 +45,9 @@ class BackupStatusController extends Controller
|
||||
// from messing with backups that they don't own.
|
||||
/** @var Server $server */
|
||||
$server = $model->server;
|
||||
if ($server->node_id !== $node->id) {
|
||||
throw new HttpForbiddenException('Requesting node does not have permission to access this server.');
|
||||
}
|
||||
throw_if($server->node_id !== $node->id, new HttpForbiddenException('Requesting node does not have permission to access this server.'));
|
||||
|
||||
if ($model->is_successful) {
|
||||
throw new BadRequestHttpException('Cannot update the status of a backup that is already marked as completed.');
|
||||
}
|
||||
throw_if($model->is_successful, new BadRequestHttpException('Cannot update the status of a backup that is already marked as completed.'));
|
||||
|
||||
$action = $request->boolean('successful') ? 'server:backup.complete' : 'server:backup.fail';
|
||||
$log = Activity::event($action)->subject($model, $model->server)->property('name', $model->name);
|
||||
@@ -99,9 +95,7 @@ class BackupStatusController extends Controller
|
||||
$model = Backup::query()->where('uuid', $backup)->firstOrFail();
|
||||
|
||||
$node = $request->attributes->get('node');
|
||||
if (!$model->server->node->is($node)) {
|
||||
throw new HttpForbiddenException('Requesting node does not have permission to access this server.');
|
||||
}
|
||||
throw_unless($model->server->node->is($node), new HttpForbiddenException('Requesting node does not have permission to access this server.'));
|
||||
|
||||
$model->server->update(['status' => null]);
|
||||
|
||||
|
||||
@@ -16,9 +16,7 @@ class ServerContainersController extends Controller
|
||||
*/
|
||||
public function status(Request $request, Server $server): JsonResponse
|
||||
{
|
||||
if (!$server->node->is($request->attributes->get('node'))) {
|
||||
throw new HttpForbiddenException('Requesting node does not have permission to access this server.');
|
||||
}
|
||||
throw_unless($server->node->is($request->attributes->get('node')), new HttpForbiddenException('Requesting node does not have permission to access this server.'));
|
||||
|
||||
$status = ContainerStatus::tryFrom($request->json('data.new_state')) ?? ContainerStatus::Missing;
|
||||
|
||||
|
||||
@@ -45,9 +45,7 @@ class ServerDetailsController extends Controller
|
||||
// to fetch these details.
|
||||
$valid = $transfer ? $node->id === $transfer->old_node || $node->id === $transfer->new_node : $node->id === $server->node_id;
|
||||
|
||||
if (!$valid) {
|
||||
throw new HttpForbiddenException('Requesting node does not have permission to access this server.');
|
||||
}
|
||||
throw_unless($valid, new HttpForbiddenException('Requesting node does not have permission to access this server.'));
|
||||
|
||||
return new JsonResponse([
|
||||
'settings' => $this->configurationStructureService->handle($server),
|
||||
|
||||
@@ -20,9 +20,7 @@ class ServerInstallController extends Controller
|
||||
*/
|
||||
public function index(Request $request, Server $server): JsonResponse
|
||||
{
|
||||
if (!$server->node->is($request->attributes->get('node'))) {
|
||||
throw new HttpForbiddenException('Requesting node does not have permission to access this server.');
|
||||
}
|
||||
throw_unless($server->node->is($request->attributes->get('node')), new HttpForbiddenException('Requesting node does not have permission to access this server.'));
|
||||
|
||||
$egg = $server->egg;
|
||||
|
||||
@@ -42,9 +40,7 @@ class ServerInstallController extends Controller
|
||||
{
|
||||
$status = null;
|
||||
|
||||
if (!$server->node->is($request->attributes->get('node'))) {
|
||||
throw new HttpForbiddenException('Requesting node does not have permission to access this server.');
|
||||
}
|
||||
throw_unless($server->node->is($request->attributes->get('node')), new HttpForbiddenException('Requesting node does not have permission to access this server.'));
|
||||
|
||||
$successful = $request->boolean('successful');
|
||||
|
||||
|
||||
@@ -35,18 +35,14 @@ class ServerTransferController extends Controller
|
||||
public function failure(Request $request, Server $server): JsonResponse
|
||||
{
|
||||
$transfer = $server->transfer;
|
||||
if (is_null($transfer)) {
|
||||
throw new ConflictHttpException('Server is not being transferred.');
|
||||
}
|
||||
throw_if(is_null($transfer), new ConflictHttpException('Server is not being transferred.'));
|
||||
|
||||
/* @var Node $node */
|
||||
Assert::isInstanceOf($node = $request->attributes->get('node'), Node::class);
|
||||
|
||||
// Either node can tell the panel that the transfer has failed. Only the new node
|
||||
// can tell the panel that it was successful.
|
||||
if (!$node->is($transfer->newNode) && !$node->is($transfer->oldNode)) {
|
||||
throw new HttpForbiddenException('Requesting node does not have permission to access this server.');
|
||||
}
|
||||
throw_if(!$node->is($transfer->newNode) && !$node->is($transfer->oldNode), new HttpForbiddenException('Requesting node does not have permission to access this server.'));
|
||||
|
||||
$this->connection->transaction(function () use ($transfer) {
|
||||
$transfer->forceFill(['successful' => false])->saveOrFail();
|
||||
@@ -68,18 +64,14 @@ class ServerTransferController extends Controller
|
||||
public function success(Request $request, Server $server): JsonResponse
|
||||
{
|
||||
$transfer = $server->transfer;
|
||||
if (is_null($transfer)) {
|
||||
throw new ConflictHttpException('Server is not being transferred.');
|
||||
}
|
||||
throw_if(is_null($transfer), new ConflictHttpException('Server is not being transferred.'));
|
||||
|
||||
/* @var Node $node */
|
||||
Assert::isInstanceOf($node = $request->attributes->get('node'), Node::class);
|
||||
|
||||
// Only the new node communicates a successful state to the panel, so we should
|
||||
// not allow the old node to hit this endpoint.
|
||||
if (!$node->is($transfer->newNode)) {
|
||||
throw new HttpForbiddenException('Requesting node does not have permission to access this server.');
|
||||
}
|
||||
throw_unless($node->is($transfer->newNode), new HttpForbiddenException('Requesting node does not have permission to access this server.'));
|
||||
|
||||
/** @var Server $server */
|
||||
$server = $this->connection->transaction(function () use ($server, $transfer) {
|
||||
|
||||
@@ -32,9 +32,7 @@ class SftpAuthenticationController extends Controller
|
||||
public function __invoke(SftpAuthenticationFormRequest $request): JsonResponse
|
||||
{
|
||||
$connection = $this->parseUsername($request->input('username'));
|
||||
if (empty($connection['server'])) {
|
||||
throw new BadRequestHttpException('No valid server identifier was included in the request.');
|
||||
}
|
||||
throw_if(empty($connection['server']), new BadRequestHttpException('No valid server identifier was included in the request.'));
|
||||
|
||||
if ($this->hasTooManyLoginAttempts($request)) {
|
||||
$seconds = $this->limiter()->availableIn($this->throttleKey($request));
|
||||
|
||||
@@ -17,9 +17,7 @@ class AuthenticateApplicationUser
|
||||
{
|
||||
/** @var User|null $user */
|
||||
$user = $request->user();
|
||||
if (!$user || !$user->isAdmin()) {
|
||||
throw new AccessDeniedHttpException('This account does not have permission to access the API.');
|
||||
}
|
||||
throw_if(!$user || !$user->isAdmin(), new AccessDeniedHttpException('This account does not have permission to access the API.'));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
@@ -17,9 +17,7 @@ class RequireClientApiKey
|
||||
{
|
||||
$token = $request->user()->currentAccessToken();
|
||||
|
||||
if ($token instanceof ApiKey && $token->key_type === ApiKey::TYPE_APPLICATION) {
|
||||
throw new AccessDeniedHttpException('You are attempting to use an application API key on an endpoint that requires a client API key.');
|
||||
}
|
||||
throw_if($token instanceof ApiKey && $token->key_type === ApiKey::TYPE_APPLICATION, new AccessDeniedHttpException('You are attempting to use an application API key on an endpoint that requires a client API key.'));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
@@ -34,18 +34,14 @@ class AuthenticateServerAccess
|
||||
$user = $request->user();
|
||||
$server = $request->route()->parameter('server');
|
||||
|
||||
if (!$server instanceof Server) {
|
||||
throw new NotFoundHttpException(trans('exceptions.api.resource_not_found'));
|
||||
}
|
||||
throw_unless($server instanceof Server, new NotFoundHttpException(trans('exceptions.api.resource_not_found')));
|
||||
|
||||
// At the very least, ensure that the user trying to make this request is the
|
||||
// server owner, a subuser, or an admin. We'll leave it up to the controllers
|
||||
// to authenticate more detailed permissions if needed.
|
||||
if ($user->id !== $server->owner_id && $user->cannot('update server', $server)) {
|
||||
// Check for subuser status.
|
||||
if (!$server->subusers->contains('user_id', $user->id)) {
|
||||
throw new NotFoundHttpException(trans('exceptions.api.resource_not_found'));
|
||||
}
|
||||
throw_unless($server->subusers->contains('user_id', $user->id), new NotFoundHttpException(trans('exceptions.api.resource_not_found')));
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -54,12 +50,8 @@ class AuthenticateServerAccess
|
||||
// Still allow users to get information about their server if it is installing or
|
||||
// being transferred.
|
||||
if (!$request->routeIs('api:client:server.view')) {
|
||||
if (($server->isSuspended() || $server->node->isUnderMaintenance()) && !$request->routeIs('api:client:server.resources')) {
|
||||
throw $exception;
|
||||
}
|
||||
if ($user->cannot('update server', $server) || !$request->routeIs($this->except)) {
|
||||
throw $exception;
|
||||
}
|
||||
throw_if(($server->isSuspended() || $server->node->isUnderMaintenance()) && !$request->routeIs('api:client:server.resources'), $exception);
|
||||
throw_if($user->cannot('update server', $server) || !$request->routeIs($this->except), $exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,9 +31,7 @@ class ResourceBelongsToServer
|
||||
$params = $request->route()->parameters();
|
||||
|
||||
$server = $params['server'] ?? null;
|
||||
if (!$server instanceof Server) {
|
||||
throw new InvalidArgumentException('This middleware cannot be used in a context that is missing a server in the parameters.');
|
||||
}
|
||||
throw_unless($server instanceof Server, new InvalidArgumentException('This middleware cannot be used in a context that is missing a server in the parameters.'));
|
||||
|
||||
/** @var Server $server */
|
||||
$server = $request->route()->parameter('server');
|
||||
@@ -55,17 +53,13 @@ class ResourceBelongsToServer
|
||||
case Database::class:
|
||||
case Schedule::class:
|
||||
case Subuser::class:
|
||||
if ($model->server_id !== $server->id) {
|
||||
throw $exception;
|
||||
}
|
||||
throw_if($model->server_id !== $server->id, $exception);
|
||||
break;
|
||||
// Regular users are a special case here as we need to make sure they're
|
||||
// currently assigned as a subuser on the server.
|
||||
case User::class:
|
||||
$subuser = $server->subusers()->where('user_id', $model->id)->first();
|
||||
if (is_null($subuser)) {
|
||||
throw $exception;
|
||||
}
|
||||
throw_if(is_null($subuser), $exception);
|
||||
// This is a special case to avoid an additional query being triggered
|
||||
// in the underlying logic.
|
||||
$request->attributes->set('subuser', $subuser);
|
||||
@@ -75,9 +69,7 @@ class ResourceBelongsToServer
|
||||
case Task::class:
|
||||
/** @var Schedule $schedule */
|
||||
$schedule = $request->route()->parameter('schedule');
|
||||
if ($model->schedule_id !== $schedule->id || $schedule->server_id !== $server->id) {
|
||||
throw $exception;
|
||||
}
|
||||
throw_if($model->schedule_id !== $schedule->id || $schedule->server_id !== $server->id, $exception);
|
||||
break;
|
||||
default:
|
||||
// Don't return a 404 here since we want to make sure no one relies
|
||||
|
||||
@@ -31,15 +31,11 @@ class DaemonAuthenticate
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
if (is_null($bearer = $request->bearerToken())) {
|
||||
throw new HttpException(401, 'Access to this endpoint must include an Authorization header.', null, ['WWW-Authenticate' => 'Bearer']);
|
||||
}
|
||||
throw_if(is_null($bearer = $request->bearerToken()), new HttpException(401, 'Access to this endpoint must include an Authorization header.', null, ['WWW-Authenticate' => 'Bearer']));
|
||||
|
||||
$parts = explode('.', $bearer);
|
||||
// Ensure that all the correct parts are provided in the header.
|
||||
if (count($parts) !== 2 || empty($parts[0]) || empty($parts[1])) {
|
||||
throw new BadRequestHttpException('The Authorization header provided was not in a valid format.');
|
||||
}
|
||||
throw_if(count($parts) !== 2 || empty($parts[0]) || empty($parts[1]), new BadRequestHttpException('The Authorization header provided was not in a valid format.'));
|
||||
|
||||
/** @var Node $node */
|
||||
$node = Node::query()->where('daemon_token_id', $parts[0])->firstOrFail();
|
||||
|
||||
@@ -49,9 +49,7 @@ class RequireTwoFactorAuthentication
|
||||
}
|
||||
|
||||
// For API calls return an exception which gets rendered nicely in the API response...
|
||||
if ($request->isJson() || Str::startsWith($request->path(), '/api')) {
|
||||
throw new TwoFactorAuthRequiredException();
|
||||
}
|
||||
throw_if($request->isJson() || Str::startsWith($request->path(), '/api'), new TwoFactorAuthRequiredException());
|
||||
|
||||
// ... otherwise display banner and redirect to profile
|
||||
AlertBanner::make('2fa_must_be_enabled')
|
||||
|
||||
@@ -33,9 +33,7 @@ abstract class ApplicationApiRequest extends FormRequest
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
if (is_null($this->resource)) {
|
||||
throw new PanelException('An ACL resource must be defined on API requests.');
|
||||
}
|
||||
throw_if(is_null($this->resource), new PanelException('An ACL resource must be defined on API requests.'));
|
||||
|
||||
/** @var TransientToken|ApiKey $token */
|
||||
$token = $this->user()->currentAccessToken();
|
||||
|
||||
@@ -68,9 +68,7 @@ class StoreSSHKeyRequest extends ClientApiRequest
|
||||
*/
|
||||
public function getKeyFingerprint(): string
|
||||
{
|
||||
if (!$this->key) {
|
||||
throw new Exception('The public key was not properly loaded for this request.');
|
||||
}
|
||||
throw_unless($this->key, new Exception('The public key was not properly loaded for this request.'));
|
||||
|
||||
return $this->key->getFingerprint('sha256');
|
||||
}
|
||||
|
||||
@@ -22,9 +22,7 @@ class UpdateEmailRequest extends ClientApiRequest
|
||||
$hasher = Container::getInstance()->make(Hasher::class);
|
||||
|
||||
// Verify password matches when changing password or email.
|
||||
if (!$hasher->check($this->input('password'), $this->user()->password)) {
|
||||
throw new InvalidPasswordProvidedException(trans('validation.internal.invalid_password'));
|
||||
}
|
||||
throw_unless($hasher->check($this->input('password'), $this->user()->password), new InvalidPasswordProvidedException(trans('validation.internal.invalid_password')));
|
||||
|
||||
return !$this->user()->is_managed_externally;
|
||||
}
|
||||
|
||||
@@ -21,9 +21,7 @@ class UpdatePasswordRequest extends ClientApiRequest
|
||||
$hasher = Container::getInstance()->make(Hasher::class);
|
||||
|
||||
// Verify password matches when changing password or email.
|
||||
if (!$hasher->check($this->input('current_password'), $this->user()->password)) {
|
||||
throw new InvalidPasswordProvidedException(trans('validation.internal.invalid_password'));
|
||||
}
|
||||
throw_unless($hasher->check($this->input('current_password'), $this->user()->password), new InvalidPasswordProvidedException(trans('validation.internal.invalid_password')));
|
||||
|
||||
return !$this->user()->is_managed_externally;
|
||||
}
|
||||
|
||||
@@ -22,9 +22,7 @@ class UpdateUsernameRequest extends ClientApiRequest
|
||||
$hasher = Container::getInstance()->make(Hasher::class);
|
||||
|
||||
// Verify password matches when changing password or email.
|
||||
if (!$hasher->check($this->input('password'), $this->user()->password)) {
|
||||
throw new InvalidPasswordProvidedException(trans('validation.internal.invalid_password'));
|
||||
}
|
||||
throw_unless($hasher->check($this->input('password'), $this->user()->password), new InvalidPasswordProvidedException(trans('validation.internal.invalid_password')));
|
||||
|
||||
return !$this->user()->is_managed_externally;
|
||||
}
|
||||
|
||||
@@ -28,9 +28,7 @@ class ViewScheduleRequest extends ClientApiRequest
|
||||
if ($server instanceof Server && $schedule instanceof Schedule) {
|
||||
$task = $this->route()->parameter('task');
|
||||
|
||||
if ($schedule->server_id !== $server->id || ($task instanceof Task && $task->schedule_id !== $schedule->id)) {
|
||||
throw new NotFoundHttpException('The requested resource does not exist on the system.');
|
||||
}
|
||||
throw_if($schedule->server_id !== $server->id || ($task instanceof Task && $task->schedule_id !== $schedule->id), new NotFoundHttpException('The requested resource does not exist on the system.'));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -70,8 +70,6 @@ abstract class SubuserRequest extends ClientApiRequest
|
||||
/** @var GetUserPermissionsService $service */
|
||||
$service = $this->container->make(GetUserPermissionsService::class);
|
||||
|
||||
if (count(array_diff($permissions, $service->handle($server, $user))) > 0) {
|
||||
throw new HttpForbiddenException('Cannot assign permissions to a subuser that your account does not actively possess.');
|
||||
}
|
||||
throw_if(count(array_diff($permissions, $service->handle($server, $user))) > 0, new HttpForbiddenException('Cannot assign permissions to a subuser that your account does not actively possess.'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,17 +56,13 @@ class RunTaskJob implements ShouldQueue
|
||||
try {
|
||||
$taskSchema = $taskService->get($this->task->action);
|
||||
|
||||
if (!$taskSchema) {
|
||||
throw new InvalidArgumentException('Invalid task action provided: ' . $this->task->action);
|
||||
}
|
||||
throw_unless($taskSchema, new InvalidArgumentException('Invalid task action provided: ' . $this->task->action));
|
||||
|
||||
$taskSchema->runTask($this->task);
|
||||
} catch (Exception $exception) {
|
||||
// If this isn't a ConnectionException on a task that allows for failures
|
||||
// throw the exception back up the chain so that the task is stopped.
|
||||
if (!($this->task->continue_on_failure && $exception instanceof ConnectionException)) {
|
||||
throw $exception;
|
||||
}
|
||||
throw_unless(($this->task->continue_on_failure && $exception instanceof ConnectionException), $exception);
|
||||
}
|
||||
|
||||
$this->markTaskNotQueued();
|
||||
@@ -89,7 +85,7 @@ class RunTaskJob implements ShouldQueue
|
||||
{
|
||||
/** @var Task|null $nextTask */
|
||||
$nextTask = Task::query()->where('schedule_id', $this->task->schedule_id)
|
||||
->orderBy('sequence_id', 'asc')
|
||||
->orderBy('sequence_id')
|
||||
->where('sequence_id', '>', $this->task->sequence_id)
|
||||
->first();
|
||||
|
||||
|
||||
@@ -79,9 +79,7 @@ class CacheStep
|
||||
->afterValidation(function (Get $get, Application $app) use ($installer) {
|
||||
$driver = $get('env_cache.CACHE_STORE');
|
||||
|
||||
if (!self::testConnection($app, $driver, $get('env_cache.REDIS_HOST'), $get('env_cache.REDIS_PORT'), $get('env_cache.REDIS_USERNAME'), $get('env_cache.REDIS_PASSWORD'))) {
|
||||
throw new Halt('Redis connection failed');
|
||||
}
|
||||
throw_unless(self::testConnection($app, $driver, $get('env_cache.REDIS_HOST'), $get('env_cache.REDIS_PORT'), $get('env_cache.REDIS_USERNAME'), $get('env_cache.REDIS_PASSWORD')), new Halt('Redis connection failed'));
|
||||
|
||||
$installer->writeToEnv('env_cache');
|
||||
});
|
||||
|
||||
@@ -97,9 +97,7 @@ class DatabaseStep
|
||||
->afterValidation(function (Get $get) use ($installer) {
|
||||
$driver = $get('env_database.DB_CONNECTION');
|
||||
|
||||
if (!self::testConnection($driver, $get('env_database.DB_HOST'), $get('env_database.DB_PORT'), $get('env_database.DB_DATABASE'), $get('env_database.DB_USERNAME'), $get('env_database.DB_PASSWORD'))) {
|
||||
throw new Halt(trans('installer.database.exceptions.connection'));
|
||||
}
|
||||
throw_unless(self::testConnection($driver, $get('env_database.DB_HOST'), $get('env_database.DB_PORT'), $get('env_database.DB_DATABASE'), $get('env_database.DB_USERNAME'), $get('env_database.DB_PASSWORD')), new Halt(trans('installer.database.exceptions.connection')));
|
||||
|
||||
$installer->writeToEnv('env_database');
|
||||
});
|
||||
|
||||
@@ -123,9 +123,7 @@ class ActivityLog extends Model implements HasIcon, HasLabel
|
||||
|
||||
public function prunable(): Builder
|
||||
{
|
||||
if (is_null(config('activity.prune_days'))) {
|
||||
throw new LogicException('Cannot prune activity logs: no "prune_days" configuration value is set.');
|
||||
}
|
||||
throw_if(is_null(config('activity.prune_days')), new LogicException('Cannot prune activity logs: no "prune_days" configuration value is set.'));
|
||||
|
||||
return static::where('timestamp', '<=', Carbon::now()->subDays(config('activity.prune_days')));
|
||||
}
|
||||
|
||||
@@ -28,9 +28,7 @@ class MultiFieldServerFilter implements Filter
|
||||
*/
|
||||
public function __invoke(Builder $query, $value, string $property): void
|
||||
{
|
||||
if ($query->getQuery()->from !== 'servers') {
|
||||
throw new BadMethodCallException('Cannot use the MultiFieldServerFilter against a non-server model.');
|
||||
}
|
||||
throw_if($query->getQuery()->from !== 'servers', new BadMethodCallException('Cannot use the MultiFieldServerFilter against a non-server model.'));
|
||||
|
||||
if (preg_match(self::IPV4_REGEX, $value) || preg_match('/^:\d{1,5}$/', $value)) {
|
||||
$query
|
||||
|
||||
@@ -133,9 +133,7 @@ class Plugin extends Model implements HasPluginSettings
|
||||
$data = File::json($path, JSON_THROW_ON_ERROR);
|
||||
$data['id'] = Str::lower($data['id']);
|
||||
|
||||
if ($data['id'] !== Str::lower($plugin)) {
|
||||
throw new PluginIdMismatchException("Plugin id mismatch for folder name ($plugin) and id in plugin.json ({$data['id']})!");
|
||||
}
|
||||
throw_if($data['id'] !== Str::lower($plugin), new PluginIdMismatchException("Plugin id mismatch for folder name ($plugin) and id in plugin.json ({$data['id']})!"));
|
||||
|
||||
$panels = null;
|
||||
if (array_key_exists('panels', $data)) {
|
||||
@@ -171,9 +169,7 @@ class Plugin extends Model implements HasPluginSettings
|
||||
|
||||
$plugins[] = $data;
|
||||
} catch (Exception $exception) {
|
||||
if (config('panel.plugin.dev_mode', false)) {
|
||||
throw ($exception);
|
||||
}
|
||||
throw_if(config('panel.plugin.dev_mode', false), ($exception));
|
||||
|
||||
report($exception);
|
||||
|
||||
|
||||
@@ -429,9 +429,7 @@ class Server extends Model implements HasAvatar, Validatable
|
||||
*/
|
||||
public function validateCurrentState(): void
|
||||
{
|
||||
if ($this->isInConflictState()) {
|
||||
throw new ServerStateConflictException($this);
|
||||
}
|
||||
throw_if($this->isInConflictState(), new ServerStateConflictException($this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -442,11 +440,9 @@ class Server extends Model implements HasAvatar, Validatable
|
||||
*/
|
||||
public function validateTransferState(): void
|
||||
{
|
||||
if (
|
||||
!$this->isInstalled() ||
|
||||
if (!$this->isInstalled() ||
|
||||
$this->status === ServerState::RestoringBackup ||
|
||||
!is_null($this->transfer)
|
||||
) {
|
||||
!is_null($this->transfer)) {
|
||||
throw new ServerStateConflictException($this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,15 +48,11 @@ trait HasIcon
|
||||
default => null,
|
||||
};
|
||||
|
||||
if (is_null($normalizedExtension)) {
|
||||
throw new Exception(trans('admin/egg.import.unknown_extension', ['extension' => $extension]));
|
||||
}
|
||||
throw_if(is_null($normalizedExtension), new Exception(trans('admin/egg.import.unknown_extension', ['extension' => $extension])));
|
||||
|
||||
$fileName = static::getIconStoragePath() . "/$this->uuid.$normalizedExtension";
|
||||
|
||||
if (!Storage::disk('public')->put($fileName, $data)) {
|
||||
throw new Exception(trans('admin/egg.import.could_not_write'));
|
||||
}
|
||||
throw_unless(Storage::disk('public')->put($fileName, $data), new Exception(trans('admin/egg.import.could_not_write')));
|
||||
|
||||
foreach (['png', 'jpg', 'jpeg', 'webp', 'svg'] as $ext) {
|
||||
if ($ext === $normalizedExtension) {
|
||||
|
||||
@@ -317,7 +317,7 @@ class WebhookConfiguration extends Model
|
||||
$serverEvents = collect(static::discoverCustomEvents())
|
||||
->merge(static::allModelEvents())
|
||||
->unique()
|
||||
->filter(fn ($event) => str($event)->contains('App\\Models\\Server') && !str($event)->contains('Subuser'))
|
||||
->filter(fn ($event) => str($event)->contains(Server::class) && !str($event)->contains('Subuser'))
|
||||
->values()
|
||||
->all();
|
||||
|
||||
|
||||
@@ -30,21 +30,15 @@ class DaemonFileRepository extends DaemonRepository
|
||||
} catch (RequestException $exception) {
|
||||
$status = $exception->response->status();
|
||||
|
||||
if ($status === 400) {
|
||||
throw new FileNotEditableException();
|
||||
}
|
||||
throw_if($status === 400, new FileNotEditableException());
|
||||
|
||||
if ($status === 404) {
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
throw_if($status === 404, new FileNotFoundException());
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
$length = $response->header('Content-Length');
|
||||
if ($notLargerThan && $length > $notLargerThan) {
|
||||
throw new FileSizeTooLargeException();
|
||||
}
|
||||
throw_if($notLargerThan && $length > $notLargerThan, new FileSizeTooLargeException());
|
||||
|
||||
return $response;
|
||||
}
|
||||
@@ -64,9 +58,7 @@ class DaemonFileRepository extends DaemonRepository
|
||||
->withBody($content)
|
||||
->post("/api/servers/{$this->server->uuid}/files/write");
|
||||
} catch (RequestException $exception) {
|
||||
if ($exception->response->status() === 400) {
|
||||
throw new FileExistsException();
|
||||
}
|
||||
throw_if($exception->response->status() === 400, new FileExistsException());
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
@@ -102,9 +94,7 @@ class DaemonFileRepository extends DaemonRepository
|
||||
]
|
||||
);
|
||||
} catch (RequestException $exception) {
|
||||
if ($exception->response->status() === 400) {
|
||||
throw new FileExistsException();
|
||||
}
|
||||
throw_if($exception->response->status() === 400, new FileExistsException());
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
@@ -59,13 +59,9 @@ abstract class DaemonRepository
|
||||
}
|
||||
|
||||
$header = $condition->header('User-Agent');
|
||||
if (
|
||||
empty($header) ||
|
||||
throw_if(empty($header) ||
|
||||
preg_match('/^Pelican Wings\/v(?:\d+\.\d+\.\d+|develop) \(id:(\w*)\)$/', $header, $matches) &&
|
||||
array_get($matches, 1, '') !== $this->node->daemon_token_id
|
||||
) {
|
||||
throw new ConnectionException($condition->effectiveUri()->__toString() . ' does not match node token_id !');
|
||||
}
|
||||
array_get($matches, 1, '') !== $this->node->daemon_token_id, new ConnectionException($condition->effectiveUri()->__toString() . ' does not match node token_id !'));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -22,9 +22,7 @@ class DaemonSystemRepository extends DaemonRepository
|
||||
->get('/api/system')
|
||||
->throwIf(function ($result) {
|
||||
$this->enforceValidNodeToken($result);
|
||||
if (!$result->collect()->has(['architecture', 'cpu_count', 'kernel_version', 'os', 'version'])) {
|
||||
throw new ConnectionException($result->effectiveUri()->__toString() . ' is not Pelican Wings !');
|
||||
}
|
||||
throw_unless($result->collect()->has(['architecture', 'cpu_count', 'kernel_version', 'os', 'version']), new ConnectionException($result->effectiveUri()->__toString() . ' is not Pelican Wings !'));
|
||||
|
||||
return true;
|
||||
})->json();
|
||||
|
||||
@@ -46,9 +46,7 @@ class AssignmentService
|
||||
{
|
||||
$explode = explode('/', $data['allocation_ip']);
|
||||
if (count($explode) !== 1) {
|
||||
if (!ctype_digit($explode[1]) || ($explode[1] > self::CIDR_MIN_BITS || $explode[1] < self::CIDR_MAX_BITS)) {
|
||||
throw new CidrOutOfRangeException();
|
||||
}
|
||||
throw_if(!ctype_digit($explode[1]) || ($explode[1] > self::CIDR_MIN_BITS || $explode[1] < self::CIDR_MAX_BITS), new CidrOutOfRangeException());
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -62,21 +60,15 @@ class AssignmentService
|
||||
$ids = [];
|
||||
foreach ($parsed as $ip) {
|
||||
foreach ($data['allocation_ports'] as $port) {
|
||||
if (!is_digit($port) && !preg_match(self::PORT_RANGE_REGEX, $port)) {
|
||||
throw new InvalidPortMappingException($port);
|
||||
}
|
||||
throw_if(!is_digit($port) && !preg_match(self::PORT_RANGE_REGEX, $port), new InvalidPortMappingException($port));
|
||||
|
||||
$newAllocations = [];
|
||||
if (preg_match(self::PORT_RANGE_REGEX, $port, $matches)) {
|
||||
$block = range($matches[1], $matches[2]);
|
||||
|
||||
if (count($block) > self::PORT_RANGE_LIMIT) {
|
||||
throw new TooManyPortsInRangeException();
|
||||
}
|
||||
throw_if(count($block) > self::PORT_RANGE_LIMIT, new TooManyPortsInRangeException());
|
||||
|
||||
if ((int) $matches[1] < self::PORT_FLOOR || (int) $matches[2] > self::PORT_CEIL) {
|
||||
throw new PortOutOfRangeException();
|
||||
}
|
||||
throw_if((int) $matches[1] < self::PORT_FLOOR || (int) $matches[2] > self::PORT_CEIL, new PortOutOfRangeException());
|
||||
|
||||
foreach ($block as $unit) {
|
||||
$newAllocations[] = [
|
||||
@@ -89,9 +81,7 @@ class AssignmentService
|
||||
];
|
||||
}
|
||||
} else {
|
||||
if ((int) $port < self::PORT_FLOOR || (int) $port > self::PORT_CEIL) {
|
||||
throw new PortOutOfRangeException();
|
||||
}
|
||||
throw_if((int) $port < self::PORT_FLOOR || (int) $port > self::PORT_CEIL, new PortOutOfRangeException());
|
||||
|
||||
$newAllocations[] = [
|
||||
'node_id' => $node->id,
|
||||
|
||||
@@ -35,9 +35,7 @@ class FindAssignableAllocationService
|
||||
*/
|
||||
public function handle(Server $server): Allocation
|
||||
{
|
||||
if (!config('panel.client_features.allocations.enabled')) {
|
||||
throw new AutoAllocationNotEnabledException();
|
||||
}
|
||||
throw_unless(config('panel.client_features.allocations.enabled'), new AutoAllocationNotEnabledException());
|
||||
|
||||
$createNew = config('panel.client_features.allocations.create_new', true);
|
||||
|
||||
@@ -67,9 +65,7 @@ class FindAssignableAllocationService
|
||||
->first();
|
||||
|
||||
// If create_new is disabled, only pick from existing allocations
|
||||
if (!$createNew && !$allocation) {
|
||||
throw new NoAutoAllocationSpaceAvailableException();
|
||||
}
|
||||
throw_if(!$createNew && !$allocation, new NoAutoAllocationSpaceAvailableException());
|
||||
|
||||
// If create_new is enabled, create a new allocation if none available
|
||||
$allocation ??= $this->createNewAllocation($server, $start, $end);
|
||||
@@ -92,9 +88,7 @@ class FindAssignableAllocationService
|
||||
*/
|
||||
protected function createNewAllocation(Server $server, ?int $start, ?int $end): Allocation
|
||||
{
|
||||
if (!$start || !$end) {
|
||||
throw new NoAutoAllocationSpaceAvailableException();
|
||||
}
|
||||
throw_if(!$start || !$end, new NoAutoAllocationSpaceAvailableException());
|
||||
|
||||
// Get all the currently allocated ports for the node so that we can figure out
|
||||
// which port might be available.
|
||||
@@ -111,9 +105,7 @@ class FindAssignableAllocationService
|
||||
$available = array_diff(range($start, $end), $ports->toArray());
|
||||
|
||||
// If we've already allocated all the ports, just abort.
|
||||
if (empty($available)) {
|
||||
throw new NoAutoAllocationSpaceAvailableException();
|
||||
}
|
||||
throw_if(empty($available), new NoAutoAllocationSpaceAvailableException());
|
||||
|
||||
// Pick a random port out of the remaining available ports.
|
||||
/** @var int $port */
|
||||
|
||||
@@ -27,9 +27,7 @@ class DeleteBackupService
|
||||
// I also don't really see any reason you'd have a locked, failed backup to keep
|
||||
// around. The logic that updates the backup to the failed state will also remove
|
||||
// the lock, so this condition should really never happen.
|
||||
if ($backup->is_locked && ($backup->is_successful && !is_null($backup->completed_at))) {
|
||||
throw new BackupLockedException();
|
||||
}
|
||||
throw_if($backup->is_locked && ($backup->is_successful && !is_null($backup->completed_at)), new BackupLockedException());
|
||||
|
||||
$schema = $this->backupService->get($backup->backupHost->schema);
|
||||
if (!$schema) {
|
||||
|
||||
@@ -95,17 +95,13 @@ class InitiateBackupService
|
||||
$successful = $server->backups()->nonFailed();
|
||||
if (!$server->backup_limit || $successful->count() >= $server->backup_limit) {
|
||||
// Do not allow the user to continue if this server is already at its limit and can't override.
|
||||
if (!$override || $server->backup_limit <= 0) {
|
||||
throw new TooManyBackupsException($server->backup_limit);
|
||||
}
|
||||
throw_if(!$override || $server->backup_limit <= 0, new TooManyBackupsException($server->backup_limit));
|
||||
|
||||
// Get the oldest backup the server has that is not "locked" (indicating a backup that should
|
||||
// never be automatically purged). If we find a backup we will delete it and then continue with
|
||||
// this process. If no backup is found that can be used an exception is thrown.
|
||||
$oldest = $successful->where('is_locked', false)->orderBy('created_at')->first();
|
||||
if (!$oldest) {
|
||||
throw new TooManyBackupsException($server->backup_limit);
|
||||
}
|
||||
throw_unless($oldest, new TooManyBackupsException($server->backup_limit));
|
||||
|
||||
$this->deleteBackupService->handle($oldest);
|
||||
}
|
||||
|
||||
@@ -70,22 +70,16 @@ class DatabaseManagementService
|
||||
*/
|
||||
public function create(Server $server, array $data): Database
|
||||
{
|
||||
if (!config('panel.client_features.databases.enabled')) {
|
||||
throw new DatabaseClientFeatureNotEnabledException();
|
||||
}
|
||||
throw_unless(config('panel.client_features.databases.enabled'), new DatabaseClientFeatureNotEnabledException());
|
||||
|
||||
if ($this->validateDatabaseLimit) {
|
||||
// If the server has a limit assigned and we've already reached that limit, throw back
|
||||
// an exception and kill the process.
|
||||
if (!is_null($server->database_limit) && $server->databases()->count() >= $server->database_limit) {
|
||||
throw new TooManyDatabasesException();
|
||||
}
|
||||
throw_if(!is_null($server->database_limit) && $server->databases()->count() >= $server->database_limit, new TooManyDatabasesException());
|
||||
}
|
||||
|
||||
// Protect against developer mistakes...
|
||||
if (empty($data['database']) || !preg_match(self::MATCH_NAME_REGEX, $data['database'])) {
|
||||
throw new InvalidArgumentException('The database name passed to DatabaseManagementService::handle MUST be prefixed with "s{server_id}_".');
|
||||
}
|
||||
throw_if(empty($data['database']) || !preg_match(self::MATCH_NAME_REGEX, $data['database']), new InvalidArgumentException('The database name passed to DatabaseManagementService::handle MUST be prefixed with "s{server_id}_".'));
|
||||
|
||||
$data = array_merge($data, [
|
||||
'server_id' => $server->id,
|
||||
@@ -171,9 +165,7 @@ class DatabaseManagementService
|
||||
->where('database', $data['database'])
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
throw new DuplicateDatabaseNameException('A database with that name already exists for this server.');
|
||||
}
|
||||
throw_if($exists, new DuplicateDatabaseNameException('A database with that name already exists for this server.'));
|
||||
|
||||
$database = (new Database())->forceFill($data);
|
||||
$database->saveOrFail();
|
||||
|
||||
@@ -21,15 +21,11 @@ readonly class DeployServerDatabaseService
|
||||
Assert::notEmpty($data['remote'] ?? null);
|
||||
|
||||
$hosts = DatabaseHost::query()->get();
|
||||
if ($hosts->isEmpty()) {
|
||||
throw new NoSuitableDatabaseHostException();
|
||||
}
|
||||
throw_if($hosts->isEmpty(), new NoSuitableDatabaseHostException());
|
||||
|
||||
$nodeHosts = $server->node->databaseHosts()->get();
|
||||
// TODO: @areyouscared remove allow random feature for database hosts
|
||||
if ($nodeHosts->isEmpty() && !config('panel.client_features.databases.allow_random')) {
|
||||
throw new NoSuitableDatabaseHostException();
|
||||
}
|
||||
throw_if($nodeHosts->isEmpty() && !config('panel.client_features.databases.allow_random'), new NoSuitableDatabaseHostException());
|
||||
|
||||
return $this->managementService->create($server, [
|
||||
'database_host_id' => $nodeHosts->isEmpty()
|
||||
|
||||
@@ -63,9 +63,7 @@ class AllocationSelectionService
|
||||
// Ranges are stored in the ports array as an array which can be
|
||||
// better processed in the repository.
|
||||
if (preg_match(AssignmentService::PORT_RANGE_REGEX, $port, $matches)) {
|
||||
if (abs((int) $matches[2] - (int) $matches[1]) > AssignmentService::PORT_RANGE_LIMIT) {
|
||||
throw new DisplayException(trans('exceptions.allocations.too_many_ports'));
|
||||
}
|
||||
throw_if(((int) $matches[2] - (int) $matches[1] + 1) > AssignmentService::PORT_RANGE_LIMIT, new DisplayException(trans('exceptions.allocations.too_many_ports')));
|
||||
|
||||
$stored[] = [$matches[1], $matches[2]];
|
||||
}
|
||||
@@ -85,9 +83,7 @@ class AllocationSelectionService
|
||||
{
|
||||
$allocation = $this->getRandomAllocation($this->nodes, $this->ports, $this->dedicated);
|
||||
|
||||
if (is_null($allocation)) {
|
||||
throw new NoViableAllocationException(trans('exceptions.deployment.no_viable_allocations'));
|
||||
}
|
||||
throw_if(is_null($allocation), new NoViableAllocationException(trans('exceptions.deployment.no_viable_allocations')));
|
||||
|
||||
return $allocation;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace App\Services\Eggs\Sharing;
|
||||
use App\Enums\EggFormat;
|
||||
use App\Models\Egg;
|
||||
use App\Models\EggVariable;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
@@ -52,9 +52,7 @@ class EggImporterService
|
||||
*/
|
||||
public function fromFile(UploadedFile $file, ?Egg $egg = null): Egg
|
||||
{
|
||||
if ($file->getError() !== UPLOAD_ERR_OK) {
|
||||
throw new InvalidFileUploadException('The selected file was not uploaded successfully');
|
||||
}
|
||||
throw_if($file->getError() !== UPLOAD_ERR_OK, new InvalidFileUploadException('The selected file was not uploaded successfully'));
|
||||
|
||||
$extension = strtolower($file->getClientOriginalExtension());
|
||||
$mime = $file->getMimeType();
|
||||
@@ -81,9 +79,7 @@ class EggImporterService
|
||||
{
|
||||
$extension = strtolower(pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION));
|
||||
|
||||
if (empty($extension)) {
|
||||
throw new InvalidFileUploadException('Unsupported file format.');
|
||||
}
|
||||
throw_if(empty($extension), new InvalidFileUploadException('Unsupported file format.'));
|
||||
|
||||
$format = match ($extension) {
|
||||
'yaml', 'yml' => EggFormat::YAML,
|
||||
|
||||
@@ -44,9 +44,7 @@ class VariableCreationService
|
||||
*/
|
||||
public function handle(int $egg, array $data): EggVariable
|
||||
{
|
||||
if (in_array(strtoupper(array_get($data, 'env_variable')), EggVariable::RESERVED_ENV_NAMES)) {
|
||||
throw new ReservedVariableNameException(sprintf('Cannot use the protected name %s for this environment variable.', array_get($data, 'env_variable')));
|
||||
}
|
||||
throw_if(in_array(strtoupper(array_get($data, 'env_variable')), EggVariable::RESERVED_ENV_NAMES), new ReservedVariableNameException(sprintf('Cannot use the protected name %s for this environment variable.', array_get($data, 'env_variable'))));
|
||||
|
||||
if (!empty($data['rules'] ?? [])) {
|
||||
$this->validateRules($data['rules']);
|
||||
|
||||
@@ -46,9 +46,7 @@ class VariableUpdateService
|
||||
public function handle(EggVariable $variable, array $data): EggVariable
|
||||
{
|
||||
if (!is_null(array_get($data, 'env_variable'))) {
|
||||
if (in_array(strtoupper(array_get($data, 'env_variable')), EggVariable::RESERVED_ENV_NAMES)) {
|
||||
throw new ReservedVariableNameException(trans('exceptions.variables.reserved_name', ['name' => array_get($data, 'env_variable')]));
|
||||
}
|
||||
throw_if(in_array(strtoupper(array_get($data, 'env_variable')), EggVariable::RESERVED_ENV_NAMES), new ReservedVariableNameException(trans('exceptions.variables.reserved_name', ['name' => array_get($data, 'env_variable')])));
|
||||
|
||||
$search = EggVariable::query()
|
||||
->where('env_variable', $data['env_variable'])
|
||||
@@ -56,9 +54,7 @@ class VariableUpdateService
|
||||
->whereNot('id', $variable->id)
|
||||
->count();
|
||||
|
||||
if ($search > 0) {
|
||||
throw new DisplayException(trans('exceptions.variables.env_not_unique', ['name' => array_get($data, 'env_variable')]));
|
||||
}
|
||||
throw_if($search > 0, new DisplayException(trans('exceptions.variables.env_not_unique', ['name' => array_get($data, 'env_variable')])));
|
||||
}
|
||||
|
||||
if (!empty($data['rules'] ?? [])) {
|
||||
|
||||
@@ -147,9 +147,7 @@ class PluginService
|
||||
|
||||
$pluginClass = $plugin->fullClass();
|
||||
|
||||
if (!class_exists($pluginClass)) {
|
||||
throw new Exception('Class "' . $pluginClass . '" not found');
|
||||
}
|
||||
throw_unless(class_exists($pluginClass), new Exception('Class "' . $pluginClass . '" not found'));
|
||||
|
||||
$panel->plugin(new $pluginClass());
|
||||
|
||||
@@ -199,9 +197,7 @@ class PluginService
|
||||
|
||||
if (count($oldPackages) > 0) {
|
||||
$result = Process::path(base_path())->timeout(600)->run(['composer', 'remove', ...$oldPackages]);
|
||||
if ($result->failed()) {
|
||||
throw new Exception('Could not remove old composer packages: ' . $result->errorOutput());
|
||||
}
|
||||
throw_if($result->failed(), new Exception('Could not remove old composer packages: ' . $result->errorOutput()));
|
||||
}
|
||||
|
||||
$newPackages = collect($newPackages)
|
||||
@@ -212,9 +208,7 @@ class PluginService
|
||||
|
||||
if (count($newPackages) > 0) {
|
||||
$result = Process::path(base_path())->timeout(600)->run(['composer', 'require', ...$newPackages]);
|
||||
if ($result->failed()) {
|
||||
throw new Exception('Could not require new composer packages: ' . $result->errorOutput());
|
||||
}
|
||||
throw_if($result->failed(), new Exception('Could not require new composer packages: ' . $result->errorOutput()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,20 +259,14 @@ class PluginService
|
||||
{
|
||||
try {
|
||||
$result = Process::path(base_path())->timeout(300)->run('yarn install');
|
||||
if ($result->failed()) {
|
||||
throw new Exception('Could not install yarn dependencies: ' . $result->errorOutput());
|
||||
}
|
||||
throw_if($result->failed(), new Exception('Could not install yarn dependencies: ' . $result->errorOutput()));
|
||||
|
||||
$result = Process::path(base_path())->timeout(600)->run('yarn build');
|
||||
if ($result->failed()) {
|
||||
throw new Exception('Could not build assets: ' . $result->errorOutput());
|
||||
}
|
||||
throw_if($result->failed(), new Exception('Could not build assets: ' . $result->errorOutput()));
|
||||
|
||||
return true;
|
||||
} catch (Exception $exception) {
|
||||
if ($throw || $this->isDevModeActive()) {
|
||||
throw ($exception);
|
||||
}
|
||||
throw_if($throw || $this->isDevModeActive(), ($exception));
|
||||
|
||||
Log::warning($exception->getMessage(), ['exception' => $exception]);
|
||||
}
|
||||
@@ -320,9 +308,7 @@ class PluginService
|
||||
public function updatePlugin(Plugin $plugin): void
|
||||
{
|
||||
$downloadUrl = $plugin->getDownloadUrlForUpdate();
|
||||
if (!$downloadUrl) {
|
||||
throw new Exception('No download url found.');
|
||||
}
|
||||
throw_unless($downloadUrl, new Exception('No download url found.'));
|
||||
|
||||
$this->downloadPluginFromUrl($downloadUrl, true);
|
||||
|
||||
@@ -361,15 +347,11 @@ class PluginService
|
||||
{
|
||||
// Validate file size to prevent zip bombs
|
||||
$maxSize = config('panel.plugin.max_import_size');
|
||||
if ($file->getSize() > $maxSize) {
|
||||
throw new Exception("Zip file too large. ($maxSize MiB)");
|
||||
}
|
||||
throw_if($file->getSize() > $maxSize, new Exception("Zip file too large. ($maxSize MiB)"));
|
||||
|
||||
$zip = new ZipArchive();
|
||||
|
||||
if (!$zip->open($file->getPathname())) {
|
||||
throw new Exception('Could not open zip file.');
|
||||
}
|
||||
throw_unless($zip->open($file->getPathname()), new Exception('Could not open zip file.'));
|
||||
|
||||
// Validate zip contents before extraction
|
||||
for ($i = 0; $i < $zip->numFiles; $i++) {
|
||||
@@ -407,13 +389,9 @@ class PluginService
|
||||
|
||||
// Validate file size to prevent zip bombs
|
||||
$maxSize = config('panel.plugin.max_import_size');
|
||||
if (strlen($content) > $maxSize) {
|
||||
throw new InvalidFileUploadException("Zip file too large. ($maxSize MiB)");
|
||||
}
|
||||
throw_if(strlen($content) > $maxSize, new InvalidFileUploadException("Zip file too large. ($maxSize MiB)"));
|
||||
|
||||
if (!file_put_contents($tmpPath, $content)) {
|
||||
throw new InvalidFileUploadException('Could not write temporary file.');
|
||||
}
|
||||
throw_unless(file_put_contents($tmpPath, $content), new InvalidFileUploadException('Could not write temporary file.'));
|
||||
|
||||
$this->downloadPluginFromFile(new UploadedFile($tmpPath, $basename, 'application/zip'), $cleanDownload);
|
||||
}
|
||||
@@ -509,9 +487,7 @@ class PluginService
|
||||
|
||||
private function handlePluginException(Plugin $plugin, Exception $exception): void
|
||||
{
|
||||
if ($this->isDevModeActive()) {
|
||||
throw ($exception);
|
||||
}
|
||||
throw_if($this->isDevModeActive(), ($exception));
|
||||
|
||||
report($exception);
|
||||
|
||||
|
||||
@@ -18,9 +18,7 @@ class NodeDeletionService
|
||||
$node = Node::findOrFail($node);
|
||||
}
|
||||
|
||||
if ($node->servers()->count() > 0) {
|
||||
throw new HasActiveServersException(trans('exceptions.node.servers_attached'));
|
||||
}
|
||||
throw_if($node->servers()->count() > 0, new HasActiveServersException(trans('exceptions.node.servers_attached')));
|
||||
|
||||
return (int) $node->delete();
|
||||
}
|
||||
|
||||
@@ -61,9 +61,7 @@ class NodeUpdateService
|
||||
return [$updated, false];
|
||||
});
|
||||
|
||||
if ($exception) {
|
||||
throw new ConfigurationNotPersistedException(trans('exceptions.node.daemon_off_config_updated'));
|
||||
}
|
||||
throw_if($exception, new ConfigurationNotPersistedException(trans('exceptions.node.daemon_off_config_updated')));
|
||||
|
||||
return $updated;
|
||||
}
|
||||
|
||||
@@ -23,9 +23,7 @@ class ProcessScheduleService
|
||||
{
|
||||
$task = $schedule->firstTask();
|
||||
|
||||
if (!$task) {
|
||||
throw new DisplayException('Cannot process schedule for task execution: no tasks are registered.');
|
||||
}
|
||||
throw_unless($task, new DisplayException('Cannot process schedule for task execution: no tasks are registered.'));
|
||||
|
||||
$this->connection->transaction(function () use ($schedule, $task) {
|
||||
$schedule->forceFill([
|
||||
|
||||
@@ -20,9 +20,7 @@ class ScheduleImporterService
|
||||
|
||||
public function fromFile(UploadedFile $file, Server $server): Schedule
|
||||
{
|
||||
if ($file->getError() !== UPLOAD_ERR_OK) {
|
||||
throw new InvalidFileUploadException('The selected file was not uploaded successfully');
|
||||
}
|
||||
throw_if($file->getError() !== UPLOAD_ERR_OK, new InvalidFileUploadException('The selected file was not uploaded successfully'));
|
||||
|
||||
try {
|
||||
$parsed = json_decode($file->getContent(), true, 512, JSON_THROW_ON_ERROR);
|
||||
@@ -73,9 +71,7 @@ class ScheduleImporterService
|
||||
|
||||
$fileContents = Http::timeout(5)->connectTimeout(1)->get($url)->throw()->body();
|
||||
|
||||
if (!$fileContents || !file_put_contents($tmpPath, $fileContents)) {
|
||||
throw new InvalidFileUploadException('Could not write temporary file.');
|
||||
}
|
||||
throw_if(!$fileContents || !file_put_contents($tmpPath, $fileContents), new InvalidFileUploadException('Could not write temporary file.'));
|
||||
|
||||
return $this->fromFile(new UploadedFile($tmpPath, $basename, 'application/json'), $server);
|
||||
}
|
||||
|
||||
@@ -73,9 +73,7 @@ class ServerCreationService
|
||||
$deployment->getTags(),
|
||||
)->pluck('id');
|
||||
|
||||
if ($nodes->isEmpty()) {
|
||||
throw new NoViableNodeException(trans('exceptions.deployment.no_viable_nodes'));
|
||||
}
|
||||
throw_if($nodes->isEmpty(), new NoViableNodeException(trans('exceptions.deployment.no_viable_nodes')));
|
||||
|
||||
$ports = $deployment->getPorts();
|
||||
if (!empty($ports)) {
|
||||
|
||||
@@ -9,9 +9,7 @@ class ToggleInstallService
|
||||
{
|
||||
public function handle(Server $server): void
|
||||
{
|
||||
if ($server->isFailedInstall()) {
|
||||
abort(500, trans('exceptions.server.marked_as_failed'));
|
||||
}
|
||||
abort_if($server->isFailedInstall(), 500, trans('exceptions.server.marked_as_failed'));
|
||||
|
||||
$server->status = $server->isInstalled() ? ServerState::Installing : null;
|
||||
$server->save();
|
||||
|
||||
@@ -42,9 +42,7 @@ class VariableValidatorService
|
||||
}
|
||||
|
||||
$validator = $this->validator->make($data, $rules, [], $customAttributes);
|
||||
if ($validator->fails()) {
|
||||
throw new ValidationException($validator);
|
||||
}
|
||||
throw_if($validator->fails(), new ValidationException($validator));
|
||||
|
||||
return Collection::make($variables)->map(function ($item) use ($fields) {
|
||||
return (object) [
|
||||
|
||||
@@ -23,18 +23,12 @@ class KeyCreationService
|
||||
throw new Exception('The public key provided is not valid');
|
||||
}
|
||||
|
||||
if ($key instanceof DSA) {
|
||||
throw new Exception('DSA keys are not supported');
|
||||
}
|
||||
throw_if($key instanceof DSA, new Exception('DSA keys are not supported'));
|
||||
|
||||
if ($key instanceof RSA && $key->getLength() < 2048) {
|
||||
throw new Exception('RSA keys must be at least 2048 bytes in length');
|
||||
}
|
||||
throw_if($key instanceof RSA && $key->getLength() < 2048, new Exception('RSA keys must be at least 2048 bytes in length'));
|
||||
|
||||
$fingerprint = $key->getFingerprint('sha256');
|
||||
if ($user->sshKeys()->where('fingerprint', $fingerprint)->exists()) {
|
||||
throw new Exception('The public key provided already exists on your account');
|
||||
}
|
||||
throw_if($user->sshKeys()->where('fingerprint', $fingerprint)->exists(), new Exception('The public key provided already exists on your account'));
|
||||
|
||||
/** @var UserSSHKey $sshKey */
|
||||
$sshKey = $user->sshKeys()->create([
|
||||
|
||||
@@ -46,14 +46,10 @@ class SubuserCreationService
|
||||
'root_admin' => false,
|
||||
]);
|
||||
} else {
|
||||
if ($server->owner_id === $user->id) {
|
||||
throw new UserIsServerOwnerException(trans('exceptions.subusers.user_is_owner'));
|
||||
}
|
||||
throw_if($server->owner_id === $user->id, new UserIsServerOwnerException(trans('exceptions.subusers.user_is_owner')));
|
||||
|
||||
$subuserCount = $server->subusers()->where('user_id', $user->id)->count();
|
||||
if ($subuserCount !== 0) {
|
||||
throw new ServerSubuserExistsException(trans('exceptions.subusers.subuser_exists'));
|
||||
}
|
||||
throw_if($subuserCount !== 0, new ServerSubuserExistsException(trans('exceptions.subusers.subuser_exists')));
|
||||
}
|
||||
|
||||
$cleanedPermissions = collect($permissions)
|
||||
|
||||
@@ -101,8 +101,6 @@ trait HasValidation
|
||||
)
|
||||
);
|
||||
|
||||
if (!$validator->passes()) {
|
||||
throw new ValidationException($validator);
|
||||
}
|
||||
throw_unless($validator->passes(), new ValidationException($validator));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,7 @@ class EggVariableTransformer extends BaseClientTransformer
|
||||
// This guards against someone incorrectly retrieving variables (haha, me) and then passing
|
||||
// them into the transformer and along to the user. Just throw an exception and break the entire
|
||||
// pathway since you should never be exposing these types of variables to a client.
|
||||
if (!$variable->user_viewable) {
|
||||
throw new BadMethodCallException('Cannot transform a hidden egg variable in a client transformer.');
|
||||
}
|
||||
throw_unless($variable->user_viewable, new BadMethodCallException('Cannot transform a hidden egg variable in a client transformer.'));
|
||||
|
||||
return [
|
||||
'name' => $variable->name,
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Transformers\Api\Client;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class FileObjectTransformer extends BaseClientTransformer
|
||||
{
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\ApiKey;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ApiKeyFactory extends Factory
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Database;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class DatabaseFactory extends Factory
|
||||
|
||||
@@ -7,8 +7,8 @@ use App\Models\Egg;
|
||||
use App\Models\Node;
|
||||
use App\Models\Server;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
|
||||
use App\Contracts\Repository\DaemonKeyRepositoryInterface;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
|
||||
use App\Contracts\Repository\DaemonKeyRepositoryInterface;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
@@ -17,12 +17,8 @@ return new class extends Migration
|
||||
$pivotRole = $columnNames['role_pivot_key'] ?? 'role_id';
|
||||
$pivotPermission = $columnNames['permission_pivot_key'] ?? 'permission_id';
|
||||
|
||||
if (empty($tableNames)) {
|
||||
throw new Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.');
|
||||
}
|
||||
if ($teams && empty($columnNames['team_foreign_key'] ?? null)) {
|
||||
throw new Exception('Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.');
|
||||
}
|
||||
throw_if(empty($tableNames), new Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.'));
|
||||
throw_if($teams && empty($columnNames['team_foreign_key'] ?? null), new Exception('Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.'));
|
||||
|
||||
Schema::create($tableNames['permissions'], function (Blueprint $table) {
|
||||
//$table->engine('InnoDB');
|
||||
@@ -127,9 +123,7 @@ return new class extends Migration
|
||||
{
|
||||
$tableNames = config('permission.table_names');
|
||||
|
||||
if (empty($tableNames)) {
|
||||
throw new Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.');
|
||||
}
|
||||
throw_if(empty($tableNames), new Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.'));
|
||||
|
||||
Schema::drop($tableNames['role_has_permissions']);
|
||||
Schema::drop($tableNames['model_has_roles']);
|
||||
|
||||
@@ -9,9 +9,9 @@ use App\Models\Server;
|
||||
use App\Models\Task;
|
||||
use App\Repositories\Daemon\DaemonServerRepository;
|
||||
use App\Tests\Integration\IntegrationTestCase;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonImmutable;
|
||||
use Illuminate\Http\Client\ConnectionException;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Bus;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user