AuthController::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 8
dl 0
loc 21
rs 9.9332
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace Jidaikobo\Kontiki\Controllers;
4
5
use Psr\Http\Message\ResponseInterface as Response;
6
use Psr\Http\Message\ServerRequestInterface as Request;
7
use Slim\App;
8
use Slim\Views\PhpRenderer;
9
use Jidaikobo\Kontiki\Core\Auth;
10
use Jidaikobo\Kontiki\Managers\CsrfManager;
11
use Jidaikobo\Kontiki\Managers\FlashManager;
12
use Jidaikobo\Kontiki\Models\UserModel;
13
use Jidaikobo\Kontiki\Services\FormService;
14
use Jidaikobo\Kontiki\Services\RateLimitService;
15
use Jidaikobo\Kontiki\Services\RoutesService;
16
17
class AuthController extends BaseController
18
{
19
    private Auth $auth;
20
    private FormService $formService;
21
    private RateLimitService $rateLimitService;
22
    private UserModel $model;
23
24
    public function __construct(
25
        CsrfManager $csrfManager,
26
        FlashManager $flashManager,
27
        PhpRenderer $view,
28
        RoutesService $routesService,
29
        Auth $auth,
30
        FormService $formService,
31
        RateLimitService $rateLimitService,
32
        UserModel $model
33
    ) {
34
        parent::__construct(
35
            $csrfManager,
36
            $flashManager,
37
            $view,
38
            $routesService
39
        );
40
        $this->auth = $auth;
41
        $this->formService = $formService;
42
        $this->formService->setModel($model);
43
        $this->rateLimitService = $rateLimitService;
44
        $this->model = $model;
45
    }
46
47
    public static function registerRoutes(App $app, string $basePath = ''): void
48
    {
49
        $app->get('/login', AuthController::class . ':showLoginForm')->setName('login');
50
        $app->post('/login', AuthController::class . ':processLogin');
51
        $app->get('/logout', AuthController::class . ':logout');
52
    }
53
54
    public function showLoginForm(Request $request, Response $response): Response
55
    {
56
        $ip = $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN';
57
        if ($this->rateLimitService->isIpBlocked($ip)) {
58
            http_response_code(403);
59
            die("Access denied due to too many failed login attempts.");
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return Psr\Http\Message\ResponseInterface. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
60
        }
61
62
        if ($this->auth->isLoggedIn()) {
63
            return $this->redirectResponse($request, $response, 'dashboard');
64
        }
65
66
        $redirectUrl = $request->getQueryParams()['redirect'] ?? '';
67
        $data = $this->flashManager->getData(
68
            'data',
69
            ['username' => '', 'redirectUrl' => $redirectUrl]
70
        );
71
72
        $content = $this->view->fetch('auth/login.php', $data);
73
        $content = $this->formService->addMessages(
74
            $content,
75
            $this->flashManager->getData('errors', [])
76
        );
77
78
        return $this->renderResponse(
79
            $response,
80
            __('login', 'Login'),
81
            $content,
82
            'layout-simple.php'
83
        );
84
    }
85
86
    public function processLogin(Request $request, Response $response): Response
87
    {
88
        $data = $request->getParsedBody() ?? [];
89
        $username = $data['username'] ?? '';
90
        $password = $data['password'] ?? '';
91
        $redirectRaw = $data['redirectUrl'] ?? '';
92
        $redirectUrl = trim($redirectRaw) !== '' ? $redirectRaw : 'dashboard';
93
        $ip = $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN';
94
95
        // Login successful
96
        if ($this->auth->login($username, $password)) {
97
            $this->rateLimitService->resetRateLimit($ip);
98
            $this->rateLimitService->cleanOldRateLimitData();
99
            return $this->redirectResponse($request, $response, $redirectUrl);
100
        }
101
102
        // Login Failed
103
        $this->rateLimitService->recordFailedLogin($ip);
104
        $this->flashManager->addErrors([
105
            ['messages' => [__('wrong_username_or_password', 'Incorrect username or password')]],
106
        ]);
107
        $this->flashManager->setData(
108
            'data',
109
            ['username' => $username, 'redirectUrl' => $redirectUrl]
110
        ); // not keep password
111
        return $this->redirectResponse($request, $response, 'login');
112
    }
113
114
    public function logout(Request $request, Response $response): Response
115
    {
116
        $this->auth->logout();
117
        return $this->redirectResponse($request, $response, 'login');
118
    }
119
}
120