Passed
Push — master ( ce2bc1...e68e02 )
by Fran
05:34
created

Security::isUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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

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