Completed
Push — master ( 5139b6...b16139 )
by Sebastian
02:13
created

Password   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 6
lcom 1
cbo 1
dl 0
loc 146
ccs 13
cts 13
cp 1
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A verify() 0 4 1
A hash() 0 5 1
A needsRehash() 0 8 2
A getInfo() 0 4 1
1
<?php
2
3
/**
4
 * Linna Framework.
5
 *
6
 * @author Sebastian Rapetti <[email protected]>
7
 * @copyright (c) 2017, 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
16
/**
17
 * Provide methods for manage password, this class use PHP password hashing function,
18
 * see php documentation for more information.
19
 * <a href="http://php.net/manual/en/book.password.php">http://php.net/manual/en/book.password.php</a>
20
 */
21
class Password
22
{
23
    use ClassOptionsTrait;
24
25
    /**
26
     * @var array An associative array containing options
27
     *
28
     * http://php.net/manual/en/password.constants.php
29
     */
30
    protected $options = [
31
            'cost' => 11,
32
            'algo' => PASSWORD_DEFAULT,
33
        ];
34
35
    /**
36
     * Class constructor.
37
     * <p><b>$options valid keys:</b></p>
38
     * <table class="parameter">
39
     * <thead>
40
     * <tr>
41
     * <th>Name</th>
42
     * <th>Default</th>
43
     * <th>Description</th>
44
     * </tr>
45
     * </thead>
46
     * <tbody>
47
     * <tr>
48
     * <td>cost</td>
49
     * <td>11</td>
50
     * <td>indicating key expansion rounds</td>
51
     * </tr>
52
     * <tr>
53
     * <td>algo</td>
54
     * <td>PASSWORD_DEFAULT</td>
55
     * <td>password algorithm denoting the algorithm to use when hashing the password</td>
56
     * </tr>
57
     * </tbody>
58
     * </table>
59
     * <p>For password algorithm constants see <a href="http://php.net/manual/en/password.constants.php">Password Constants</a>.</p>
60
     * <pre><code class="php">//Options passed to class constructor as ['key' => 'value'] array.
61
     * $password = new Password([
62
     *     'cost' => 11,
63
     *     'algo' => PASSWORD_DEFAULT,
64
     * ]);
65
     * </code></pre>
66
     *
67
     * @param array $options
68
     */
69 35
    public function __construct(array $options = [])
70
    {
71
        //set options
72 35
        $this->setOptions($options);
73 35
    }
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 9
    public function verify(string $password, string $hash): bool
91
    {
92 9
        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 11
    public function hash(string $password): string
111
    {
112
        //generate hash from password
113 11
        return password_hash($password, $this->options['algo'], $this->options);
114
    }
115
116
    /**
117
     * Checks if the given hash matches the algorithm and the options provided.
118
     * <pre><code class="php">$password = new Password();
119
     *
120
     * $hash = '$2y$11$cq3ZWO18l68X7pGs9Y1fveTGcNJ/iyehrDZ10BAvbY8LaBXNvnyk6';
121
     *
122
     * //true if rehash is needed, false if no
123
     * $rehashCheck = $password->needsRehash($hash);
124
     * </code></pre>
125
     *
126
     * @param string $hash
127
     *
128
     * @return bool
129
     */
130 2
    public function needsRehash(string $hash): bool
131
    {
132 2
        if (password_needs_rehash($hash, $this->options['algo'], $this->options)) {
133 1
            return true;
134
        }
135
136 1
        return false;
137
    }
138
139
    /**
140
     * Returns information about the given hash.
141
     * <pre><code class="php">$password = new Password();
142
     *
143
     * $hash = '$2y$11$cq3ZWO18l68X7pGs9Y1fveTGcNJ/iyehrDZ10BAvbY8LaBXNvnyk6';
144
     *
145
     * $info = $password->getInfo($hash);
146
     *
147
     * //var_dump result
148
     * //[
149
     * //    'algo' => 1,
150
     * //    'algoName' => 'bcrypt',
151
     * //    'options' => [
152
     * //        'cost' => int 11
153
     * //    ]
154
     * //]
155
     * var_dump($info);
156
     * </code></pre>
157
     *
158
     * @param string $hash
159
     *
160
     * @return array
161
     */
162 2
    public function getInfo(string $hash) : array
163
    {
164 2
        return password_get_info($hash);
165
    }
166
}
167