Passed
Push — master ( 147718...79af4d )
by Fran
02:42
created

Security::getAdmins()   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\ResponseHelper;
6
use PSFS\base\types\traits\SecureTrait;
7
use PSFS\base\types\traits\Security\FlashesTrait;
8
use PSFS\base\types\traits\Security\ProfileTrait;
9
use PSFS\base\types\traits\SingletonTrait;
10
use PSFS\base\types\traits\TestTrait;
11
12
/**
13
 * Class Security
14
 * @package PSFS
15
 */
16
class Security
17
{
18
    // sha1('user')
19
    const USER_ID_TOKEN = '12dea96fec20593566ab75692c9949596833adc9';
20
    // sha1('admin')
21
    const MANAGER_ID_TOKEN = 'd033e22ae348aeb5660fc2140aec35850c4da997';
22
    // sha1('superadmin')
23
    const ADMIN_ID_TOKEN = '889a3a791b3875cfae413574b53da4bb8a90d53e';
24
    // sha1('FLASHES')
25
    const FLASH_MESSAGE_TOKEN = '4680c68435db1bfbf17c3fcc4f7b39d2c6122504';
26
    const LOGGED_USER_TOKEN = '__U_T_L__';
27
28
    use SecureTrait;
29
    use SingletonTrait;
30
    use TestTrait;
31
    use ProfileTrait;
32
    use FlashesTrait;
33
34
    /**
35
     * @var bool $authorized
36
     */
37
    private $authorized = FALSE;
38
39
    /**
40
     * @var bool $checked
41
     */
42
    private $checked = false;
43
44
    /**
45
     * Constructor por defecto
46
     */
47 2
    public function init()
48
    {
49 2
        $this->initSession();
50 2
        if (NULL === $this->getSessionKey('__FLASH_CLEAR__')) {
51 2
            $this->clearFlashes();
52 2
            $this->setSessionKey('__FLASH_CLEAR__', microtime(TRUE));
53
        }
54 2
        $this->user = $this->hasSessionKey(self::USER_ID_TOKEN) ? unserialize($this->getSessionKey(self::USER_ID_TOKEN)) : null;
55 2
        $this->admin = $this->hasSessionKey(self::ADMIN_ID_TOKEN) ? unserialize($this->getSessionKey(self::ADMIN_ID_TOKEN)) : null;
56 2
        if (null === $this->admin) {
57 2
            $this->checkAdmin();
58
        }
59 2
        $this->setLoaded(true);
60 2
    }
61
62
    /**
63
     * @return array|null
64
     */
65 4
    public function getAdmins()
66
    {
67 4
        return Cache::getInstance()->getDataFromFile(CONFIG_DIR . DIRECTORY_SEPARATOR . 'admins.json', Cache::JSONGZ, true);
68
    }
69
70
    /**
71
     * @param string $user
72
     * @param string $pass
73
     * @param boolean $force
74
     *
75
     * @return bool
76
     */
77 3
    public function checkAdmin($user = NULL, $pass = NULL, $force = false)
78
    {
79 3
        Logger::log('Checking admin session');
80 3
        if ((!$this->authorized && !$this->checked) || $force) {
81 3
            $admins = $this->getAdmins();
82 3
            if (null !== $admins) {
83 1
                $request = Request::getInstance();
84
                //Sacamos las credenciales de la petición
85 1
                $user = $user ?: $request->getServer('PHP_AUTH_USER');
86 1
                $pass = $pass ?: $request->getServer('PHP_AUTH_PW');
87 1
                if (NULL === $user || (array_key_exists($user, $admins) && empty($admins[$user]))) {
88 1
                    list($user, $pass) = $this->getAdminFromCookie();
89
                }
90 1
                if (!empty($user) && !empty($admins[$user])) {
91 1
                    $auth = $admins[$user]['hash'];
92 1
                    $this->authorized = ($auth === sha1($user . $pass));
93 1
                    if ($this->authorized) {
94 1
                        $this->updateAdmin($user, $admins[$user]['profile']);
95 1
                        ResponseHelper::setCookieHeaders([
96
                            [
97 1
                                'name' => $this->getHash(),
98 1
                                'value' => base64_encode("$user:$pass"),
99
                                'http' => true,
100 1
                                'domain' => '',
101
                            ]
102
                        ]);
103 1
                        $this->setSessionKey(self::LOGGED_USER_TOKEN, base64_encode("{$user}:{$pass}"));
104
                    }
105
                } else {
106 1
                    $this->admin = null;
107 1
                    $this->setSessionKey(self::ADMIN_ID_TOKEN, null);
108
                }
109 1
                $this->checked = true;
110
            }
111
        }
112
113 3
        return $this->authorized || self::isTest();
114
    }
115
116
    /**
117
     * Método que calcula si se está logado o para acceder a administración
118
     * @return bool
119
     */
120 4
    public function canAccessRestrictedAdmin()
121
    {
122 4
        return (null !== $this->admin && !preg_match('/^\/admin\/login/i', Request::requestUri())) || self::isTest();
123
    }
124
125
    /**
126
     * Servicio que devuelve una pantalla de error porque se necesita estar authenticado
127
     *
128
     * @param string|null $route
129
     *
130
     * @return string|null
131
     * @throws exception\GeneratorException
132
     */
133
    public function notAuthorized($route)
134
    {
135
        return Template::getInstance()->render('notauthorized.html.twig', array(
136
            'route' => $route,
137
        ));
138
    }
139
140
    /**
141
     * @return bool
142
     */
143 1
    public function isSuperAdmin()
144
    {
145 1
        $users = $this->getAdmins();
146 1
        $logged = $this->getAdmin();
147 1
        if (is_array($logged)
148 1
            && array_key_exists('alias', $logged)
149 1
            && array_key_exists($logged['alias'], $users)) {
0 ignored issues
show
Bug introduced by
It seems like $users can also be of type null; however, parameter $search of array_key_exists() does only seem to accept array, 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

149
            && array_key_exists($logged['alias'], /** @scrutinizer ignore-type */ $users)) {
Loading history...
150 1
            $security = $users[$logged['alias']]['profile'];
151 1
            return self::ADMIN_ID_TOKEN === $security;
152
        }
153
154
        return FALSE;
155
    }
156
157
}
158