Skip to content

Commit

Permalink
[10.x] Add purging of invalid refresh tokens to command (laravel#1396)
Browse files Browse the repository at this point in the history
* Delete invalid refresh tokens

Delete refresh tokens referring to non-existing access tokens.

* Use whereDoesntHave() instead

* Add test for purge command

* Update description and output of command

* Update PurgeCommand.php

Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
carestad and taylorotwell authored Jan 14, 2021
1 parent c2b93a7 commit 985577c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
11 changes: 7 additions & 4 deletions src/Console/PurgeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class PurgeCommand extends Command
*
* @var string
*/
protected $description = 'Purge revoked and / or expired tokens and authentication codes';
protected $description = 'Purge revoked and / or expired tokens, authentication codes, and refresh tokens.';

/**
* Execute the console command.
Expand All @@ -36,20 +36,23 @@ public function handle()
Passport::token()->where('revoked', 1)->orWhereDate('expires_at', '<', $expired)->delete();
Passport::authCode()->where('revoked', 1)->orWhereDate('expires_at', '<', $expired)->delete();
Passport::refreshToken()->where('revoked', 1)->orWhereDate('expires_at', '<', $expired)->delete();
Passport::refreshToken()->whereDoesntHave('accessToken')->delete();

$this->info('Purged revoked items and items expired for more than seven days.');
$this->info('Purged invalid refresh tokens, revoked tokens, and tokens expired for more than seven days.');
} elseif ($this->option('revoked')) {
Passport::token()->where('revoked', 1)->delete();
Passport::authCode()->where('revoked', 1)->delete();
Passport::refreshToken()->where('revoked', 1)->delete();
Passport::refreshToken()->whereDoesntHave('accessToken')->delete();

$this->info('Purged revoked items.');
$this->info('Purged invalid refresh tokens and revoked tokens.');
} elseif ($this->option('expired')) {
Passport::token()->whereDate('expires_at', '<', $expired)->delete();
Passport::authCode()->whereDate('expires_at', '<', $expired)->delete();
Passport::refreshToken()->whereDate('expires_at', '<', $expired)->delete();
Passport::refreshToken()->whereDoesntHave('accessToken')->delete();

$this->info('Purged items expired for more than seven days.');
$this->info('Purged invalid refresh tokens and tokens expired for more than seven days.');
}
}
}
45 changes: 45 additions & 0 deletions tests/Feature/Console/PurgeCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Laravel\Passport\Tests\Feature\Console;

use Laravel\Passport\AuthCode;
use Laravel\Passport\RefreshToken;
use Laravel\Passport\Tests\Feature\PassportTestCase;
use Laravel\Passport\Token;

class PurgeCommand extends PassportTestCase
{
public function test_purge()
{
$expired = now()->subDays(8);
$notExpired = now();

$accessTokenExpired = Token::create(['id' => 'a', 'user_id' => 1, 'client_id' => 1, 'revoked' => 0, 'expires_at' => $expired]);
$accessTokenRevoked = Token::create(['id' => 'b', 'user_id' => 1, 'client_id' => 1, 'revoked' => 1, 'expires_at' => $notExpired]);
$accessTokenOk = Token::create(['id' => 'c', 'user_id' => 1, 'client_id' => 1, 'revoked' => 0, 'expires_at' => $notExpired]);

$authCodeExpired = AuthCode::create(['id' => 'a', 'user_id' => 1, 'client_id' => 1, 'revoked' => 0, 'expires_at' => $expired]);
$authCodeRevoked = AuthCode::create(['id' => 'b', 'user_id' => 1, 'client_id' => 1, 'revoked' => 1, 'expires_at' => $notExpired]);
$authCodeOk = AuthCode::create(['id' => 'c', 'user_id' => 1, 'client_id' => 1, 'revoked' => 0, 'expires_at' => $notExpired]);

$refreshTokenExpired = RefreshToken::create(['id' => 'a', 'access_token_id' => $accessTokenExpired->id, 'revoked' => 0, 'expires_at' => $expired]);
$refreshTokenRevoked = RefreshToken::create(['id' => 'b', 'access_token_id' => $accessTokenRevoked->id, 'revoked' => 1, 'expires_at' => $notExpired]);
$refreshTokenInvalidAccessToken = RefreshToken::create(['id' => 'c', 'access_token_id' => 'xyz', 'revoked' => 0, 'expires_at' => $notExpired]);
$refreshTokenOk = RefreshToken::create(['id' => 'd', 'access_token_id' => $accessTokenOk->id, 'revoked' => 0, 'expires_at' => $notExpired]);

$this->artisan('passport:purge');

$this->assertFalse(Token::whereKey($accessTokenExpired->id)->exists());
$this->assertFalse(Token::whereKey($accessTokenRevoked->id)->exists());
$this->assertTrue(Token::whereKey($accessTokenOk->id)->exists());

$this->assertFalse(AuthCode::whereKey($authCodeExpired->id)->exists());
$this->assertFalse(AuthCode::whereKey($authCodeRevoked->id)->exists());
$this->assertTrue(AuthCode::whereKey($authCodeOk->id)->exists());

$this->assertFalse(RefreshToken::whereKey($refreshTokenExpired->id)->exists());
$this->assertFalse(RefreshToken::whereKey($refreshTokenRevoked->id)->exists());
$this->assertFalse(RefreshToken::whereKey($refreshTokenInvalidAccessToken->id)->exists());
$this->assertTrue(RefreshToken::whereKey($refreshTokenOk->id)->exists());
}
}

0 comments on commit 985577c

Please sign in to comment.