AuthController   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
eloc 49
c 3
b 0
f 1
dl 0
loc 90
rs 10
wmc 8

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 21 1
A logout() 0 4 1
A showLoginForm() 0 25 3
A registerRoutes() 0 5 1
A processLogin() 0 19 2
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
        $data = $this->flashManager->getData('data', ['username' => '']);
67
68
        $content = $this->view->fetch('auth/login.php', $data);
69
        $content = $this->formService->addMessages(
70
            $content,
71
            $this->flashManager->getData('errors', [])
72
        );
73
74
        return $this->renderResponse(
75
            $response,
76
            __('login', 'Login'),
77
            $content,
78
            'layout-simple.php'
79
        );
80
    }
81
82
    public function processLogin(Request $request, Response $response): Response
83
    {
84
        $data = $request->getParsedBody() ?? [];
85
        $username = $data['username'] ?? '';
86
        $password = $data['password'] ?? '';
87
        $ip = $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN';
88
89
        if ($this->auth->login($username, $password)) {
90
            $this->rateLimitService->resetRateLimit($ip);
91
            $this->rateLimitService->cleanOldRateLimitData();
92
            return $this->redirectResponse($request, $response, 'dashboard');
93
        }
94
95
        $this->rateLimitService->recordFailedLogin($ip);
96
        $this->flashManager->addErrors([
97
            ['messages' => [__('wrong_username_or_password', 'Incorrect username or password')]],
98
        ]);
99
        $this->flashManager->setData('data', ['username' => $username]); // not keep password
100
        return $this->redirectResponse($request, $response, 'login');
101
    }
102
103
    public function logout(Request $request, Response $response): Response
104
    {
105
        $this->auth->logout();
106
        return $this->redirectResponse($request, $response, 'login');
107
    }
108
}
109