ImpersonateServiceProvider::registerMiddleware()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Lab404\Impersonate;
4
5
use Illuminate\Auth\AuthManager;
6
use Illuminate\Auth\Events\Login;
7
use Illuminate\Auth\Events\Logout;
8
use Illuminate\Foundation\Application;
9
use Illuminate\Support\Facades\Event;
10
use Illuminate\View\Compilers\BladeCompiler;
11
use Lab404\Impersonate\Guard\SessionGuard;
12
use Lab404\Impersonate\Middleware\ProtectFromImpersonation;
13
use Lab404\Impersonate\Services\ImpersonateManager;
14
15
/**
16
 * Class ServiceProvider
17
 *
18
 * @package Lab404\Impersonate
19
 */
20
class ImpersonateServiceProvider extends \Illuminate\Support\ServiceProvider
21
{
22
    /** @var string $configName */
23
    protected $configName = 'laravel-impersonate';
24
25
    /**
26
     * Register the service provider.
27
     *
28
     * @return void
29
     */
30
    public function register()
31
    {
32
        $this->mergeConfig();
33
34
        $this->app->bind(ImpersonateManager::class, ImpersonateManager::class);
35
36
        $this->app->singleton(ImpersonateManager::class, function ($app) {
37
            return new ImpersonateManager($app);
38
        });
39
40
        $this->app->alias(ImpersonateManager::class, 'impersonate');
41
42
        $this->registerRoutesMacro();
43
        $this->registerBladeDirectives();
44
        $this->registerMiddleware();
45
        $this->registerAuthDriver();
46
    }
47
48
    /**
49
     * Bootstrap the application events.
50
     *
51
     * @return void
52
     */
53
    public function boot()
54
    {
55
        $this->publishConfig();
56
57
        // We want to remove data from storage on real login and logout
58
        Event::listen(Login::class, function ($event) {
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
59
            app('impersonate')->clear();
60
        });
61
        Event::listen(Logout::class, function ($event) {
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
62
            app('impersonate')->clear();
63
        });
64
    }
65
66
    /**
67
     * Register plugin blade directives.
68
     *
69
     * @param void
70
     * @return  void
71
     */
72
    protected function registerBladeDirectives()
73
    {
74
        $this->app->afterResolving('blade.compiler', function (BladeCompiler $bladeCompiler) {
75
            $bladeCompiler->directive('impersonating', function ($guard = null) {
76
                return "<?php if (is_impersonating({$guard})) : ?>";
77
            });
78
79
            $bladeCompiler->directive('endImpersonating', function () {
80
                return '<?php endif; ?>';
81
            });
82
83
            $bladeCompiler->directive('canImpersonate', function ($guard = null) {
84
                return "<?php if (can_impersonate({$guard})) : ?>";
85
            });
86
87
            $bladeCompiler->directive('endCanImpersonate', function () {
88
                return '<?php endif; ?>';
89
            });
90
91
            $bladeCompiler->directive('canBeImpersonated', function ($expression) {
92
                $args = preg_split("/,(\s+)?/", $expression);
93
                $guard = $args[1] ?? null;
94
95
                return "<?php if (can_be_impersonated({$args[0]}, {$guard})) : ?>";
96
            });
97
98
            $bladeCompiler->directive('endCanBeImpersonated', function () {
99
                return '<?php endif; ?>';
100
            });
101
        });
102
    }
103
104
    /**
105
     * Register routes macro.
106
     *
107
     * @param void
108
     * @return  void
109
     */
110
    protected function registerRoutesMacro()
111
    {
112
        $router = $this->app['router'];
113
114
        $router->macro('impersonate', function () use ($router) {
115
            $router->get('/impersonate/take/{id}/{guardName?}',
116
                '\Lab404\Impersonate\Controllers\ImpersonateController@take')->name('impersonate');
117
            $router->get('/impersonate/leave',
118
                '\Lab404\Impersonate\Controllers\ImpersonateController@leave')->name('impersonate.leave');
119
        });
120
    }
121
122
    /**
123
     * @param void
124
     * @return  void
125
     */
126
    protected function registerAuthDriver()
127
    {
128
        /** @var AuthManager $auth */
129
        $auth = $this->app['auth'];
130
131
        $auth->extend('session', function (Application $app, $name, array $config) use ($auth) {
132
            $provider = $auth->createUserProvider($config['provider']);
133
134
            $guard = new SessionGuard($name, $provider, $app['session.store']);
0 ignored issues
show
Bug introduced by
It seems like $provider defined by $auth->createUserProvider($config['provider']) on line 132 can be null; however, Illuminate\Auth\SessionGuard::__construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
135
136
            if (method_exists($guard, 'setCookieJar')) {
137
                $guard->setCookieJar($app['cookie']);
138
            }
139
140
            if (method_exists($guard, 'setDispatcher')) {
141
                $guard->setDispatcher($app['events']);
142
            }
143
144
            if (method_exists($guard, 'setRequest')) {
145
                $guard->setRequest($app->refresh('request', $guard, 'setRequest'));
146
            }
147
148
            return $guard;
149
        });
150
    }
151
152
    /**
153
     * Register plugin middleware.
154
     *
155
     * @param void
156
     * @return  void
157
     */
158
    public function registerMiddleware()
159
    {
160
        $this->app['router']->aliasMiddleware('impersonate.protect', ProtectFromImpersonation::class);
161
    }
162
163
    /**
164
     * Merge config file.
165
     *
166
     * @param void
167
     * @return  void
168
     */
169
    protected function mergeConfig()
170
    {
171
        $configPath = __DIR__ . '/../config/' . $this->configName . '.php';
172
173
        $this->mergeConfigFrom($configPath, $this->configName);
174
    }
175
176
    /**
177
     * Publish config file.
178
     *
179
     * @param void
180
     * @return  void
181
     */
182
    protected function publishConfig()
183
    {
184
        $configPath = __DIR__ . '/../config/' . $this->configName . '.php';
185
186
        $this->publishes([$configPath => config_path($this->configName . '.php')], 'impersonate');
187
    }
188
}
189