Completed
Push — master ( 298f23...fc3917 )
by ARCANEDEV
04:48
created

Impersonator::mustBeDifferentImpersonatable()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 2
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
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 66
    public function __construct(Application $app)
33
    {
34 66
        $this->app = $app;
35 66
    }
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 27
    protected function auth()
48
    {
49 27
        return $this->app['auth'];
50
    }
51
52
    /**
53
     * Get the session store instance.
54
     *
55
     * @return \Illuminate\Contracts\Session\Session
56
     */
57 33
    protected function session()
58
    {
59 33
        return $this->app['session'];
60
    }
61
62
    /**
63
     * Get the config repository.
64
     *
65
     * @return \Illuminate\Contracts\Config\Repository
66
     */
67 51
    protected function config()
68
    {
69 51
        return $this->app['config'];
70
    }
71
72
    /**
73
     * Get the event dispatcher.
74
     *
75
     * @return \Illuminate\Contracts\Events\Dispatcher
76
     */
77 24
    protected function events()
78
    {
79 24
        return $this->app['events'];
80
    }
81
82
    /**
83
     * Get the session key.
84
     *
85
     * @return string
86
     */
87 36
    public function getSessionKey()
88
    {
89 36
        return $this->config()->get('impersonator.session.key', 'impersonator_id');
90
    }
91
92
    /**
93
     * Get the impersonator id.
94
     *
95
     * @return  int|null
96
     */
97 27
    public function getImpersonatorId()
98
    {
99 27
        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 36
    public function start(Impersonatable $impersonater, Impersonatable $impersonated)
116
    {
117 36
        $this->checkImpersonation($impersonater, $impersonated);
118
119
        try {
120 24
            session()->put($this->getSessionKey(), $impersonater->getAuthIdentifier());
121 24
            $this->auth()->silentLogout();
122 24
            $this->auth()->silentLogin($impersonated);
123
124 24
            $this->events()->dispatch(
125 24
                new Events\ImpersonationStarted($impersonater, $impersonated)
126 8
            );
127
128 24
            return true;
129
        }
130
        catch (\Exception $e) { return false; }
131
    }
132
133
    /**
134
     * Stop the impersonation.
135
     *
136
     * @return bool
137
     */
138 21
    public function stop()
139
    {
140
        try {
141 21
            $impersonated = $this->auth()->user();
142 21
            $impersonater = $this->findUserById($this->getImpersonatorId());
143
144 18
            $this->auth()->silentLogout();
145 18
            $this->auth()->silentLogin($impersonater);
146 18
            $this->clear();
147
148 18
            $this->events()->dispatch(
149 18
                new Events\ImpersonationStopped($impersonater, $impersonated)
150 6
            );
151
152 18
            return true;
153
        }
154 3
        catch (\Exception $e) { return false; }
155
    }
156
157
    /**
158
     * Clear the impersonation.
159
     */
160 21
    public function clear()
161
    {
162 21
        $this->session()->forget($this->getSessionKey());
163 21
    }
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 39
    public function findUserById($id)
175
    {
176 39
        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 27
    public function isImpersonating()
190
    {
191 27
        return $this->session()->has($this->getSessionKey());
192
    }
193
194
    /**
195
     * Check if the impersonations is enabled.
196
     *
197
     * @return bool
198
     */
199 36
    public function isEnabled()
200
    {
201 36
        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 36
    private function checkImpersonation(Impersonatable $impersonater, Impersonatable $impersonated)
218
    {
219 36
        $this->mustBeEnabled();
220 33
        $this->mustBeDifferentImpersonatable($impersonater, $impersonated);
221 30
        $this->checkImpersonater($impersonater);
222 27
        $this->checkImpersonated($impersonated);
223 24
    }
224
225
    /**
226
     * Check if the impersonation is enabled.
227
     *
228
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
229
     */
230 36
    private function mustBeEnabled()
231
    {
232 36
        if ( ! $this->isEnabled())
233 14
            throw new Exceptions\ImpersonationException("The impersonation is disabled.");
234 33
    }
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 33
    private function mustBeDifferentImpersonatable(Impersonatable $impersonater, Impersonatable $impersonated)
245
    {
246 33
        if ($impersonater->getAuthIdentifier() == $impersonated->getAuthIdentifier())
247 13
            throw new Exceptions\ImpersonationException('The impersonater & impersonated with must be different.');
248 30
    }
249
250
    /**
251
     * Check the impersonater.
252
     *
253
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonater
254
     *
255
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
256
     */
257 30
    private function checkImpersonater(Impersonatable $impersonater)
258
    {
259 30
        if ( ! $impersonater->canImpersonate())
260 12
            throw new Exceptions\ImpersonationException(
261 3
                "The impersonater with `{$impersonater->getAuthIdentifierName()}`=[{$impersonater->getAuthIdentifier()}] doesn't have the ability to impersonate."
262 1
            );
263 27
    }
264
265
    /**
266
     * Check the impersonated.
267
     *
268
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonated
269
     *
270
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
271
     */
272 27
    private function checkImpersonated(Impersonatable $impersonated)
273
    {
274 27
        if ( ! $impersonated->canBeImpersonated())
275 11
            throw new Exceptions\ImpersonationException(
276 3
                "The impersonated with `{$impersonated->getAuthIdentifierName()}`=[{$impersonated->getAuthIdentifier()}] cannot be impersonated."
277 1
            );
278 24
    }
279
}
280