Passed
Pull Request — master (#5)
by Florian
03:11
created

FallbackPasswordHasher::hash()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
c 1
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
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
 */
0 ignored issues
show
Coding Style introduced by
Header blocks must be separated by a single blank line
Loading history...
15
16
17
declare(strict_types=1);
18
19
namespace Phauthentic\PasswordHasher;
20
21
use RuntimeException;
22
23
/**
24
 * A password hasher that can use multiple different hashes where only
25
 * one is the preferred one. This is useful when trying to migrate an
26
 * existing database of users from one password type to another.
27
 */
28
class FallbackPasswordHasher extends AbstractPasswordHasher
29
{
30
    /**
31
     * Holds the list of password hasher objects that will be used
32
     *
33
     * @var \Phauthentic\PasswordHasher\PasswordHasherCollectionInterface
34
     */
35
    protected $hashers;
36
37
    /**
38
     * Constructor
39
     *
40
     * @param \Phauthentic\PasswordHasher\PasswordHasherCollectionInterface $hasherCollection Hasher Collection
41
     */
42 10
    public function __construct(PasswordHasherCollectionInterface $hasherCollection)
43
    {
44 10
        if ($hasherCollection->count() === 0) {
45 2
            throw new RuntimeException('Your password hasher collection is empty. It must contain at least one hasher.');
46
        }
47
48 8
        $this->hashers = $hasherCollection;
49 8
    }
50
51
    /**
52
     * Adds a hasher
53
     *
54
     * @param PasswordHasherInterface $hasher Hasher instance.
55
     * @return void
56
     */
57
    public function addHasher(PasswordHasherInterface $hasher): void
58
    {
59
        $this->hashers->add($hasher);
60
    }
61
62
    /**
63
     * Generates password hash.
64
     *
65
     * Uses the first password hasher in the list to generate the hash
66
     *
67
     * @param string $password Plain text password to hash.
68
     * @return string Password hash
69
     */
70 2
    public function hash(string $password): string
71
    {
72 2
        $password = $this->saltPassword($password);
73
74 2
        return $this->hashers[0]->hash($password);
75
    }
76
77
    /**
78
     * Verifies that the provided password corresponds to its hashed version
79
     *
80
     * This will iterate over all configured hashers until one of them returns
81
     * true.
82
     *
83
     * @param string $password Plain text password to hash.
84
     * @param string $hashedPassword Existing hashed password.
85
     * @return bool True if hashes match else false.
86
     */
87 4
    public function check(string $password, string $hashedPassword): bool
88
    {
89 4
        $password = $this->saltPassword($password);
90
91
        /* @var $hasher \Phauthentic\PasswordHasher\PasswordHasherInterface */
92 4
        foreach ($this->hashers as $hasher) {
93 4
            if ($hasher->check($password, $hashedPassword)) {
94 4
                return true;
95
            }
96
        }
97
98
        return false;
99
    }
100
101
    /**
102
     * Returns true if the password need to be rehashed, with the first hasher present
103
     * in the list of hashers
104
     *
105
     * @param string $password The password to verify
106
     * @return bool
107
     */
108 2
    public function needsRehash(string $password): bool
109
    {
110 2
        $password = $this->saltPassword($password);
111
112 2
        return $this->hashers[0]->needsRehash($password);
113
    }
114
}
115