Passed
Push — master ( bdfe7b...8f2aab )
by Alexander
01:12
created

PasswordHasher::validate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
nc 2
nop 2
dl 0
loc 7
rs 10
c 1
b 0
f 0
ccs 4
cts 4
cp 1
crap 2
1
<?php declare(strict_types=1);
2
3
namespace Yiisoft\Security;
4
5
/**
6
 * PasswordHasher allows generating password hash and verifying passwords against a hash.
7
 */
8
class PasswordHasher
9
{
10
    private $algorithm;
11
    private $parameters;
12
13
    private const SAFE_PARAMETERS = [
14
        PASSWORD_BCRYPT => [
15
            'cost' => 13,
16
        ],
17
    ];
18
19
    /**
20
     * @see https://www.php.net/manual/en/function.password-hash.php
21
     * @param int|string $algorithm
22
     * @param array|null $parameters
23
     */
24 3
    public function __construct($algorithm = PASSWORD_DEFAULT, array $parameters = null)
25
    {
26 3
        $this->algorithm = $algorithm;
27
28 3
        if ($parameters === null) {
29 2
            $parameters = self::SAFE_PARAMETERS[$algorithm] ?? null;
30
        }
31 3
        $this->parameters = $parameters;
32 3
    }
33
34
35
    /**
36
     * Generates a secure hash from a password and a random salt.
37
     *
38
     * The generated hash can be stored in database.
39
     * Later when a password needs to be validated, the hash can be fetched and passed
40
     * to {@see validate()}. For example,
41
     *
42
     * ```php
43
     * // generates the hash (usually done during user registration or when the password is changed)
44
     * $hash = (new PasswordHasher())->hash($password);
45
     * // ...save $hash in database...
46
     *
47
     * // during login, validate if the password entered is correct using $hash fetched from database
48
     * if ((new PasswordHasher())->validate($password, $hash)) {
49
     *     // password is good
50
     * } else {
51
     *     // password is bad
52
     * }
53
     * ```
54
     *
55
     * @param string $password The password to be hashed.
56
     * @return string The password hash string. The output length might increase
57
     * in future versions of PHP (http://php.net/manual/en/function.password-hash.php)
58
     * @see validate()
59
     */
60 1
    public function hash(string $password): string
61
    {
62 1
        return password_hash($password, $this->algorithm, $this->parameters);
0 ignored issues
show
Bug introduced by
It seems like $this->algorithm can also be of type string; however, parameter $algo of password_hash() does only seem to accept integer, 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

62
        return password_hash($password, /** @scrutinizer ignore-type */ $this->algorithm, $this->parameters);
Loading history...
63
    }
64
65
    /**
66
     * Verifies a password against a hash.
67
     * @param string $password The password to verify.
68
     * @param string $hash The hash to verify the password against.
69
     * @return bool whether the password is correct.
70
     * @throws \InvalidArgumentException on bad password/hash parameters or if crypt() with Blowfish hash is not
71
     * available.
72
     * @see hash()
73
     */
74 2
    public function validate(string $password, string $hash): bool
75
    {
76 2
        if ($password === '') {
77 1
            throw new \InvalidArgumentException('Password must be a string and cannot be empty.');
78
        }
79
80 1
        return password_verify($password, $hash);
81
    }
82
}
83