Passed
Pull Request — master (#2)
by Florian
03:36
created

FallbackPasswordHasher::needsRehash()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
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 5
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
declare(strict_types=1);
3
/**
4
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
5
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
6
 *
7
 * Licensed under The MIT License
8
 * For full copyright and license information, please see the LICENSE.txt
9
 * Redistributions of files must retain the above copyright notice.
10
 *
11
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
12
 * @link          http://cakephp.org CakePHP(tm) Project
13
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
14
 */
15
namespace Phauthentic\PasswordHasher;
16
17
use RuntimeException;
18
19
/**
20
 * A password hasher that can use multiple different hashes where only
21
 * one is the preferred one. This is useful when trying to migrate an
22
 * existing database of users from one password type to another.
23
 */
24
class FallbackPasswordHasher extends AbstractPasswordHasher
25
{
26
    /**
27
     * Holds the list of password hasher objects that will be used
28
     *
29
     * @var \Phauthentic\PasswordHasher\PasswordHasherCollectionInterface
30
     */
31
    protected $hashers;
32
33
    /**
34
     * Constructor
35
     *
36
     * @param \Phauthentic\PasswordHasher\PasswordHasherCollectionInterface $hasherCollection Hasher Collection
37
     */
38 5
    public function __construct(PasswordHasherCollectionInterface $hasherCollection)
39
    {
40 5
        if ($hasherCollection->count() === 0) {
41 1
            throw new RuntimeException('Your password hasher collection is empty. It must contain at least one hasher.');
42
        }
43
44 4
        $this->hashers = $hasherCollection;
45 4
    }
46
47
    /**
48
     * Adds a hasher
49
     *
50
     * @param PasswordHasherInterface $hasher Hasher instance.
51
     * @return void
52
     */
53
    public function addHasher(PasswordHasherInterface $hasher): void
54
    {
55
        $this->hashers->add($hasher);
56
    }
57
58
    /**
59
     * Generates password hash.
60
     *
61
     * Uses the first password hasher in the list to generate the hash
62
     *
63
     * @param string $password Plain text password to hash.
64
     * @return string Password hash
65
     */
66 1
    public function hash(string $password): string
67
    {
68 1
        return $this->hashers[0]->hash($password);
69
    }
70
71
    /**
72
     * Verifies that the provided password corresponds to its hashed version
73
     *
74
     * This will iterate over all configured hashers until one of them returns
75
     * true.
76
     *
77
     * @param string $password Plain text password to hash.
78
     * @param string $hashedPassword Existing hashed password.
79
     * @return bool True if hashes match else false.
80
     */
81 2
    public function check(string $password, string $hashedPassword): bool
82
    {
83
        /* @var $hasher \Phauthentic\PasswordHasher\PasswordHasherInterface */
84 2
        foreach ($this->hashers as $hasher) {
85 2
            if ($hasher->check($password, $hashedPassword)) {
86 2
                return true;
87
            }
88
        }
89
90
        return false;
91
    }
92
93
    /**
94
     * Returns true if the password need to be rehashed, with the first hasher present
95
     * in the list of hashers
96
     *
97
     * @param string $password The password to verify
98
     * @return bool
99
     */
100 1
    public function needsRehash(string $password): bool
101
    {
102
103
104 1
        return $this->hashers[0]->needsRehash($password);
105
    }
106
}
107