Completed
Branch feature/Authentication4 (554da3)
by Schlaefer
03:43
created

Application::getAuthenticationService()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 2
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
7
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
8
 *
9
 * Licensed under The MIT License
10
 * For full copyright and license information, please see the LICENSE.txt
11
 * Redistributions of files must retain the above copyright notice.
12
 *
13
 * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
14
 * @link      https://cakephp.org CakePHP(tm) Project
15
 * @since     3.3.0
16
 * @license   https://opensource.org/licenses/mit-license.php MIT License
17
 */
18
namespace App;
19
20
use App\Auth\AuthenticationServiceFactory;
21
use App\Middleware\SaitoBootstrapMiddleware;
22
use Authentication\AuthenticationService;
23
use Authentication\AuthenticationServiceProviderInterface;
24
use Authentication\Middleware\AuthenticationMiddleware;
25
use Authentication\UrlChecker\DefaultUrlChecker;
26
use Cake\Core\Configure;
27
use Cake\Core\Exception\MissingPluginException;
28
use Cake\Core\Plugin;
29
use Cake\Error\Middleware\ErrorHandlerMiddleware;
30
use Cake\Event\EventManagerInterface;
31
use Cake\Http\BaseApplication;
32
use Cake\Http\Middleware\EncryptedCookieMiddleware;
33
use Cake\Http\Middleware\SecurityHeadersMiddleware;
34
use Cake\Routing\Middleware\AssetMiddleware;
35
use Cake\Routing\Middleware\RoutingMiddleware;
36
use Psr\Http\Message\ResponseInterface;
37
use Psr\Http\Message\ServerRequestInterface;
38
use Saito\App\Registry;
39
use Stopwatch\Lib\Stopwatch;
40
41
/**
42
 * Application setup class.
43
 *
44
 * This defines the bootstrapping logic and middleware layers you
45
 * want to use in your application.
46
 */
