Passed
Push — master ( 8a1c29...aa2240 )
by Fran
06:43
created

Security::init()   A

Complexity

Conditions 5
Paths 16

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 9
nc 16
nop 0
dl 0
loc 13
ccs 10
cts 10
cp 1
crap 5
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
namespace PSFS\base;
4
5
use PSFS\base\config\Config;
6
use PSFS\base\types\helpers\AuthHelper;
7
use PSFS\base\types\helpers\Inspector;
8
use PSFS\base\types\helpers\ResponseHelper;
9
use PSFS\base\types\traits\SecureTrait;
10
use PSFS\base\types\traits\Security\FlashesTrait;
11
use PSFS\base\types\traits\Security\ProfileTrait;
12
use PSFS\base\types\traits\SingletonTrait;
13
use PSFS\base\types\traits\TestTrait;
14
15
/**
16
 * Class Security
17
 * @package PSFS
18
 */
19
class Security
20
{
21
    // sha1('FLASHES')
22
    const FLASH_MESSAGE_TOKEN = '4680c68435db1bfbf17c3fcc4f7b39d2c6122504';
23
    const LOGGED_USER_TOKEN = '__U_T_L__';
24
25
    use SecureTrait;
26
    use SingletonTrait;
27
    use TestTrait;
28
    use ProfileTrait;
29
    use FlashesTrait;
30
31
    /**
32
     * @var bool $authorized
33
     */
34
    private $authorized = false;
35
36
    /**
37
     * @var bool $checked
38
     */
39
    private $checked = false;
40
41
    /**
42
     * Constructor por defecto
43
     */
44 2
    public function init()
45
    {
46 2
        $this->initSession();
47 2
        if (NULL === $this->getSessionKey('__FLASH_CLEAR__')) {
48 2
            $this->clearFlashes();
49 2
            $this->setSessionKey('__FLASH_CLEAR__', microtime(TRUE));
50
        }
51 2
        $this->user = $this->hasSessionKey(AuthHelper::USER_ID_TOKEN) ? unserialize($this->getSessionKey(AuthHelper::USER_ID_TOKEN)) : null;
52 2
        $this->admin = $this->hasSessionKey(AuthHelper::ADMIN_ID_TOKEN) ? unserialize($this->getSessionKey(AuthHelper::ADMIN_ID_TOKEN)) : null;
53 2
        if (null === $this->admin) {
54 2
            $this->checkAdmin();
55
        }
56 2
        $this->setLoaded(true);
57
    }
58
59
    /**
60
     * @return array|null
61
     */
62 5
    public function getAdmins()
63
    {
64 5
        return Cache::getInstance()->getDataFromFile(CONFIG_DIR . DIRECTORY_SEPARATOR . 'admins.json', Cache::JSONGZ, true);
65
    }
66
67
    /**
68
     * @param string $user
69
     * @param string $pass
70
     * @param boolean $force
71
     *
72
     * @return bool
73
     */
74 5
    public function checkAdmin($user = NULL, $pass = NULL, $force = false)
75
    {
76 5
        Logger::log('Checking admin session');
77 5
        if ((!$this->authorized && !$this->checked) || $force) {
78 4
            $admins = $this->getAdmins();
79 4
            $token = null;
80 4
            if (null !== $admins) {
81 2
                if (empty($user)) {
82
                    // First try, traditional basic auth
83 2
                    Inspector::stats('[Auth] Checking Basic Auth');
84 2
                    list($user, $token) = AuthHelper::checkBasicAuth($user, $pass, $admins);
85
                }
86 2
                if (empty($user)) {
87
                    // Second try, cookie auth
88 1
                    Inspector::stats('[Auth] Checking Basic Auth PSFS');
89 1
                    list($user, $token) = AuthHelper::checkComplexAuth($admins);
90
                }
91 2
                if (empty($user) && Config::getParam('enable.jwt', false)) {
92
                    // Third try, jwt auth
93
                    Inspector::stats('[Auth] Checking JWT Auth');
94
                    list($user, $token) = AuthHelper::checkJwtAuth($admins);
95
                }
96 2
                if (!empty($user) && !empty($admins[$user])) {
97 1
                    $auth = $admins[$user]['hash'];
98 1
                    $this->authorized = ($auth === $token);
99 1
                    if ($this->authorized) {
100 1
                        $this->updateAdmin($user, $admins[$user]['profile']);
101 1
                        $encrypted = AuthHelper::encrypt("$user:$pass", AuthHelper::SESSION_TOKEN);
102 1
                        ResponseHelper::setCookieHeaders([
103 1
                            [
104 1
                                'name' => AuthHelper::generateProfileHash(),
105 1
                                'value' => $encrypted,
106 1
                                'http' => true,
107 1
                                'domain' => '',
108 1
                            ]
109 1
                        ]);
110 1
                        $this->setSessionKey(AuthHelper::ADMIN_ID_TOKEN, $encrypted);
111
                    }
112
                } else {
113 2
                    $this->admin = null;
114 2
                    $this->setSessionKey(AuthHelper::ADMIN_ID_TOKEN, null);
115
                }
116 2
                $this->checked = true;
117
            }
118
        }
119
120 5
        return $this->authorized || self::isTest();
121
    }
122
123
    /**
124
     * Método que calcula si se está logado o para acceder a administración
125
     * @return bool
126
     */
127 4
    public function canAccessRestrictedAdmin()
128
    {
129 4
        return (null !== $this->admin && !preg_match('/^\/admin\/login/i', Request::requestUri())) || self::isTest();
0 ignored issues
show
Bug introduced by
It seems like PSFS\base\Request::requestUri() can also be of type null; however, parameter $subject of preg_match() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

129
        return (null !== $this->admin && !preg_match('/^\/admin\/login/i', /** @scrutinizer ignore-type */ Request::requestUri())) || self::isTest();
Loading history...
130
    }
131
132
    /**
133
     * Servicio que devuelve una pantalla de error porque se necesita estar authenticado
134
     *
135
     * @param string|null $route
136
     *
137
     * @return string|null
138
     * @throws exception\GeneratorException
139
     */
140 1
    public function notAuthorized($route)
141
    {
142 1
        return Template::getInstance()->render('notauthorized.html.twig', array(
143 1
            'route' => $route,
144 1
        ));
145
    }
146
147 2
    private function checkAdminRole($role = AuthHelper::USER_ID_TOKEN)
148
    {
149 2
        $users = $this->getAdmins();
150 2
        $logged = $this->getAdmin();
151 2
        if (is_array($logged)
152 2
            && array_key_exists('alias', $logged)
153 2
            && array_key_exists($logged['alias'], $users)) {
154 1
            $security = $users[$logged['alias']]['profile'];
155 1
            return $role === $security;
156
        }
157
158 2
        return false;
159
    }
160
161
    /**
162
     * @return bool
163
     */
164 1
    public function isSuperAdmin()
165
    {
166 1
        $users = $this->getAdmins();
167 1
        $logged = $this->getAdmin();
168 1
        if (is_array($logged)
169 1
            && array_key_exists('alias', $logged)
170 1
            && array_key_exists($logged['alias'], $users)) {
171 1
            $security = $users[$logged['alias']]['profile'];
172 1
            return AuthHelper::ADMIN_ID_TOKEN === $security;
173
        }
174
175 1
        return FALSE;
176
    }
177
178
    /**
179
     * @return bool
180
     */
181 1
    public function isManager()
182
    {
183 1
        return $this->checkAdminRole(AuthHelper::MANAGER_ID_TOKEN);
184
    }
185
186
    /**
187
     * @return bool
188
     */
189 2
    public function isUser()
190
    {
191 2
        return $this->checkAdminRole();
192
    }
193
194
195
}
196