Completed
Push — master ( 8feb4f...1df8b5 )
by Marceau
01:52 queued 11s
created

src/ImpersonateServiceProvider.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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) {
59
            app('impersonate')->clear();
60
        });
61
        Event::listen(Logout::class, function ($event) {
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 () {
76
                $guard = $this->app['impersonate']->getCurrentAuthGuardName();
77
                return "<?php if (app()['auth']->guard('$guard')->check() && app()['auth']->guard('$guard')->user()->isImpersonated()): ?>";
78
            });
79
80
            $bladeCompiler->directive('endImpersonating', function () {
81
                return '<?php endif; ?>';
82
            });
83
84
            $bladeCompiler->directive('canImpersonate', function () {
85
                $guard = $this->app['impersonate']->getCurrentAuthGuardName();
86
                return "<?php if (app()['auth']->guard('$guard')->check()
87
                    && app()['auth']->guard('$guard')->user()->canImpersonate()): ?>";
88
            });
89
90
            $bladeCompiler->directive('endCanImpersonate', function () {
91
                return '<?php endif; ?>';
92
            });
93
94
            $bladeCompiler->directive('canBeImpersonated', function ($expression) {
95
                $user = trim($expression);
96
                $guard = $this->app['impersonate']->getCurrentAuthGuardName();
97
98
                return "<?php if (app()['auth']->guard('$guard')->check()
99
                    && app()['auth']->guard('$guard')->user()->id != {$user}->id && {$user}->canBeImpersonated()): ?>";
100
            });
101
102
            $bladeCompiler->directive('endCanBeImpersonated', function () {
103
                return '<?php endif; ?>';
104
            });
105
        });
106
    }
107
108
    /**
109
     * Register routes macro.
110
     *
111
     * @param void
112
     * @return  void
113
     */
114
    protected function registerRoutesMacro()
115
    {
116
        $router = $this->app['router'];
117
118
        $router->macro('impersonate', function () use ($router) {
119
            $router->get('/impersonate/take/{id}/{guardName?}',
120
                '\Lab404\Impersonate\Controllers\ImpersonateController@take')->name('impersonate');
121
            $router->get('/impersonate/leave',
122
                '\Lab404\Impersonate\Controllers\ImpersonateController@leave')->name('impersonate.leave');
123
        });
124
    }
125
126
    /**
127
     * @param void
128
     * @return  void
129
     */
130
    protected function registerAuthDriver()
131
    {
132
        /** @var AuthManager $auth */
133
        $auth = $this->app['auth'];
134
135
        $auth->extend('session', function (Application $app, $name, array $config) use ($auth) {
136
            $provider = $auth->createUserProvider($config['provider']);
137
138
            $guard = new SessionGuard($name, $provider, $app['session.store']);
0 ignored issues
show
It seems like $provider defined by $auth->createUserProvider($config['provider']) on line 136 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...
139
140
            if (method_exists($guard, 'setCookieJar')) {
141
                $guard->setCookieJar($app['cookie']);
142
            }
143
144
            if (method_exists($guard, 'setDispatcher')) {
145
                $guard->setDispatcher($app['events']);
146
            }
147
148
            if (method_exists($guard, 'setRequest')) {
149
                $guard->setRequest($app->refresh('request', $guard, 'setRequest'));
150
            }
151
152
            return $guard;
153
        });
154
    }
155
156
    /**
157
     * Register plugin middleware.
158
     *
159
     * @param void
160
     * @return  void
161
     */
162
    public function registerMiddleware()
163
    {
164
        $this->app['router']->aliasMiddleware('impersonate.protect', ProtectFromImpersonation::class);
165
    }
166
167
    /**
168
     * Merge config file.
169
     *
170
     * @param void
171
     * @return  void
172
     */
173
    protected function mergeConfig()
174
    {
175
        $configPath = __DIR__ . '/../config/' . $this->configName . '.php';
176
177
        $this->mergeConfigFrom($configPath, $this->configName);
178
    }
179
180
    /**
181
     * Publish config file.
182
     *
183
     * @param void
184
     * @return  void
185
     */
186
    protected function publishConfig()
187
    {
188
        $configPath = __DIR__ . '/../config/' . $this->configName . '.php';
189
190
        $this->publishes([$configPath => config_path($this->configName . '.php')], 'impersonate');
191
    }
192
}