Completed
Push — master ( ca3d38...2ed863 )
by ARCANEDEV
13s queued 10s
created

Impersonator   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 272
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 98.57%

Importance

Changes 0
Metric Value
dl 0
loc 272
ccs 69
cts 70
cp 0.9857
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 checkImpersonation() 0 7 1
A start() 0 17 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 mustBeEnabled() 0 7 2
A mustBeDifferentImpersonatable() 0 7 2
A checkImpersonater() 0 7 2
A checkImpersonated() 0 7 2
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 88
    public function __construct(Application $app)
33
    {
34 88
        $this->app = $app;
35 88
    }
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 36
    protected function auth()
48
    {
49 36
        return $this->app['auth'];
50
    }
51
52
    /**
53
     * Get the session store instance.
54
     *
55
     * @return \Illuminate\Contracts\Session\Session
56
     */
57 44
    protected function session()
58
    {
59 44
        return $this->app['session'];
60
    }
61
62
    /**
63
     * Get the config repository.
64
     *
65
     * @return \Illuminate\Contracts\Config\Repository
66
     */
67 68
    protected function config()
68
    {
69 68
        return $this->app['config'];
70
    }
71
72
    /**
73
     * Get the event dispatcher.
74
     *
75
     * @return \Illuminate\Contracts\Events\Dispatcher
76
     */
77 32
    protected function events()
78
    {
79 32
        return $this->app['events'];
80
    }
81
82
    /**
83
     * Get the session key.
84
     *
85
     * @return string
86
     */
87 48
    public function getSessionKey()
88
    {
89 48
        return $this->config()->get('impersonator.session.key', 'impersonator_id');
90
    }
91
92
    /**
93
     * Get the impersonator id.
94
     *
95
     * @return  int|null
96
     */
97 36
    public function getImpersonatorId()
98
    {
99 36
        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 48
    public function start(Impersonatable $impersonater, Impersonatable $impersonated)
116
    {
117 48
        $this->checkImpersonation($impersonater, $impersonated);
118
119
        try {
120 32
            session()->put($this->getSessionKey(), $impersonater->getAuthIdentifier());
121 32
            $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...
122 32
            $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...
123
124 32
            $this->events()->dispatch(
125 32
                new Events\ImpersonationStarted($impersonater, $impersonated)
126
            );
127
128 32
            return true;
129
        }
130
        catch (\Exception $e) { return false; }
131
    }
132
133
    /**
134
     * Stop the impersonation.
135
     *
136
     * @return bool
137
     */
138 28
    public function stop()
139
    {
140
        try {
141 28
            $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...
142 28
            $impersonater = $this->findUserById($this->getImpersonatorId());
143
144 24
            $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...
145 24
            $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...
146 24
            $this->clear();
147
148 24
            $this->events()->dispatch(
149 24
                new Events\ImpersonationStopped($impersonater, $impersonated)
150
            );
151
152 24
            return true;
153
        }
154 4
        catch (\Exception $e) {
155 4
            return false;
156
        }
157
    }
158
159
    /**
160
     * Clear the impersonation.
161
     */
162 28
    public function clear()
163
    {
164 28
        $this->session()->forget($this->getSessionKey());
165 28
    }
166
167
    /**
168
     * Find a user by the given id.
169
     *
170
     * @param  int|string  $id
171
     *
172
     * @return \Arcanedev\LaravelImpersonator\Contracts\Impersonatable
173
     *
174
     * @throws \Exception
175
     */
176 52
    public function findUserById($id)
177
    {
178 52
        return call_user_func([$this->config()->get('auth.providers.users.model'), 'findOrFail'], $id);
179
    }
180
181
    /* -----------------------------------------------------------------
182
     |  Check Functions
183
     | -----------------------------------------------------------------
184
     */
185
186
    /**
187
     * Check if it's impersonating.
188
     *
189
     * @return bool
190
     */
191 36
    public function isImpersonating()
192
    {
193 36
        return $this->session()->has($this->getSessionKey());
194
    }
195
196
    /**
197
     * Check if the impersonations is enabled.
198
     *
199
     * @return bool
200
     */
201 48
    public function isEnabled()
202
    {
203 48
        return $this->config()->get('impersonator.enabled', false);
204
    }
205
206
    /* -----------------------------------------------------------------
207
     |  Other Methods
208
     | -----------------------------------------------------------------
209
     */
210
211
    /**
212
     * Check the impersonation.
213
     *
214
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonater
215
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonated
216
     */
217 48
    private function checkImpersonation(Impersonatable $impersonater, Impersonatable $impersonated)
218
    {
219 48
        $this->mustBeEnabled();
220 44
        $this->mustBeDifferentImpersonatable($impersonater, $impersonated);
221 40
        $this->checkImpersonater($impersonater);
222 36
        $this->checkImpersonated($impersonated);
223 32
    }
224
225
    /**
226
     * Check if the impersonation is enabled.
227
     *
228
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
229
     */
230 48
    private function mustBeEnabled()
231
    {
232 48
        if ( ! $this->isEnabled())
233 4
            throw new Exceptions\ImpersonationException(
234 4
                'The impersonation is disabled.'
235
            );
236 44
    }
237
238
    /**
239
     * Check the impersonater and the impersonated are different.
240
     *
241
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonater
242
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonated
243
     *
244
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
245
     */
246 44
    private function mustBeDifferentImpersonatable(Impersonatable $impersonater, Impersonatable $impersonated)
247
    {
248 44
        if ($impersonater->getAuthIdentifier() == $impersonated->getAuthIdentifier())
249 4
            throw new Exceptions\ImpersonationException(
250 4
                'The impersonater & impersonated with must be different.'
251
            );
252 40
    }
253
254
    /**
255
     * Check the impersonater.
256
     *
257
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonater
258
     *
259
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
260
     */
261 40
    private function checkImpersonater(Impersonatable $impersonater)
262
    {
263 40
        if ( ! $impersonater->canImpersonate())
264 4
            throw new Exceptions\ImpersonationException(
265 4
                "The impersonater with `{$impersonater->getAuthIdentifierName()}`=[{$impersonater->getAuthIdentifier()}] doesn't have the ability to impersonate."
266
            );
267 36
    }
268
269
    /**
270
     * Check the impersonated.
271
     *
272
     * @param  \Arcanedev\LaravelImpersonator\Contracts\Impersonatable  $impersonated
273
     *
274
     * @throws \Arcanedev\LaravelImpersonator\Exceptions\ImpersonationException
275
     */
276 36
    private function checkImpersonated(Impersonatable $impersonated)
277
    {
278 36
        if ( ! $impersonated->canBeImpersonated())
279 4
            throw new Exceptions\ImpersonationException(
280 4
                "The impersonated with `{$impersonated->getAuthIdentifierName()}`=[{$impersonated->getAuthIdentifier()}] cannot be impersonated."
281
            );
282 32
    }
283
}
284