diff --git a/README.md b/README.md index b4a6d9c..434f4cd 100644 --- a/README.md +++ b/README.md @@ -331,7 +331,7 @@ Auth::hasAnyScope(['scope-f', 'scope-k']) // false # Acting as a Keycloak user in tests -As an equivelant feature like `$this->actingAs($user)` in Laravel, with this package you can use `KeycloakGuard\ActingAsKeycloakUser` trait in your test class and then use `actingAsKeycloakUser()` method to act as a user and somehow skip the Keycloak auth: +As an equivalent feature like `$this->actingAs($user)` in Laravel, with this package you can use `KeycloakGuard\ActingAsKeycloakUser` trait in your test class and then use `actingAsKeycloakUser()` method to act as a user and somehow skip the Keycloak auth: ```php use KeycloakGuard\ActingAsKeycloakUser; @@ -346,6 +346,22 @@ public test_a_protected_route() If you are not using `keycloak.load_user_from_database` option, set `keycloak.preferred_username` with a valid `preferred_username` for tests. +You can also specify exact expectations for the token payload by passing the payload array in the second argument: + +```php +use KeycloakGuard\ActingAsKeycloakUser; + +public test_a_protected_route() +{ + $this->actingAsKeycloakUser($user, [ + 'aud' => 'account', + 'exp' => 1715926026, + 'iss' => 'https://localhost:8443/realms/master' + ])->getJson('/api/somewhere') + ->assertOk(); +} +``` + # Contribute You can run this project on VSCODE with Remote Container. Make sure you will use internal VSCODE terminal (inside running container). diff --git a/tests/AuthenticateTest.php b/tests/AuthenticateTest.php index 609c8b1..212b89c 100644 --- a/tests/AuthenticateTest.php +++ b/tests/AuthenticateTest.php @@ -2,6 +2,7 @@ namespace KeycloakGuard\Tests; +use Firebase\JWT\JWT; use Illuminate\Auth\AuthenticationException; use Illuminate\Hashing\BcryptHasher; use Illuminate\Support\Facades\Auth; @@ -11,6 +12,7 @@ use KeycloakGuard\Exceptions\UserNotFoundException; use KeycloakGuard\KeycloakGuard; use KeycloakGuard\Tests\Extensions\CustomUserProvider; +use KeycloakGuard\Tests\Factories\UserFactory; use KeycloakGuard\Tests\Models\User; use KeycloakGuard\Token; @@ -415,6 +417,40 @@ public function test_with_keycloak_token_trait() $this->actingAsKeycloakUser($this->user)->json('GET', '/foo/secret'); $this->assertEquals($this->user->username, Auth::user()->username); + $token = Token::decode(request()->bearerToken(), config('keycloak.realm_public_key'), config('keycloak.leeway'), config('keycloak.token_encryption_algorithm')); + $this->assertNotNull($token->iat); + $this->assertNotNull($token->exp); + } + + public function test_with_keycloak_token_trait_with_username() + { + $this->actingAsKeycloakUser($this->user->username)->json('GET', '/foo/secret'); + + $this->assertEquals($this->user->username, Auth::user()->username); + $token = Token::decode(request()->bearerToken(), config('keycloak.realm_public_key'), config('keycloak.leeway'), config('keycloak.token_encryption_algorithm')); + $this->assertNotNull($token->iat); + $this->assertNotNull($token->exp); + } + + public function test_with_keycloak_token_trait_with_custom_payload() + { + UserFactory::new()->create([ + 'username' => 'test_username', + ]); + $this->actingAsKeycloakUser($this->user, [ + 'sub' => 'test_sub', + 'aud' => 'test_aud', + 'preferred_username' => 'test_username', + 'iat' => 12345, + 'exp' => 9999999999999, + ])->json('GET', '/foo/secret'); + + $this->assertEquals('test_username', Auth::user()->username); + $token = Token::decode(request()->bearerToken(), config('keycloak.realm_public_key'), config('keycloak.leeway'), config('keycloak.token_encryption_algorithm')); + $this->assertEquals(12345, $token->iat); + $this->assertEquals(9999999999999, $token->exp); + $this->assertEquals('test_sub', $token->sub); + $this->assertEquals('test_aud', $token->aud); } public function test_acting_as_keycloak_user_trait_without_user()