Impersonator::getImpersonatorId()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arcanedev\LaravelImpersonator;
6
7
use Arcanedev\LaravelImpersonator\Contracts\Impersonatable;
8
use Arcanedev\LaravelImpersonator\Contracts\Impersonator as ImpersonatorContract;
9
use Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException;
10
use Exception;
11
use Illuminate\Contracts\Foundation\Application;
12
13
/**
14
 * Class     Impersonator
15
 *
16
 * @author   ARCANEDEV <[email protected]>
17
 */
18
class Impersonator implements ImpersonatorContract
19
{
20
    /* -----------------------------------------------------------------
21
     |  Properties
22
     | -----------------------------------------------------------------
23
     */
24
25
    /** @var  \Illuminate\Contracts\Foundation\Application */
26
    protected $app;
27
28
    /* -----------------------------------------------------------------
29
     |  Constructor
30
     | -----------------------------------------------------------------
31
     */
32
33
    /**
34
     * Impersonator constructor.
35
     *
36
     * @param  \Illuminate\Contracts\Foundation\Application  $app
37
     */
38 84
    public function __construct(Application $app)
39
    {
40 84
        $this->app = $app;
41 84
    }
42
43
    /* -----------------------------------------------------------------
44
     |  Getters & Setters
45
     | -----------------------------------------------------------------
46
     */
47
48
    /**
49
     * Get the guard session instance.
50
     *
51
     * @return \Illuminate\Auth\AuthManager|\Arcanedev\LaravelImpersonator\Guard\SessionGuard
52
     */
53 36
    protected function auth()
54
    {
55 36
        return $this->app['auth'];
56
    }
57
58
    /**
59
     * Get the session store instance.
60
     *
61
     * @return \Illuminate\Contracts\Session\Session
62
     */
63 48
    protected function session()
64
    {
65 48
        return $this->app['session'];
66
    }
67
68
    /**
69
     * Get the config repository.
70
     *
71
     * @return \Illuminate\Contracts\Config\Repository
72
     */
73 64
    protected function config()
74
    {
75 64
        return $this->app['config'];
76
    }
77
78
    /**
79
     * Get the event dispatcher.
80
     *
81
     * @return \Illuminate\Contracts\Events\Dispatcher
82
     */
83 32
    protected function events()
84
    {
85 32
        return $this->app['events'];
86
    }
87
88
    /**
89
     * Get the session key.
90
     *
91
     * @return string
92
     */
93 48
    public function getSessionKey(): string
94
    {
95 48
        return $this->config()->get('impersonator.session.key', 'impersonator_id');
96
    }
97
98
    /**
99
     * Get the session guard.
100
     *
101
     * @return string
102
     */
103 48
    public function getSessionGuard(): string
104
    {
105 48
        return $this->config()->get('impersonator.session.guard', 'impersonator_guard');
106
    }
107
108
    /**
109
     * Get the impersonator id.
110
     *
111
     * @return int|null
112
     */
113 36
    public function getImpersonatorId(): ?int
114
    {
115 36
        return $this->session()->get($this->getSessionKey(), null);
116
    }
117
118
    /**
119
     * Get the impersonator guard.
120
     *
121
     * @return string|null
122
     */
123 32
    public function getImpersonatorGuard(): ?string
124
    {
125 32
        return $this->session()->get($this->getSessionGuard(), null)
126 32
            ?: $this->auth()->getDefaultDriver();
0 ignored issues
show
Bug introduced by
The method getDefaultDriver does only exist in Illuminate\Auth\AuthManager, but not in Arcanedev\LaravelImpersonator\Guard\SessionGuard.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
127
    }
128
129
    /* -----------------------------------------------------------------
130
     |  Main Methods
131
     | -----------------------------------------------------------------
132
     */
133
134
    /**
135
     * Start the impersonation.
136
     *
137
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonator
138
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonated
139
     * @param  string|null                                                    $guard
140
     *
141
     * @return bool
142
     */
143 48
    public function start(Impersonatable $impersonator, Impersonatable $impersonated, $guard = null): bool
144
    {
145 48
        $this->checkImpersonation($impersonator, $impersonated);
146
147
        try {
148 32
            $this->rememberImpersonater($impersonator);
149
150 32
            $auth = $this->auth();
151 32
            $auth->guard()->silentLogout();
0 ignored issues
show
Bug introduced by
The method guard does only exist in Illuminate\Auth\AuthManager, but not in Arcanedev\LaravelImpersonator\Guard\SessionGuard.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
152 32
            $auth->guard($guard)->silentLogin($impersonated);
153
154 32
            $this->events()->dispatch(
155 32
                new Events\ImpersonationStarted($impersonator, $impersonated)
156
            );
157
158 32
            return true;
159
        }
160
        catch (Exception $e) {
161
            return false;
162
        }
163
    }
164
165
    /**
166
     * Stop the impersonation.
167
     *
168
     * @return bool
169
     */
170 28
    public function stop(): bool
171
    {
172
        try {
173 28
            $auth = $this->auth();
174
175 28
            $impersonated = $auth->user();
0 ignored issues
show
Bug introduced by
The method user does only exist in Arcanedev\LaravelImpersonator\Guard\SessionGuard, but not in Illuminate\Auth\AuthManager.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
176 28
            $impersonator = $this->getImpersonatorFromSession();
177
178 24
            $auth->silentLogout();
0 ignored issues
show
Bug introduced by
The method silentLogout does only exist in Arcanedev\LaravelImpersonator\Guard\SessionGuard, but not in Illuminate\Auth\AuthManager.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
179 24
            $auth->guard($this->getImpersonatorGuard())->silentLogin($impersonator);
0 ignored issues
show
Bug introduced by
The method guard does only exist in Illuminate\Auth\AuthManager, but not in Arcanedev\LaravelImpersonator\Guard\SessionGuard.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
180 24
            $this->clear();
181
182 24
            $this->events()->dispatch(
183 24
                new Events\ImpersonationStopped($impersonator, $impersonated)
184
            );
185
186 24
            return true;
187
        }
188 4
        catch (Exception $e) {
189 4
            return false;
190
        }
191
    }
192
193
    /**
194
     * Clear the impersonation.
195
     */
196 28
    public function clear(): void
197
    {
198 28
        $this->session()->forget([
199 28
            $this->getSessionKey(),
200 28
            $this->getSessionGuard(),
201
        ]);
202 28
    }
203
204
    /**
205
     * Get the impersonator from session.
206
     *
207
     * @return \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed|null
208
     *
209
     * @throws \Exception
210
     */
211 28
    protected function getImpersonatorFromSession()
212
    {
213 28
        $user = $this->auth()
0 ignored issues
show
Bug introduced by
The method guard does only exist in Illuminate\Auth\AuthManager, but not in Arcanedev\LaravelImpersonator\Guard\SessionGuard.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
214 28
            ->guard($this->getImpersonatorGuard())
215 28
            ->getProvider()
216 28
            ->retrieveById($this->getImpersonatorId());
217
218 28
        abort_if(is_null($user), 404, 'User not found');
219
220 24
        return $user;
221
    }
222
223
    /* -----------------------------------------------------------------
224
     |  Check Methods
225
     | -----------------------------------------------------------------
226
     */
227
228
    /**
229
     * Check if it's impersonating.
230
     *
231
     * @return bool
232
     */
233 36
    public function isImpersonating(): bool
234
    {
235 36
        return $this->session()->has([
236 36
            $this->getSessionKey(),
237 36
            $this->getSessionGuard(),
238
        ]);
239
    }
240
241
    /**
242
     * Check if the impersonations is enabled.
243
     *
244
     * @return bool
245
     */
246 48
    public function isEnabled(): bool
247
    {
248 48
        return $this->config()->get('impersonator.enabled', false);
249
    }
250
251
    /* -----------------------------------------------------------------
252
     |  Other Methods
253
     | -----------------------------------------------------------------
254
     */
255
256
    /**
257
     * Check the impersonation.
258
     *
259
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonator
260
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonated
261
     */
262 48
    private function checkImpersonation(Impersonatable $impersonator, Impersonatable $impersonated): void
263
    {
264 48
        $this->mustBeEnabled();
265 44
        $this->mustBeDifferentImpersonatable($impersonator, $impersonated);
266 40
        $this->checkImpersonater($impersonator);
267 36
        $this->checkImpersonated($impersonated);
268 32
    }
269
270
    /**
271
     * Check if the impersonation is enabled.
272
     *
273
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
274
     */
275 48
    private function mustBeEnabled(): void
276
    {
277 48
        if ( ! $this->isEnabled())
278 4
            throw new ImpersonationException(
279 4
                'The impersonation is disabled.'
280
            );
281 44
    }
282
283
    /**
284
     * Check the impersonator and the impersonated are different.
285
     *
286
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonator
287
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonated
288
     *
289
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
290
     */
291 44
    private function mustBeDifferentImpersonatable(Impersonatable $impersonator, Impersonatable $impersonated): void
292
    {
293 44
        if ($impersonator->isSamePerson($impersonated)) {
294 4
            throw Exceptions\ImpersonationException::selfImpersonation();
295
        }
296 40
    }
297
298
    /**
299
     * Check the impersonator.
300
     *
301
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonator
302
     *
303
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
304
     */
305 40
    private function checkImpersonater(Impersonatable $impersonator): void
306
    {
307 40
        if ( ! $impersonator->canImpersonate())
308 4
            throw ImpersonationException::cannotImpersonate($impersonator);
309 36
    }
310
311
    /**
312
     * Check the impersonated.
313
     *
314
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonated
315
     *
316
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
317
     */
318 36
    private function checkImpersonated(Impersonatable $impersonated): void
319
    {
320 36
        if ( ! $impersonated->canBeImpersonated())
321 4
            throw ImpersonationException::cannotBeImpersonated($impersonated);
322 32
    }
323
324
    /**
325
     * Remember the impersonator.
326
     *
327
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonator
328
     */
329 32
    private function rememberImpersonater(Impersonatable $impersonator)
330
    {
331 32
        $this->session()->put([
332 32
            $this->getSessionKey()   => $impersonator->getAuthIdentifier(),
333 32
            $this->getSessionGuard() => $this->auth()->getDefaultDriver(),
0 ignored issues
show
Bug introduced by
The method getDefaultDriver does only exist in Illuminate\Auth\AuthManager, but not in Arcanedev\LaravelImpersonator\Guard\SessionGuard.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
334
        ]);
335 32
    }
336
}
337