Passed
Push — master ( 5a8eeb...17aa29 )
by Alexander
01:33
created

PasswordHasher::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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