Completed
Push — master ( 3c4a1c...eb23e0 )
by ARCANEDEV
12s queued 10s
created

Impersonator   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 269
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 97.06%

Importance

Changes 0
Metric Value
dl 0
loc 269
ccs 66
cts 68
cp 0.9706
rs 10
c 0
b 0
f 0
wmc 24
lcom 1
cbo 7

18 Methods

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