mirror of
https://github.com/archtechx/tenancy.git
synced 2026-02-04 16:04:04 +00:00
Add and test command for deleteing expired impersonation tokens
This commit is contained in:
parent
2d5b6aa0c8
commit
f0b395ce23
3 changed files with 91 additions and 0 deletions
36
src/Commands/ClearExpiredImpersonationTokens.php
Normal file
36
src/Commands/ClearExpiredImpersonationTokens.php
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Stancl\Tenancy\Features\UserImpersonation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Stancl\Tenancy\Features\UserImpersonation
|
||||||
|
*/
|
||||||
|
class ClearExpiredImpersonationTokens extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'tenants:clear-expired-impersonation-tokens
|
||||||
|
{--ttl= : TTL in seconds for impersonation tokens (default is UserImpersonation::$ttl)}';
|
||||||
|
|
||||||
|
protected $description = 'Remove expired impersonation tokens.';
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
$this->components->info('Removing expired impersonation tokens.');
|
||||||
|
|
||||||
|
$ttl = (int) $this->option('ttl') ?: UserImpersonation::$ttl;
|
||||||
|
$expirationDate = now()->subSeconds($ttl);
|
||||||
|
|
||||||
|
$impersonationTokenModel = UserImpersonation::modelClass();
|
||||||
|
|
||||||
|
$deletedTokenCount = $impersonationTokenModel::where('created_at', '<', $expirationDate)
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
$this->components->info($deletedTokenCount . ' expired impersonation ' . str('token')->plural($deletedTokenCount) . ' deleted.');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -104,6 +104,7 @@ class TenancyServiceProvider extends ServiceProvider
|
||||||
Commands\ClearPendingTenants::class,
|
Commands\ClearPendingTenants::class,
|
||||||
Commands\CreatePendingTenants::class,
|
Commands\CreatePendingTenants::class,
|
||||||
Commands\CreateUserWithRLSPolicies::class,
|
Commands\CreateUserWithRLSPolicies::class,
|
||||||
|
Commands\ClearExpiredImpersonationTokens::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (static::$migrateFreshOverride) {
|
if (static::$migrateFreshOverride) {
|
||||||
|
|
|
||||||
|
|
@ -350,6 +350,60 @@ test('tokens are cleaned up when in wrong tenant context before aborting', funct
|
||||||
expect(ImpersonationToken::find($token->token))->toBeNull();
|
expect(ImpersonationToken::find($token->token))->toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('expired impersonation tokens can be cleaned up using a command', function () {
|
||||||
|
$tenant = Tenant::create();
|
||||||
|
migrateTenants();
|
||||||
|
$user = $tenant->run(function () {
|
||||||
|
return ImpersonationUser::create([
|
||||||
|
'name' => 'foo',
|
||||||
|
'email' => 'foo@bar',
|
||||||
|
'password' => bcrypt('password'),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create tokens
|
||||||
|
$oldToken = tenancy()->impersonate($tenant, $user->id, '/dashboard');
|
||||||
|
$activeToken = tenancy()->impersonate($tenant, $user->id, '/dashboard');
|
||||||
|
|
||||||
|
// Make one of the tokens expired by updating its created_at
|
||||||
|
$oldToken->update([
|
||||||
|
'created_at' => Carbon::now()->subSeconds(UserImpersonation::$ttl + 10),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Both tokens exist
|
||||||
|
expect(ImpersonationToken::find($activeToken->token))->not()->toBeNull();
|
||||||
|
expect(ImpersonationToken::find($oldToken->token))->not()->toBeNull();
|
||||||
|
|
||||||
|
pest()->artisan('tenants:clear-expired-impersonation-tokens')
|
||||||
|
->assertExitCode(0);
|
||||||
|
|
||||||
|
// The expired token was deleted
|
||||||
|
expect(ImpersonationToken::find($oldToken->token))->toBeNull();
|
||||||
|
// The active token still exists
|
||||||
|
expect(ImpersonationToken::find($activeToken->token))->not()->toBeNull();
|
||||||
|
|
||||||
|
// Update the active token to make it expired according to the default ttl (60s)
|
||||||
|
$activeToken->update([
|
||||||
|
'created_at' => Carbon::now()->subSeconds(70),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// The --ttl option can be used to specify a custom TTL instead of updating UserImpersonation::$ttl.
|
||||||
|
// The passed ttl will be used in place of the default ttl,
|
||||||
|
// and with ttl set to 80s, the active token should not be deleted
|
||||||
|
pest()->artisan('tenants:clear-expired-impersonation-tokens', [
|
||||||
|
'--ttl' => 80,
|
||||||
|
])->assertExitCode(0);
|
||||||
|
|
||||||
|
expect(ImpersonationToken::find($activeToken->token))->not()->toBeNull();
|
||||||
|
|
||||||
|
// With ttl set to 40s, the active token should be deleted
|
||||||
|
pest()->artisan('tenants:clear-expired-impersonation-tokens', [
|
||||||
|
'--ttl' => 40,
|
||||||
|
])->assertExitCode(0);
|
||||||
|
|
||||||
|
expect(ImpersonationToken::find($activeToken->token))->toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
function migrateTenants()
|
function migrateTenants()
|
||||||
{
|
{
|
||||||
pest()->artisan('tenants:migrate')->assertExitCode(0);
|
pest()->artisan('tenants:migrate')->assertExitCode(0);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue