Passed
Pull Request — master (#5)
by Florian
02:22
created

FallbackPasswordHasher   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Test Coverage

Coverage 80%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 8
eloc 15
dl 0
loc 85
ccs 16
cts 20
cp 0.8
rs 10
c 1
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A addHasher() 0 3 1
A __construct() 0 7 2
A needsRehash() 0 5 1
A check() 0 12 3
A hash() 0 5 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
        $password = $this->saltPassword($password);
69
70 1
        return $this->hashers[0]->hash($password);
71
    }
72
73
    /**
74
     * Verifies that the provided password corresponds to its hashed version
75
     *
76
     * This will iterate over all configured hashers until one of them returns
77
     * true.
78
     *
79
     * @param string $password Plain text password to hash.
80
     * @param string $hashedPassword Existing hashed password.
81
     * @return bool True if hashes match else false.
82
     */
83 2
    public function check(string $password, string $hashedPassword): bool
84
    {
85 2
        $password = $this->saltPassword($password);
86
87
        /* @var $hasher \Phauthentic\PasswordHasher\PasswordHasherInterface */
88 2
        foreach ($this->hashers as $hasher) {
89 2
            if ($hasher->check($password, $hashedPassword)) {
90 2
                return true;
91
            }
92
        }
93
94
        return false;
95
    }
96
97
    /**
98
     * Returns true if the password need to be rehashed, with the first hasher present
99
     * in the list of hashers
100
     *
101
     * @param string $password The password to verify
102
     * @return bool
103
     */
104 1
    public function needsRehash(string $password): bool
105
    {
106 1
        $password = $this->saltPassword($password);
107
108 1
        return $this->hashers[0]->needsRehash($password);
109
    }
110
}
111