mirror of
https://github.com/pelican-dev/panel.git
synced 2025-05-19 22:14:45 +02:00
parent
e980877bbc
commit
b6e46f758d
@ -17,9 +17,6 @@ CACHE_STORE=file
|
||||
QUEUE_CONNECTION=database
|
||||
SESSION_DRIVER=file
|
||||
|
||||
HASHIDS_SALT=
|
||||
HASHIDS_LENGTH=8
|
||||
|
||||
MAIL_MAILER=log
|
||||
MAIL_HOST=smtp.example.com
|
||||
MAIL_PORT=25
|
||||
|
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
@ -34,7 +34,6 @@ jobs:
|
||||
MAIL_MAILER: array
|
||||
SESSION_DRIVER: array
|
||||
QUEUE_CONNECTION: sync
|
||||
HASHIDS_SALT: alittlebitofsalt1234
|
||||
DB_CONNECTION: mysql
|
||||
DB_HOST: 127.0.0.1
|
||||
DB_DATABASE: testing
|
||||
@ -97,7 +96,6 @@ jobs:
|
||||
MAIL_MAILER: array
|
||||
SESSION_DRIVER: array
|
||||
QUEUE_CONNECTION: sync
|
||||
HASHIDS_SALT: alittlebitofsalt1234
|
||||
DB_CONNECTION: sqlite
|
||||
DB_DATABASE: testing.sqlite
|
||||
steps:
|
||||
|
@ -32,7 +32,6 @@ class AppSettingsCommand extends Command
|
||||
protected $description = 'Configure basic environment settings for the Panel.';
|
||||
|
||||
protected $signature = 'p:environment:setup
|
||||
{--new-salt : Whether or not to generate a new salt for Hashids.}
|
||||
{--url= : The URL that this Panel is running on.}
|
||||
{--cache= : The cache driver backend to use.}
|
||||
{--session= : The session driver backend to use.}
|
||||
@ -61,10 +60,6 @@ class AppSettingsCommand extends Command
|
||||
{
|
||||
$this->variables['APP_TIMEZONE'] = 'UTC';
|
||||
|
||||
if (empty(config('hashids.salt')) || $this->option('new-salt')) {
|
||||
$this->variables['HASHIDS_SALT'] = str_random(20);
|
||||
}
|
||||
|
||||
$this->output->comment(__('commands.appsettings.comment.url'));
|
||||
$this->variables['APP_URL'] = $this->option('url') ?? $this->ask(
|
||||
'Application URL',
|
||||
|
@ -62,7 +62,7 @@ class ProcessRunnableCommand extends Command
|
||||
|
||||
$this->line(trans('command/messages.schedule.output_line', [
|
||||
'schedule' => $schedule->name,
|
||||
'hash' => $schedule->hashid,
|
||||
'id' => $schedule->id,
|
||||
]));
|
||||
} catch (\Throwable|\Exception $exception) {
|
||||
logger()->error($exception, ['schedule_id' => $schedule->id]);
|
||||
|
@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Contracts\Extensions;
|
||||
|
||||
use Hashids\HashidsInterface as VendorHashidsInterface;
|
||||
|
||||
interface HashidsInterface extends VendorHashidsInterface
|
||||
{
|
||||
/**
|
||||
* Decode an encoded hashid and return the first result.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function decodeFirst(string $encoded, string $default = null): mixed;
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions;
|
||||
|
||||
use Hashids\Hashids as VendorHashids;
|
||||
use App\Contracts\Extensions\HashidsInterface;
|
||||
|
||||
class Hashids extends VendorHashids implements HashidsInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decodeFirst(string $encoded, string $default = null): mixed
|
||||
{
|
||||
$result = $this->decode($encoded);
|
||||
if (!is_array($result)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return array_first($result, null, $default);
|
||||
}
|
||||
}
|
@ -22,7 +22,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
* @property bool $has_alias
|
||||
* @property \App\Models\Server|null $server
|
||||
* @property \App\Models\Node $node
|
||||
* @property string $hashid
|
||||
*
|
||||
* @method static \Database\Factories\AllocationFactory factory(...$parameters)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Allocation newModelQuery()
|
||||
@ -88,14 +87,6 @@ class Allocation extends Model
|
||||
return $this->getKeyName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a hashid encoded string to represent the ID of the allocation.
|
||||
*/
|
||||
public function getHashidAttribute(): string
|
||||
{
|
||||
return app()->make('hashids')->encode($this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to automatically provide the IP alias if defined.
|
||||
*/
|
||||
|
@ -2,9 +2,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use App\Contracts\Extensions\HashidsInterface;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
@ -72,26 +70,6 @@ class Database extends Model
|
||||
return $this->getKeyName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the database using the ID by checking if the value provided is a HashID
|
||||
* string value, or just the ID to the database itself.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param string|null $field
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function resolveRouteBinding($value, $field = null): ?\Illuminate\Database\Eloquent\Model
|
||||
{
|
||||
if (is_scalar($value) && ($field ?? $this->getRouteKeyName()) === 'id') {
|
||||
$value = ctype_digit((string) $value)
|
||||
? $value
|
||||
: Container::getInstance()->make(HashidsInterface::class)->decodeFirst($value);
|
||||
}
|
||||
|
||||
return $this->where($field ?? $this->getRouteKeyName(), $value)->firstOrFail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the host database server associated with a database.
|
||||
*/
|
||||
|
@ -4,10 +4,8 @@ namespace App\Models;
|
||||
|
||||
use Cron\CronExpression;
|
||||
use Carbon\CarbonImmutable;
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use App\Contracts\Extensions\HashidsInterface;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
@ -25,7 +23,6 @@ use App\Contracts\Extensions\HashidsInterface;
|
||||
* @property \Carbon\Carbon|null $next_run_at
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property string $hashid
|
||||
* @property \App\Models\Server $server
|
||||
* @property \App\Models\Task[]|\Illuminate\Support\Collection $tasks
|
||||
*/
|
||||
@ -124,14 +121,6 @@ class Schedule extends Model
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a hashid encoded string to represent the ID of the schedule.
|
||||
*/
|
||||
public function getHashidAttribute(): string
|
||||
{
|
||||
return Container::getInstance()->make(HashidsInterface::class)->encode($this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return tasks belonging to a schedule.
|
||||
*/
|
||||
|
@ -52,14 +52,6 @@ class Subuser extends Model
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a hashid encoded string to represent the ID of the subuser.
|
||||
*/
|
||||
public function getHashidAttribute(): string
|
||||
{
|
||||
return app()->make('hashids')->encode($this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server associated with a subuser.
|
||||
*/
|
||||
|
@ -2,10 +2,8 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use App\Contracts\Extensions\HashidsInterface;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
@ -18,7 +16,6 @@ use App\Contracts\Extensions\HashidsInterface;
|
||||
* @property bool $continue_on_failure
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property string $hashid
|
||||
* @property \App\Models\Schedule $schedule
|
||||
* @property \App\Models\Server $server
|
||||
*/
|
||||
@ -96,14 +93,6 @@ class Task extends Model
|
||||
return $this->getKeyName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a hashid encoded string to represent the ID of the task.
|
||||
*/
|
||||
public function getHashidAttribute(): string
|
||||
{
|
||||
return Container::getInstance()->make(HashidsInterface::class)->encode($this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the schedule that a task belongs to.
|
||||
*/
|
||||
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Extensions\Hashids;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use App\Contracts\Extensions\HashidsInterface;
|
||||
|
||||
class HashidsServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register the ability to use Hashids.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$this->app->singleton(HashidsInterface::class, function () {
|
||||
return new Hashids(
|
||||
config('hashids.salt', ''),
|
||||
config('hashids.length', 0),
|
||||
config('hashids.alphabet', 'abcdefghijkmlnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890')
|
||||
);
|
||||
});
|
||||
|
||||
$this->app->alias(HashidsInterface::class, 'hashids');
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Database;
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
@ -29,11 +28,6 @@ class RouteServiceProvider extends ServiceProvider
|
||||
return preg_match(self::FILE_PATH_REGEX, $request->getPathInfo()) === 1;
|
||||
});
|
||||
|
||||
// This is needed to make use of the "resolveRouteBinding" functionality in the
|
||||
// model. Without it you'll never trigger that logic flow thus resulting in a 404
|
||||
// error because we request databases with a HashID, and not with a normal ID.
|
||||
Route::model('database', Database::class);
|
||||
|
||||
$this->routes(function () {
|
||||
Route::middleware('web')->group(function () {
|
||||
Route::middleware(['auth.session', RequireTwoFactorAuthentication::class])
|
||||
|
@ -6,22 +6,11 @@ use App\Models\Database;
|
||||
use League\Fractal\Resource\Item;
|
||||
use App\Models\Permission;
|
||||
use League\Fractal\Resource\NullResource;
|
||||
use App\Contracts\Extensions\HashidsInterface;
|
||||
|
||||
class DatabaseTransformer extends BaseClientTransformer
|
||||
{
|
||||
protected array $availableIncludes = ['password'];
|
||||
|
||||
private HashidsInterface $hashids;
|
||||
|
||||
/**
|
||||
* Handle dependency injection.
|
||||
*/
|
||||
public function handle(HashidsInterface $hashids)
|
||||
{
|
||||
$this->hashids = $hashids;
|
||||
}
|
||||
|
||||
public function getResourceName(): string
|
||||
{
|
||||
return Database::RESOURCE_NAME;
|
||||
@ -32,7 +21,7 @@ class DatabaseTransformer extends BaseClientTransformer
|
||||
$model->loadMissing('host');
|
||||
|
||||
return [
|
||||
'id' => $this->hashids->encode($model->id),
|
||||
'id' => $model->id,
|
||||
'host' => [
|
||||
'address' => $model->getRelation('host')->host,
|
||||
'port' => $model->getRelation('host')->port,
|
||||
|
@ -6,7 +6,6 @@ return [
|
||||
App\Providers\BackupsServiceProvider::class,
|
||||
App\Providers\EventServiceProvider::class,
|
||||
App\Providers\Filament\AdminPanelProvider::class,
|
||||
App\Providers\HashidsServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
App\Providers\ViewComposerServiceProvider::class,
|
||||
];
|
||||
|
@ -16,7 +16,6 @@
|
||||
"doctrine/dbal": "~3.6.0",
|
||||
"filament/filament": "^3.2",
|
||||
"guzzlehttp/guzzle": "^7.8.1",
|
||||
"hashids/hashids": "~5.0.0",
|
||||
"laracasts/utilities": "~3.2.2",
|
||||
"laravel/framework": "^11.7",
|
||||
"laravel/helpers": "^1.7",
|
||||
|
73
composer.lock
generated
73
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "dc1c1e5ee766f2e31e84c50670fa0c98",
|
||||
"content-hash": "e5ad978f95a98d7b1af728ade36c5f0d",
|
||||
"packages": [
|
||||
{
|
||||
"name": "abdelhamiderrahmouni/filament-monaco-editor",
|
||||
@ -2613,75 +2613,6 @@
|
||||
],
|
||||
"time": "2023-12-03T19:50:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "hashids/hashids",
|
||||
"version": "5.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vinkla/hashids.git",
|
||||
"reference": "197171016b77ddf14e259e186559152eb3f8cf33"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vinkla/hashids/zipball/197171016b77ddf14e259e186559152eb3f8cf33",
|
||||
"reference": "197171016b77ddf14e259e186559152eb3f8cf33",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^10.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-bcmath": "Required to use BC Math arbitrary precision mathematics (*).",
|
||||
"ext-gmp": "Required to use GNU multiple precision mathematics (*)."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Hashids\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ivan Akimov",
|
||||
"email": "ivan@barreleye.com"
|
||||
},
|
||||
{
|
||||
"name": "Vincent Klaiber",
|
||||
"email": "hello@doubledip.se"
|
||||
}
|
||||
],
|
||||
"description": "Generate short, unique, non-sequential ids (like YouTube and Bitly) from numbers",
|
||||
"homepage": "https://hashids.org/php",
|
||||
"keywords": [
|
||||
"bitly",
|
||||
"decode",
|
||||
"encode",
|
||||
"hash",
|
||||
"hashid",
|
||||
"hashids",
|
||||
"ids",
|
||||
"obfuscate",
|
||||
"youtube"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/vinkla/hashids/issues",
|
||||
"source": "https://github.com/vinkla/hashids/tree/5.0.2"
|
||||
},
|
||||
"time": "2023-02-23T15:00:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "kirschbaum-development/eloquent-power-joins",
|
||||
"version": "3.5.6",
|
||||
@ -13061,5 +12992,5 @@
|
||||
"ext-zip": "*"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.3.0"
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Hashids Configuration
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here are the settings that control the Hashids setup and usage in the panel.
|
||||
|
|
||||
*/
|
||||
'salt' => env('HASHIDS_SALT'),
|
||||
'length' => env('HASHIDS_LENGTH', 8),
|
||||
'alphabet' => env('HASHIDS_ALPHABET', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'),
|
||||
];
|
@ -23,7 +23,7 @@ return [
|
||||
'2fa_disabled' => '2-Factor authentication has been disabled for :email.',
|
||||
],
|
||||
'schedule' => [
|
||||
'output_line' => 'Dispatching job for first task in `:schedule` (:hash).',
|
||||
'output_line' => 'Dispatching job for first task in `:schedule` (:id).',
|
||||
],
|
||||
'maintenance' => [
|
||||
'deleting_service_backup' => 'Deleting service backup file :file.',
|
||||
|
@ -5,7 +5,6 @@ namespace App\Tests\Integration\Api\Client\Server\Database;
|
||||
use App\Models\Subuser;
|
||||
use App\Models\Database;
|
||||
use App\Models\DatabaseHost;
|
||||
use App\Contracts\Extensions\HashidsInterface;
|
||||
use App\Services\Databases\DatabasePasswordService;
|
||||
use App\Services\Databases\DatabaseManagementService;
|
||||
use App\Tests\Integration\Api\Client\ClientApiIntegrationTestCase;
|
||||
@ -39,23 +38,22 @@ class DatabaseAuthorizationTest extends ClientApiIntegrationTestCase
|
||||
->expects($method === 'POST' ? 'handle' : 'delete')
|
||||
->andReturn($method === 'POST' ? 'foo' : null);
|
||||
|
||||
$hashids = $this->app->make(HashidsInterface::class);
|
||||
// This is the only valid call for this test, accessing the database for the same
|
||||
// server that the API user is the owner of.
|
||||
$this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $hashids->encode($database1->id) . $endpoint))
|
||||
$this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $database1->id . $endpoint))
|
||||
->assertStatus($method === 'DELETE' ? 204 : 200);
|
||||
|
||||
// This request fails because the database is valid for that server but the user
|
||||
// making the request is not authorized to perform that action.
|
||||
$this->actingAs($user)->json($method, $this->link($server2, '/databases/' . $hashids->encode($database2->id) . $endpoint))->assertForbidden();
|
||||
$this->actingAs($user)->json($method, $this->link($server2, '/databases/' . $database2->id . $endpoint))->assertForbidden();
|
||||
|
||||
// Both of these should report a 404 error due to the database being linked to
|
||||
// servers that are not the same as the server in the request, or are assigned
|
||||
// to a server for which the user making the request has no access to.
|
||||
$this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $hashids->encode($database2->id) . $endpoint))->assertNotFound();
|
||||
$this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $hashids->encode($database3->id) . $endpoint))->assertNotFound();
|
||||
$this->actingAs($user)->json($method, $this->link($server2, '/databases/' . $hashids->encode($database3->id) . $endpoint))->assertNotFound();
|
||||
$this->actingAs($user)->json($method, $this->link($server3, '/databases/' . $hashids->encode($database3->id) . $endpoint))->assertNotFound();
|
||||
$this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $database2->id . $endpoint))->assertNotFound();
|
||||
$this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $database3->id . $endpoint))->assertNotFound();
|
||||
$this->actingAs($user)->json($method, $this->link($server2, '/databases/' . $database3->id . $endpoint))->assertNotFound();
|
||||
$this->actingAs($user)->json($method, $this->link($server3, '/databases/' . $database3->id . $endpoint))->assertNotFound();
|
||||
}
|
||||
|
||||
public static function methodDataProvider(): array
|
||||
|
Loading…
x
Reference in New Issue
Block a user