47
class Application extends BaseApplication implements AuthenticationServiceProviderInterface
48
{
49
    /**
50
     * {@inheritDoc}
51
     */
52
    public function __construct($configDir, EventManagerInterface $eventManager = null)
53
    {
54
        Stopwatch::init();
55
        Stopwatch::enable();
56
        Stopwatch::start('Application::__construct');
57
        parent::__construct($configDir, $eventManager);
58
        Stopwatch::stop('Application::__construct');
59
    }
60
61
    /**
62
     * {@inheritDoc}
63
     */
64
    public function bootstrap()
65
    {
66
        Stopwatch::start('Application::bootstrap');
67
68
        parent::bootstrap();
69
70
        if (PHP_SAPI === 'cli') {
71
            $this->bootstrapCli();
72
        }
73
        /*
74
         * Only try to load DebugKit in development mode
75
         * Debug Kit should not be installed on a production system
76
         */
77
        if (Configure::read('debug')) {
78
            // $this->addPlugin(\DebugKit\Plugin::class);
79
        }
80
        // Load more plugins here
81
82
        Registry::initialize();
83
84
        $this->addPlugin('Authentication');
85
        $this->addPlugin(\Admin\Plugin::class, ['routes' => true]);
86
        $this->addPlugin(\Api\Plugin::class, ['bootstrap' => true, 'routes' => true]);
87
        $this->addPlugin(\Bookmarks\Plugin::class, ['routes' => true]);
88
        $this->addPlugin(\BbcodeParser\Plugin::class);
89
        $this->addPlugin(\Feeds\Plugin::class, ['routes' => true]);
90
        $this->addPlugin(\Installer\Plugin::class);
91
        $this->addPlugin(\SaitoHelp\Plugin::class, ['routes' => true]);
92
        $this->addPlugin(\SaitoSearch\Plugin::class, ['routes' => true]);
93
        $this->addPlugin(\Sitemap\Plugin::class, ['bootstrap' => true, 'routes' => true]);
94
        $this->addPlugin(\ImageUploader\Plugin::class, ['routes' => true]);
95
96
        $this->addPlugin(\Cron\Plugin::class);
97
        $this->addPlugin(\Commonmark\Plugin::class);
98
        $this->addPlugin(\Detectors\Plugin::class);
99
        $this->addPlugin(\MailObfuscator\Plugin::class);
100
        $this->addPlugin(\SpectrumColorpicker\Plugin::class);
101
        $this->addPlugin(\Stopwatch\Plugin::class);
102
103
        $this->addPlugin('Proffer');
104
105
        $this->loadDefaultThemePlugin();
106
107
        Stopwatch::stop('Application::bootstrap');
108
    }
109
110
    /**
111
     * Setup the middleware queue your application will use.
112
     *
113
     * @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to setup.
114
     * @return \Cake\Http\MiddlewareQueue The updated middleware queue.
115
     */
116
    public function middleware($middlewareQueue)
117
    {
118
        $middlewareQueue
119
            // Catch any exceptions in the lower layers,
120
            // and make an error page/response
121
            ->add(ErrorHandlerMiddleware::class)
122
123
            // Handle plugin/theme assets like CakePHP normally does.
124
            ->add(AssetMiddleware::class)
125
126
            // Add routing middleware.
127
            // Routes collection cache enabled by default, to disable route caching
128
            // pass null as cacheConfig, example: `new RoutingMiddleware($this)`
129
            // you might want to disable this cache in case your routing is extremely simple
130
            ->add(new RoutingMiddleware($this, '_cake_routes_'))
131
132
            ->insertAfter(RoutingMiddleware::class, new SaitoBootstrapMiddleware())
133
134
            ->add(new EncryptedCookieMiddleware(
135
                // Names of cookies to protect
136
                [Configure::read('Security.cookieAuthName')],
137
                Configure::read('Security.cookieSalt')
138
            ))
139
140
            // CakePHP authentication provider
141
            ->insertAfter(
142
                EncryptedCookieMiddleware::class,
143
                new AuthenticationMiddleware($this)
144
            );
145
146
        $security = (new SecurityHeadersMiddleware())
147
            ->setXFrameOptions(strtolower(Configure::read('Saito.X-Frame-Options')));
148
        $middlewareQueue->add($security);
149
150
        return $middlewareQueue;
151
    }
152
153
    /**
154
     * Get authentication service.
155
     *
156
     * Part of AuthenticationServiceProviderInterface.
157
     *
158
     * {@inheritDoc}
159
     */
160
    public function getAuthenticationService(ServerRequestInterface $request, ResponseInterface $response): AuthenticationService
161
    {
162
        $isApi = (new DefaultUrlChecker())
163
            ->check($request, ['#api/v2#'], ['useRegex' => true]);
164
        if ($isApi) {
165
            return AuthenticationServiceFactory::buildJwt();
166
        }
167
168
        return AuthenticationServiceFactory::buildApp();
169
    }
170
171
    /**
172
     * Load the plugin for Saito's default theme
173
     *
174
     * @return void
175
     */
176
    private function loadDefaultThemePlugin()
177
    {
178
        $defaultTheme = Configure::read('Saito.themes.default');
179
        if (empty($defaultTheme)) {
180
            throw new \RuntimeException(
181
                'Could not resolve default theme for plugin loading.',
182
                1556562215
183
            );
184
        }
185
        if (Plugin::isLoaded($defaultTheme) !== true) {
186
            $this->addPlugin($defaultTheme);
187
        }
188
    }
189
190
    /**
191
     * @return void
192
     */
193
    protected function bootstrapCli()
194
    {
195
        try {
196
            $this->addPlugin('Bake');
197
        } catch (MissingPluginException $e) {
198
            // Do not halt if the plugin is missing
199
        }
200
        $this->addPlugin('Migrations');
201
        // Load more plugins here
202
    }
203
}
204