Test Failed
Push — master ( 80cfda...6865f4 )
by Vítězslav
03:49
created

User::validatePassword()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 4
eloc 13
c 1
b 0
f 1
nc 4
nop 1
dl 0
loc 19
ccs 0
cts 10
cp 0
crap 20
rs 9.8333
1
<?php
2
/**
3
 * Objekty uživatelů.
4
 *
5
 * PHP Version 7
6
 *
7
 * @author    Vítězslav Dvořák <[email protected]>
8
 * @copyright 2009-2019 [email protected] (G)
9
 */
10
11
namespace Ease;
12
13
/**
14
 * Třída uživatele.
15
 *
16
 * @author  Vítězslav Dvořák <[email protected]>
17
 */
18
class User extends Anonym
19
{
20
    /**
21
     * @var Locale Singleton is stored here
22
     */
23
    public static $instance;
24
25
    /**
26
     * ID prave nacteneho uzivatele.
27
     *
28
     * @var int unsigned
29
     */
30
    public $userID = null;
31
32
    /**
33
     * Přihlašovací jméno uživatele.
34
     *
35
     * @var string
36
     */
37
    public $userLogin = null;
38
39
    /**
40
     * Pole uživatelských nastavení.
41
     *
42
     * @var array
43
     */
44
    public $settings = [];
45
46
    /**
47
     * Sloupeček s loginem.
48
     *
49
     * @var string
50
     */
51
    public $loginColumn = 'login';
52
53
    /**
54
     * Sloupeček s heslem.
55
     *
56
     * @var string
57
     */
58
    public $passwordColumn = 'password';
59
60
    /**
61
     * Sloupecek pro docasne zablokovani uctu.
62
     *
63
     * @var string
64
     */
65
    public $disableColumn = null;
66
67
    /**
68
     * Column for user mail.
69
     *
70
     * @var string
71
     */
72
    public $mailColumn = 'email';
73
74
    /**
75
     * Sloupeček obsahující serializované rozšířené informace.
76
     *
77
     * @var string
78
     */
79
    public $settingsColumn = null;
80
81
    /**
82
     * Objekt uživatele aplikace.
83
     *
84
     * @param int|string $userID ID nebo Login uživatele jenž se má načíst při
85
     *                           inicializaci třídy
86
     */
87
    public function __construct($userID = null)
0 ignored issues
show
Unused Code introduced by
The parameter $userID is not used and could be removed. ( Ignorable by Annotation )

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

87
    public function __construct(/** @scrutinizer ignore-unused */ $userID = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
88
    {
89
        $this->setObjectName();
90
    }
91
92
    /**
93
     * Give you user name.
94
     *
95
     * @return string
96
     */
97
    public function getUserName()
98
    {
99
        return $this->getDataValue($this->loginColumn);
100
    }
101
102
    /**
103
     * Retrun user's mail address.
104
     *
105
     * @return string
106
     */
107
    public function getUserEmail()
108
    {
109
        return $this->getDataValue($this->mailColumn);
110
    }
111
112
    /**
113
     * Vykreslí GrAvatara uživatele.
114
     */
115
    public function draw()
116
    {
117
        echo '<img class="avatar" src="'.$this->getIcon().'">';
118
    }
119
120
    /**
121
     * Vrací odkaz na url ikony.
122
     *
123
     * @return string url ikony
124
     */
125
    public function getIcon()
126
    {
127
        $email = $this->getUserEmail();
128
        if ($email) {
129
            return self::getGravatar($email, 800, 'mm', 'g', true,
0 ignored issues
show
Unused Code introduced by
The call to Ease\User::getGravatar() has too many arguments starting with true. ( Ignorable by Annotation )

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

129
            return self::/** @scrutinizer ignore-call */ getGravatar($email, 800, 'mm', 'g', true,

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
130
                    ['title' => $this->getUserName(), 'class' => 'gravatar_icon']);
131
        } else {
132
            return;
133
        }
134
    }
135
136
    /**
137
     * Pokusí se o přihlášení.
138
     * Try to Sign in.
139
     *
140
     * @param array $formData pole dat z přihlaš. formuláře např. $_REQUEST
141
     *
142
     * @return null|boolean
143
     */
144
    public function tryToLogin($formData)
145
    {
146
        if (!count($formData)) {
147
            return;
148
        }
149
        $login    = $formData[$this->loginColumn];
150
        $password = $formData[$this->passwordColumn];
151
        if (empty($login)) {
152
            $this->addStatusMessage(_('missing login'), 'error');
153
154
            return;
155
        }
156
        if (!$password) {
157
            $this->addStatusMessage(_('missing password'), 'error');
158
159
            return;
160
        }
161
        if ($this->authentize()) {
162
            $this->setObjectName();
163
        } else {
164
            $this->addStatusMessage(sprintf(_('user %s does not exist'), $login,
165
                    'error'));
166
167
            return false;
168
        }
169
    }
170
171
    /**
172
     * Try to authentize user 
173
     * 
174
     * @return boolean
175
     */
176
    public function authentize()
177
    {
178
        return false;
179
    }
180
181
    /**
182
     * Try to validate Password
183
     * 
184
     * @param string $password plaintext
185
     * 
186
     * @return boolean
187
     */
188
    public function validatePassword($password)
189
    {
190
        if ($this->passwordValidation($password,
191
                $this->getDataValue($this->passwordColumn))) {
192
            if ($this->isAccountEnabled()) {
193
                return $this->loginSuccess();
194
            } else {
195
                $this->userID = null;
196
197
                return false;
198
            }
199
        } else {
200
            $this->userID = null;
201
            if (count($this->getData())) {
202
                $this->addStatusMessage(_('invalid password'), 'error');
203
            }
204
            $this->dataReset();
205
206
            return false;
207
        }
208
    }
209
210
    /**
211
     * Je učet povolen ?
212
     *
213
     * @return bool
214
     */
215
    public function isAccountEnabled()
216
    {
217
        if (is_null($this->disableColumn)) {
0 ignored issues
show
introduced by
The condition is_null($this->disableColumn) is always false.
Loading history...
218
            return true;
219
        }
220
        if ($this->getDataValue($this->disableColumn)) {
221
            $this->addStatusMessage(_('Sign in denied by administrator'),
222
                'warning');
223
224
            return false;
225
        }
226
227
        return true;
228
    }
229
230
    /**
231
     * Akce provedené po úspěšném přihlášení
232
     * pokud tam jeste neexistuje zaznam, vytvori se novy.
233
     * 
234
     * @return boolean
235
     */
236
    public function loginSuccess()
237
    {
238
        $this->userID = (int) $this->getMyKey();
239
        $this->setUserLogin($this->getDataValue($this->loginColumn));
240
        $this->logged = true;
241
        $this->addStatusMessage(sprintf(_('Sign in %s all ok'), $this->userLogin),
242
            'success');
243
        $this->setObjectName();
244
        return true;
245
    }
246
247
    /**
248
     * Ověření hesla.
249
     *
250
     * @param string $plainPassword     heslo v nešifrované podobě
251
     * @param string $encryptedPassword šifrovné heslo
252
     *
253
     * @return bool
254
     */
255
    public static function passwordValidation($plainPassword, $encryptedPassword)
256
    {
257
        if ($plainPassword && $encryptedPassword) {
258
            $passwordStack = explode(':', $encryptedPassword);
259
            if (sizeof($passwordStack) != 2) {
260
                return false;
261
            }
262
            if (md5($passwordStack[1].$plainPassword) == $passwordStack[0]) {
263
                return true;
264
            }
265
        }
266
267
        return false;
268
    }
269
270
    /**
271
     * Zašifruje heslo.
272
     *
273
     * @param string $plainTextPassword nešifrované heslo (plaintext)
274
     *
275
     * @return string Encrypted password
276
     */
277
    public static function encryptPassword($plainTextPassword)
278
    {
279
        $encryptedPassword = '';
280
        for ($i = 0; $i < 10; ++$i) {
281
            $encryptedPassword .= $this->randomNumber();
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using $this inside a static method is generally not recommended and can lead to errors in newer PHP versions.
Loading history...
Bug introduced by
The method randomNumber() does not exist on Ease\User. ( Ignorable by Annotation )

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

281
            $encryptedPassword .= $this->/** @scrutinizer ignore-call */ randomNumber();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
282
        }
283
        $passwordSalt      = substr(md5($encryptedPassword), 0, 2);
284
        $encryptedPassword = md5($passwordSalt.$plainTextPassword).':'.$passwordSalt;
285
286
        return $encryptedPassword;
287
    }
288
289
    /**
290
     * Změní uživateli uložené heslo.
291
     *
292
     * @param string $newPassword nové heslo
293
     *
294
     * @return boolean success
295
     */
296
    public function passwordChange($newPassword)
0 ignored issues
show
Unused Code introduced by
The parameter $newPassword is not used and could be removed. ( Ignorable by Annotation )

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

296
    public function passwordChange(/** @scrutinizer ignore-unused */ $newPassword)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
297
    {
298
        return false;
299
    }
300
301
    /**
302
     * Vraci ID přihlášeného uživatele.
303
     *
304
     * @return int ID uživatele
305
     */
306
    public function getUserID()
307
    {
308
        return isset($this->userID) ? (int) $this->userID : (int) $this->getMyKey();
309
    }
310
311
    /**
312
     * Vrací login uživatele.
313
     *
314
     * @return string
315
     */
316
    public function getUserLogin()
317
    {
318
        return isset($this->userLogin) ? $this->userLogin : $this->getDataValue($this->loginColumn);
319
    }
320
321
    /**
322
     * Nastavuje login uživatele.
323
     *
324
     * @return string
325
     */
326
    public function setUserLogin($login)
327
    {
328
        $this->userLogin = $login;
329
        if (isset($this->loginColumn)) {
330
            return $this->setDataValue($this->loginColumn, $login);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->setDataVal...s->loginColumn, $login) returns the type boolean which is incompatible with the documented return type string.
Loading history...
331
        }
332
333
        return $this->userLogin;
334
    }
335
336
    /**
337
     * Vrací hodnotu uživatelského oprávnění.
338
     *
339
     * @param string $permKeyword klíčové slovo oprávnění
340
     *
341
     * @return mixed
342
     */
343
    public function getPermission($permKeyword = null)
344
    {
345
        if (isset($this->permissions[$permKeyword])) {
0 ignored issues
show
Bug Best Practice introduced by
The property permissions does not exist on Ease\User. Did you maybe forget to declare it?
Loading history...
346
            return $this->permissions[$permKeyword];
347
        } else {
348
            return;
349
        }
350
    }
351
352
    /**
353
     * Provede odhlášení uživatele.
354
     */
355
    public function logout()
356
    {
357
        $this->logged = false;
358
        $this->addStatusMessage(_('Sign Out successful'), 'success');
359
360
        return true;
361
    }
362
363
    /**
364
     * Vrací hodnotu nastavení.
365
     *
366
     * @param string $settingName jméno nastavení
367
     *
368
     * @return mixed
369
     */
370
    public function getSettingValue($settingName = null)
371
    {
372
        if (isset($this->settings[$settingName])) {
373
            return $this->settings[$settingName];
374
        } else {
375
            return;
376
        }
377
    }
378
379
    /**
380
     * Nastavuje nastavení.
381
     *
382
     * @param array $settings asociativní pole nastavení
383
     */
384
    public function setSettings($settings)
385
    {
386
        $this->settings = array_merge($this->settings, $settings);
387
    }
388
389
    /**
390
     * Nastaví položku nastavení.
391
     *
392
     * @param string $settingName  klíčové slovo pro nastavení
393
     * @param mixed  $settingValue hodnota nastavení
394
     */
395
    public function setSettingValue($settingName, $settingValue)
396
    {
397
        $this->settings[$settingName] = $settingValue;
398
    }
399
400
    /**
401
     * Načte oprávnění.
402
     *
403
     * @return mixed
404
     */
405
    public function loadPermissions()
406
    {
407
        return;
408
    }
409
410
    /**
411
     * Vrací jméno objektu uživatele.
412
     *
413
     * @return string
414
     */
415
    public function getName()
416
    {
417
        return $this->getObjectName();
418
    }
419
420
    /**
421
     * Get either a Gravatar URL or complete image tag for a specified email
422
     * address.
423
     *
424
     * @param string $email     The email address
425
     * @param integer $size      Size in pixels, defaults to 80px [ 1 - 512 ]
426
     * @param string $default   [ 404 | mm | identicon | monsterid | wavatar ]
427
     * @param string $maxRating Maximum rating (inclusive) [ g | pg | r | x ]
428
     *
429
     * @return string containing either just a URL or a complete image tag
430
     *
431
     * @source http://gravatar.com/site/implement/images/php/
432
     */
433
    public static function getGravatar(
434
        $email, $size = 80, $default = 'mm', $maxRating = 'g'
435
    )
436
    {
437
        $url = 'http://www.gravatar.com/avatar/';
438
        $url .= md5(strtolower(trim($email)));
439
        $url .= "?s=$size&d=$default&r=$maxRating";
440
441
        return $url;
442
    }
443
444
    /**
445
     * Nastavení jména objektu uživatele.
446
     *
447
     * @param string $objectName vynucené jméno objektu
448
     *
449
     * @return string
450
     */
451
    public function setObjectName($objectName = null)
452
    {
453
454
        if (empty($objectName) && isset($_SERVER['REMOTE_ADDR'])) {
455
            $name = parent::setObjectName(get_class($this).':'.$this->getUserName().'@'.self::remoteToIdentity());
456
        } else {
457
            $name = parent::setObjectName($objectName);
458
        }
459
        return $name;
460
    }
461
462
    /**
463
     * Common instance of User class
464
     * 
465
     * @return \Ease\User
466
     */
467
    public static function singleton()
468
    {
469
        if (!isset(self::$instance)) {
470
            self::$instance = new self();
0 ignored issues
show
Documentation Bug introduced by
It seems like new self() of type Ease\User is incompatible with the declared type Ease\Locale of property $instance.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
471
        }
472
        return self::$instance;
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::instance also could return the type Ease\Locale which is incompatible with the documented return type Ease\User.
Loading history...
473
    }
474
}
475