Passed
Push — master ( 40dfc1...2d1e51 )
by Alxarafe
03:36
created

AuthController::checkLoginAPI()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 11
nc 3
nop 0
dl 0
loc 16
ccs 0
cts 11
cp 0
crap 30
rs 9.6111
c 0
b 0
f 0
1
<?php
2
/**
3
 * Alxarafe. Development of PHP applications in a flash!
4
 * Copyright (C) 2018-2019 Alxarafe <[email protected]>
5
 */
6
7
namespace Alxarafe\Core\Base;
8
9
use Alxarafe\Core\Models\User;
10
use Alxarafe\Core\Providers\FlashMessages;
11
use Alxarafe\Core\Providers\Logger;
12
use Symfony\Component\HttpFoundation\RedirectResponse;
13
use Symfony\Component\HttpFoundation\Response;
14
15
/**
16
 * Class AuthController
17
 *
18
 * @package Alxarafe\Core\Base
19
 */
20
class AuthController extends Controller
21
{
22
    /**
23
     * Minimum cookie time expiration.
24
     */
25
    public const COOKIE_EXPIRATION_MIN = 3600;     // 1 hour
26
27
    /**
28
     * The user logged.
29
     *
30
     * @var User
31
     */
32
    public $user;
33
34
    /**
35
     * User log key.
36
     *
37
     * @var string|null
38
     */
39
40
    public $logkey = null;
41
42
    /**
43
     * Page to redirect.
44
     *
45
     * @var string
46
     */
47
    private $defaultRedirect = 'index.php?call=Login';
48
49
    /**
50
     * @param string $methodName
51
     *
52
     * @return Response
53
     */
54
    public function runMethod(string $methodName): Response
55
    {
56
        $method = $methodName . 'Method';
57
        Logger::getInstance()->getLogger()->addDebug($this->translator->trans('call-to', ['%called%' => $this->shortName . '->' . $method . '()']));
58
        if (!$this->checkAuth()) {
59
            Logger::getInstance()->getLogger()->addDebug($this->translator->trans('user-not-authenticated'));
60
            return $this->redirect(baseUrl($this->defaultRedirect));
61
        }
62
        return $this->{$method}();
63
    }
64
65
    /**
66
     * Check that user is logged in.
67
     */
68
    public function checkAuth(): bool
69
    {
70
        return $this->checkLoginWeb() || $this->checkLoginAPI();
71
    }
72
73
    /**
74
     * Check if user is logged-in from Login.
75
     *
76
     * @return bool
77
     */
78
    private function checkLoginWeb(): bool
79
    {
80
        $return = false;
81
82
        $username = $this->request->cookies->get('user', '');
83
        $logKey = $this->request->cookies->get('logkey', '');
84
        $remember = $this->request->cookies->get('remember', self::COOKIE_EXPIRATION_MIN);
85
        if (!empty($username) && !empty($logKey)) {
86
            $user = new User();
87
            if ($user->verifyLogKey($username, $logKey)) {
88
                Logger::getInstance()->getLogger()->addDebug($this->translator->trans('user-logged-in-from-cookie', ['%username%' => $username]));
89
                $this->user = $user;
90
                $this->username = $this->user->username;
91
                $this->logkey = $this->user->logkey;
92
                // Re-set cookie time to persist cookie time from last use
93
                $time = time() + $remember;
94
                $this->adjustCookieUser($time, $remember);
95
                $return = true;
96
            }
97
        }
98
        return $return;
99
    }
100
101
    /**
102
     * Check if user is logged-in from API.
103
     *
104
     * @return bool
105
     */
106
    private function checkLoginAPI(): bool
107
    {
108
        $return = false;
109
110
        $userAuth = $this->request->headers->get('PHP_AUTH_USER');
111
        $passAuth = $this->request->headers->get('PHP_AUTH_PW');
112
        if (!empty($userAuth) && !empty($passAuth)) {
113
            $user = new User();
114
            if ($user->getBy('username', $userAuth) && password_verify($passAuth, $user->password)) {
115
                Logger::getInstance()->getLogger()->addDebug($this->translator->trans('api-user-logged', ['%username%' => $userAuth]));
116
                $return = true;
117
            } else {
118
                Logger::getInstance()->getLogger()->addDebug($this->translator->trans('api-user-logged-fail', ['%username%' => $userAuth]));
119
            }
120
        }
121
        return $return;
122
    }
123
124
    /**
125
     * Adjust auth cookie user.
126
     *
127
     * @param int $time
128
     * @param int $remember
129
     */
130
    private function adjustCookieUser($time = 0, int $remember = 0): void
131
    {
132
        if ($time === 0) {
133
            $time = time() - 3600;
134
            $remember = null;
135
        }
136
137
        if (!$this->username) {
138
            $this->logkey = $this->user->generateLogKey($this->request->getClientIp() ?? '', false);
139
        }
140
        setcookie('user', $this->username, $time, constant('APP_URI'), $_SERVER['HTTP_HOST']);
141
        setcookie('logkey', $this->logkey, $time, constant('APP_URI'), $_SERVER['HTTP_HOST']);
142
        setcookie('remember', $remember, $time, constant('APP_URI'), $_SERVER['HTTP_HOST']);
143
    }
144
145
    /**
146
     * Close the user session and go to the main page
147
     *
148
     * @return RedirectResponse
149
     */
150
    public function logout(): RedirectResponse
151
    {
152
        FlashMessages::getInstance()::setInfo($this->translator->trans('user-logged-out'));
153
        $this->username = null;
154
        $this->logkey = null;
155
        $this->adjustCookieUser();
156
        return $this->redirect(baseUrl('index.php?call=Login'));
157
    }
158
}
159