Completed
Push — master ( d2f599...3fd322 )
by Alexander
07:48
created

Impersonator::getImpersonatingIdentifier()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php declare(strict_types=1);
2
3
namespace Scif\LaravelPretend\Service;
4
5
use HttpException;
6
use Illuminate\Auth\AuthManager;
7
use Illuminate\Contracts\Auth\Authenticatable;
8
use Illuminate\Contracts\Auth\Guard;
9
use Illuminate\Contracts\Auth\UserProvider;
10
use Illuminate\Contracts\Config\Repository;
11
use Illuminate\Contracts\Events\Dispatcher;
12
use Illuminate\Session\Store;
13
use Scif\LaravelPretend\Event\Impersonated;
14
use Scif\LaravelPretend\Event\Unimpersonated;
15
16
class Impersonator
17
{
18
    /** @var  Guard $guard */
19
    protected $guard;
20
21
    /** @var Repository $config */
22
    protected $config;
23
24
    /** @var  UserProvider */
25
    protected $userProvider;
26
27
    /** @var Store $session */
28
    protected $session;
29
30
    /** @var Dispatcher $eventDispatcher */
31
    protected $eventDispatcher;
32
33
    /** @var  Authenticatable */
34
    protected $realUser;
35
36
    /** @var  Authenticatable */
37
    protected $impersonationUser;
38
39
    /** @var  bool */
40
    protected $isForbidden;
41
42
    const SESSION_NAME = 'pretend:_switch_user';
43
44 7
    public function __construct(
45
        AuthManager $auth,
46
        Repository $config,
47
        UserProvider $userProvider,
48
        Store $session,
49
        Dispatcher $eventDispatcher
50
    ) {
51 7
        $this->guard           = $auth->guard();
52 7
        $this->realUser        = $this->guard->user();
53 7
        $this->config          = $config;
54 7
        $this->userProvider    = $userProvider;
55 7
        $this->session         = $session;
56 7
        $this->eventDispatcher = $eventDispatcher;
57 7
        $this->isForbidden     = false;
58 7
    }
59
60
    /**
61
     * @throws HttpException Throw 403 exception if cannot find user
62
     */
63 1
    public function exitImpersonation()
64
    {
65 1
        $username = $this->session->get(static::SESSION_NAME);
66
67 1
        if (null === $username) {
68 1
            return;
69
        }
70
71
        $this->session->remove(static::SESSION_NAME);
72
73
        $user  = $this->retrieveUser($username);
74
        $event = new Unimpersonated($this->realUser, $user);
75
76
        $this->eventDispatcher->fire($event);
77
    }
78
79
    /**
80
     * @throws HttpException Throw 403 exception if cannot find user
81
     */
82 4
    protected function retrieveUser(string $username): Authenticatable
83
    {
84
        $conditions = [
85 4
            $this->config->get('pretend.impersonate.user_identifier') => $username,
86
        ];
87
88 4
        $user = $this->userProvider->retrieveByCredentials($conditions);
89
90 4
        if (null === $user) {
91 1
            abort(403, 'Cannot find user by this credentials');
92
        }
93
94 3
        return $user;
95
    }
96
97
    /**
98
     * @throws HttpException Throw 403 exception if you try to impersonate yourself
99
     *
100
     * @param string $username Username of user you want to enter impersonate
101
     */
102 4
    public function enterImpersonation(string $username)
103
    {
104 4
        $user     = $this->retrieveUser($username);
105
106 3
        if ($user->getAuthIdentifier() === $this->realUser->getAuthIdentifier()) {
107 1
            abort(403, 'Cannot impersonate yourself');
108
        }
109
110 1
        $this->impersonationUser = $user;
111 1
        $this->guard->setUser($user);
112
113 1
        if (!$this->session->has(static::SESSION_NAME)) {
114 1
            $this->session->put(static::SESSION_NAME, $username);
115
116 1
            $this->eventDispatcher->fire(new Impersonated($this->realUser, $user));
117
        }
118 1
    }
119
120 4
    public function isImpersonated(): bool
121
    {
122 4
        return $this->session->has(static::SESSION_NAME);
123
    }
124
125
    /**
126
     * @throws HttpException Throw 403 exception if cannot find data in session
127
     */
128
    public function continueImpersonation()
129
    {
130
        $name = $this->getImpersonatingIdentifier();
131
132
        $this->enterImpersonation($name);
133
    }
134
135
    public function getImpersonatingIdentifier(): string
136
    {
137
        return $this->session->get(static::SESSION_NAME, '');
138
    }
139
}
140