1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-12 08:24:04 +00:00

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 <phpcsfixer@example.com>
This commit is contained in:
Samuel Štancl 2024-03-28 03:17:55 +01:00 committed by GitHub
parent bf1ba69fe3
commit dc430666ba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 126 additions and 9 deletions

View file

@ -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 [
/**
@ -26,9 +27,14 @@ return [
*
* - 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).
*
* 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,
],
/**

View file

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

View file

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

View file

@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\UniqueIdentifierGenerators;
use Illuminate\Database\Eloquent\Model;
use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
/**
* Generates a cryptographically secure random hex string for the tenant key.
*
* To customize the byte length, change the static `bytes` property.
* The produced string length is 2 * byte length.
* The number of unique combinations is 2 ^ (8 * byte length).
*/
class RandomHexGenerator implements UniqueIdentifierGenerator
{
public static int $bytes = 6;
public static function generate(Model $model): string
{
return bin2hex(random_bytes(static::$bytes));
}
}

View file

@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\UniqueIdentifierGenerators;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
/**
* Generates a cryptographically secure random string for the tenant key.
*
* To customize the string length, change the static `$length` property.
* The number of unique combinations is 36 ^ string length.
*/
class RandomStringGenerator implements UniqueIdentifierGenerator
{
public static int $length = 8;
public static function generate(Model $model): string
{
return Str::random(static::$length);
}
}

View file

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\UniqueIdentifierGenerators;
use Illuminate\Database\Eloquent\Model;
use Ramsey\Uuid\Uuid;
use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
/**
* Generates a UUID for the tenant key.
*/
class UUIDGenerator implements UniqueIdentifierGenerator
{
public static function generate(Model $model): string
{
return Uuid::uuid4()->toString();
}
}

View file

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