Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.14% covered (success)
90.14%
64 / 71
60.00% covered (warning)
60.00%
3 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
Application
90.14% covered (success)
90.14%
64 / 71
60.00% covered (warning)
60.00%
3 / 5
8.06
0.00% covered (danger)
0.00%
0 / 1
 bootstrap
55.56% covered (warning)
55.56%
5 / 9
0.00% covered (danger)
0.00%
0 / 1
2.35
 middleware
91.89% covered (success)
91.89%
34 / 37
0.00% covered (danger)
0.00%
0 / 1
3.00
 services
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 bootstrapCli
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAuthenticationService
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2declare(strict_types=1);
3
4/**
5 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
6 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
7 *
8 * Licensed under The MIT License
9 * For full copyright and license information, please see the LICENSE.txt
10 * Redistributions of files must retain the above copyright notice.
11 *
12 * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
13 * @link      https://cakephp.org CakePHP(tm) Project
14 * @since     3.3.0
15 * @license   https://opensource.org/licenses/mit-license.php MIT License
16 */
17namespace App;
18
19use ADmad\I18n\Middleware\I18nMiddleware;
20use App\Middleware\IpBlockerMiddleware;
21use App\Middleware\RateLimitMiddleware;
22use App\Utility\I18nManager;
23use Authentication\AuthenticationService;
24use Authentication\AuthenticationServiceInterface;
25use Authentication\AuthenticationServiceProviderInterface;
26use Authentication\Middleware\AuthenticationMiddleware;
27use Cake\Core\Configure;
28use Cake\Core\ContainerInterface;
29use Cake\Datasource\FactoryLocator;
30use Cake\Error\Middleware\ErrorHandlerMiddleware;
31use Cake\Http\BaseApplication;
32use Cake\Http\Middleware\BodyParserMiddleware;
33use Cake\Http\Middleware\CsrfProtectionMiddleware;
34use Cake\Http\MiddlewareQueue;
35use Cake\ORM\Locator\TableLocator;
36use Cake\Routing\Middleware\AssetMiddleware;
37use Cake\Routing\Middleware\RoutingMiddleware;
38use Cake\Routing\Router;
39use Psr\Http\Message\ServerRequestInterface;
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 * @extends \Cake\Http\BaseApplication<\App\Application>
48 */
49class Application extends BaseApplication implements AuthenticationServiceProviderInterface
50{
51    /**
52     * Load all the application configuration and bootstrap logic.
53     *
54     * @return void
55     */
56    public function bootstrap(): void
57    {
58        // Call parent to load bootstrap from files.
59        parent::bootstrap();
60        require CONFIG . 'log_config.php';
61
62        // All plugins are now loaded via config/plugins.php
63        // This provides a single source of truth for plugin configuration
64        // and handles environment-specific loading automatically
65
66        if (PHP_SAPI === 'cli') {
67            $this->bootstrapCli();
68        } else {
69            FactoryLocator::add(
70                'Table',
71                (new TableLocator())->allowFallbackClass(false),
72            );
73        }
74
75        I18nManager::setEnabledLanguages();
76
77        // Load more plugins here
78    }
79
80    /**
81     * Setup the middleware queue your application will use.
82     *
83     * @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to setup.
84     * @return \Cake\Http\MiddlewareQueue The updated middleware queue.
85     */
86    public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
87    {
88        $middlewareQueue
89            // Catch any exceptions in the lower layers,
90            // and make an error page/response
91            ->add(new ErrorHandlerMiddleware(Configure::read('Error'), $this));
92
93        $middlewareQueue
94            // Handle plugin/theme assets like CakePHP normally does.
95            ->add(new AssetMiddleware([
96                'cacheTime' => Configure::read('Asset.cacheTime'),
97            ]))
98
99            // Add routing middleware.
100            // If you have a large number of routes connected, turning on routes
101            // caching in production could improve performance.
102            // See https://github.com/CakeDC/cakephp-cached-routing
103            ->add(new RoutingMiddleware($this))
104
105            ->add(new I18nMiddleware([
106                // If `true` will attempt to get matching languges in "languages" list based
107                // on browser locale and redirect to that when going to site root.
108                'detectLanguage' => true,
109                // Default language for app. If language detection is disabled or no
110                // matching language is found redirect to this language
111                'defaultLanguage' => 'en',
112                // Languages available in app. The keys should match the language prefix used
113                // in URLs. Based on the language the locale will be also set.
114                'languages' => [
115                    'en' => ['locale' => 'en_GB'],
116                ],
117            ]))
118
119            // Parse various types of encoded request bodies so that they are
120            // available as array through $request->getData()
121            // https://book.cakephp.org/4/en/controllers/middleware.html#body-parser-middleware
122            ->add(new BodyParserMiddleware())
123
124            // Add authentication middleware
125            ->add(new AuthenticationMiddleware($this))
126
127            // Cross Site Request Forgery (CSRF) Protection Middleware
128            // https://book.cakephp.org/4/en/security/csrf.html#cross-site-request-forgery-csrf-middleware
129            ->add(new CsrfProtectionMiddleware([
130                'httponly' => true,
131            ]));
132
133            // Only add security middleware if not in test environment
134            // or if specifically enabled for testing
135        if (env('CAKE_ENV') !== 'test' || Configure::read('TestSecurity.enabled', false)) {
136            $middlewareQueue
137                ->add(new IpBlockerMiddleware())
138                ->add(new RateLimitMiddleware());
139        }
140
141        return $middlewareQueue;
142    }
143
144    /**
145     * Register application container services.
146     *
147     * @param \Cake\Core\ContainerInterface $container The Container to update.
148     * @return void
149     * @link https://book.cakephp.org/4/en/development/dependency-injection.html#dependency-injection
150     */
151    public function services(ContainerInterface $container): void
152    {
153    }
154
155    /**
156     * Bootstrapping for CLI application.
157     *
158     * That is when running commands.
159     *
160     * @return void
161     */
162    protected function bootstrapCli(): void
163    {
164        // $this->addOptionalPlugin('Bake');
165
166        // $this->addPlugin('Migrations');
167
168        // Load more plugins here
169    }
170
171    /**
172     * Returns an authentication service instance.
173     *
174     * This method configures and returns an instance of the `AuthenticationService` class,
175     * which is responsible for handling authentication in the application.
176     *
177     * The authentication service is configured with the following settings:
178     * - `unauthenticatedRedirect`: The URL to redirect users to if they are not authenticated.
179     * - `queryParam`: The query parameter to use for redirecting after successful authentication.
180     *
181     * The `loadAuthenticator` method is used to add authenticators to the service. The `Session`
182     * authenticator is loaded first, and the `Form` authenticator is loaded next with the specified
183     * fields and login URL.
184     *
185     * The `loadIdentifier` method is used to add identifiers to the service. The `Password` identifier
186     * is loaded with the specified fields and resolver configuration.
187     *
188     * The resolver configuration specifies the user model and finder to be used for authentication.
189     * The `finder` option is set to `auth` to use a custom finder for retrieving user records.
190     *
191     * @param \Psr\Http\Message\ServerRequestInterface $request The request object.
192     * @return \Authentication\AuthenticationServiceInterface The authentication service instance.
193     */
194    public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
195    {
196        $authenticationService = new AuthenticationService([
197            'unauthenticatedRedirect' => Router::url(['prefix' => false, 'controller' => 'Users', 'action' => 'login']),
198            'queryParam' => 'redirect',
199        ]);
200
201        $fields = [
202            'username' => 'email',
203            'password' => 'password',
204        ];
205
206        // Load the authenticators, you want session first
207        $authenticationService->loadAuthenticator('Authentication.Session');
208        // Configure form data check to pick email and password
209        $authenticationService->loadAuthenticator('Authentication.Form', [
210            'fields' => $fields,
211            'loginUrl' => Router::url(['prefix' => false, 'controller' => 'Users', 'action' => 'login']),
212            'identifier' => [
213                'className' => 'Authentication.Password',
214                'fields' => $fields,
215                'resolver' => [
216                    'className' => 'Authentication.Orm',
217                    'userModel' => 'Users',
218                    'finder' => 'auth',
219                ],
220            ],
221        ]);
222
223        return $authenticationService;
224    }
225}