From 073ec758cabd99f72a9f180482a36b8ae7062558 Mon Sep 17 00:00:00 2001 From: Philipp Date: Mon, 20 Jan 2025 12:06:57 +0100 Subject: [PATCH 1/4] feat: fallback to session guard --- src/Impersonate.php | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/Impersonate.php b/src/Impersonate.php index 769828f..60b923b 100644 --- a/src/Impersonate.php +++ b/src/Impersonate.php @@ -97,7 +97,7 @@ public function impersonated() : Model|Authenticatable * @return $this * @throws ImpersonateException */ - public function begin(mixed $impersonator, mixed $impersonated) : Impersonate + public function begin(mixed $impersonator, mixed $impersonated): Impersonate { $impersonator = $this->fetchModel($impersonator); $impersonated = $this->fetchModel($impersonated); @@ -107,7 +107,37 @@ public function begin(mixed $impersonator, mixed $impersonated) : Impersonate ->setImpersonator($impersonator) ->setImpersonated($impersonated); - $this->auth->login($impersonated); + + if ($this->auth instanceof \Illuminate\Auth\SessionGuard) { + $this->auth->login($impersonated); + } else { + //Fallback to Laravel's Auth facade + $found_session_guard = false; + + //Use server's default guard + $guard = \Illuminate\Support\Facades\Auth::guard(config('auth.defaults.guard')); + + if ($guard instanceof \Illuminate\Auth\SessionGuard) { + $found_session_guard = true; + $guard->login($impersonated); + } + + if (!$found_session_guard) { + //Fallback to the first SessionGuard + $guard_names = array_keys(config('auth.guards')); + foreach ($guard_names as $guard_name) { + if ($found_session_guard) { + continue; + } + $guard = \Illuminate\Support\Facades\Auth::guard($guard_name); + + if ($guard instanceof \Illuminate\Auth\SessionGuard) { + $guard->login($impersonated); + $found_session_guard = true; + } + } + } + } if (class_exists(Jetstream::class)) { $this->session->setPasswordHash( @@ -116,7 +146,8 @@ public function begin(mixed $impersonator, mixed $impersonated) : Impersonate } event(new BeginImpersonation( - $impersonator, $impersonated + $impersonator, + $impersonated )); } From a3da55e5f3c9ab308d09692168884ce26ba949df Mon Sep 17 00:00:00 2001 From: Philipp Date: Mon, 20 Jan 2025 12:14:56 +0100 Subject: [PATCH 2/4] feat: replace factory auth with facade --- src/Impersonate.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Impersonate.php b/src/Impersonate.php index 60b923b..3ec9c4c 100644 --- a/src/Impersonate.php +++ b/src/Impersonate.php @@ -120,6 +120,7 @@ public function begin(mixed $impersonator, mixed $impersonated): Impersonate if ($guard instanceof \Illuminate\Auth\SessionGuard) { $found_session_guard = true; $guard->login($impersonated); + \Illuminate\Support\Facades\Auth::guard(config('auth.defaults.guard'))->login($impersonated); } if (!$found_session_guard) { @@ -132,7 +133,7 @@ public function begin(mixed $impersonator, mixed $impersonated): Impersonate $guard = \Illuminate\Support\Facades\Auth::guard($guard_name); if ($guard instanceof \Illuminate\Auth\SessionGuard) { - $guard->login($impersonated); + \Illuminate\Support\Facades\Auth::guard($guard_name)->login($impersonated); $found_session_guard = true; } } From c30182c1c2df13bf962ccba816335986f5724924 Mon Sep 17 00:00:00 2001 From: Philipp Date: Mon, 20 Jan 2025 12:17:39 +0100 Subject: [PATCH 3/4] feat: fallback for leave too --- src/Impersonate.php | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/Impersonate.php b/src/Impersonate.php index 3ec9c4c..ca57c89 100644 --- a/src/Impersonate.php +++ b/src/Impersonate.php @@ -119,7 +119,6 @@ public function begin(mixed $impersonator, mixed $impersonated): Impersonate if ($guard instanceof \Illuminate\Auth\SessionGuard) { $found_session_guard = true; - $guard->login($impersonated); \Illuminate\Support\Facades\Auth::guard(config('auth.defaults.guard'))->login($impersonated); } @@ -165,7 +164,37 @@ public function leave() : Impersonate $impersonated = $this->impersonated(); if ($this->session->flush()) { - $this->auth->login($impersonator); + + if ($this->auth instanceof \Illuminate\Auth\SessionGuard) { + $this->auth->login($impersonator); + } else { + //Fallback to Laravel's Auth facade + $found_session_guard = false; + + //Use server's default guard + $guard = \Illuminate\Support\Facades\Auth::guard(config('auth.defaults.guard')); + + if ($guard instanceof \Illuminate\Auth\SessionGuard) { + $found_session_guard = true; + \Illuminate\Support\Facades\Auth::guard(config('auth.defaults.guard'))->login($impersonator); + } + + if (!$found_session_guard) { + //Fallback to the first SessionGuard + $guard_names = array_keys(config('auth.guards')); + foreach ($guard_names as $guard_name) { + if ($found_session_guard) { + continue; + } + $guard = \Illuminate\Support\Facades\Auth::guard($guard_name); + + if ($guard instanceof \Illuminate\Auth\SessionGuard) { + \Illuminate\Support\Facades\Auth::guard($guard_name)->login($impersonator); + $found_session_guard = true; + } + } + } + } if (class_exists(Jetstream::class)) { $this->session->setPasswordHash( From 83e4da8b891a936cc3cb8a76a5299b2c14651f9d Mon Sep 17 00:00:00 2001 From: Philipp Date: Mon, 20 Jan 2025 12:23:20 +0100 Subject: [PATCH 4/4] fix: redo jetsteam handling for fallback --- src/Impersonate.php | 56 ++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/src/Impersonate.php b/src/Impersonate.php index ca57c89..117715c 100644 --- a/src/Impersonate.php +++ b/src/Impersonate.php @@ -30,8 +30,8 @@ class Impersonate */ public function __construct(protected Auth $auth) { - $this->repository = new Repository; - $this->session = new SessionStorage; + $this->repository = new Repository(); + $this->session = new SessionStorage(); $this->guard(config( 'impersonate.guard' @@ -44,7 +44,7 @@ public function __construct(protected Auth $auth) * @param string $guard * @return $this */ - public function guard(string $guard) : self + public function guard(string $guard): self { $this->auth->guard($guard); @@ -54,7 +54,7 @@ public function guard(string $guard) : self /** * @return bool */ - public function check() : bool + public function check(): bool { return $this->session->isInImpersonatingMode(); } @@ -62,7 +62,7 @@ public function check() : bool /** * @return bool */ - public function authorized() : bool + public function authorized(): bool { if (! in_array(HasImpersonation::class, class_uses(config('impersonate.model')))) { return false; @@ -74,7 +74,7 @@ public function authorized() : bool /** * @return Model|Authenticatable */ - public function impersonator() : Model|Authenticatable + public function impersonator(): Model|Authenticatable { if ($this->check()) { return $this->repository->find($this->session->getImpersonator()); @@ -86,7 +86,7 @@ public function impersonator() : Model|Authenticatable /** * @return Model|Authenticatable */ - public function impersonated() : Model|Authenticatable + public function impersonated(): Model|Authenticatable { return $this->repository->find($this->session->getImpersonated()); } @@ -110,6 +110,12 @@ public function begin(mixed $impersonator, mixed $impersonated): Impersonate if ($this->auth instanceof \Illuminate\Auth\SessionGuard) { $this->auth->login($impersonated); + + if (class_exists(Jetstream::class)) { + $this->session->setPasswordHash( + $this->auth->user()->getAuthPassword() + ); + } } else { //Fallback to Laravel's Auth facade $found_session_guard = false; @@ -137,12 +143,12 @@ public function begin(mixed $impersonator, mixed $impersonated): Impersonate } } } - } - if (class_exists(Jetstream::class)) { - $this->session->setPasswordHash( - $this->auth->user()->getAuthPassword() - ); + if (class_exists(Jetstream::class)) { + $this->session->setPasswordHash( + \Illuminate\Support\Facades\Auth::user()->getAuthPassword() + ); + } } event(new BeginImpersonation( @@ -157,7 +163,7 @@ public function begin(mixed $impersonator, mixed $impersonated): Impersonate /** * @return Impersonate */ - public function leave() : Impersonate + public function leave(): Impersonate { if ($this->check()) { $impersonator = $this->impersonator(); @@ -167,6 +173,12 @@ public function leave() : Impersonate if ($this->auth instanceof \Illuminate\Auth\SessionGuard) { $this->auth->login($impersonator); + + if (class_exists(Jetstream::class)) { + $this->session->setPasswordHash( + $this->auth->user()->getAuthPassword() + ); + } } else { //Fallback to Laravel's Auth facade $found_session_guard = false; @@ -194,16 +206,18 @@ public function leave() : Impersonate } } } - } - if (class_exists(Jetstream::class)) { - $this->session->setPasswordHash( - $this->auth->user()->getAuthPassword() - ); + if (class_exists(Jetstream::class)) { + $this->session->setPasswordHash( + \Illuminate\Support\Facades\Auth::user()->getAuthPassword() + ); + } } + event(new LeaveImpersonation( - $impersonator, $impersonated + $impersonator, + $impersonated )); } } @@ -217,7 +231,7 @@ public function leave() : Impersonate * @return bool * @throws ImpersonateException */ - private function validate(Model $impersonator, Model $impersonated) : bool + private function validate(Model $impersonator, Model $impersonated): bool { if (! in_array(HasImpersonation::class, class_uses($impersonator))) { throw new ImpersonateException(get_class($impersonator) . ' does not uses ' . HasImpersonation::class); @@ -246,7 +260,7 @@ private function validate(Model $impersonator, Model $impersonated) : bool * @param mixed $modelOrId * @return Model|Authenticatable */ - private function fetchModel(mixed $modelOrId) : Model|Authenticatable + private function fetchModel(mixed $modelOrId): Model|Authenticatable { if (! $modelOrId instanceof Model) { return $this->repository->find($modelOrId);