Completed
Push — master ( 498a70...30444a )
by ARCANEDEV
14s queued 11s
created

Impersonator::getImpersonatorGuard()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
c 0
b 0
f 0
cc 2
nc 2
nop 0
ccs 3
cts 3
cp 1
crap 2
rs 10
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
 * @package  Arcanedev\LaravelImpersonator
17
 * @author   ARCANEDEV <[email protected]>
18
 */
19
class Impersonator implements ImpersonatorContract
20
{
21
    /* -----------------------------------------------------------------
22
     |  Properties
23
     | -----------------------------------------------------------------
24
     */
25
26
    /** @var  \Illuminate\Contracts\Foundation\Application */
27
    protected $app;
28
29
    /* -----------------------------------------------------------------
30
     |  Constructor
31
     | -----------------------------------------------------------------
32
     */
33
34
    /**
35
     * Impersonator constructor.
36
     *
37
     * @param  \Illuminate\Contracts\Foundation\Application  $app
38
     */
39 126
    public function __construct(Application $app)
40
    {
41 126
        $this->app = $app;
42 126
    }
43
44
    /* -----------------------------------------------------------------
45
     |  Getters & Setters
46
     | -----------------------------------------------------------------
47
     */
48
49
    /**
50
     * Get the guard session instance.
51
     *
52
     * @return \Illuminate\Auth\AuthManager|\Arcanedev\LaravelImpersonator\Guard\SessionGuard
53
     */
54 54
    protected function auth()
55
    {
56 54
        return $this->app['auth'];
57
    }
58
59
    /**
60
     * Get the session store instance.
61
     *
62
     * @return \Illuminate\Contracts\Session\Session
63
     */
64 72
    protected function session()
65
    {
66 72
        return $this->app['session'];
67
    }
68
69
    /**
70
     * Get the config repository.
71
     *
72
     * @return \Illuminate\Contracts\Config\Repository
73
     */
74 96
    protected function config()
75
    {
76 96
        return $this->app['config'];
77
    }
78
79
    /**
80
     * Get the event dispatcher.
81
     *
82
     * @return \Illuminate\Contracts\Events\Dispatcher
83
     */
84 48
    protected function events()
85
    {
86 48
        return $this->app['events'];
87
    }
88
89
    /**
90
     * Get the session key.
91
     *
92
     * @return string
93
     */
94 72
    public function getSessionKey(): string
95
    {
96 72
        return $this->config()->get('impersonator.session.key', 'impersonator_id');
97
    }
98
99
    /**
100
     * Get the session guard.
101
     *
102
     * @return string
103
     */
104 72
    public function getSessionGuard(): string
105
    {
106 72
        return $this->config()->get('impersonator.session.guard', 'impersonator_guard');
107
    }
108
109
    /**
110
     * Get the impersonator id.
111
     *
112
     * @return int|null
113
     */
114 54
    public function getImpersonatorId(): ?int
115
    {
116 54
        return $this->session()->get($this->getSessionKey(), null);
117
    }
118
119
    /**
120
     * Get the impersonator guard.
121
     *
122
     * @return string|null
123
     */
124 48
    public function getImpersonatorGuard(): ?string
125
    {
126 48
        return $this->session()->get($this->getSessionGuard(), null)
127 48
            ?: $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...
128
    }
129
130
    /* -----------------------------------------------------------------
131
     |  Main Methods
132
     | -----------------------------------------------------------------
133
     */
134
135
    /**
136
     * Start the impersonation.
137
     *
138
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonator
139
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonated
140
     * @param  string|null                                                    $guard
141
     *
142
     * @return bool
143
     */
144 72
    public function start(Impersonatable $impersonator, Impersonatable $impersonated, $guard = null): bool
145
    {
146 72
        $this->checkImpersonation($impersonator, $impersonated);
147
148
        try {
149 48
            $this->rememberImpersonater($impersonator);
150
151 48
            $auth = $this->auth();
152 48
            $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...
153 48
            $auth->guard($guard)->silentLogin($impersonated);
154
155 48
            $this->events()->dispatch(
156 48
                new Events\ImpersonationStarted($impersonator, $impersonated)
157
            );
158
159 48
            return true;
160
        }
161
        catch (Exception $e) {
162
            return false;
163
        }
164
    }
165
166
    /**
167
     * Stop the impersonation.
168
     *
169
     * @return bool
170
     */
171 42
    public function stop(): bool
172
    {
173
        try {
174 42
            $auth = $this->auth();
175
176 42
            $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...
177 42
            $impersonator = $this->getImpersonatorFromSession();
178
179 36
            $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...
180 36
            $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...
181 36
            $this->clear();
182
183 36
            $this->events()->dispatch(
184 36
                new Events\ImpersonationStopped($impersonator, $impersonated)
185
            );
186
187 36
            return true;
188
        }
189 6
        catch (Exception $e) {
190 6
            return false;
191
        }
192
    }
193
194
    /**
195
     * Clear the impersonation.
196
     */
197 42
    public function clear(): void
198
    {
199 42
        $this->session()->forget([
200 42
            $this->getSessionKey(),
201 42
            $this->getSessionGuard(),
202
        ]);
203 42
    }
204
205
    /**
206
     * Get the impersonator from session.
207
     *
208
     * @return \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed|null
209
     *
210
     * @throws \Exception
211
     */
212 42
    protected function getImpersonatorFromSession()
213
    {
214 42
        $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...
215 42
            ->guard($this->getImpersonatorGuard())
216 42
            ->getProvider()
217 42
            ->retrieveById($this->getImpersonatorId());
218
219 42
        abort_if(is_null($user), 404, 'User not found');
220
221 36
        return $user;
222
    }
223
224
    /* -----------------------------------------------------------------
225
     |  Check Methods
226
     | -----------------------------------------------------------------
227
     */
228
229
    /**
230
     * Check if it's impersonating.
231
     *
232
     * @return bool
233
     */
234 54
    public function isImpersonating(): bool
235
    {
236 54
        return $this->session()->has([
237 54
            $this->getSessionKey(),
238 54
            $this->getSessionGuard(),
239
        ]);
240
    }
241
242
    /**
243
     * Check if the impersonations is enabled.
244
     *
245
     * @return bool
246
     */
247 72
    public function isEnabled(): bool
248
    {
249 72
        return $this->config()->get('impersonator.enabled', false);
250
    }
251
252
    /* -----------------------------------------------------------------
253
     |  Other Methods
254
     | -----------------------------------------------------------------
255
     */
256
257
    /**
258
     * Check the impersonation.
259
     *
260
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonator
261
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonated
262
     */
263 72
    private function checkImpersonation(Impersonatable $impersonator, Impersonatable $impersonated): void
264
    {
265 72
        $this->mustBeEnabled();
266 66
        $this->mustBeDifferentImpersonatable($impersonator, $impersonated);
267 60
        $this->checkImpersonater($impersonator);
268 54
        $this->checkImpersonated($impersonated);
269 48
    }
270
271
    /**
272
     * Check if the impersonation is enabled.
273
     *
274
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
275
     */
276 72
    private function mustBeEnabled(): void
277
    {
278 72
        if ( ! $this->isEnabled())
279 6
            throw new ImpersonationException(
280 6
                'The impersonation is disabled.'
281
            );
282 66
    }
283
284
    /**
285
     * Check the impersonator and the impersonated are different.
286
     *
287
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonator
288
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonated
289
     *
290
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
291
     */
292 66
    private function mustBeDifferentImpersonatable(Impersonatable $impersonator, Impersonatable $impersonated): void
293
    {
294 66
        if ($impersonator->isSamePerson($impersonated)) {
295 6
            throw Exceptions\ImpersonationException::selfImpersonation();
296
        }
297 60
    }
298
299
    /**
300
     * Check the impersonator.
301
     *
302
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonator
303
     *
304
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
305
     */
306 60
    private function checkImpersonater(Impersonatable $impersonator): void
307
    {
308 60
        if ( ! $impersonator->canImpersonate())
309 6
            throw ImpersonationException::cannotImpersonate($impersonator);
310 54
    }
311
312
    /**
313
     * Check the impersonated.
314
     *
315
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable|mixed  $impersonated
316
     *
317
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
318
     */
319 54
    private function checkImpersonated(Impersonatable $impersonated): void
320
    {
321 54
        if ( ! $impersonated->canBeImpersonated())
322 6
            throw ImpersonationException::cannotBeImpersonated($impersonated);
323 48
    }
324
325
    /**
326
     * Remember the impersonator.
327
     *
328
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonator
329
     */
330 48
    private function rememberImpersonater(Impersonatable $impersonator)
331
    {
332 48
        $this->session()->put([
333 48
            $this->getSessionKey()   => $impersonator->getAuthIdentifier(),
334 48
            $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...
335
        ]);
336 48
    }
337
}
338