Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/Controllers/ImpersonateController.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ public function take(Request $request, $id, $guardName = null)
if ($id == $request->user()->getAuthIdentifier() && ($this->manager->getCurrentAuthGuardName() == $guardName)) {
abort(403);
}

// Cannot impersonate again if you're already impersonate a user
if ($this->manager->isImpersonating()) {

if (!$request->user()->canImpersonate()) {
abort(403);
}

if (!$request->user()->canImpersonate()) {
abort(403);
if ($this->manager->isImpersonating()) {
$this->manager->leave();
// abort(403);
}

$userToImpersonate = $this->manager->findUserById($id, $guardName);
Expand Down
12 changes: 12 additions & 0 deletions src/ImpersonateServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,22 @@ protected function registerBladeDirectives()
return "<?php if (is_impersonating({$guard})) : ?>";
});

$bladeCompiler->directive('elseImpersonating', function () {
return '<?php else: ?>';
});

$bladeCompiler->directive('endImpersonating', function () {
return '<?php endif; ?>';
});

$bladeCompiler->directive('notImpersonating', function ($guard = null) {
return "<?php if (!is_impersonating({$guard})) : ?>";
});

$bladeCompiler->directive('endNotImpersonating', function () {
return '<?php endif; ?>';
});

$bladeCompiler->directive('canImpersonate', function ($guard = null) {
return "<?php if (can_impersonate({$guard})) : ?>";
});
Expand Down
47 changes: 43 additions & 4 deletions src/Services/ImpersonateManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,53 @@ public function getDefaultSessionGuard(): string

public function getTakeRedirectTo(): string
{
// Get the intended redirect, e.g. saved in session or the previous URL
$previousUrl = session()->pull('impersonate.redirect_to', url()->previous());
// Define a safe fallback route, e.g., 'home' or another route name
$fallbackUrl = route('dashboard');

// Get the impersonated guard name that the system already switched to
$guardName = $this->getImpersonatorGuardUsingName();
$impersonatedUser = $this->app['auth']->guard($guardName)->user();

// Create a dummy request to simulate accessing the previous URL
$request = \Illuminate\Http\Request::create($previousUrl);
// Ensure the request is resolved for the impersonated user
$request->setUserResolver(function () use ($impersonatedUser) {
return $impersonatedUser;
});

try {
$uri = route(config('laravel-impersonate.take_redirect_to'));
} catch (\InvalidArgumentException $e) {
$uri = config('laravel-impersonate.take_redirect_to');
// Use Laravel's HTTP Kernel to handle this sub-request. The "catch" flag
// is important so that exceptions are returned as responses.
$response = $this->app->make(\Illuminate\Contracts\Http\Kernel::class)
->handle($request, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST, true);

// If the response indicates forbidden access, use the fallback
if ($response->getStatusCode() === 403) {
return $fallbackUrl;
}
} catch (\Symfony\Component\HttpKernel\Exception\HttpException $e) {
// If a HttpException was thrown and it's 403, go to the fallback
if ($e->getStatusCode() === 403) {
return $fallbackUrl;
}
// Optionally, you can log the exception or decide on a default behavior
} catch (\Exception $e) {
// If any other exception occurs, fall back to the safe URL
return $fallbackUrl;
}

return $uri;
// If no issues, return the previous URL
return $previousUrl;
}
// try {
// $uri = route(config('laravel-impersonate.take_redirect_to'));
// } catch (\InvalidArgumentException $e) {
// $uri = config('laravel-impersonate.take_redirect_to');
// }

// return $uri

public function getLeaveRedirectTo(): string
{
Expand Down
43 changes: 43 additions & 0 deletions tests/BladeDirectivesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,47 @@ public function it_displays_can_be_impersonated_content_directive()
$this->assertStringNotContainsString('Impersonate this user', $this->view);
$this->logout();
}

/** @test */
public function it_displays_else_impersonating_content_directive_when_not_impersonating()
{
$this->actingAs($this->admin);
// The impersonate_else view uses @elseImpersonating to show alternative content.
$this->makeView('impersonate_else');
$this->assertStringContainsString('Impersonate this user', $this->view);
$this->assertStringNotContainsString('Leave impersonation', $this->view);
$this->logout();
}

/** @test */
public function it_displays_else_impersonating_content_directive_when_impersonating()
{
$this->actingAs($this->admin);
$this->admin->impersonate($this->user);
$this->makeView('impersonate_else');
$this->assertStringContainsString('Leave impersonation', $this->view);
$this->assertStringNotContainsString('Impersonate this user', $this->view);
$this->logout();
}

/** @test */
public function it_displays_not_impersonating_content_directive()
{
$this->actingAs($this->admin);
// The not_impersonating view uses @notImpersonating to show content when not impersonating.
$this->makeView('not_impersonating');
$this->assertStringContainsString('Not impersonating', $this->view);
$this->logout();
}

/** @test */
public function it_not_displays_not_impersonating_content_directive_when_impersonating()
{
$this->actingAs($this->admin);
$this->admin->impersonate($this->user);
$this->makeView('not_impersonating');
$this->assertStringNotContainsString('Not impersonating', $this->view);
$this->logout();
}

}
7 changes: 7 additions & 0 deletions tests/Stubs/views/impersonate_else.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<h1>impersonate_else.blade.php</h1>

@impersonating
Leave impersonation
@elseImpersonating
Impersonate this user
@endImpersonating
3 changes: 3 additions & 0 deletions tests/Stubs/views/not_impersonating.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@notImpersonating
Not impersonating
@endNotImpersonating