Skip to content

Commit

Permalink
Merge pull request #27 from Scaenicus/main
Browse files Browse the repository at this point in the history
fix: fallback if the defined guard is not a SessionGuard
  • Loading branch information
SupianIDz authored Jan 29, 2025
2 parents d8259df + 83e4da8 commit 3b3f267
Showing 1 changed file with 98 additions and 23 deletions.
121 changes: 98 additions & 23 deletions src/Impersonate.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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);

Expand All @@ -54,15 +54,15 @@ public function guard(string $guard) : self
/**
* @return bool
*/
public function check() : bool
public function check(): bool
{
return $this->session->isInImpersonatingMode();
}

/**
* @return bool
*/
public function authorized() : bool
public function authorized(): bool
{
if (! in_array(HasImpersonation::class, class_uses(config('impersonate.model')))) {
return false;
Expand All @@ -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());
Expand All @@ -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());
}
Expand All @@ -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);
Expand All @@ -107,16 +107,53 @@ public function begin(mixed $impersonator, mixed $impersonated) : Impersonate
->setImpersonator($impersonator)
->setImpersonated($impersonated);

$this->auth->login($impersonated);

if (class_exists(Jetstream::class)) {
$this->session->setPasswordHash(
$this->auth->user()->getAuthPassword()
);
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;

//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($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) {
\Illuminate\Support\Facades\Auth::guard($guard_name)->login($impersonated);
$found_session_guard = true;
}
}
}

if (class_exists(Jetstream::class)) {
$this->session->setPasswordHash(
\Illuminate\Support\Facades\Auth::user()->getAuthPassword()
);
}
}

event(new BeginImpersonation(
$impersonator, $impersonated
$impersonator,
$impersonated
));
}

Expand All @@ -126,23 +163,61 @@ public function begin(mixed $impersonator, mixed $impersonated) : Impersonate
/**
* @return Impersonate
*/
public function leave() : Impersonate
public function leave(): Impersonate
{
if ($this->check()) {
$impersonator = $this->impersonator();
$impersonated = $this->impersonated();

if ($this->session->flush()) {
$this->auth->login($impersonator);

if (class_exists(Jetstream::class)) {
$this->session->setPasswordHash(
$this->auth->user()->getAuthPassword()
);
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;

//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(
\Illuminate\Support\Facades\Auth::user()->getAuthPassword()
);
}
}


event(new LeaveImpersonation(
$impersonator, $impersonated
$impersonator,
$impersonated
));
}
}
Expand All @@ -156,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);
Expand Down Expand Up @@ -185,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);
Expand Down

0 comments on commit 3b3f267

Please sign in to comment.