Remove hashids (#282) and close #269

This commit is contained in:
Boy132 2024-05-30 00:41:44 +02:00 committed by GitHub
parent e980877bbc
commit b6e46f758d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 11 additions and 250 deletions

View File

@ -17,9 +17,6 @@ CACHE_STORE=file
QUEUE_CONNECTION=database QUEUE_CONNECTION=database
SESSION_DRIVER=file SESSION_DRIVER=file
HASHIDS_SALT=
HASHIDS_LENGTH=8
MAIL_MAILER=log MAIL_MAILER=log
MAIL_HOST=smtp.example.com MAIL_HOST=smtp.example.com
MAIL_PORT=25 MAIL_PORT=25

View File

@ -34,7 +34,6 @@ jobs:
MAIL_MAILER: array MAIL_MAILER: array
SESSION_DRIVER: array SESSION_DRIVER: array
QUEUE_CONNECTION: sync QUEUE_CONNECTION: sync
HASHIDS_SALT: alittlebitofsalt1234
DB_CONNECTION: mysql DB_CONNECTION: mysql
DB_HOST: 127.0.0.1 DB_HOST: 127.0.0.1
DB_DATABASE: testing DB_DATABASE: testing
@ -97,7 +96,6 @@ jobs:
MAIL_MAILER: array MAIL_MAILER: array
SESSION_DRIVER: array SESSION_DRIVER: array
QUEUE_CONNECTION: sync QUEUE_CONNECTION: sync
HASHIDS_SALT: alittlebitofsalt1234
DB_CONNECTION: sqlite DB_CONNECTION: sqlite
DB_DATABASE: testing.sqlite DB_DATABASE: testing.sqlite
steps: steps:

View File

@ -32,7 +32,6 @@ class AppSettingsCommand extends Command
protected $description = 'Configure basic environment settings for the Panel.'; protected $description = 'Configure basic environment settings for the Panel.';
protected $signature = 'p:environment:setup 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.} {--url= : The URL that this Panel is running on.}
{--cache= : The cache driver backend to use.} {--cache= : The cache driver backend to use.}
{--session= : The session driver backend to use.} {--session= : The session driver backend to use.}
@ -61,10 +60,6 @@ class AppSettingsCommand extends Command
{ {
$this->variables['APP_TIMEZONE'] = 'UTC'; $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->output->comment(__('commands.appsettings.comment.url'));
$this->variables['APP_URL'] = $this->option('url') ?? $this->ask( $this->variables['APP_URL'] = $this->option('url') ?? $this->ask(
'Application URL', 'Application URL',

View File

@ -62,7 +62,7 @@ class ProcessRunnableCommand extends Command
$this->line(trans('command/messages.schedule.output_line', [ $this->line(trans('command/messages.schedule.output_line', [
'schedule' => $schedule->name, 'schedule' => $schedule->name,
'hash' => $schedule->hashid, 'id' => $schedule->id,
])); ]));
} catch (\Throwable|\Exception $exception) { } catch (\Throwable|\Exception $exception) {
logger()->error($exception, ['schedule_id' => $schedule->id]); logger()->error($exception, ['schedule_id' => $schedule->id]);

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -22,7 +22,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
* @property bool $has_alias * @property bool $has_alias
* @property \App\Models\Server|null $server * @property \App\Models\Server|null $server
* @property \App\Models\Node $node * @property \App\Models\Node $node
* @property string $hashid
* *
* @method static \Database\Factories\AllocationFactory factory(...$parameters) * @method static \Database\Factories\AllocationFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Builder|Allocation newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Allocation newModelQuery()
@ -88,14 +87,6 @@ class Allocation extends Model
return $this->getKeyName(); 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. * Accessor to automatically provide the IP alias if defined.
*/ */

View File

@ -2,9 +2,7 @@
namespace App\Models; namespace App\Models;
use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
use App\Contracts\Extensions\HashidsInterface;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
/** /**
@ -72,26 +70,6 @@ class Database extends Model
return $this->getKeyName(); 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. * Gets the host database server associated with a database.
*/ */

View File

@ -4,10 +4,8 @@ namespace App\Models;
use Cron\CronExpression; use Cron\CronExpression;
use Carbon\CarbonImmutable; use Carbon\CarbonImmutable;
use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
use App\Contracts\Extensions\HashidsInterface;
/** /**
* @property int $id * @property int $id
@ -25,7 +23,6 @@ use App\Contracts\Extensions\HashidsInterface;
* @property \Carbon\Carbon|null $next_run_at * @property \Carbon\Carbon|null $next_run_at
* @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at * @property \Carbon\Carbon $updated_at
* @property string $hashid
* @property \App\Models\Server $server * @property \App\Models\Server $server
* @property \App\Models\Task[]|\Illuminate\Support\Collection $tasks * @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. * Return tasks belonging to a schedule.
*/ */

View File

@ -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. * Gets the server associated with a subuser.
*/ */

View File

@ -2,10 +2,8 @@
namespace App\Models; namespace App\Models;
use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Relations\HasOneThrough; use Illuminate\Database\Eloquent\Relations\HasOneThrough;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
use App\Contracts\Extensions\HashidsInterface;
/** /**
* @property int $id * @property int $id
@ -18,7 +16,6 @@ use App\Contracts\Extensions\HashidsInterface;
* @property bool $continue_on_failure * @property bool $continue_on_failure
* @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at * @property \Carbon\Carbon $updated_at
* @property string $hashid
* @property \App\Models\Schedule $schedule * @property \App\Models\Schedule $schedule
* @property \App\Models\Server $server * @property \App\Models\Server $server
*/ */
@ -96,14 +93,6 @@ class Task extends Model
return $this->getKeyName(); 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. * Return the schedule that a task belongs to.
*/ */

View File

@ -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');
}
}

View File

@ -3,7 +3,6 @@
namespace App\Providers; namespace App\Providers;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Models\Database;
use Illuminate\Foundation\Http\Middleware\TrimStrings; use Illuminate\Foundation\Http\Middleware\TrimStrings;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Cache\RateLimiting\Limit;
@ -29,11 +28,6 @@ class RouteServiceProvider extends ServiceProvider
return preg_match(self::FILE_PATH_REGEX, $request->getPathInfo()) === 1; 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 () { $this->routes(function () {
Route::middleware('web')->group(function () { Route::middleware('web')->group(function () {
Route::middleware(['auth.session', RequireTwoFactorAuthentication::class]) Route::middleware(['auth.session', RequireTwoFactorAuthentication::class])

View File

@ -6,22 +6,11 @@ use App\Models\Database;
use League\Fractal\Resource\Item; use League\Fractal\Resource\Item;
use App\Models\Permission; use App\Models\Permission;
use League\Fractal\Resource\NullResource; use League\Fractal\Resource\NullResource;
use App\Contracts\Extensions\HashidsInterface;
class DatabaseTransformer extends BaseClientTransformer class DatabaseTransformer extends BaseClientTransformer
{ {
protected array $availableIncludes = ['password']; protected array $availableIncludes = ['password'];
private HashidsInterface $hashids;
/**
* Handle dependency injection.
*/
public function handle(HashidsInterface $hashids)
{
$this->hashids = $hashids;
}
public function getResourceName(): string public function getResourceName(): string
{ {
return Database::RESOURCE_NAME; return Database::RESOURCE_NAME;
@ -32,7 +21,7 @@ class DatabaseTransformer extends BaseClientTransformer
$model->loadMissing('host'); $model->loadMissing('host');
return [ return [
'id' => $this->hashids->encode($model->id), 'id' => $model->id,
'host' => [ 'host' => [
'address' => $model->getRelation('host')->host, 'address' => $model->getRelation('host')->host,
'port' => $model->getRelation('host')->port, 'port' => $model->getRelation('host')->port,

View File

@ -6,7 +6,6 @@ return [
App\Providers\BackupsServiceProvider::class, App\Providers\BackupsServiceProvider::class,
App\Providers\EventServiceProvider::class, App\Providers\EventServiceProvider::class,
App\Providers\Filament\AdminPanelProvider::class, App\Providers\Filament\AdminPanelProvider::class,
App\Providers\HashidsServiceProvider::class,
App\Providers\RouteServiceProvider::class, App\Providers\RouteServiceProvider::class,
App\Providers\ViewComposerServiceProvider::class, App\Providers\ViewComposerServiceProvider::class,
]; ];

View File

@ -16,7 +16,6 @@
"doctrine/dbal": "~3.6.0", "doctrine/dbal": "~3.6.0",
"filament/filament": "^3.2", "filament/filament": "^3.2",
"guzzlehttp/guzzle": "^7.8.1", "guzzlehttp/guzzle": "^7.8.1",
"hashids/hashids": "~5.0.0",
"laracasts/utilities": "~3.2.2", "laracasts/utilities": "~3.2.2",
"laravel/framework": "^11.7", "laravel/framework": "^11.7",
"laravel/helpers": "^1.7", "laravel/helpers": "^1.7",

73
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "dc1c1e5ee766f2e31e84c50670fa0c98", "content-hash": "e5ad978f95a98d7b1af728ade36c5f0d",
"packages": [ "packages": [
{ {
"name": "abdelhamiderrahmouni/filament-monaco-editor", "name": "abdelhamiderrahmouni/filament-monaco-editor",
@ -2613,75 +2613,6 @@
], ],
"time": "2023-12-03T19:50:20+00:00" "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", "name": "kirschbaum-development/eloquent-power-joins",
"version": "3.5.6", "version": "3.5.6",
@ -13061,5 +12992,5 @@
"ext-zip": "*" "ext-zip": "*"
}, },
"platform-dev": [], "platform-dev": [],
"plugin-api-version": "2.3.0" "plugin-api-version": "2.6.0"
} }

View File

@ -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'),
];

View File

@ -23,7 +23,7 @@ return [
'2fa_disabled' => '2-Factor authentication has been disabled for :email.', '2fa_disabled' => '2-Factor authentication has been disabled for :email.',
], ],
'schedule' => [ 'schedule' => [
'output_line' => 'Dispatching job for first task in `:schedule` (:hash).', 'output_line' => 'Dispatching job for first task in `:schedule` (:id).',
], ],
'maintenance' => [ 'maintenance' => [
'deleting_service_backup' => 'Deleting service backup file :file.', 'deleting_service_backup' => 'Deleting service backup file :file.',

View File

@ -5,7 +5,6 @@ namespace App\Tests\Integration\Api\Client\Server\Database;
use App\Models\Subuser; use App\Models\Subuser;
use App\Models\Database; use App\Models\Database;
use App\Models\DatabaseHost; use App\Models\DatabaseHost;
use App\Contracts\Extensions\HashidsInterface;
use App\Services\Databases\DatabasePasswordService; use App\Services\Databases\DatabasePasswordService;
use App\Services\Databases\DatabaseManagementService; use App\Services\Databases\DatabaseManagementService;
use App\Tests\Integration\Api\Client\ClientApiIntegrationTestCase; use App\Tests\Integration\Api\Client\ClientApiIntegrationTestCase;
@ -39,23 +38,22 @@ class DatabaseAuthorizationTest extends ClientApiIntegrationTestCase
->expects($method === 'POST' ? 'handle' : 'delete') ->expects($method === 'POST' ? 'handle' : 'delete')
->andReturn($method === 'POST' ? 'foo' : null); ->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 // This is the only valid call for this test, accessing the database for the same
// server that the API user is the owner of. // 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); ->assertStatus($method === 'DELETE' ? 204 : 200);
// This request fails because the database is valid for that server but the user // This request fails because the database is valid for that server but the user
// making the request is not authorized to perform that action. // 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 // 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 // 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. // 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/' . $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($server1, '/databases/' . $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($server2, '/databases/' . $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($server3, '/databases/' . $database3->id . $endpoint))->assertNotFound();
} }
public static function methodDataProvider(): array public static function methodDataProvider(): array