Completed
Push — b0.24.0 ( 127adf...72b353 )
by Sebastian
13:53 queued 06:30
created

Password::verify()   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
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
/**
4
 * Linna Framework.
5
 *
6
 * @author Sebastian Rapetti <[email protected]>
7
 * @copyright (c) 2018, Sebastian Rapetti
8
 * @license http://opensource.org/licenses/MIT MIT License
9
 */
10
declare(strict_types=1);
11
12
namespace Linna\Authentication;
13
14
use Linna\Shared\ClassOptionsTrait;
15
use UnexpectedValueException;
16
17
/**
18
 * Provide methods for manage password, this class use PHP password hashing function,
19
 * see php documentation for more information.
20
 * <a href="http://php.net/manual/en/book.password.php">http://php.net/manual/en/book.password.php</a>
21
 */
22
class Password
23
{
24
    use ClassOptionsTrait;
25
26
    /**
27
     * @var array An associative array containing options
28
     *
29
     * http://php.net/manual/en/password.constants.php
30
     */
31
    protected $options = [
32
        'cost' => 11,
33
        'algo' => PASSWORD_DEFAULT,
34
    ];
35
36
    /**
37
     * Class constructor.
38
     * <p><b>$options valid keys:</b></p>
39
     * <table class="parameter">
40
     * <thead>
41
     * <tr>
42
     * <th>Name</th>
43
     * <th>Default</th>
44
     * <th>Description</th>
45
     * </tr>
46
     * </thead>
47
     * <tbody>
48
     * <tr>
49
     * <td>cost</td>
50
     * <td>11</td>
51
     * <td>indicating key expansion rounds</td>
52
     * </tr>
53
     * <tr>
54
     * <td>algo</td>
55
     * <td>PASSWORD_DEFAULT</td>
56
     * <td>password algorithm denoting the algorithm to use when hashing the password</td>
57
     * </tr>
58
     * </tbody>
59
     * </table>
60
     * <p>For password algorithm constants see <a href="http://php.net/manual/en/password.constants.php">Password Constants</a>.</p>
61
     * <pre><code class="php">//Options passed to class constructor as ['key' => 'value'] array.
62
     * $password = new Password([
63
     *     'cost' => 11,
64
     *     'algo' => PASSWORD_DEFAULT,
65
     * ]);
66
     * </code></pre>
67
     *
68
     * @param array $options
69
     */
70 70
    public function __construct(array $options = [])
71
    {
72 70
        $this->setOptions($options);
73 70
    }
74
75
    /**
76
     * Verifies if a password matches an hash and return the result as boolean.
77
     * <pre><code class="php">$password = new Password();
78
     *
79
     * $storedHash = '$2y$11$cq3ZWO18l68X7pGs9Y1fveTGcNJ/iyehrDZ10BAvbY8LaBXNvnyk6';
80
     * $password = 'FooPassword';
81
     *
82
     * $verified = $password->verify($password, $storedHash);
83
     * </code></pre>
84
     *
85
     * @param string $password
86
     * @param string $hash
87
     *
88
     * @return bool True if password match, false if not.
89
     */
90 44
    public function verify(string $password, string $hash): bool
91
    {
92 44
        return password_verify($password, $hash);
93
    }
94
95
    /**
96
     * Create password hash from the given string and return it.
97
     * <pre><code class="php">$password = new Password();
98
     *
99
     * $hash = $password->hash('FooPassword');
100
     *
101
     * //var_dump result
102
     * //$2y$11$cq3ZWO18l68X7pGs9Y1fveTGcNJ/iyehrDZ10BAvbY8LaBXNvnyk6
103
     * var_dump($hash)
104
     * </code></pre>
105
     *
106
     * @param string $password
107
     *
108
     * @return string
109
     */
110 21
    public function hash(string $password): string
111
    {
112 21
        $hash = password_hash($password, $this->options['algo'], $this->options);
113
114 21
        if ($hash === false) {
115
            throw new UnexpectedValueException('Password hashing fails.');
116
        }
117
118 21
        return $hash;
119
    }
120
121
    /**
122
     * Checks if the given hash matches the algorithm and the options provided.
123
     * <pre><code class="php">$password = new Password();
124
     *
125
     * $hash = '$2y$11$cq3ZWO18l68X7pGs9Y1fveTGcNJ/iyehrDZ10BAvbY8LaBXNvnyk6';
126
     *
127
     * //true if rehash is needed, false if no
128
     * $rehashCheck = $password->needsRehash($hash);
129
     * </code></pre>
130
     *
131
     * @param string $hash
132
     *
133
     * @return bool
134
     */
135 2
    public function needsRehash(string $hash): bool
136
    {
137 2
        return password_needs_rehash($hash, $this->options['algo'], $this->options);
138
    }
139
140
    /**
141
     * Returns information about the given hash.
142
     * <pre><code class="php">$password = new Password();
143
     *
144
     * $hash = '$2y$11$cq3ZWO18l68X7pGs9Y1fveTGcNJ/iyehrDZ10BAvbY8LaBXNvnyk6';
145
     *
146
     * $info = $password->getInfo($hash);
147
     *
148
     * //var_dump result
149
     * //[
150
     * //    'algo' => 1,
151
     * //    'algoName' => 'bcrypt',
152
     * //    'options' => [
153
     * //        'cost' => int 11
154
     * //    ]
155
     * //]
156
     * var_dump($info);
157
     * </code></pre>
158
     *
159
     * @param string $hash
160
     *
161
     * @return array
162
     */
163 2
    public function getInfo(string $hash): array
164
    {
165 2
        return password_get_info($hash);
166
    }
167
}
168