Completed
Pull Request — master (#4)
by ARCANEDEV
04:17
created

Impersonator::clear()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php namespace Arcanedev\LaravelImpersonator;
2
3
use Arcanedev\LaravelImpersonator\Contracts\Impersonatable;
4
use Illuminate\Contracts\Foundation\Application;
5
6
/**
7
 * Class     Impersonator
8
 *
9
 * @package  Arcanedev\LaravelImpersonator
10
 * @author   ARCANEDEV <[email protected]>
11
 */
12
class Impersonator implements Contracts\Impersonator
13
{
14
    /* -----------------------------------------------------------------
15
     |  Properties
16
     | -----------------------------------------------------------------
17
     */
18
19
    /** @var  \Illuminate\Contracts\Foundation\Application */
20
    protected $app;
21
22
    /* -----------------------------------------------------------------
23
     |  Constructor
24
     | -----------------------------------------------------------------
25
     */
26
27
    /**
28
     * Impersonator constructor.
29
     *
30
     * @param  \Illuminate\Contracts\Foundation\Application  $app
31
     */
32 44
    public function __construct(Application $app)
33
    {
34 44
        $this->app = $app;
35 44
    }
36
37
    /* -----------------------------------------------------------------
38
     |  Getters & Setters
39
     | -----------------------------------------------------------------
40
     */
41
42
    /**
43
     * Get the guard session instance.
44
     *
45
     * @return \Illuminate\Auth\AuthManager|\Arcanedev\LaravelImpersonator\Guard\SessionGuard
46
     */
47 18
    protected function auth()
48
    {
49 18
        return $this->app['auth'];
50
    }
51
52
    /**
53
     * Get the session store instance.
54
     *
55
     * @return \Illuminate\Contracts\Session\Session
56
     */
57 22
    protected function session()
58
    {
59 22
        return $this->app['session'];
60
    }
61
62
    /**
63
     * Get the config repository.
64
     *
65
     * @return \Illuminate\Contracts\Config\Repository
66
     */
67 34
    protected function config()
68
    {
69 34
        return $this->app['config'];
70
    }
71
72
    /**
73
     * Get the event dispatcher.
74
     *
75
     * @return \Illuminate\Contracts\Events\Dispatcher
76
     */
77 16
    protected function events()
78
    {
79 16
        return $this->app['events'];
80
    }
81
82
    /**
83
     * Get the session key.
84
     *
85
     * @return string
86
     */
87 24
    public function getSessionKey()
88
    {
89 24
        return $this->config()->get('impersonator.session.key', 'impersonator_id');
90
    }
91
92
    /**
93
     * Get the impersonator id.
94
     *
95
     * @return  int|null
96
     */
97 18
    public function getImpersonatorId()
98
    {
99 18
        return $this->session()->get($this->getSessionKey(), null);
100
    }
101
102
    /* -----------------------------------------------------------------
103
     |  Main Methods
104
     | -----------------------------------------------------------------
105
     */
106
107
    /**
108
     * Start the impersonation.
109
     *
110
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonater
111
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonated
112
     *
113
     * @return bool
114
     */
115 24
    public function start(Impersonatable $impersonater, Impersonatable $impersonated)
116
    {
117 24
        $this->checkImpersonation($impersonater, $impersonated);
118
119
        try {
120 16
            session()->put($this->getSessionKey(), $impersonater->getAuthIdentifier());
121 16
            $this->auth()->silentLogout();
122 16
            $this->auth()->silentLogin($impersonated);
123
124 16
            $this->events()->dispatch(
125 16
                new Events\ImpersonationStarted($impersonater, $impersonated)
126
            );
127
128 16
            return true;
129
        }
130
        catch (\Exception $e) { return false; }
131
    }
132
133
    /**
134
     * Stop the impersonation.
135
     *
136
     * @return bool
137
     */
138 14
    public function stop()
139
    {
140
        try {
141 14
            $impersonated = $this->auth()->user();
142 14
            $impersonater = $this->findUserById($this->getImpersonatorId());
143
144 12
            $this->auth()->silentLogout();
145 12
            $this->auth()->silentLogin($impersonater);
146 12
            $this->clear();
147
148 12
            $this->events()->dispatch(
149 12
                new Events\ImpersonationStopped($impersonater, $impersonated)
150
            );
151
152 12
            return true;
153
        }
154 2
        catch (\Exception $e) { return false; }
155
    }
156
157
    /**
158
     * Clear the impersonation.
159
     */
160 14
    public function clear()
161
    {
162 14
        $this->session()->forget($this->getSessionKey());
163 14
    }
164
165
    /**
166
     * Find a user by the given id.
167
     *
168
     * @param  int|string  $id
169
     *
170
     * @return \Arcanedev\LaravelImpersonator\Contracts\Impersonatable
171
     *
172
     * @throws \Exception
173
     */
174 26
    public function findUserById($id)
175
    {
176 26
        return call_user_func([$this->config()->get('auth.providers.users.model'), 'findOrFail'], $id);
177
    }
178
179
    /* -----------------------------------------------------------------
180
     |  Check Functions
181
     | -----------------------------------------------------------------
182
     */
183
184
    /**
185
     * Check if it's impersonating.
186
     *
187
     * @return bool
188
     */
189 18
    public function isImpersonating()
190
    {
191 18
        return $this->session()->has($this->getSessionKey());
192
    }
193
194
    /**
195
     * Check if the impersonations is enabled.
196
     *
197
     * @return bool
198
     */
199 24
    public function isEnabled()
200
    {
201 24
        return $this->config()->get('impersonator.enabled', false);
202
    }
203
204
    /* -----------------------------------------------------------------
205
     |  Other Methods
206
     | -----------------------------------------------------------------
207
     */
208
209
    /**
210
     * Check the impersonation.
211
     *
212
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonater
213
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonated
214
     *
215
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
216
     */
217 24
    private function checkImpersonation(Impersonatable $impersonater, Impersonatable $impersonated)
218
    {
219 24
        $this->mustBeEnabled();
220 22
        $this->mustBeDifferentImpersonatable($impersonater, $impersonated);
221 20
        $this->checkImpersonater($impersonater);
222 18
        $this->checkImpersonated($impersonated);
223 16
    }
224
225
    /**
226
     * Check if the impersonation is enabled.
227
     *
228
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
229
     */
230 24
    private function mustBeEnabled()
231
    {
232 24
        if ( ! $this->isEnabled())
233 2
            throw new Exceptions\ImpersonationException("The impersonation is disabled.");
234 22
    }
235
236
    /**
237
     * Check the impersonater and the impersonated are different.
238
     *
239
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonater
240
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonated
241
     *
242
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
243
     */
244 22
    private function mustBeDifferentImpersonatable(Impersonatable $impersonater, Impersonatable $impersonated)
245
    {
246 22
        if ($impersonater->getAuthIdentifier() == $impersonated->getAuthIdentifier())
247 2
            throw new Exceptions\ImpersonationException('The impersonater & impersonated with must be different.');
248 20
    }
249
250
    /**
251
     * Check the impersonater.
252
     *
253
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonater
254
     *
255
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
256
     */
257 20
    private function checkImpersonater(Impersonatable $impersonater)
258
    {
259 20
        if ( ! $impersonater->canImpersonate())
260 2
            throw new Exceptions\ImpersonationException(
261 2
                "The impersonater with `{$impersonater->getAuthIdentifierName()}`=[{$impersonater->getAuthIdentifier()}] doesn't have the ability to impersonate."
262
            );
263 18
    }
264
265
    /**
266
     * Check the impersonated.
267
     *
268
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonated
269
     *
270
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
271
     */
272 18
    private function checkImpersonated(Impersonatable $impersonated)
273
    {
274 18
        if ( ! $impersonated->canBeImpersonated())
275 2
            throw new Exceptions\ImpersonationException(
276 2
                "The impersonated with `{$impersonated->getAuthIdentifierName()}`=[{$impersonated->getAuthIdentifier()}] cannot be impersonated."
277
            );
278 16
    }
279
}
280