diff --git a/src/JWTGuard.php b/src/JWTGuard.php index 97616263..1ed77670 100644 --- a/src/JWTGuard.php +++ b/src/JWTGuard.php @@ -13,7 +13,10 @@ use BadMethodCallException; use Illuminate\Auth\Events\Attempting; +use Illuminate\Auth\Events\Authenticated; use Illuminate\Auth\Events\Failed; +use Illuminate\Auth\Events\Login; +use Illuminate\Auth\Events\Logout; use Illuminate\Auth\Events\Validated; use Illuminate\Auth\GuardHelpers; use Illuminate\Contracts\Auth\Authenticatable; @@ -28,7 +31,10 @@ class JWTGuard implements Guard { - use GuardHelpers, Macroable { + use GuardHelpers { + setUser as guardHelperSetUser; + } + use Macroable { __call as macroCall; } @@ -167,6 +173,8 @@ public function login(JWTSubject $user) $token = $this->jwt->fromUser($user); $this->setToken($token)->setUser($user); + $this->fireLoginEvent($user); + return $token; } @@ -181,6 +189,8 @@ public function logout($forceForever = false) { $this->requireToken()->invalidate($forceForever); + $this->fireLogoutEvent($this->user); + $this->user = null; $this->jwt->unsetToken(); } @@ -368,6 +378,21 @@ public function getUser() return $this->user; } + /** + * Set the current user. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @return $this + */ + public function setUser(Authenticatable $user) + { + $result = $this->guardHelperSetUser($user); + + $this->fireAuthenticatedEvent($user); + + return $result; + } + /** * Get the current request instance. * @@ -501,6 +526,52 @@ protected function fireFailedEvent($user, array $credentials) )); } + /** + * Fire the authenticated event. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @return void + */ + protected function fireAuthenticatedEvent($user) + { + $this->events->dispatch(new Authenticated( + $this->name, + $user + )); + } + + /** + * Fire the login event. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param bool $remember + * @return void + */ + protected function fireLoginEvent($user, $remember = false) + { + $this->events->dispatch(new Login( + $this->name, + $user, + $remember + )); + } + + /** + * Fire the logout event. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param bool $remember + * @return void + */ + protected function fireLogoutEvent($user, $remember = false) + { + $this->events->dispatch(new Logout( + $this->name, + $user + )); + } + + /** * Magically call the JWT instance. * diff --git a/tests/JWTGuardTest.php b/tests/JWTGuardTest.php index 78bb34da..3fa76170 100644 --- a/tests/JWTGuardTest.php +++ b/tests/JWTGuardTest.php @@ -13,7 +13,10 @@ use Illuminate\Auth\EloquentUserProvider; use Illuminate\Auth\Events\Attempting; +use Illuminate\Auth\Events\Authenticated; use Illuminate\Auth\Events\Failed; +use Illuminate\Auth\Events\Login; +use Illuminate\Auth\Events\Logout; use Illuminate\Auth\Events\Validated; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Contracts\Auth\UserProvider; @@ -229,6 +232,14 @@ public function it_should_return_a_token_if_credentials_are_ok_and_user_is_found ->once() ->with(Mockery::type(Validated::class)); + $this->eventDispatcher->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(Authenticated::class)); + + $this->eventDispatcher->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(Login::class)); + $token = $this->guard->claims(['foo' => 'bar'])->attempt($credentials); $this->assertSame($this->guard->getLastAttempted(), $user); @@ -259,6 +270,14 @@ public function it_should_return_true_if_credentials_are_ok_and_user_is_found_wh ->twice() ->with(Mockery::type(Validated::class)); + $this->eventDispatcher->shouldReceive('dispatch') + ->never() + ->with(Mockery::type(Authenticated::class)); + + $this->eventDispatcher->shouldReceive('dispatch') + ->never() + ->with(Mockery::type(Login::class)); + $this->assertTrue($this->guard->attempt($credentials, false)); // once $this->assertTrue($this->guard->validate($credentials)); // twice } @@ -287,6 +306,14 @@ public function it_should_return_false_if_credentials_are_invalid() ->once() ->with(Mockery::type(Failed::class)); + $this->eventDispatcher->shouldReceive('dispatch') + ->never() + ->with(Mockery::type(Authenticated::class)); + + $this->eventDispatcher->shouldReceive('dispatch') + ->never() + ->with(Mockery::type(Login::class)); + $this->assertFalse($this->guard->attempt($credentials)); } @@ -305,6 +332,14 @@ public function it_should_logout_the_user_by_invalidating_the_token() $this->jwt->shouldReceive('invalidate')->once()->andReturn(true); $this->jwt->shouldReceive('unsetToken')->once(); + $this->eventDispatcher->shouldReceive('dispatch') + ->never() + ->with(Mockery::type(Authenticated::class)); + + $this->eventDispatcher->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(Logout::class)); + $this->guard->logout(); $this->assertNull($this->guard->getUser()); } @@ -357,6 +392,14 @@ public function it_should_generate_a_token_by_id() ->with($user) ->andReturn('foo.bar.baz'); + $this->eventDispatcher->shouldReceive('dispatch') + ->never() + ->with(Mockery::type(Authenticated::class)); + + $this->eventDispatcher->shouldReceive('dispatch') + ->never() + ->with(Mockery::type(Login::class)); + $this->assertSame('foo.bar.baz', $this->guard->tokenById(1)); } @@ -395,6 +438,14 @@ public function it_should_authenticate_the_user_by_credentials_and_return_true_i ->once() ->with(Mockery::type(Validated::class)); + $this->eventDispatcher->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(Authenticated::class)); + + $this->eventDispatcher->shouldReceive('dispatch') + ->never() + ->with(Mockery::type(Login::class)); + $this->assertTrue($this->guard->once($credentials)); } @@ -435,6 +486,10 @@ public function it_should_authenticate_the_user_by_id_and_return_boolean() ->with(1) ->andReturn($user); + $this->eventDispatcher->shouldReceive('dispatch') + ->twice() + ->with(Mockery::type(Authenticated::class)); + $this->assertTrue($this->guard->onceUsingId(1)); // once $this->assertTrue($this->guard->byId(1)); // twice } @@ -466,6 +521,14 @@ public function it_should_create_a_token_from_a_user_object() ->with('foo.bar.baz') ->andReturnSelf(); + $this->eventDispatcher->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(Authenticated::class)); + + $this->eventDispatcher->shouldReceive('dispatch') + ->once() + ->with(Mockery::type(Login::class)); + $token = $this->guard->login($user); $this->assertSame('foo.bar.baz', $token);