From 11144888ffb2c0756d54c3b6823b6db67ea5c445 Mon Sep 17 00:00:00 2001 From: ARCANEDEV Date: Sat, 25 Jul 2020 15:36:49 +0100 Subject: [PATCH] Adding the ability to impersonate different guard --- composer.json | 2 +- config/impersonator.php | 3 +- src/Contracts/Impersonator.php | 40 ++++--- src/Exceptions/ImpersonationException.php | 3 +- src/Impersonator.php | 132 +++++++++++++++------- tests/EventsTest.php | 64 ++++++----- tests/ImpersonationPoliciesTest.php | 12 +- tests/ImpersonationTraitTest.php | 14 ++- tests/ImpersonatorServiceProviderTest.php | 21 ++-- tests/ImpersonatorTest.php | 100 +++++++--------- tests/MiddlewareTest.php | 2 +- tests/TestCase.php | 82 +++++++------- 12 files changed, 264 insertions(+), 211 deletions(-) diff --git a/composer.json b/composer.json index 1f58d41..8f00fcc 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "require-dev": { "arcanedev/laravel-policies": "^2.0", "orchestra/testbench": "^5.0", - "phpunit/phpunit": "^8.5|^9.0" + "phpunit/phpunit": "^8.5" }, "autoload": { "psr-4": { diff --git a/config/impersonator.php b/config/impersonator.php index e426be7..a59db24 100644 --- a/config/impersonator.php +++ b/config/impersonator.php @@ -15,7 +15,8 @@ */ 'session' => [ - 'key' => 'impersonator_id', + 'key' => 'impersonator_id', + 'guard' => 'impersonator_guard', ], ]; diff --git a/src/Contracts/Impersonator.php b/src/Contracts/Impersonator.php index 06bf760..298fc43 100644 --- a/src/Contracts/Impersonator.php +++ b/src/Contracts/Impersonator.php @@ -22,14 +22,28 @@ interface Impersonator * * @return string */ - public function getSessionKey(); + public function getSessionKey(): string; + + /** + * Get the session guard. + * + * @return string + */ + public function getSessionGuard(): string; /** * Get the impersonator id. * * @return int|null */ - public function getImpersonatorId(); + public function getImpersonatorId(): ?int; + + /** + * Get the impersonator guard. + * + * @return string|null + */ + public function getImpersonatorGuard(): ?string; /* ----------------------------------------------------------------- | Main Methods @@ -41,33 +55,23 @@ public function getImpersonatorId(); * * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed $impersonater * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed $impersonated + * @param string|null $guard * * @return bool */ - public function start(Impersonatable $impersonater, Impersonatable $impersonated); + public function start(Impersonatable $impersonater, Impersonatable $impersonated, $guard = null): bool; /** * Stop the impersonation. * * @return bool */ - public function stop(); + public function stop(): bool; /** * Clear the impersonation. */ - public function clear(); - - /** - * Find a user by the given id. - * - * @param int|string $id - * - * @return \Arcanedev\LaravelImpersonator\Contracts\Impersonatable - * - * @throws \Exception - */ - public function findUserById($id); + public function clear(): void; /* ----------------------------------------------------------------- | Check Methods @@ -79,12 +83,12 @@ public function findUserById($id); * * @return bool */ - public function isEnabled(); + public function isEnabled(): bool; /** * Check if the impersonator is impersonating. * * @return bool */ - public function isImpersonating(); + public function isImpersonating(): bool; } diff --git a/src/Exceptions/ImpersonationException.php b/src/Exceptions/ImpersonationException.php index 70d13df..579cf90 100644 --- a/src/Exceptions/ImpersonationException.php +++ b/src/Exceptions/ImpersonationException.php @@ -5,6 +5,7 @@ namespace Arcanedev\LaravelImpersonator\Exceptions; use Arcanedev\LaravelImpersonator\Contracts\Impersonatable; +use Exception; /** * Class ImpersonationException @@ -12,7 +13,7 @@ * @package Arcanedev\LaravelImpersonator\Exceptions * @author ARCANEDEV */ -class ImpersonationException extends \Exception +class ImpersonationException extends Exception { /* ----------------------------------------------------------------- | Main Methods diff --git a/src/Impersonator.php b/src/Impersonator.php index c56d7a2..8b925ab 100644 --- a/src/Impersonator.php +++ b/src/Impersonator.php @@ -91,21 +91,42 @@ protected function events() * * @return string */ - public function getSessionKey() + public function getSessionKey(): string { return $this->config()->get('impersonator.session.key', 'impersonator_id'); } + /** + * Get the session guard. + * + * @return string + */ + public function getSessionGuard(): string + { + return $this->config()->get('impersonator.session.guard', 'impersonator_guard'); + } + /** * Get the impersonator id. * - * @return int|null + * @return int|null */ - public function getImpersonatorId() + public function getImpersonatorId(): ?int { return $this->session()->get($this->getSessionKey(), null); } + /** + * Get the impersonator guard. + * + * @return string|null + */ + public function getImpersonatorGuard(): ?string + { + return $this->session()->get($this->getSessionGuard(), null) + ?: $this->auth()->getDefaultDriver(); + } + /* ----------------------------------------------------------------- | Main Methods | ----------------------------------------------------------------- @@ -114,22 +135,25 @@ public function getImpersonatorId() /** * Start the impersonation. * - * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed $impersonater + * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed $impersonator * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed $impersonated + * @param string|null $guard * * @return bool */ - public function start(Impersonatable $impersonater, Impersonatable $impersonated) + public function start(Impersonatable $impersonator, Impersonatable $impersonated, $guard = null): bool { - $this->checkImpersonation($impersonater, $impersonated); + $this->checkImpersonation($impersonator, $impersonated); try { - session()->put($this->getSessionKey(), $impersonater->getAuthIdentifier()); - $this->auth()->silentLogout(); - $this->auth()->silentLogin($impersonated); + $this->rememberImpersonater($impersonator); + + $auth = $this->auth(); + $auth->guard()->silentLogout(); + $auth->guard($guard)->silentLogin($impersonated); $this->events()->dispatch( - new Events\ImpersonationStarted($impersonater, $impersonated) + new Events\ImpersonationStarted($impersonator, $impersonated) ); return true; @@ -144,18 +168,20 @@ public function start(Impersonatable $impersonater, Impersonatable $impersonated * * @return bool */ - public function stop() + public function stop(): bool { try { - $impersonated = $this->auth()->user(); - $impersonater = $this->findUserById($this->getImpersonatorId()); + $auth = $this->auth(); + + $impersonated = $auth->user(); + $impersonator = $this->getImpersonatorFromSession(); - $this->auth()->silentLogout(); - $this->auth()->silentLogin($impersonater); + $auth->silentLogout(); + $auth->guard($this->getImpersonatorGuard())->silentLogin($impersonator); $this->clear(); $this->events()->dispatch( - new Events\ImpersonationStopped($impersonater, $impersonated) + new Events\ImpersonationStopped($impersonator, $impersonated) ); return true; @@ -168,23 +194,31 @@ public function stop() /** * Clear the impersonation. */ - public function clear() + public function clear(): void { - $this->session()->forget($this->getSessionKey()); + $this->session()->forget([ + $this->getSessionKey(), + $this->getSessionGuard(), + ]); } /** - * Find a user by the given id. + * Get the impersonator from session. * - * @param int|string $id - * - * @return \Arcanedev\LaravelImpersonator\Contracts\Impersonatable + * @return \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed|null * * @throws \Exception */ - public function findUserById($id) + protected function getImpersonatorFromSession() { - return call_user_func([$this->config()->get('auth.providers.users.model'), 'findOrFail'], $id); + $user = $this->auth() + ->guard($this->getImpersonatorGuard()) + ->getProvider() + ->retrieveById($this->getImpersonatorId()); + + abort_if(is_null($user), 404, 'User not found'); + + return $user; } /* ----------------------------------------------------------------- @@ -197,9 +231,12 @@ public function findUserById($id) * * @return bool */ - public function isImpersonating() + public function isImpersonating(): bool { - return $this->session()->has($this->getSessionKey()); + return $this->session()->has([ + $this->getSessionKey(), + $this->getSessionGuard(), + ]); } /** @@ -207,7 +244,7 @@ public function isImpersonating() * * @return bool */ - public function isEnabled() + public function isEnabled(): bool { return $this->config()->get('impersonator.enabled', false); } @@ -220,14 +257,14 @@ public function isEnabled() /** * Check the impersonation. * - * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed $impersonater + * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed $impersonator * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed $impersonated */ - private function checkImpersonation(Impersonatable $impersonater, Impersonatable $impersonated): void + private function checkImpersonation(Impersonatable $impersonator, Impersonatable $impersonated): void { $this->mustBeEnabled(); - $this->mustBeDifferentImpersonatable($impersonater, $impersonated); - $this->checkImpersonater($impersonater); + $this->mustBeDifferentImpersonatable($impersonator, $impersonated); + $this->checkImpersonater($impersonator); $this->checkImpersonated($impersonated); } @@ -245,31 +282,31 @@ private function mustBeEnabled(): void } /** - * Check the impersonater and the impersonated are different. + * Check the impersonator and the impersonated are different. * - * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed $impersonater + * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed $impersonator * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed $impersonated * * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException */ - private function mustBeDifferentImpersonatable(Impersonatable $impersonater, Impersonatable $impersonated): void + private function mustBeDifferentImpersonatable(Impersonatable $impersonator, Impersonatable $impersonated): void { - if ($impersonater->isSamePerson($impersonated)) { - throw Exceptions\ImpersonationException::impersonaterAndImpersonatedAreSame(); + if ($impersonator->isSamePerson($impersonated)) { + throw Exceptions\ImpersonationException::selfImpersonation(); } } /** - * Check the impersonater. + * Check the impersonator. * - * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed $impersonater + * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed $impersonator * * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException */ - private function checkImpersonater(Impersonatable $impersonater): void + private function checkImpersonater(Impersonatable $impersonator): void { - if ( ! $impersonater->canImpersonate()) - throw ImpersonationException::cannotImpersonate($impersonater); + if ( ! $impersonator->canImpersonate()) + throw ImpersonationException::cannotImpersonate($impersonator); } /** @@ -284,4 +321,17 @@ private function checkImpersonated(Impersonatable $impersonated): void if ( ! $impersonated->canBeImpersonated()) throw ImpersonationException::cannotBeImpersonated($impersonated); } + + /** + * Remember the impersonator. + * + * @param \Arcanedev\LaravelImpersonator\Contracts\Impersonatable $impersonator + */ + private function rememberImpersonater(Impersonatable $impersonator) + { + $this->session()->put([ + $this->getSessionKey() => $impersonator->getAuthIdentifier(), + $this->getSessionGuard() => $this->auth()->getDefaultDriver(), + ]); + } } diff --git a/tests/EventsTest.php b/tests/EventsTest.php index 03e552e..424846a 100644 --- a/tests/EventsTest.php +++ b/tests/EventsTest.php @@ -4,11 +4,8 @@ namespace Arcanedev\LaravelImpersonator\Tests; -use Arcanedev\LaravelImpersonator\Events\ImpersonationStopped; -use Arcanedev\LaravelImpersonator\Events\ImpersonationStarted; -use Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User; -use Illuminate\Auth\Events\Login; -use Illuminate\Auth\Events\Logout; +use Arcanedev\LaravelImpersonator\Events\{ImpersonationStarted, ImpersonationStopped}; +use Illuminate\Auth\Events\{Login, Logout}; use Illuminate\Support\Facades\Event; /** @@ -37,10 +34,10 @@ protected function setUp(): void */ /** @test */ - public function it_must_dispatches_events_when_starting_and_stopping_impersonations() + public function it_must_dispatches_events_when_starting_and_stopping_impersonations(): void { $admin = $this->getAdminUser(); - $user = $this->getRegularUSer(); + $user = $this->getRegularUser(); static::assertTrue($admin->impersonate($user)); static::assertTrue($user->stopImpersonation()); @@ -53,41 +50,21 @@ public function it_must_dispatches_events_when_starting_and_stopping_impersonati } /* ----------------------------------------------------------------- - | Other Methods + | Custom Assertions | ----------------------------------------------------------------- */ - /** - * Get the admin user. - * - * @return \Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User|mixed - */ - protected function getAdminUser() - { - return User::query()->find(1); - } - - /** - * Get the regular user. - * - * @return \Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User|mixed - */ - protected function getRegularUSer() - { - return User::query()->find(2); - } - - protected static function assertLoginEventNotDispatched() + protected static function assertLoginEventNotDispatched(): void { Event::assertNotDispatched(Login::class); } - private static function assertLogoutEventNotDispatched() + private static function assertLogoutEventNotDispatched(): void { Event::assertNotDispatched(Logout::class); } - protected static function assertImpersonationStartedEventDispatched($impersonater, $impersonated) + protected static function assertImpersonationStartedEventDispatched($impersonater, $impersonated): void { Event::assertDispatched(ImpersonationStarted::class, function ($event) use ($impersonater, $impersonated) { return $event->impersonater->id == $impersonater->id && $event->impersonated->id == $impersonated->id; @@ -100,4 +77,29 @@ protected static function assertImpersonationStoppedEventDispatched($impersonate return $event->impersonater->id == $impersonater->id && $event->impersonated->id == $impersonated->id; }); } + + /* ----------------------------------------------------------------- + | Other Methods + | ----------------------------------------------------------------- + */ + + /** + * Get the admin user. + * + * @return \Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User|mixed + */ + protected function getAdminUser() + { + return $this->getUserById(1); + } + + /** + * Get the regular user. + * + * @return \Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User|mixed + */ + protected function getRegularUser() + { + return $this->getUserById(2); + } } diff --git a/tests/ImpersonationPoliciesTest.php b/tests/ImpersonationPoliciesTest.php index 461c500..772540b 100644 --- a/tests/ImpersonationPoliciesTest.php +++ b/tests/ImpersonationPoliciesTest.php @@ -20,7 +20,7 @@ class ImpersonationPoliciesTest extends TestCase */ /** @test */ - public function it_can_allow_access_to_impersonator() + public function it_can_allow_access_to_impersonator(): void { $this->loginWithId(1); @@ -31,7 +31,7 @@ public function it_can_allow_access_to_impersonator() } /** @test */ - public function it_can_deny_access_to_impersonator() + public function it_can_deny_access_to_impersonator(): void { $this->loginWithId(2); @@ -40,7 +40,7 @@ public function it_can_deny_access_to_impersonator() } /** @test */ - public function it_can_deny_access_if_impersonated_can_not_be_impersonated() + public function it_can_deny_access_if_impersonated_can_not_be_impersonated(): void { $this->loginWithId(1); @@ -49,7 +49,7 @@ public function it_can_deny_access_if_impersonated_can_not_be_impersonated() } /** @test */ - public function it_can_stop_ongoing_impersonation() + public function it_can_stop_ongoing_impersonation(): void { $this->loginWithId(1); @@ -65,7 +65,7 @@ public function it_can_stop_ongoing_impersonation() } /** @test */ - public function it_can_redirect_if_impersonation_not_started() + public function it_can_redirect_if_impersonation_not_started(): void { $this->loginWithId(1); @@ -74,7 +74,7 @@ public function it_can_redirect_if_impersonation_not_started() } /** @test */ - public function it_can_deny_access_if_impersonation_is_disabled() + public function it_can_deny_access_if_impersonation_is_disabled(): void { $this->disableImpersonations(); diff --git a/tests/ImpersonationTraitTest.php b/tests/ImpersonationTraitTest.php index 50c657d..f635074 100644 --- a/tests/ImpersonationTraitTest.php +++ b/tests/ImpersonationTraitTest.php @@ -4,6 +4,8 @@ namespace Arcanedev\LaravelImpersonator\Tests; +use Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User; + /** * Class ImpersonationTraitTest * @@ -18,7 +20,7 @@ class ImpersonationTraitTest extends TestCase */ /** @test */ - public function it_can_impersonate() + public function it_can_impersonate(): void { $admin = $this->loginWithId(1); @@ -26,7 +28,7 @@ public function it_can_impersonate() } /** @test */ - public function it_can_not_impersonate() + public function it_can_not_impersonate(): void { $user = $this->loginWithId(2); @@ -34,7 +36,7 @@ public function it_can_not_impersonate() } /** @test */ - public function it_can_be_impersonated() + public function it_can_be_impersonated(): void { $user = $this->loginWithId(2); @@ -42,7 +44,7 @@ public function it_can_be_impersonated() } /** @test */ - public function it_can_not_be_impersonated() + public function it_can_not_be_impersonated(): void { $admin = $this->loginWithId(1); @@ -50,7 +52,7 @@ public function it_can_not_be_impersonated() } /** @test */ - public function it_can_start_and_stop_the_impersonation() + public function it_can_start_and_stop_the_impersonation(): void { /** @var \Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User $admin */ $admin = $this->loginWithId(1); @@ -58,7 +60,7 @@ public function it_can_start_and_stop_the_impersonation() static::assertFalse($admin->isImpersonated()); /** @var \Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User $user */ - $user = $this->impersonator()->findUserById(2); + $user = User::query()->findOrFail(2); $admin->impersonate($user); diff --git a/tests/ImpersonatorServiceProviderTest.php b/tests/ImpersonatorServiceProviderTest.php index 83db619..310a045 100644 --- a/tests/ImpersonatorServiceProviderTest.php +++ b/tests/ImpersonatorServiceProviderTest.php @@ -4,7 +4,12 @@ namespace Arcanedev\LaravelImpersonator\Tests; +use Arcanedev\LaravelImpersonator\Contracts\Impersonator as ImpersonatorContract; use Arcanedev\LaravelImpersonator\ImpersonatorServiceProvider; +use Arcanedev\Support\Providers\PackageServiceProvider; +use Arcanedev\Support\Providers\ServiceProvider; +use Illuminate\Contracts\Support\DeferrableProvider; +use Illuminate\Support\ServiceProvider as IlluminateServiceProvider; /** * Class ImpersonatorServiceProviderTest @@ -47,14 +52,14 @@ protected function tearDown(): void */ /** @test */ - public function it_can_be_instantiated() + public function it_can_be_instantiated(): void { $expectations = [ - \Illuminate\Support\ServiceProvider::class, - \Illuminate\Contracts\Support\DeferrableProvider::class, - \Arcanedev\Support\Providers\ServiceProvider::class, - \Arcanedev\Support\Providers\PackageServiceProvider::class, - \Arcanedev\LaravelImpersonator\ImpersonatorServiceProvider::class, + IlluminateServiceProvider::class, + DeferrableProvider::class, + ServiceProvider::class, + PackageServiceProvider::class, + ImpersonatorServiceProvider::class, ]; foreach ($expectations as $expected) { @@ -63,10 +68,10 @@ public function it_can_be_instantiated() } /** @test */ - public function it_can_provides() + public function it_can_provides(): void { $expected = [ - \Arcanedev\LaravelImpersonator\Contracts\Impersonator::class, + ImpersonatorContract::class, ]; static::assertSame($expected, $this->provider->provides()); diff --git a/tests/ImpersonatorTest.php b/tests/ImpersonatorTest.php index 79fac63..f2a7df2 100644 --- a/tests/ImpersonatorTest.php +++ b/tests/ImpersonatorTest.php @@ -4,8 +4,9 @@ namespace Arcanedev\LaravelImpersonator\Tests; -use Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User; use Arcanedev\LaravelImpersonator\Contracts\Impersonator as ImpersonatorContract; +use Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException; +use Arcanedev\LaravelImpersonator\Impersonator; /** * Class ImpersonatorTest @@ -48,11 +49,11 @@ protected function tearDown(): void */ /** @test */ - public function it_can_be_instantiated() + public function it_can_be_instantiated(): void { $expectations = [ ImpersonatorContract::class, - \Arcanedev\LaravelImpersonator\Impersonator::class, + Impersonator::class, ]; foreach ($expectations as $expected) { @@ -61,13 +62,13 @@ public function it_can_be_instantiated() } /** @test */ - public function it_can_be_instantiated_with_helper() + public function it_can_be_instantiated_with_helper(): void { $impersonator = impersonator(); $expectations = [ ImpersonatorContract::class, - \Arcanedev\LaravelImpersonator\Impersonator::class, + Impersonator::class, ]; foreach ($expectations as $expected) { @@ -76,33 +77,20 @@ public function it_can_be_instantiated_with_helper() } /** @test */ - public function it_can_find_a_user() - { - /** @var \Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User $admin */ - $admin = $this->impersonator->findUserById(1); - /** @var \Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User $user */ - $user = $this->impersonator->findUserById(2); - - static::assertInstanceOf(User::class, $admin); - static::assertInstanceOf(User::class, $user); - - static::assertSame('Admin 1', $admin->name); - static::assertSame('User 1', $user->name); - } - - /** @test */ - public function it_can_check_is_impersonating() + public function it_can_check_is_impersonating(): void { static::assertFalse($this->impersonator->isImpersonating()); $this->app['session']->put($this->impersonator->getSessionKey(), 1); + $this->app['session']->put($this->impersonator->getSessionGuard(), 'custom'); static::assertTrue($this->impersonator->isImpersonating()); static::assertSame(1, $this->impersonator->getImpersonatorId()); + static::assertSame('custom', $this->impersonator->getImpersonatorGuard()); } /** @test */ - public function it_can_clear_impersonating() + public function it_can_clear_impersonating(): void { $this->app['session']->put($this->impersonator->getSessionKey(), 1); @@ -114,55 +102,51 @@ public function it_can_clear_impersonating() } /** @test */ - public function it_can_start_impersonation() + public function it_can_start_impersonation(): void { - $this->loginWithId(1); + $impersonator = $this->loginWithId($impersonatorId = 1); static::assertIsLoggedIn(); - $this->impersonator->start( - $this->getAuthenticatedUser(), - $this->impersonator->findUserById(2) - ); + $impersonated = $this->getUserById($impersonatedId = 2); - static::assertSame(2, $this->getAuthenticatedUser()->getKey()); - static::assertSame(1, $this->impersonator->getImpersonatorId()); + $this->impersonator->start($impersonator, $impersonated); + + static::assertSame($impersonatedId, $this->getAuthenticatedUser()->getKey()); + static::assertSame($impersonatorId, $this->impersonator->getImpersonatorId()); static::assertTrue($this->impersonator->isImpersonating()); } /** @test */ - public function it_can_stop_impersonation() + public function it_can_stop_impersonation(): void { - $this->loginWithId(1); + $this->loginWithId($impersonatorId = 1); - $this->impersonator->start( - $this->getAuthenticatedUser(), - $this->impersonator->findUserById(2) - ); + $impersonated = $this->getUserById($impersonatedId = 2); + + $this->impersonator->start($this->getAuthenticatedUser(), $impersonated); static::assertIsLoggedIn(); static::assertTrue($this->impersonator->isImpersonating()); - static::assertSame(2, $this->getAuthenticatedUser()->getKey()); + static::assertSame($impersonatedId, $this->getAuthenticatedUser()->getKey()); static::assertTrue($this->impersonator->stop()); static::assertIsLoggedIn(); static::assertFalse($this->impersonator->isImpersonating()); - static::assertSame(1, $this->getAuthenticatedUser()->getKey()); + static::assertSame($impersonatorId, $this->getAuthenticatedUser()->getKey()); } /** @test */ - public function it_must_preserve_the_remember_token_when_starting_and_stopping_impersonation() + public function it_must_preserve_the_remember_token_when_starting_and_stopping_impersonation(): void { /** @var \Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User $admin */ - $admin = $this->impersonator->findUserById(1); - $admin->remember_token = 'impersonator_token'; - $admin->save(); + $admin = $this->getUserById(1); + $admin->forceFill(['remember_token' => 'impersonator_token'])->save(); /** @var \Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User $user */ - $user = $this->impersonator->findUserById(2); - $user->remember_token = 'impersonated_token'; - $user->save(); + $user = $this->getUserById(2); + $user->forceFill(['remember_token' => 'impersonated_token'])->save(); $admin->impersonate($user); $user->stopImpersonation(); @@ -175,51 +159,51 @@ public function it_must_preserve_the_remember_token_when_starting_and_stopping_i } /** @test */ - public function it_must_throw_exception_if_impersonater_cannot_impersonate() + public function it_must_throw_exception_if_impersonater_cannot_impersonate(): void { - $this->expectException(\Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException::class); + $this->expectException(ImpersonationException::class); $this->expectExceptionMessage('The impersonater with `id`=[2] doesn\'t have the ability to impersonate.'); $this->loginWithId(2); $this->impersonator->start( $this->getAuthenticatedUser(), - $this->impersonator->findUserById(3) + $this->getUserById(3) ); } /** @test */ - public function it_must_throw_exception_if_impersonater_and_impersonated_are_same() + public function it_must_throw_exception_if_impersonater_and_impersonated_are_same(): void { - $this->expectException(\Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException::class); + $this->expectException(ImpersonationException::class); $this->expectExceptionMessage('The impersonater & impersonated with must be different.'); $this->loginWithId(1); $this->impersonator->start( $this->getAuthenticatedUser(), - $this->impersonator->findUserById(1) + $this->getUserById(1) ); } /** @test */ - public function it_must_throw_exception_if_impersonated_cannot_be_impersonated() // WHAT ?? + public function it_must_throw_exception_if_impersonated_cannot_be_impersonated(): void // WHAT ?? { - $this->expectException(\Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException::class); + $this->expectException(ImpersonationException::class); $this->expectExceptionMessage('The impersonated with `id`=[4] cannot be impersonated.'); $this->loginWithId(1); $this->impersonator->start( $this->getAuthenticatedUser(), - $this->impersonator->findUserById(4) + $this->getUserById(4) ); } /** @test */ - public function it_must_throw_exception_if_impersonater_is_disabled() + public function it_must_throw_exception_if_impersonater_is_disabled(): void { - $this->expectException(\Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException::class); + $this->expectException(ImpersonationException::class); $this->expectExceptionMessage('The impersonation is disabled.'); $this->disableImpersonations(); @@ -228,12 +212,12 @@ public function it_must_throw_exception_if_impersonater_is_disabled() $this->impersonator->start( $this->getAuthenticatedUser(), - $this->impersonator->findUserById(2) + $this->getUserById(2) ); } /** @test */ - public function it_must_return_false_if_not_in_impersonating_mode() + public function it_must_return_false_if_not_in_impersonating_mode(): void { static::assertFalse($this->impersonator->stop()); } diff --git a/tests/MiddlewareTest.php b/tests/MiddlewareTest.php index 2b3557f..02c0116 100644 --- a/tests/MiddlewareTest.php +++ b/tests/MiddlewareTest.php @@ -18,7 +18,7 @@ class MiddlewareTest extends TestCase */ /** @test */ - public function it_can_block_the_access_to_secured_routes_while_impersonating() + public function it_can_block_the_access_to_secured_routes_while_impersonating(): void { $this->loginWithId(1); diff --git a/tests/TestCase.php b/tests/TestCase.php index 8eeb667..3ca8430 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -4,6 +4,12 @@ namespace Arcanedev\LaravelImpersonator\Tests; +use Arcanedev\LaravelImpersonator\Contracts\Impersonator as ImpersonatorContract; +use Arcanedev\LaravelImpersonator\Http\Middleware\ImpersonationNotAllowed; +use Arcanedev\LaravelImpersonator\ImpersonatorServiceProvider; +use Arcanedev\LaravelImpersonator\Tests\Stubs\Controllers\ImpersonatorController; +use Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User; +use Arcanedev\LaravelImpersonator\Tests\Stubs\Providers\AuthorizationServiceProvider; use Arcanedev\LaravelPolicies\PoliciesServiceProvider; use Orchestra\Testbench\TestCase as BaseTestCase; @@ -42,12 +48,12 @@ protected function setUp(): void * * @return array */ - protected function getPackageProviders($app) + protected function getPackageProviders($app): array { return [ - \Arcanedev\LaravelPolicies\PoliciesServiceProvider::class, - \Arcanedev\LaravelImpersonator\ImpersonatorServiceProvider::class, - \Arcanedev\LaravelImpersonator\Tests\Stubs\Providers\AuthorizationServiceProvider::class, + PoliciesServiceProvider::class, + ImpersonatorServiceProvider::class, + AuthorizationServiceProvider::class, ]; } @@ -55,10 +61,8 @@ protected function getPackageProviders($app) * Define environment setup. * * @param \Illuminate\Foundation\Application $app - * - * @return void */ - protected function getEnvironmentSetUp($app) + protected function getEnvironmentSetUp($app): void { $app['config']->set('app.debug', true); $app['config']->set('auth.providers.users.model', Stubs\Models\User::class); @@ -74,17 +78,17 @@ protected function getEnvironmentSetUp($app) /** * Get the impersonator instance. * - * @return \Arcanedev\LaravelImpersonator\Contracts\Impersonator::class + * @return \Arcanedev\LaravelImpersonator\Contracts\Impersonator */ - protected function impersonator() + protected function impersonator(): ImpersonatorContract { - return $this->app[\Arcanedev\LaravelImpersonator\Contracts\Impersonator::class]; + return $this->app[ImpersonatorContract::class]; } /** * Disable the impersonations. */ - protected function disableImpersonations() + protected function disableImpersonations(): void { $this->app['config']->set('impersonator.enabled', false); } @@ -114,44 +118,44 @@ protected function getAuthenticatedUser() /** * Check if the user is logged in. */ - protected function assertIsLoggedIn() + protected function assertIsLoggedIn(): void { static::assertTrue($this->app['auth']->check()); } /** + * Get a user by the given id. + * + * @param int $id + * + * @return \Arcanedev\LaravelImpersonator\Tests\Stubs\Models\User|mixed + */ + protected function getUserById(int $id) + { + return User::query()->findOrFail($id); + } + + /** + * Setup the routes. + * * @param \Illuminate\Routing\Router $router */ - private function setUpRoutes($router) + private function setUpRoutes($router): void { - $router->aliasMiddleware( - 'no-impersonations', - \Arcanedev\LaravelImpersonator\Http\Middleware\ImpersonationNotAllowed::class - ); - - $router->group([ - 'namespace' => 'Arcanedev\LaravelImpersonator\Tests\Stubs\Controllers', - 'as' => 'auth::impersonator.', - 'middleware' => 'web', - ], function () use ($router) { - $router->get('start/{id}', [ - 'uses' => 'ImpersonatorController@start', - 'as' => 'start', // auth::impersonator.start - ]); - - $router->get('stop', [ - 'uses' => 'ImpersonatorController@stop', - 'as' => 'stop', // auth::impersonator.stop - ]); + $router->aliasMiddleware('no-impersonations', ImpersonationNotAllowed::class); + + $router->name('auth::impersonator.')->middleware('web')->group(function () use ($router) { + $router->get('start/{id}', [ImpersonatorController::class, 'start']) + ->name('start'); // auth::impersonator.start + + $router->get('stop', [ImpersonatorController::class, 'stop']) + ->name('stop'); // auth::impersonator.stop; }); - $router->group(['middleware' => ['web', 'auth', 'no-impersonations']], function () use ($router) { - $router->get('dashboard', [ - 'as' => 'admin::dashboard', - 'uses' => function() { - return 'Dashboard page'; - } - ]); + $router->middleware(['web', 'auth', 'no-impersonations'])->group(function () use ($router) { + $router->get('dashboard', function() { + return 'Dashboard page'; + })->name('admin::dashboard'); }); } }