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