From ff0340c546b8b66bb4c5f892135dd98b4da88fcd Mon Sep 17 00:00:00 2001 From: fmeccanici Date: Fri, 22 Dec 2023 20:27:45 +0100 Subject: [PATCH] Get/set leave redirect to url from/to session --- config/laravel-impersonate.php | 5 +++ src/Controllers/ImpersonateController.php | 7 ++- src/Services/ImpersonateManager.php | 13 +++++- tests/ImpersonateControllerTest.php | 52 +++++++++++++++++++++++ tests/ImpersonateManagerTest.php | 15 +++++++ 5 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 tests/ImpersonateControllerTest.php diff --git a/config/laravel-impersonate.php b/config/laravel-impersonate.php index f1aef8d..0e5e40c 100644 --- a/config/laravel-impersonate.php +++ b/config/laravel-impersonate.php @@ -17,6 +17,11 @@ */ 'session_guard_using' => 'impersonator_guard_using', + /** + * The session key used to store the URI to go to after leaving an impersonation. + */ + 'session_leave_redirect_to' => 'impersonator_leave_redirect_to', + /** * The default impersonator guard used. */ diff --git a/src/Controllers/ImpersonateController.php b/src/Controllers/ImpersonateController.php index eb71254..e04cf98 100644 --- a/src/Controllers/ImpersonateController.php +++ b/src/Controllers/ImpersonateController.php @@ -49,8 +49,10 @@ public function take(Request $request, $id, $guardName = null) $userToImpersonate = $this->manager->findUserById($id, $guardName); + $leaveRedirectUrl = $request->get('leaveRedirectTo'); + if ($userToImpersonate->canBeImpersonated()) { - if ($this->manager->take($request->user(), $userToImpersonate, $guardName)) { + if ($this->manager->take($request->user(), $userToImpersonate, $guardName, $leaveRedirectUrl)) { $takeRedirect = $this->manager->getTakeRedirectTo(); if ($takeRedirect !== 'back') { return redirect()->to($takeRedirect); @@ -70,9 +72,10 @@ public function leave() abort(403); } + $leaveRedirect = $this->manager->getLeaveRedirectTo(); + $this->manager->leave(); - $leaveRedirect = $this->manager->getLeaveRedirectTo(); if ($leaveRedirect !== 'back') { return redirect()->to($leaveRedirect); } diff --git a/src/Services/ImpersonateManager.php b/src/Services/ImpersonateManager.php index 5bdd05a..87d77f2 100644 --- a/src/Services/ImpersonateManager.php +++ b/src/Services/ImpersonateManager.php @@ -107,7 +107,7 @@ public function getImpersonatorGuardUsingName() * @param string|null $guardName * @return bool */ - public function take($from, $to, $guardName = null) + public function take($from, $to, $guardName = null, $leaveRedirectUrl = null) { $this->saveAuthCookieInSession(); @@ -116,6 +116,7 @@ public function take($from, $to, $guardName = null) session()->put($this->getSessionKey(), $from->getAuthIdentifier()); session()->put($this->getSessionGuard(), $currentGuard); session()->put($this->getSessionGuardUsing(), $guardName); + session()->put($this->getSessionLeaveRedirectTo(), $leaveRedirectUrl); $this->app['auth']->guard($currentGuard)->quietLogout(); $this->app['auth']->guard($guardName)->quietLogin($to); @@ -158,6 +159,7 @@ public function clear() session()->forget($this->getSessionKey()); session()->forget($this->getSessionGuard()); session()->forget($this->getSessionGuardUsing()); + session()->forget($this->getSessionLeaveRedirectTo()); } public function getSessionKey(): string @@ -180,6 +182,11 @@ public function getDefaultSessionGuard(): string return config('laravel-impersonate.default_impersonator_guard'); } + public function getSessionLeaveRedirectTo(): string + { + return config('laravel-impersonate.session_leave_redirect_to'); + } + public function getTakeRedirectTo(): string { try { @@ -194,6 +201,10 @@ public function getTakeRedirectTo(): string public function getLeaveRedirectTo(): string { try { + if ($uri = session($this->getSessionLeaveRedirectTo())) { + return $uri; + } + $uri = route(config('laravel-impersonate.leave_redirect_to')); } catch (\InvalidArgumentException $e) { $uri = config('laravel-impersonate.leave_redirect_to'); diff --git a/tests/ImpersonateControllerTest.php b/tests/ImpersonateControllerTest.php new file mode 100644 index 0000000..1c6a3bf --- /dev/null +++ b/tests/ImpersonateControllerTest.php @@ -0,0 +1,52 @@ +manager = $this->app->make(ImpersonateManager::class); + $this->guard = 'web'; + } + + /** @test */ + public function it_gets_leave_redirect_to_from_session_if_exists() + { + // Arrange + $leaveRedirectTo = 'http://example.com'; + $this->app['session']->put($this->manager->getSessionLeaveRedirectTo(), $leaveRedirectTo); + $this->app['session']->put($this->manager->getSessionKey(), 'test_session_key'); + + // Act + $response = $this->get(route('impersonate.leave')); + + // Assert + $response->assertRedirect($leaveRedirectTo); + } + + /** @test */ + public function it_gets_leave_redirect_to_from_query_parameter_and_stores_it_in_session() + { + // Arrange + $this->withoutExceptionHandling(); + $this->app['auth']->loginUsingId('admin@test.rocks'); + $leaveRedirectTo = 'http://example.com'; + + // Act + $response = $this->get(route('impersonate', ['id' => 'user@test.rocks', 'guardName' => 'web', 'leaveRedirectTo' => $leaveRedirectTo])); + + // Assert + $this->assertEquals($leaveRedirectTo, $this->app['session']->get($this->manager->getSessionLeaveRedirectTo())); + } +} diff --git a/tests/ImpersonateManagerTest.php b/tests/ImpersonateManagerTest.php index 1c31866..1a585ff 100644 --- a/tests/ImpersonateManagerTest.php +++ b/tests/ImpersonateManagerTest.php @@ -214,4 +214,19 @@ public function it_renames_the_remember_web_cookie_when_taking_and_reverts_the_c $this->assertEquals($cookie->getName(), $response->headers->getCookies()[0]->getName()); $this->assertEquals($cookie->getValue(), $response->headers->getCookies()[0]->getValue()); } + + /** @test */ + public function it_puts_leave_redirect_to_in_session_when_take_is_called() + { + // Arrange + $this->app['auth']->loginUsingId('admin@test.rocks'); + $leaveRedirectTo = 'http://localhost/custom-redirect-url'; + + // Act + $this->manager->take($this->app['auth']->user(), $this->manager->findUserById('user@test.rocks'), null, $leaveRedirectTo); + + // Assert + $this->assertEquals($leaveRedirectTo, $this->app['session']->get($this->manager->getSessionLeaveRedirectTo())); + } + }