-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPossessionManager.php
More file actions
99 lines (75 loc) · 2.62 KB
/
Copy pathPossessionManager.php
File metadata and controls
99 lines (75 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<?php
namespace Verseles\Possession;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use Verseles\Possession\Exceptions\ImpersonationException;
class PossessionManager
{
public function possess ( $user, ?string $guard = null ): void
{
if (Session::has(config('possession.session_keys.original_user'))) {
throw ImpersonationException::alreadyImpersonating();
}
$admin = Auth::guard(config('possession.admin_guard'))->user();
if (!$admin) {
throw ImpersonationException::notAuthenticated();
}
$user = $this->resolveUser($user);
$this->validateImpersonation($admin, $user);
$this->logoutAndDestroySession(config('possession.admin_guard'));
$guard = $guard ?? config('auth.defaults.guard');
Auth::guard($guard)->login($user);
Session::put(config('possession.session_keys.original_user'), $admin->id);
Session::put(config('possession.session_keys.impersonation_guard'), $guard);
}
public function unpossess (): void
{
$originalUserId = Session::get(config('possession.session_keys.original_user'));
$impersonationGuard = Session::get(config('possession.session_keys.impersonation_guard'));
if (!$originalUserId) {
throw ImpersonationException::noImpersonationActive();
}
$guard = config('possession.admin_guard');
$admin = Auth::guard($guard)->getProvider()->retrieveById($originalUserId);
if (!$admin) {
throw ImpersonationException::adminNotFound();
}
if (!$admin->canPossess()) {
throw ImpersonationException::unauthorizedUnpossess();
}
$this->logoutAndDestroySession($impersonationGuard);
Auth::guard($guard)->login($admin);
Session::forget(config('possession.session_keys.original_user'));
Session::forget(config('possession.session_keys.impersonation_guard'));
}
protected function resolveUser ( $user ): Authenticatable
{
if ($user instanceof Authenticatable) return $user;
$model = config('possession.user_model');
if (is_string($user) && filter_var($user, FILTER_VALIDATE_EMAIL)) {
return $model::where('email', $user)->firstOrFail();
}
return $model::findOrFail($user);
}
protected function validateImpersonation ( $admin, $user ): void
{
if (!$admin->canPossess()) {
throw ImpersonationException::unauthorizedPossess();
}
if (!$user->canBePossessed()) {
throw ImpersonationException::targetCannotBePossessed();
}
if ($admin->is($user)) {
throw ImpersonationException::selfPossession();
}
}
protected function logoutAndDestroySession ( $guard = null ): void
{
if ($guard) {
Auth::guard($guard)->logout();
} else {
Auth::logout();
}
}
}