From dc430666babce2f215bd6a025fa14ebc023f6113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Thu, 28 Mar 2024 03:17:55 +0100 Subject: [PATCH] Add more tenant key generators (#36) * Add RandomHexGenerator, create new namespace * phpstan ignore * add base64 generator * add note about base64 being case sensitive * docblock updates * replace old UUIDGenerator with a class that throws an exception * replace base64 generator with a random string generator * Fix namespace * Fix code style (php-cs-fixer) * add test for the deprecated uuid generator * update comments --------- Co-authored-by: PHP CS Fixer --- assets/config.php | 14 ++++-- phpstan.neon | 1 + src/UUIDGenerator.php | 7 ++- .../RandomHexGenerator.php | 25 +++++++++++ .../RandomStringGenerator.php | 25 +++++++++++ .../UUIDGenerator.php | 20 +++++++++ tests/TenantModelTest.php | 43 ++++++++++++++++++- 7 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 src/UniqueIdentifierGenerators/RandomHexGenerator.php create mode 100644 src/UniqueIdentifierGenerators/RandomStringGenerator.php create mode 100644 src/UniqueIdentifierGenerators/UUIDGenerator.php diff --git a/assets/config.php b/assets/config.php index cd03a068..b4adcf4a 100644 --- a/assets/config.php +++ b/assets/config.php @@ -5,6 +5,7 @@ declare(strict_types=1); use Stancl\Tenancy\Middleware; use Stancl\Tenancy\Resolvers; use Stancl\Tenancy\Enums\RouteMode; +use Stancl\Tenancy\UniqueIdentifierGenerators; return [ /** @@ -24,11 +25,16 @@ return [ /** * Used for generating tenant IDs. * - * - Feel free to override this with a custom class that implements the UniqueIdentifierGenerator interface. - * - To use autoincrement IDs, set this to null and update the `tenants` table migration to use an autoincrement column. - * SECURITY NOTE: Keep in mind that autoincrement IDs come with *potential* enumeration issues (such as tenant storage URLs). + * - Feel free to override this with a custom class that implements the UniqueIdentifierGenerator interface. + * - To use autoincrement IDs, set this to null and update the `tenants` table migration to use an autoincrement column. + * + * SECURITY NOTE: Keep in mind that autoincrement IDs come with potential enumeration issues (such as tenant storage URLs). + * + * @see \Stancl\Tenancy\UniqueIdentifierGenerators\UUIDGenerator + * @see \Stancl\Tenancy\UniqueIdentifierGenerators\RandomHexGenerator + * @see \Stancl\Tenancy\UniqueIdentifierGenerators\RandomStringGenerator */ - 'id_generator' => Stancl\Tenancy\UUIDGenerator::class, + 'id_generator' => UniqueIdentifierGenerators\UUIDGenerator::class, ], /** diff --git a/phpstan.neon b/phpstan.neon index e333380e..e9851c60 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -51,6 +51,7 @@ parameters: message: '#string\|false#' paths: - src/Controllers/TenantAssetController.php + - '#expects int<1, max>, int given#' checkMissingIterableValueType: false checkGenericClassInNonGenericObjectType: false # later we may want to enable this diff --git a/src/UUIDGenerator.php b/src/UUIDGenerator.php index 6ac59519..04e0d92c 100644 --- a/src/UUIDGenerator.php +++ b/src/UUIDGenerator.php @@ -4,16 +4,15 @@ declare(strict_types=1); namespace Stancl\Tenancy; +use Exception; use Illuminate\Database\Eloquent\Model; -use Ramsey\Uuid\Uuid; use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator; -// todo@move move to separate namespace - +// todo@deprecation remove after 2024-04-12 class UUIDGenerator implements UniqueIdentifierGenerator { public static function generate(Model $model): string { - return Uuid::uuid4()->toString(); + throw new Exception('Tenancy update note: UUIDGenerator has been renamed to Stancl\Tenancy\UniqueIdentifierGenerators\UUIDGenerator. Please update your config/tenancy.php'); } } diff --git a/src/UniqueIdentifierGenerators/RandomHexGenerator.php b/src/UniqueIdentifierGenerators/RandomHexGenerator.php new file mode 100644 index 00000000..3da05208 --- /dev/null +++ b/src/UniqueIdentifierGenerators/RandomHexGenerator.php @@ -0,0 +1,25 @@ +toString(); + } +} diff --git a/tests/TenantModelTest.php b/tests/TenantModelTest.php index 1c5a7700..7f07a75f 100644 --- a/tests/TenantModelTest.php +++ b/tests/TenantModelTest.php @@ -17,8 +17,10 @@ use Stancl\Tenancy\Events\TenantCreated; use Stancl\Tenancy\Jobs\CreateDatabase; use Stancl\Tenancy\Listeners\BootstrapTenancy; use Stancl\Tenancy\Tests\Etc\Tenant; -use Stancl\Tenancy\UUIDGenerator; +use Stancl\Tenancy\UniqueIdentifierGenerators\UUIDGenerator; use Stancl\Tenancy\Exceptions\TenancyNotInitializedException; +use Stancl\Tenancy\UniqueIdentifierGenerators\RandomHexGenerator; +use Stancl\Tenancy\UniqueIdentifierGenerators\RandomStringGenerator; test('created event is dispatched', function () { Event::fake([TenantCreated::class]); @@ -69,6 +71,45 @@ test('autoincrement ids are supported', function () { expect($tenant2->id)->toBe(2); }); +test('hex ids are supported', function () { + app()->bind(UniqueIdentifierGenerator::class, RandomHexGenerator::class); + + RandomHexGenerator::$bytes = 6; + $tenant1 = Tenant::create(); + expect($tenant1->id)->toBeString(); + expect(strlen($tenant1->id))->toBe(12); + + RandomHexGenerator::$bytes = 8; + $tenant2 = Tenant::create(); + expect($tenant2->id)->toBeString(); + expect(strlen($tenant2->id))->toBe(16); + + RandomHexGenerator::$bytes = 6; // reset +}); + +test('random string ids are supported', function () { + app()->bind(UniqueIdentifierGenerator::class, RandomStringGenerator::class); + + RandomStringGenerator::$length = 8; + $tenant1 = Tenant::create(); + expect($tenant1->id)->toBeString(); + expect(strlen($tenant1->id))->toBe(8); + + RandomStringGenerator::$length = 12; + $tenant2 = Tenant::create(); + expect($tenant2->id)->toBeString(); + expect(strlen($tenant2->id))->toBe(12); + + RandomStringGenerator::$length = 8; // reset +}); + +// todo@deprecation remove this after deleting the class +test('referencing the old uuid generator throws an exception', function () { + $tenant = Tenant::create(); + expect(fn() => app(\Stancl\Tenancy\UUIDGenerator::class)->generate($tenant)) + ->toThrow(Exception::class, 'Tenancy update note: UUIDGenerator has been renamed to Stancl\Tenancy\UniqueIdentifierGenerators\UUIDGenerator. Please update your config/tenancy.php'); +}); + test('custom tenant model can be used', function () { $tenant = MyTenant::create();