1: <?php
2: /**
3: * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
4: * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
5: *
6: * Licensed under The MIT License
7: * For full copyright and license information, please see the LICENSE.txt
8: * Redistributions of files must retain the above copyright notice.
9: *
10: * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
11: * @link https://cakephp.org CakePHP(tm) Project
12: * @since 3.0.0
13: * @license https://opensource.org/licenses/mit-license.php MIT License
14: */
15: namespace Cake\Auth;
16:
17: /**
18: * A password hasher that can use multiple different hashes where only
19: * one is the preferred one. This is useful when trying to migrate an
20: * existing database of users from one password type to another.
21: */
22: class FallbackPasswordHasher extends AbstractPasswordHasher
23: {
24:
25: /**
26: * Default config for this object.
27: *
28: * @var array
29: */
30: protected $_defaultConfig = [
31: 'hashers' => []
32: ];
33:
34: /**
35: * Holds the list of password hasher objects that will be used
36: *
37: * @var array
38: */
39: protected $_hashers = [];
40:
41: /**
42: * Constructor
43: *
44: * @param array $config configuration options for this object. Requires the
45: * `hashers` key to be present in the array with a list of other hashers to be
46: * used
47: */
48: public function __construct(array $config = [])
49: {
50: parent::__construct($config);
51: foreach ($this->_config['hashers'] as $key => $hasher) {
52: if (is_array($hasher) && !isset($hasher['className'])) {
53: $hasher['className'] = $key;
54: }
55: $this->_hashers[] = PasswordHasherFactory::build($hasher);
56: }
57: }
58:
59: /**
60: * Generates password hash.
61: *
62: * Uses the first password hasher in the list to generate the hash
63: *
64: * @param string $password Plain text password to hash.
65: * @return string Password hash
66: */
67: public function hash($password)
68: {
69: return $this->_hashers[0]->hash($password);
70: }
71:
72: /**
73: * Verifies that the provided password corresponds to its hashed version
74: *
75: * This will iterate over all configured hashers until one of them returns
76: * true.
77: *
78: * @param string $password Plain text password to hash.
79: * @param string $hashedPassword Existing hashed password.
80: * @return bool True if hashes match else false.
81: */
82: public function check($password, $hashedPassword)
83: {
84: foreach ($this->_hashers as $hasher) {
85: if ($hasher->check($password, $hashedPassword)) {
86: 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: public function needsRehash($password)
101: {
102: return $this->_hashers[0]->needsRehash($password);
103: }
104: }
105: